1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * TI TPS6591x GPIO driver 4 * 5 * Copyright 2010 Texas Instruments Inc. 6 * 7 * Author: Graeme Gregory <gg@slimlogic.co.uk> 8 * Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk> 9 */ 10 11 #include <linux/kernel.h> 12 #include <linux/init.h> 13 #include <linux/errno.h> 14 #include <linux/gpio/driver.h> 15 #include <linux/i2c.h> 16 #include <linux/platform_device.h> 17 #include <linux/mfd/tps65910.h> 18 #include <linux/of.h> 19 20 struct tps65910_gpio { 21 struct gpio_chip gpio_chip; 22 struct tps65910 *tps65910; 23 }; 24 25 static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset) 26 { 27 struct tps65910_gpio *tps65910_gpio = gpiochip_get_data(gc); 28 struct tps65910 *tps65910 = tps65910_gpio->tps65910; 29 unsigned int val; 30 31 regmap_read(tps65910->regmap, TPS65910_GPIO0 + offset, &val); 32 33 if (val & GPIO_STS_MASK) 34 return 1; 35 36 return 0; 37 } 38 39 static int tps65910_gpio_set(struct gpio_chip *gc, unsigned int offset, 40 int value) 41 { 42 struct tps65910_gpio *tps65910_gpio = gpiochip_get_data(gc); 43 struct tps65910 *tps65910 = tps65910_gpio->tps65910; 44 45 if (value) 46 return regmap_set_bits(tps65910->regmap, 47 TPS65910_GPIO0 + offset, GPIO_SET_MASK); 48 49 return regmap_clear_bits(tps65910->regmap, TPS65910_GPIO0 + offset, 50 GPIO_SET_MASK); 51 } 52 53 static int tps65910_gpio_output(struct gpio_chip *gc, unsigned offset, 54 int value) 55 { 56 struct tps65910_gpio *tps65910_gpio = gpiochip_get_data(gc); 57 struct tps65910 *tps65910 = tps65910_gpio->tps65910; 58 int ret; 59 60 /* Set the initial value */ 61 ret = tps65910_gpio_set(gc, offset, value); 62 if (ret) 63 return ret; 64 65 return regmap_set_bits(tps65910->regmap, TPS65910_GPIO0 + offset, 66 GPIO_CFG_MASK); 67 } 68 69 static int tps65910_gpio_input(struct gpio_chip *gc, unsigned offset) 70 { 71 struct tps65910_gpio *tps65910_gpio = gpiochip_get_data(gc); 72 struct tps65910 *tps65910 = tps65910_gpio->tps65910; 73 74 return regmap_clear_bits(tps65910->regmap, TPS65910_GPIO0 + offset, 75 GPIO_CFG_MASK); 76 } 77 78 #ifdef CONFIG_OF 79 static struct tps65910_board *tps65910_parse_dt_for_gpio(struct device *dev, 80 struct tps65910 *tps65910, int chip_ngpio) 81 { 82 struct tps65910_board *tps65910_board = tps65910->of_plat_data; 83 unsigned int prop_array[TPS6591X_MAX_NUM_GPIO]; 84 int ngpio = min(chip_ngpio, TPS6591X_MAX_NUM_GPIO); 85 int ret; 86 int idx; 87 88 tps65910_board->gpio_base = -1; 89 ret = of_property_read_u32_array(tps65910->dev->of_node, 90 "ti,en-gpio-sleep", prop_array, ngpio); 91 if (ret < 0) { 92 dev_dbg(dev, "ti,en-gpio-sleep not specified\n"); 93 return tps65910_board; 94 } 95 96 for (idx = 0; idx < ngpio; idx++) 97 tps65910_board->en_gpio_sleep[idx] = (prop_array[idx] != 0); 98 99 return tps65910_board; 100 } 101 #else 102 static struct tps65910_board *tps65910_parse_dt_for_gpio(struct device *dev, 103 struct tps65910 *tps65910, int chip_ngpio) 104 { 105 return NULL; 106 } 107 #endif 108 109 static int tps65910_gpio_probe(struct platform_device *pdev) 110 { 111 struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); 112 struct tps65910_board *pdata = dev_get_platdata(tps65910->dev); 113 struct tps65910_gpio *tps65910_gpio; 114 int ret; 115 int i; 116 117 device_set_node(&pdev->dev, dev_fwnode(pdev->dev.parent)); 118 119 tps65910_gpio = devm_kzalloc(&pdev->dev, 120 sizeof(*tps65910_gpio), GFP_KERNEL); 121 if (!tps65910_gpio) 122 return -ENOMEM; 123 124 tps65910_gpio->tps65910 = tps65910; 125 126 tps65910_gpio->gpio_chip.owner = THIS_MODULE; 127 tps65910_gpio->gpio_chip.label = tps65910->i2c_client->name; 128 129 switch (tps65910_chip_id(tps65910)) { 130 case TPS65910: 131 tps65910_gpio->gpio_chip.ngpio = TPS65910_NUM_GPIO; 132 break; 133 case TPS65911: 134 tps65910_gpio->gpio_chip.ngpio = TPS65911_NUM_GPIO; 135 break; 136 default: 137 return -EINVAL; 138 } 139 tps65910_gpio->gpio_chip.can_sleep = true; 140 tps65910_gpio->gpio_chip.direction_input = tps65910_gpio_input; 141 tps65910_gpio->gpio_chip.direction_output = tps65910_gpio_output; 142 tps65910_gpio->gpio_chip.set = tps65910_gpio_set; 143 tps65910_gpio->gpio_chip.get = tps65910_gpio_get; 144 tps65910_gpio->gpio_chip.parent = &pdev->dev; 145 146 if (pdata && pdata->gpio_base) 147 tps65910_gpio->gpio_chip.base = pdata->gpio_base; 148 else 149 tps65910_gpio->gpio_chip.base = -1; 150 151 if (!pdata && tps65910->dev->of_node) 152 pdata = tps65910_parse_dt_for_gpio(&pdev->dev, tps65910, 153 tps65910_gpio->gpio_chip.ngpio); 154 155 if (!pdata) 156 goto skip_init; 157 158 /* Configure sleep control for gpios if provided */ 159 for (i = 0; i < tps65910_gpio->gpio_chip.ngpio; ++i) { 160 if (!pdata->en_gpio_sleep[i]) 161 continue; 162 163 ret = regmap_set_bits(tps65910->regmap, 164 TPS65910_GPIO0 + i, GPIO_SLEEP_MASK); 165 if (ret < 0) 166 dev_warn(tps65910->dev, 167 "GPIO Sleep setting failed with err %d\n", ret); 168 } 169 170 skip_init: 171 return devm_gpiochip_add_data(&pdev->dev, &tps65910_gpio->gpio_chip, 172 tps65910_gpio); 173 } 174 175 static struct platform_driver tps65910_gpio_driver = { 176 .driver.name = "tps65910-gpio", 177 .probe = tps65910_gpio_probe, 178 }; 179 180 static int __init tps65910_gpio_init(void) 181 { 182 return platform_driver_register(&tps65910_gpio_driver); 183 } 184 subsys_initcall(tps65910_gpio_init); 185