1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Dialog DA9062 pinctrl and GPIO driver. 4 * Based on DA9055 GPIO driver. 5 * 6 * TODO: 7 * - add pinmux and pinctrl support (gpio alternate mode) 8 * 9 * Documents: 10 * [1] https://www.dialog-semiconductor.com/sites/default/files/da9062_datasheet_3v6.pdf 11 * 12 * Copyright (C) 2019 Pengutronix, Marco Felsch <kernel@pengutronix.de> 13 */ 14 #include <linux/bits.h> 15 #include <linux/module.h> 16 #include <linux/platform_device.h> 17 #include <linux/property.h> 18 #include <linux/regmap.h> 19 20 #include <linux/gpio/consumer.h> 21 #include <linux/gpio/driver.h> 22 23 #include <linux/mfd/da9062/core.h> 24 #include <linux/mfd/da9062/registers.h> 25 26 #define DA9062_TYPE(offset) (4 * (offset % 2)) 27 #define DA9062_PIN_SHIFT(offset) (4 * (offset % 2)) 28 #define DA9062_PIN_ALTERNATE 0x00 /* gpio alternate mode */ 29 #define DA9062_PIN_GPI 0x01 /* gpio in */ 30 #define DA9062_PIN_GPO_OD 0x02 /* gpio out open-drain */ 31 #define DA9062_PIN_GPO_PP 0x03 /* gpio out push-pull */ 32 #define DA9062_GPIO_NUM 5 33 34 struct da9062_pctl { 35 struct da9062 *da9062; 36 struct gpio_chip gc; 37 unsigned int pin_config[DA9062_GPIO_NUM]; 38 }; 39 40 static int da9062_pctl_get_pin_mode(struct da9062_pctl *pctl, 41 unsigned int offset) 42 { 43 struct regmap *regmap = pctl->da9062->regmap; 44 int ret, val; 45 46 ret = regmap_read(regmap, DA9062AA_GPIO_0_1 + (offset >> 1), &val); 47 if (ret < 0) 48 return ret; 49 50 val >>= DA9062_PIN_SHIFT(offset); 51 val &= DA9062AA_GPIO0_PIN_MASK; 52 53 return val; 54 } 55 56 static int da9062_pctl_set_pin_mode(struct da9062_pctl *pctl, 57 unsigned int offset, unsigned int mode_req) 58 { 59 struct regmap *regmap = pctl->da9062->regmap; 60 unsigned int mode = mode_req; 61 unsigned int mask; 62 int ret; 63 64 mode &= DA9062AA_GPIO0_PIN_MASK; 65 mode <<= DA9062_PIN_SHIFT(offset); 66 mask = DA9062AA_GPIO0_PIN_MASK << DA9062_PIN_SHIFT(offset); 67 68 ret = regmap_update_bits(regmap, DA9062AA_GPIO_0_1 + (offset >> 1), 69 mask, mode); 70 if (!ret) 71 pctl->pin_config[offset] = mode_req; 72 73 return ret; 74 } 75 76 static int da9062_gpio_get(struct gpio_chip *gc, unsigned int offset) 77 { 78 struct da9062_pctl *pctl = gpiochip_get_data(gc); 79 struct regmap *regmap = pctl->da9062->regmap; 80 int gpio_mode, val; 81 int ret; 82 83 gpio_mode = da9062_pctl_get_pin_mode(pctl, offset); 84 if (gpio_mode < 0) 85 return gpio_mode; 86 87 switch (gpio_mode) { 88 case DA9062_PIN_ALTERNATE: 89 return -ENOTSUPP; 90 case DA9062_PIN_GPI: 91 ret = regmap_read(regmap, DA9062AA_STATUS_B, &val); 92 if (ret < 0) 93 return ret; 94 break; 95 case DA9062_PIN_GPO_OD: 96 case DA9062_PIN_GPO_PP: 97 ret = regmap_read(regmap, DA9062AA_GPIO_MODE0_4, &val); 98 if (ret < 0) 99 return ret; 100 } 101 102 return !!(val & BIT(offset)); 103 } 104 105 static void da9062_gpio_set(struct gpio_chip *gc, unsigned int offset, 106 int value) 107 { 108 struct da9062_pctl *pctl = gpiochip_get_data(gc); 109 struct regmap *regmap = pctl->da9062->regmap; 110 111 regmap_update_bits(regmap, DA9062AA_GPIO_MODE0_4, BIT(offset), 112 value << offset); 113 } 114 115 static int da9062_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) 116 { 117 struct da9062_pctl *pctl = gpiochip_get_data(gc); 118 int gpio_mode; 119 120 gpio_mode = da9062_pctl_get_pin_mode(pctl, offset); 121 if (gpio_mode < 0) 122 return gpio_mode; 123 124 switch (gpio_mode) { 125 case DA9062_PIN_ALTERNATE: 126 return -ENOTSUPP; 127 case DA9062_PIN_GPI: 128 return GPIO_LINE_DIRECTION_IN; 129 case DA9062_PIN_GPO_OD: 130 case DA9062_PIN_GPO_PP: 131 return GPIO_LINE_DIRECTION_OUT; 132 } 133 134 return -EINVAL; 135 } 136 137 static int da9062_gpio_direction_input(struct gpio_chip *gc, 138 unsigned int offset) 139 { 140 struct da9062_pctl *pctl = gpiochip_get_data(gc); 141 struct regmap *regmap = pctl->da9062->regmap; 142 struct gpio_desc *desc = gpiochip_get_desc(gc, offset); 143 unsigned int gpi_type; 144 int ret; 145 146 ret = da9062_pctl_set_pin_mode(pctl, offset, DA9062_PIN_GPI); 147 if (ret) 148 return ret; 149 150 /* 151 * If the gpio is active low we should set it in hw too. No worries 152 * about gpio_get() because we read and return the gpio-level. So the 153 * gpiolib active_low handling is still correct. 154 * 155 * 0 - active low, 1 - active high 156 */ 157 gpi_type = !gpiod_is_active_low(desc); 158 159 return regmap_update_bits(regmap, DA9062AA_GPIO_0_1 + (offset >> 1), 160 DA9062AA_GPIO0_TYPE_MASK << DA9062_TYPE(offset), 161 gpi_type << DA9062_TYPE(offset)); 162 } 163 164 static int da9062_gpio_direction_output(struct gpio_chip *gc, 165 unsigned int offset, int value) 166 { 167 struct da9062_pctl *pctl = gpiochip_get_data(gc); 168 unsigned int pin_config = pctl->pin_config[offset]; 169 int ret; 170 171 ret = da9062_pctl_set_pin_mode(pctl, offset, pin_config); 172 if (ret) 173 return ret; 174 175 da9062_gpio_set(gc, offset, value); 176 177 return 0; 178 } 179 180 static int da9062_gpio_set_config(struct gpio_chip *gc, unsigned int offset, 181 unsigned long config) 182 { 183 struct da9062_pctl *pctl = gpiochip_get_data(gc); 184 struct regmap *regmap = pctl->da9062->regmap; 185 int gpio_mode; 186 187 /* 188 * We need to meet the following restrictions [1, Figure 18]: 189 * - PIN_CONFIG_BIAS_PULL_DOWN -> only allowed if the pin is used as 190 * gpio input 191 * - PIN_CONFIG_BIAS_PULL_UP -> only allowed if the pin is used as 192 * gpio output open-drain. 193 */ 194 195 switch (pinconf_to_config_param(config)) { 196 case PIN_CONFIG_BIAS_DISABLE: 197 return regmap_update_bits(regmap, DA9062AA_CONFIG_K, 198 BIT(offset), 0); 199 case PIN_CONFIG_BIAS_PULL_DOWN: 200 gpio_mode = da9062_pctl_get_pin_mode(pctl, offset); 201 if (gpio_mode < 0) 202 return -EINVAL; 203 else if (gpio_mode != DA9062_PIN_GPI) 204 return -ENOTSUPP; 205 return regmap_update_bits(regmap, DA9062AA_CONFIG_K, 206 BIT(offset), BIT(offset)); 207 case PIN_CONFIG_BIAS_PULL_UP: 208 gpio_mode = da9062_pctl_get_pin_mode(pctl, offset); 209 if (gpio_mode < 0) 210 return -EINVAL; 211 else if (gpio_mode != DA9062_PIN_GPO_OD) 212 return -ENOTSUPP; 213 return regmap_update_bits(regmap, DA9062AA_CONFIG_K, 214 BIT(offset), BIT(offset)); 215 case PIN_CONFIG_DRIVE_OPEN_DRAIN: 216 return da9062_pctl_set_pin_mode(pctl, offset, 217 DA9062_PIN_GPO_OD); 218 case PIN_CONFIG_DRIVE_PUSH_PULL: 219 return da9062_pctl_set_pin_mode(pctl, offset, 220 DA9062_PIN_GPO_PP); 221 default: 222 return -ENOTSUPP; 223 } 224 } 225 226 static int da9062_gpio_to_irq(struct gpio_chip *gc, unsigned int offset) 227 { 228 struct da9062_pctl *pctl = gpiochip_get_data(gc); 229 struct da9062 *da9062 = pctl->da9062; 230 231 return regmap_irq_get_virq(da9062->regmap_irq, 232 DA9062_IRQ_GPI0 + offset); 233 } 234 235 static const struct gpio_chip reference_gc = { 236 .owner = THIS_MODULE, 237 .get = da9062_gpio_get, 238 .set = da9062_gpio_set, 239 .get_direction = da9062_gpio_get_direction, 240 .direction_input = da9062_gpio_direction_input, 241 .direction_output = da9062_gpio_direction_output, 242 .set_config = da9062_gpio_set_config, 243 .to_irq = da9062_gpio_to_irq, 244 .can_sleep = true, 245 .ngpio = DA9062_GPIO_NUM, 246 .base = -1, 247 }; 248 249 static int da9062_pctl_probe(struct platform_device *pdev) 250 { 251 struct device *parent = pdev->dev.parent; 252 struct da9062_pctl *pctl; 253 int i; 254 255 device_set_node(&pdev->dev, dev_fwnode(pdev->dev.parent)); 256 257 pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); 258 if (!pctl) 259 return -ENOMEM; 260 261 pctl->da9062 = dev_get_drvdata(parent); 262 if (!pctl->da9062) 263 return -EINVAL; 264 265 if (!device_property_present(parent, "gpio-controller")) 266 return 0; 267 268 for (i = 0; i < ARRAY_SIZE(pctl->pin_config); i++) 269 pctl->pin_config[i] = DA9062_PIN_GPO_PP; 270 271 /* 272 * Currently the driver handles only the GPIO support. The 273 * pinctrl/pinmux support can be added later if needed. 274 */ 275 pctl->gc = reference_gc; 276 pctl->gc.label = dev_name(&pdev->dev); 277 pctl->gc.parent = &pdev->dev; 278 279 platform_set_drvdata(pdev, pctl); 280 281 return devm_gpiochip_add_data(&pdev->dev, &pctl->gc, pctl); 282 } 283 284 static struct platform_driver da9062_pctl_driver = { 285 .probe = da9062_pctl_probe, 286 .driver = { 287 .name = "da9062-gpio", 288 }, 289 }; 290 module_platform_driver(da9062_pctl_driver); 291 292 MODULE_AUTHOR("Marco Felsch <kernel@pengutronix.de>"); 293 MODULE_DESCRIPTION("DA9062 PMIC pinctrl and GPIO Driver"); 294 MODULE_LICENSE("GPL v2"); 295 MODULE_ALIAS("platform:da9062-gpio"); 296