Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.9 149 lines 3.9 kB view raw
1/* 2 * GPIO driver for TI TPS65912x PMICs 3 * 4 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ 5 * Andrew F. Davis <afd@ti.com> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 12 * kind, whether expressed or implied; without even the implied warranty 13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License version 2 for more details. 15 * 16 * Based on the Arizona GPIO driver and the previous TPS65912 driver by 17 * Margarita Olaya Cabrera <magi@slimlogic.co.uk> 18 */ 19 20#include <linux/gpio.h> 21#include <linux/module.h> 22#include <linux/platform_device.h> 23 24#include <linux/mfd/tps65912.h> 25 26struct tps65912_gpio { 27 struct gpio_chip gpio_chip; 28 struct tps65912 *tps; 29}; 30 31static int tps65912_gpio_get_direction(struct gpio_chip *gc, 32 unsigned offset) 33{ 34 struct tps65912_gpio *gpio = gpiochip_get_data(gc); 35 36 int ret, val; 37 38 ret = regmap_read(gpio->tps->regmap, TPS65912_GPIO1 + offset, &val); 39 if (ret) 40 return ret; 41 42 if (val & GPIO_CFG_MASK) 43 return GPIOF_DIR_OUT; 44 else 45 return GPIOF_DIR_IN; 46} 47 48static int tps65912_gpio_direction_input(struct gpio_chip *gc, unsigned offset) 49{ 50 struct tps65912_gpio *gpio = gpiochip_get_data(gc); 51 52 return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset, 53 GPIO_CFG_MASK, 0); 54} 55 56static int tps65912_gpio_direction_output(struct gpio_chip *gc, 57 unsigned offset, int value) 58{ 59 struct tps65912_gpio *gpio = gpiochip_get_data(gc); 60 61 /* Set the initial value */ 62 regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset, 63 GPIO_SET_MASK, value ? GPIO_SET_MASK : 0); 64 65 return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset, 66 GPIO_CFG_MASK, GPIO_CFG_MASK); 67} 68 69static int tps65912_gpio_get(struct gpio_chip *gc, unsigned offset) 70{ 71 struct tps65912_gpio *gpio = gpiochip_get_data(gc); 72 int ret, val; 73 74 ret = regmap_read(gpio->tps->regmap, TPS65912_GPIO1 + offset, &val); 75 if (ret) 76 return ret; 77 78 if (val & GPIO_STS_MASK) 79 return 1; 80 81 return 0; 82} 83 84static void tps65912_gpio_set(struct gpio_chip *gc, unsigned offset, 85 int value) 86{ 87 struct tps65912_gpio *gpio = gpiochip_get_data(gc); 88 89 regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset, 90 GPIO_SET_MASK, value ? GPIO_SET_MASK : 0); 91} 92 93static const struct gpio_chip template_chip = { 94 .label = "tps65912-gpio", 95 .owner = THIS_MODULE, 96 .get_direction = tps65912_gpio_get_direction, 97 .direction_input = tps65912_gpio_direction_input, 98 .direction_output = tps65912_gpio_direction_output, 99 .get = tps65912_gpio_get, 100 .set = tps65912_gpio_set, 101 .base = -1, 102 .ngpio = 5, 103 .can_sleep = true, 104}; 105 106static int tps65912_gpio_probe(struct platform_device *pdev) 107{ 108 struct tps65912 *tps = dev_get_drvdata(pdev->dev.parent); 109 struct tps65912_gpio *gpio; 110 int ret; 111 112 gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); 113 if (!gpio) 114 return -ENOMEM; 115 116 gpio->tps = dev_get_drvdata(pdev->dev.parent); 117 gpio->gpio_chip = template_chip; 118 gpio->gpio_chip.parent = tps->dev; 119 120 ret = devm_gpiochip_add_data(&pdev->dev, &gpio->gpio_chip, 121 gpio); 122 if (ret < 0) { 123 dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); 124 return ret; 125 } 126 127 platform_set_drvdata(pdev, gpio); 128 129 return 0; 130} 131 132static const struct platform_device_id tps65912_gpio_id_table[] = { 133 { "tps65912-gpio", }, 134 { /* sentinel */ } 135}; 136MODULE_DEVICE_TABLE(platform, tps65912_gpio_id_table); 137 138static struct platform_driver tps65912_gpio_driver = { 139 .driver = { 140 .name = "tps65912-gpio", 141 }, 142 .probe = tps65912_gpio_probe, 143 .id_table = tps65912_gpio_id_table, 144}; 145module_platform_driver(tps65912_gpio_driver); 146 147MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>"); 148MODULE_DESCRIPTION("TPS65912 GPIO driver"); 149MODULE_LICENSE("GPL v2");