1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright 2015 Verifone Int. 4 * 5 * Author: Nicolas Saenz Julienne <nicolassaenzj@gmail.com> 6 * 7 * This driver is based on the gpio-tps65912 implementation. 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/module.h> 12 #include <linux/errno.h> 13 #include <linux/gpio/driver.h> 14 #include <linux/platform_device.h> 15 #include <linux/regmap.h> 16 #include <linux/mfd/tps65218.h> 17 18 struct tps65218_gpio { 19 struct tps65218 *tps65218; 20 struct gpio_chip gpio_chip; 21 }; 22 23 static int tps65218_gpio_get(struct gpio_chip *gc, unsigned offset) 24 { 25 struct tps65218_gpio *tps65218_gpio = gpiochip_get_data(gc); 26 struct tps65218 *tps65218 = tps65218_gpio->tps65218; 27 unsigned int val; 28 int ret; 29 30 ret = regmap_read(tps65218->regmap, TPS65218_REG_ENABLE2, &val); 31 if (ret) 32 return ret; 33 34 return !!(val & (TPS65218_ENABLE2_GPIO1 << offset)); 35 } 36 37 static int tps65218_gpio_set(struct gpio_chip *gc, unsigned int offset, 38 int value) 39 { 40 struct tps65218_gpio *tps65218_gpio = gpiochip_get_data(gc); 41 struct tps65218 *tps65218 = tps65218_gpio->tps65218; 42 43 if (value) 44 return tps65218_set_bits(tps65218, TPS65218_REG_ENABLE2, 45 TPS65218_ENABLE2_GPIO1 << offset, 46 TPS65218_ENABLE2_GPIO1 << offset, 47 TPS65218_PROTECT_L1); 48 49 return tps65218_clear_bits(tps65218, TPS65218_REG_ENABLE2, 50 TPS65218_ENABLE2_GPIO1 << offset, 51 TPS65218_PROTECT_L1); 52 } 53 54 static int tps65218_gpio_output(struct gpio_chip *gc, unsigned offset, 55 int value) 56 { 57 /* Only drives GPOs */ 58 return tps65218_gpio_set(gc, offset, value); 59 } 60 61 static int tps65218_gpio_request(struct gpio_chip *gc, unsigned offset) 62 { 63 struct tps65218_gpio *tps65218_gpio = gpiochip_get_data(gc); 64 struct tps65218 *tps65218 = tps65218_gpio->tps65218; 65 int ret; 66 67 if (gpiochip_line_is_open_source(gc, offset)) { 68 dev_err(gc->parent, "can't work as open source\n"); 69 return -EINVAL; 70 } 71 72 switch (offset) { 73 case 0: 74 if (!gpiochip_line_is_open_drain(gc, offset)) { 75 dev_err(gc->parent, "GPO1 works only as open drain\n"); 76 return -EINVAL; 77 } 78 79 /* Disable sequencer for GPO1 */ 80 ret = tps65218_clear_bits(tps65218, TPS65218_REG_SEQ7, 81 TPS65218_SEQ7_GPO1_SEQ_MASK, 82 TPS65218_PROTECT_L1); 83 if (ret) 84 return ret; 85 86 /* Setup GPO1 */ 87 ret = tps65218_clear_bits(tps65218, TPS65218_REG_CONFIG1, 88 TPS65218_CONFIG1_IO1_SEL, 89 TPS65218_PROTECT_L1); 90 if (ret) 91 return ret; 92 93 break; 94 case 1: 95 /* Setup GPO2 */ 96 ret = tps65218_clear_bits(tps65218, TPS65218_REG_CONFIG1, 97 TPS65218_CONFIG1_IO1_SEL, 98 TPS65218_PROTECT_L1); 99 if (ret) 100 return ret; 101 102 break; 103 104 case 2: 105 if (!gpiochip_line_is_open_drain(gc, offset)) { 106 dev_err(gc->parent, "GPO3 works only as open drain\n"); 107 return -EINVAL; 108 } 109 110 /* Disable sequencer for GPO3 */ 111 ret = tps65218_clear_bits(tps65218, TPS65218_REG_SEQ7, 112 TPS65218_SEQ7_GPO3_SEQ_MASK, 113 TPS65218_PROTECT_L1); 114 if (ret) 115 return ret; 116 117 /* Setup GPO3 */ 118 ret = tps65218_clear_bits(tps65218, TPS65218_REG_CONFIG2, 119 TPS65218_CONFIG2_DC12_RST, 120 TPS65218_PROTECT_L1); 121 if (ret) 122 return ret; 123 124 break; 125 default: 126 return -EINVAL; 127 } 128 129 return 0; 130 } 131 132 static int tps65218_gpio_set_config(struct gpio_chip *gc, unsigned offset, 133 unsigned long config) 134 { 135 struct tps65218_gpio *tps65218_gpio = gpiochip_get_data(gc); 136 struct tps65218 *tps65218 = tps65218_gpio->tps65218; 137 enum pin_config_param param = pinconf_to_config_param(config); 138 139 switch (offset) { 140 case 0: 141 case 2: 142 /* GPO1 is hardwired to be open drain */ 143 if (param == PIN_CONFIG_DRIVE_OPEN_DRAIN) 144 return 0; 145 return -ENOTSUPP; 146 case 1: 147 /* GPO2 is push-pull by default, can be set as open drain. */ 148 if (param == PIN_CONFIG_DRIVE_OPEN_DRAIN) 149 return tps65218_clear_bits(tps65218, 150 TPS65218_REG_CONFIG1, 151 TPS65218_CONFIG1_GPO2_BUF, 152 TPS65218_PROTECT_L1); 153 if (param == PIN_CONFIG_DRIVE_PUSH_PULL) 154 return tps65218_set_bits(tps65218, 155 TPS65218_REG_CONFIG1, 156 TPS65218_CONFIG1_GPO2_BUF, 157 TPS65218_CONFIG1_GPO2_BUF, 158 TPS65218_PROTECT_L1); 159 return -ENOTSUPP; 160 default: 161 break; 162 } 163 return -ENOTSUPP; 164 } 165 166 static const struct gpio_chip template_chip = { 167 .label = "gpio-tps65218", 168 .owner = THIS_MODULE, 169 .request = tps65218_gpio_request, 170 .direction_output = tps65218_gpio_output, 171 .get = tps65218_gpio_get, 172 .set = tps65218_gpio_set, 173 .set_config = tps65218_gpio_set_config, 174 .can_sleep = true, 175 .ngpio = 3, 176 .base = -1, 177 }; 178 179 static int tps65218_gpio_probe(struct platform_device *pdev) 180 { 181 struct tps65218 *tps65218 = dev_get_drvdata(pdev->dev.parent); 182 struct tps65218_gpio *tps65218_gpio; 183 184 tps65218_gpio = devm_kzalloc(&pdev->dev, sizeof(*tps65218_gpio), 185 GFP_KERNEL); 186 if (!tps65218_gpio) 187 return -ENOMEM; 188 189 tps65218_gpio->tps65218 = tps65218; 190 tps65218_gpio->gpio_chip = template_chip; 191 tps65218_gpio->gpio_chip.parent = &pdev->dev; 192 193 return devm_gpiochip_add_data(&pdev->dev, &tps65218_gpio->gpio_chip, 194 tps65218_gpio); 195 } 196 197 static const struct of_device_id tps65218_dt_match[] = { 198 { .compatible = "ti,tps65218-gpio" }, 199 { } 200 }; 201 MODULE_DEVICE_TABLE(of, tps65218_dt_match); 202 203 static const struct platform_device_id tps65218_gpio_id_table[] = { 204 { "tps65218-gpio", }, 205 { /* sentinel */ } 206 }; 207 MODULE_DEVICE_TABLE(platform, tps65218_gpio_id_table); 208 209 static struct platform_driver tps65218_gpio_driver = { 210 .driver = { 211 .name = "tps65218-gpio", 212 .of_match_table = tps65218_dt_match, 213 }, 214 .probe = tps65218_gpio_probe, 215 .id_table = tps65218_gpio_id_table, 216 }; 217 218 module_platform_driver(tps65218_gpio_driver); 219 220 MODULE_AUTHOR("Nicolas Saenz Julienne <nicolassaenzj@gmail.com>"); 221 MODULE_DESCRIPTION("GPO interface for TPS65218 PMICs"); 222 MODULE_LICENSE("GPL v2"); 223