1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Support to GPIOs on ROHM BD72720 and BD79300 4 * Copyright 2025 ROHM Semiconductors. 5 * Author: Matti Vaittinen <mazziesaccount@gmail.com> 6 */ 7 8 #include <linux/gpio/driver.h> 9 #include <linux/init.h> 10 #include <linux/irq.h> 11 #include <linux/module.h> 12 #include <linux/of.h> 13 #include <linux/platform_device.h> 14 #include <linux/mfd/rohm-bd72720.h> 15 16 #define BD72720_GPIO_OPEN_DRAIN 0 17 #define BD72720_GPIO_CMOS BIT(1) 18 #define BD72720_INT_GPIO1_IN_SRC 4 19 /* 20 * The BD72720 has several "one time programmable" (OTP) configurations which 21 * can be set at manufacturing phase. A set of these options allow using pins 22 * as GPIO. The OTP configuration can't be read at run-time, so drivers rely on 23 * device-tree to advertise the correct options. 24 * 25 * Both DVS[0,1] pins can be configured to be used for: 26 * - OTP0: regulator RUN state control 27 * - OTP1: GPI 28 * - OTP2: GPO 29 * - OTP3: Power sequencer output 30 * Data-sheet also states that these PINs can always be used for IRQ but the 31 * driver limits this by allowing them to be used for IRQs with OTP1 only. 32 * 33 * Pins GPIO_EXTEN0 (GPIO3), GPIO_EXTEN1 (GPIO4), GPIO_FAULT_B (GPIO5) have OTP 34 * options for a specific (non GPIO) purposes, but also an option to configure 35 * them to be used as a GPO. 36 * 37 * OTP settings can be separately configured for each pin. 38 * 39 * DT properties: 40 * "rohm,pin-dvs0" and "rohm,pin-dvs1" can be set to one of the values: 41 * "dvs-input", "gpi", "gpo". 42 * 43 * "rohm,pin-exten0", "rohm,pin-exten1" and "rohm,pin-fault_b" can be set to: 44 * "gpo" 45 */ 46 47 enum bd72720_gpio_state { 48 BD72720_PIN_UNKNOWN, 49 BD72720_PIN_GPI, 50 BD72720_PIN_GPO, 51 }; 52 53 enum { 54 BD72720_GPIO1, 55 BD72720_GPIO2, 56 BD72720_GPIO3, 57 BD72720_GPIO4, 58 BD72720_GPIO5, 59 BD72720_GPIO_EPDEN, 60 BD72720_NUM_GPIOS 61 }; 62 63 struct bd72720_gpio { 64 /* chip.parent points the MFD which provides DT node and regmap */ 65 struct gpio_chip chip; 66 /* dev points to the platform device for devm and prints */ 67 struct device *dev; 68 struct regmap *regmap; 69 int gpio_is_input; 70 }; 71 72 static int bd72720gpi_get(struct bd72720_gpio *bdgpio, unsigned int reg_offset) 73 { 74 int ret, val, shift; 75 76 ret = regmap_read(bdgpio->regmap, BD72720_REG_INT_ETC1_SRC, &val); 77 if (ret) 78 return ret; 79 80 shift = BD72720_INT_GPIO1_IN_SRC + reg_offset; 81 82 return (val >> shift) & 1; 83 } 84 85 static int bd72720gpo_get(struct bd72720_gpio *bdgpio, 86 unsigned int offset) 87 { 88 static const int regs[] = { 89 BD72720_REG_GPIO1_CTRL, BD72720_REG_GPIO2_CTRL, 90 BD72720_REG_GPIO3_CTRL, BD72720_REG_GPIO4_CTRL, 91 BD72720_REG_GPIO5_CTRL, BD72720_REG_EPDEN_CTRL 92 }; 93 int ret, val; 94 95 ret = regmap_read(bdgpio->regmap, regs[offset], &val); 96 if (ret) 97 return ret; 98 99 return val & BD72720_GPIO_HIGH; 100 } 101 102 static int bd72720gpio_get(struct gpio_chip *chip, unsigned int offset) 103 { 104 struct bd72720_gpio *bdgpio = gpiochip_get_data(chip); 105 106 if (BIT(offset) & bdgpio->gpio_is_input) 107 return bd72720gpi_get(bdgpio, offset); 108 109 return bd72720gpo_get(bdgpio, offset); 110 } 111 112 static int bd72720gpo_set(struct gpio_chip *chip, unsigned int offset, 113 int value) 114 { 115 struct bd72720_gpio *bdgpio = gpiochip_get_data(chip); 116 static const int regs[] = { 117 BD72720_REG_GPIO1_CTRL, BD72720_REG_GPIO2_CTRL, 118 BD72720_REG_GPIO3_CTRL, BD72720_REG_GPIO4_CTRL, 119 BD72720_REG_GPIO5_CTRL, BD72720_REG_EPDEN_CTRL 120 }; 121 122 if (BIT(offset) & bdgpio->gpio_is_input) { 123 dev_dbg(bdgpio->dev, "pin %d not output.\n", offset); 124 return -EINVAL; 125 } 126 127 if (value) 128 return regmap_set_bits(bdgpio->regmap, regs[offset], 129 BD72720_GPIO_HIGH); 130 131 return regmap_clear_bits(bdgpio->regmap, regs[offset], 132 BD72720_GPIO_HIGH); 133 } 134 135 static int bd72720_gpio_set_config(struct gpio_chip *chip, unsigned int offset, 136 unsigned long config) 137 { 138 struct bd72720_gpio *bdgpio = gpiochip_get_data(chip); 139 static const int regs[] = { 140 BD72720_REG_GPIO1_CTRL, BD72720_REG_GPIO2_CTRL, 141 BD72720_REG_GPIO3_CTRL, BD72720_REG_GPIO4_CTRL, 142 BD72720_REG_GPIO5_CTRL, BD72720_REG_EPDEN_CTRL 143 }; 144 145 /* 146 * We can only set the output mode, which makes sense only when output 147 * OTP configuration is used. 148 */ 149 if (BIT(offset) & bdgpio->gpio_is_input) 150 return -ENOTSUPP; 151 152 switch (pinconf_to_config_param(config)) { 153 case PIN_CONFIG_DRIVE_OPEN_DRAIN: 154 return regmap_update_bits(bdgpio->regmap, 155 regs[offset], 156 BD72720_GPIO_DRIVE_MASK, 157 BD72720_GPIO_OPEN_DRAIN); 158 case PIN_CONFIG_DRIVE_PUSH_PULL: 159 return regmap_update_bits(bdgpio->regmap, 160 regs[offset], 161 BD72720_GPIO_DRIVE_MASK, 162 BD72720_GPIO_CMOS); 163 default: 164 break; 165 } 166 167 return -ENOTSUPP; 168 } 169 170 static int bd72720gpo_direction_get(struct gpio_chip *chip, 171 unsigned int offset) 172 { 173 struct bd72720_gpio *bdgpio = gpiochip_get_data(chip); 174 175 if (BIT(offset) & bdgpio->gpio_is_input) 176 return GPIO_LINE_DIRECTION_IN; 177 178 return GPIO_LINE_DIRECTION_OUT; 179 } 180 181 static int bd72720_valid_mask(struct gpio_chip *gc, 182 unsigned long *valid_mask, 183 unsigned int ngpios) 184 { 185 static const char * const properties[] = { 186 "rohm,pin-dvs0", "rohm,pin-dvs1", "rohm,pin-exten0", 187 "rohm,pin-exten1", "rohm,pin-fault_b" 188 }; 189 struct bd72720_gpio *g = gpiochip_get_data(gc); 190 const char *val; 191 int i, ret; 192 193 *valid_mask = BIT(BD72720_GPIO_EPDEN); 194 195 if (!gc->parent) 196 return 0; 197 198 for (i = 0; i < ARRAY_SIZE(properties); i++) { 199 ret = fwnode_property_read_string(dev_fwnode(gc->parent), 200 properties[i], &val); 201 202 if (ret) { 203 if (ret == -EINVAL) 204 continue; 205 206 dev_err(g->dev, "pin %d (%s), bad configuration\n", i, 207 properties[i]); 208 209 return ret; 210 } 211 212 if (strcmp(val, "gpi") == 0) { 213 if (i != BD72720_GPIO1 && i != BD72720_GPIO2) { 214 dev_warn(g->dev, 215 "pin %d (%s) does not support INPUT mode", 216 i, properties[i]); 217 continue; 218 } 219 220 *valid_mask |= BIT(i); 221 g->gpio_is_input |= BIT(i); 222 } else if (strcmp(val, "gpo") == 0) { 223 *valid_mask |= BIT(i); 224 } 225 } 226 227 return 0; 228 } 229 230 /* Template for GPIO chip */ 231 static const struct gpio_chip bd72720gpo_chip = { 232 .label = "bd72720", 233 .owner = THIS_MODULE, 234 .get = bd72720gpio_get, 235 .get_direction = bd72720gpo_direction_get, 236 .set = bd72720gpo_set, 237 .set_config = bd72720_gpio_set_config, 238 .init_valid_mask = bd72720_valid_mask, 239 .can_sleep = true, 240 .ngpio = BD72720_NUM_GPIOS, 241 .base = -1, 242 }; 243 244 static int gpo_bd72720_probe(struct platform_device *pdev) 245 { 246 struct bd72720_gpio *g; 247 struct device *parent, *dev; 248 249 /* 250 * Bind devm lifetime to this platform device => use dev for devm. 251 * also the prints should originate from this device. 252 */ 253 dev = &pdev->dev; 254 /* The device-tree and regmap come from MFD => use parent for that */ 255 parent = dev->parent; 256 257 g = devm_kzalloc(dev, sizeof(*g), GFP_KERNEL); 258 if (!g) 259 return -ENOMEM; 260 261 g->chip = bd72720gpo_chip; 262 g->dev = dev; 263 g->chip.parent = parent; 264 g->regmap = dev_get_regmap(parent, NULL); 265 if (!g->regmap) 266 return -ENODEV; 267 268 return devm_gpiochip_add_data(dev, &g->chip, g); 269 } 270 271 static const struct platform_device_id bd72720_gpio_id[] = { 272 { .name = "bd72720-gpio" }, 273 { } 274 }; 275 MODULE_DEVICE_TABLE(platform, bd72720_gpio_id); 276 277 static struct platform_driver gpo_bd72720_driver = { 278 .driver = { 279 .name = "bd72720-gpio", 280 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 281 }, 282 .probe = gpo_bd72720_probe, 283 .id_table = bd72720_gpio_id, 284 }; 285 module_platform_driver(gpo_bd72720_driver); 286 287 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); 288 MODULE_DESCRIPTION("GPIO interface for BD72720 and BD73900"); 289 MODULE_LICENSE("GPL"); 290