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 const int regs[] = { BD72720_REG_GPIO1_CTRL, BD72720_REG_GPIO2_CTRL, 89 BD72720_REG_GPIO3_CTRL, BD72720_REG_GPIO4_CTRL, 90 BD72720_REG_GPIO5_CTRL, BD72720_REG_EPDEN_CTRL }; 91 int ret, val; 92 93 ret = regmap_read(bdgpio->regmap, regs[offset], &val); 94 if (ret) 95 return ret; 96 97 return val & BD72720_GPIO_HIGH; 98 } 99 100 static int bd72720gpio_get(struct gpio_chip *chip, unsigned int offset) 101 { 102 struct bd72720_gpio *bdgpio = gpiochip_get_data(chip); 103 104 if (BIT(offset) & bdgpio->gpio_is_input) 105 return bd72720gpi_get(bdgpio, offset); 106 107 return bd72720gpo_get(bdgpio, offset); 108 } 109 110 static int bd72720gpo_set(struct gpio_chip *chip, unsigned int offset, 111 int value) 112 { 113 struct bd72720_gpio *bdgpio = gpiochip_get_data(chip); 114 const int regs[] = { BD72720_REG_GPIO1_CTRL, BD72720_REG_GPIO2_CTRL, 115 BD72720_REG_GPIO3_CTRL, BD72720_REG_GPIO4_CTRL, 116 BD72720_REG_GPIO5_CTRL, BD72720_REG_EPDEN_CTRL }; 117 118 if (BIT(offset) & bdgpio->gpio_is_input) { 119 dev_dbg(bdgpio->dev, "pin %d not output.\n", offset); 120 return -EINVAL; 121 } 122 123 if (value) 124 return regmap_set_bits(bdgpio->regmap, regs[offset], 125 BD72720_GPIO_HIGH); 126 127 return regmap_clear_bits(bdgpio->regmap, regs[offset], 128 BD72720_GPIO_HIGH); 129 } 130 131 static int bd72720_gpio_set_config(struct gpio_chip *chip, unsigned int offset, 132 unsigned long config) 133 { 134 struct bd72720_gpio *bdgpio = gpiochip_get_data(chip); 135 const int regs[] = { BD72720_REG_GPIO1_CTRL, BD72720_REG_GPIO2_CTRL, 136 BD72720_REG_GPIO3_CTRL, BD72720_REG_GPIO4_CTRL, 137 BD72720_REG_GPIO5_CTRL, BD72720_REG_EPDEN_CTRL }; 138 139 /* 140 * We can only set the output mode, which makes sense only when output 141 * OTP configuration is used. 142 */ 143 if (BIT(offset) & bdgpio->gpio_is_input) 144 return -ENOTSUPP; 145 146 switch (pinconf_to_config_param(config)) { 147 case PIN_CONFIG_DRIVE_OPEN_DRAIN: 148 return regmap_update_bits(bdgpio->regmap, 149 regs[offset], 150 BD72720_GPIO_DRIVE_MASK, 151 BD72720_GPIO_OPEN_DRAIN); 152 case PIN_CONFIG_DRIVE_PUSH_PULL: 153 return regmap_update_bits(bdgpio->regmap, 154 regs[offset], 155 BD72720_GPIO_DRIVE_MASK, 156 BD72720_GPIO_CMOS); 157 default: 158 break; 159 } 160 161 return -ENOTSUPP; 162 } 163 164 static int bd72720gpo_direction_get(struct gpio_chip *chip, 165 unsigned int offset) 166 { 167 struct bd72720_gpio *bdgpio = gpiochip_get_data(chip); 168 169 if (BIT(offset) & bdgpio->gpio_is_input) 170 return GPIO_LINE_DIRECTION_IN; 171 172 return GPIO_LINE_DIRECTION_OUT; 173 } 174 175 static int bd72720_valid_mask(struct gpio_chip *gc, 176 unsigned long *valid_mask, 177 unsigned int ngpios) 178 { 179 static const char * const properties[] = { 180 "rohm,pin-dvs0", "rohm,pin-dvs1", "rohm,pin-exten0", 181 "rohm,pin-exten1", "rohm,pin-fault_b" 182 }; 183 struct bd72720_gpio *g = gpiochip_get_data(gc); 184 const char *val; 185 int i, ret; 186 187 *valid_mask = BIT(BD72720_GPIO_EPDEN); 188 189 if (!gc->parent) 190 return 0; 191 192 for (i = 0; i < ARRAY_SIZE(properties); i++) { 193 ret = fwnode_property_read_string(dev_fwnode(gc->parent), 194 properties[i], &val); 195 196 if (ret) { 197 if (ret == -EINVAL) 198 continue; 199 200 dev_err(g->dev, "pin %d (%s), bad configuration\n", i, 201 properties[i]); 202 203 return ret; 204 } 205 206 if (strcmp(val, "gpi") == 0) { 207 if (i != BD72720_GPIO1 && i != BD72720_GPIO2) { 208 dev_warn(g->dev, 209 "pin %d (%s) does not support INPUT mode", 210 i, properties[i]); 211 continue; 212 } 213 214 *valid_mask |= BIT(i); 215 g->gpio_is_input |= BIT(i); 216 } else if (strcmp(val, "gpo") == 0) { 217 *valid_mask |= BIT(i); 218 } 219 } 220 221 return 0; 222 } 223 224 /* Template for GPIO chip */ 225 static const struct gpio_chip bd72720gpo_chip = { 226 .label = "bd72720", 227 .owner = THIS_MODULE, 228 .get = bd72720gpio_get, 229 .get_direction = bd72720gpo_direction_get, 230 .set = bd72720gpo_set, 231 .set_config = bd72720_gpio_set_config, 232 .init_valid_mask = bd72720_valid_mask, 233 .can_sleep = true, 234 .ngpio = BD72720_NUM_GPIOS, 235 .base = -1, 236 }; 237 238 static int gpo_bd72720_probe(struct platform_device *pdev) 239 { 240 struct bd72720_gpio *g; 241 struct device *parent, *dev; 242 243 /* 244 * Bind devm lifetime to this platform device => use dev for devm. 245 * also the prints should originate from this device. 246 */ 247 dev = &pdev->dev; 248 /* The device-tree and regmap come from MFD => use parent for that */ 249 parent = dev->parent; 250 251 g = devm_kzalloc(dev, sizeof(*g), GFP_KERNEL); 252 if (!g) 253 return -ENOMEM; 254 255 g->chip = bd72720gpo_chip; 256 g->dev = dev; 257 g->chip.parent = parent; 258 g->regmap = dev_get_regmap(parent, NULL); 259 260 return devm_gpiochip_add_data(dev, &g->chip, g); 261 } 262 263 static const struct platform_device_id bd72720_gpio_id[] = { 264 { "bd72720-gpio" }, 265 { }, 266 }; 267 MODULE_DEVICE_TABLE(platform, bd72720_gpio_id); 268 269 static struct platform_driver gpo_bd72720_driver = { 270 .driver = { 271 .name = "bd72720-gpio", 272 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 273 }, 274 .probe = gpo_bd72720_probe, 275 .id_table = bd72720_gpio_id, 276 }; 277 module_platform_driver(gpo_bd72720_driver); 278 279 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); 280 MODULE_DESCRIPTION("GPIO interface for BD72720 and BD73900"); 281 MODULE_LICENSE("GPL"); 282