1 /* 2 * MAXIM MAX77620 GPIO driver 3 * 4 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 */ 10 11 #include <linux/gpio/driver.h> 12 #include <linux/interrupt.h> 13 #include <linux/mfd/max77620.h> 14 #include <linux/module.h> 15 #include <linux/platform_device.h> 16 #include <linux/regmap.h> 17 18 #define GPIO_REG_ADDR(offset) (MAX77620_REG_GPIO0 + offset) 19 20 struct max77620_gpio { 21 struct gpio_chip gpio_chip; 22 struct regmap *rmap; 23 struct device *dev; 24 }; 25 26 static const struct regmap_irq max77620_gpio_irqs[] = { 27 [0] = { 28 .mask = MAX77620_IRQ_LVL2_GPIO_EDGE0, 29 .type_rising_mask = MAX77620_CNFG_GPIO_INT_RISING, 30 .type_falling_mask = MAX77620_CNFG_GPIO_INT_FALLING, 31 .reg_offset = 0, 32 .type_reg_offset = 0, 33 }, 34 [1] = { 35 .mask = MAX77620_IRQ_LVL2_GPIO_EDGE1, 36 .type_rising_mask = MAX77620_CNFG_GPIO_INT_RISING, 37 .type_falling_mask = MAX77620_CNFG_GPIO_INT_FALLING, 38 .reg_offset = 0, 39 .type_reg_offset = 1, 40 }, 41 [2] = { 42 .mask = MAX77620_IRQ_LVL2_GPIO_EDGE2, 43 .type_rising_mask = MAX77620_CNFG_GPIO_INT_RISING, 44 .type_falling_mask = MAX77620_CNFG_GPIO_INT_FALLING, 45 .reg_offset = 0, 46 .type_reg_offset = 2, 47 }, 48 [3] = { 49 .mask = MAX77620_IRQ_LVL2_GPIO_EDGE3, 50 .type_rising_mask = MAX77620_CNFG_GPIO_INT_RISING, 51 .type_falling_mask = MAX77620_CNFG_GPIO_INT_FALLING, 52 .reg_offset = 0, 53 .type_reg_offset = 3, 54 }, 55 [4] = { 56 .mask = MAX77620_IRQ_LVL2_GPIO_EDGE4, 57 .type_rising_mask = MAX77620_CNFG_GPIO_INT_RISING, 58 .type_falling_mask = MAX77620_CNFG_GPIO_INT_FALLING, 59 .reg_offset = 0, 60 .type_reg_offset = 4, 61 }, 62 [5] = { 63 .mask = MAX77620_IRQ_LVL2_GPIO_EDGE5, 64 .type_rising_mask = MAX77620_CNFG_GPIO_INT_RISING, 65 .type_falling_mask = MAX77620_CNFG_GPIO_INT_FALLING, 66 .reg_offset = 0, 67 .type_reg_offset = 5, 68 }, 69 [6] = { 70 .mask = MAX77620_IRQ_LVL2_GPIO_EDGE6, 71 .type_rising_mask = MAX77620_CNFG_GPIO_INT_RISING, 72 .type_falling_mask = MAX77620_CNFG_GPIO_INT_FALLING, 73 .reg_offset = 0, 74 .type_reg_offset = 6, 75 }, 76 [7] = { 77 .mask = MAX77620_IRQ_LVL2_GPIO_EDGE7, 78 .type_rising_mask = MAX77620_CNFG_GPIO_INT_RISING, 79 .type_falling_mask = MAX77620_CNFG_GPIO_INT_FALLING, 80 .reg_offset = 0, 81 .type_reg_offset = 7, 82 }, 83 }; 84 85 static struct regmap_irq_chip max77620_gpio_irq_chip = { 86 .name = "max77620-gpio", 87 .irqs = max77620_gpio_irqs, 88 .num_irqs = ARRAY_SIZE(max77620_gpio_irqs), 89 .num_regs = 1, 90 .num_type_reg = 8, 91 .irq_reg_stride = 1, 92 .type_reg_stride = 1, 93 .status_base = MAX77620_REG_IRQ_LVL2_GPIO, 94 .type_base = MAX77620_REG_GPIO0, 95 }; 96 97 static int max77620_gpio_dir_input(struct gpio_chip *gc, unsigned int offset) 98 { 99 struct max77620_gpio *mgpio = gpiochip_get_data(gc); 100 int ret; 101 102 ret = regmap_update_bits(mgpio->rmap, GPIO_REG_ADDR(offset), 103 MAX77620_CNFG_GPIO_DIR_MASK, 104 MAX77620_CNFG_GPIO_DIR_INPUT); 105 if (ret < 0) 106 dev_err(mgpio->dev, "CNFG_GPIOx dir update failed: %d\n", ret); 107 108 return ret; 109 } 110 111 static int max77620_gpio_get(struct gpio_chip *gc, unsigned int offset) 112 { 113 struct max77620_gpio *mgpio = gpiochip_get_data(gc); 114 unsigned int val; 115 int ret; 116 117 ret = regmap_read(mgpio->rmap, GPIO_REG_ADDR(offset), &val); 118 if (ret < 0) { 119 dev_err(mgpio->dev, "CNFG_GPIOx read failed: %d\n", ret); 120 return ret; 121 } 122 123 if (val & MAX77620_CNFG_GPIO_DIR_MASK) 124 return !!(val & MAX77620_CNFG_GPIO_INPUT_VAL_MASK); 125 else 126 return !!(val & MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK); 127 } 128 129 static int max77620_gpio_dir_output(struct gpio_chip *gc, unsigned int offset, 130 int value) 131 { 132 struct max77620_gpio *mgpio = gpiochip_get_data(gc); 133 u8 val; 134 int ret; 135 136 val = (value) ? MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH : 137 MAX77620_CNFG_GPIO_OUTPUT_VAL_LOW; 138 139 ret = regmap_update_bits(mgpio->rmap, GPIO_REG_ADDR(offset), 140 MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK, val); 141 if (ret < 0) { 142 dev_err(mgpio->dev, "CNFG_GPIOx val update failed: %d\n", ret); 143 return ret; 144 } 145 146 ret = regmap_update_bits(mgpio->rmap, GPIO_REG_ADDR(offset), 147 MAX77620_CNFG_GPIO_DIR_MASK, 148 MAX77620_CNFG_GPIO_DIR_OUTPUT); 149 if (ret < 0) 150 dev_err(mgpio->dev, "CNFG_GPIOx dir update failed: %d\n", ret); 151 152 return ret; 153 } 154 155 static int max77620_gpio_set_debounce(struct max77620_gpio *mgpio, 156 unsigned int offset, 157 unsigned int debounce) 158 { 159 u8 val; 160 int ret; 161 162 switch (debounce) { 163 case 0: 164 val = MAX77620_CNFG_GPIO_DBNC_None; 165 break; 166 case 1 ... 8: 167 val = MAX77620_CNFG_GPIO_DBNC_8ms; 168 break; 169 case 9 ... 16: 170 val = MAX77620_CNFG_GPIO_DBNC_16ms; 171 break; 172 case 17 ... 32: 173 val = MAX77620_CNFG_GPIO_DBNC_32ms; 174 break; 175 default: 176 dev_err(mgpio->dev, "Illegal value %u\n", debounce); 177 return -EINVAL; 178 } 179 180 ret = regmap_update_bits(mgpio->rmap, GPIO_REG_ADDR(offset), 181 MAX77620_CNFG_GPIO_DBNC_MASK, val); 182 if (ret < 0) 183 dev_err(mgpio->dev, "CNFG_GPIOx_DBNC update failed: %d\n", ret); 184 185 return ret; 186 } 187 188 static void max77620_gpio_set(struct gpio_chip *gc, unsigned int offset, 189 int value) 190 { 191 struct max77620_gpio *mgpio = gpiochip_get_data(gc); 192 u8 val; 193 int ret; 194 195 val = (value) ? MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH : 196 MAX77620_CNFG_GPIO_OUTPUT_VAL_LOW; 197 198 ret = regmap_update_bits(mgpio->rmap, GPIO_REG_ADDR(offset), 199 MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK, val); 200 if (ret < 0) 201 dev_err(mgpio->dev, "CNFG_GPIO_OUT update failed: %d\n", ret); 202 } 203 204 static int max77620_gpio_set_config(struct gpio_chip *gc, unsigned int offset, 205 unsigned long config) 206 { 207 struct max77620_gpio *mgpio = gpiochip_get_data(gc); 208 209 switch (pinconf_to_config_param(config)) { 210 case PIN_CONFIG_DRIVE_OPEN_DRAIN: 211 return regmap_update_bits(mgpio->rmap, GPIO_REG_ADDR(offset), 212 MAX77620_CNFG_GPIO_DRV_MASK, 213 MAX77620_CNFG_GPIO_DRV_OPENDRAIN); 214 case PIN_CONFIG_DRIVE_PUSH_PULL: 215 return regmap_update_bits(mgpio->rmap, GPIO_REG_ADDR(offset), 216 MAX77620_CNFG_GPIO_DRV_MASK, 217 MAX77620_CNFG_GPIO_DRV_PUSHPULL); 218 case PIN_CONFIG_INPUT_DEBOUNCE: 219 return max77620_gpio_set_debounce(mgpio, offset, 220 pinconf_to_config_argument(config)); 221 default: 222 break; 223 } 224 225 return -ENOTSUPP; 226 } 227 228 static int max77620_gpio_to_irq(struct gpio_chip *gc, unsigned int offset) 229 { 230 struct max77620_gpio *mgpio = gpiochip_get_data(gc); 231 struct max77620_chip *chip = dev_get_drvdata(mgpio->dev->parent); 232 233 return regmap_irq_get_virq(chip->gpio_irq_data, offset); 234 } 235 236 static int max77620_gpio_probe(struct platform_device *pdev) 237 { 238 struct max77620_chip *chip = dev_get_drvdata(pdev->dev.parent); 239 struct max77620_gpio *mgpio; 240 int gpio_irq; 241 int ret; 242 243 gpio_irq = platform_get_irq(pdev, 0); 244 if (gpio_irq <= 0) { 245 dev_err(&pdev->dev, "GPIO irq not available %d\n", gpio_irq); 246 return -ENODEV; 247 } 248 249 mgpio = devm_kzalloc(&pdev->dev, sizeof(*mgpio), GFP_KERNEL); 250 if (!mgpio) 251 return -ENOMEM; 252 253 mgpio->rmap = chip->rmap; 254 mgpio->dev = &pdev->dev; 255 256 mgpio->gpio_chip.label = pdev->name; 257 mgpio->gpio_chip.parent = &pdev->dev; 258 mgpio->gpio_chip.direction_input = max77620_gpio_dir_input; 259 mgpio->gpio_chip.get = max77620_gpio_get; 260 mgpio->gpio_chip.direction_output = max77620_gpio_dir_output; 261 mgpio->gpio_chip.set = max77620_gpio_set; 262 mgpio->gpio_chip.set_config = max77620_gpio_set_config; 263 mgpio->gpio_chip.to_irq = max77620_gpio_to_irq; 264 mgpio->gpio_chip.ngpio = MAX77620_GPIO_NR; 265 mgpio->gpio_chip.can_sleep = 1; 266 mgpio->gpio_chip.base = -1; 267 #ifdef CONFIG_OF_GPIO 268 mgpio->gpio_chip.of_node = pdev->dev.parent->of_node; 269 #endif 270 271 platform_set_drvdata(pdev, mgpio); 272 273 ret = devm_gpiochip_add_data(&pdev->dev, &mgpio->gpio_chip, mgpio); 274 if (ret < 0) { 275 dev_err(&pdev->dev, "gpio_init: Failed to add max77620_gpio\n"); 276 return ret; 277 } 278 279 ret = devm_regmap_add_irq_chip(&pdev->dev, chip->rmap, gpio_irq, 280 IRQF_ONESHOT, -1, 281 &max77620_gpio_irq_chip, 282 &chip->gpio_irq_data); 283 if (ret < 0) { 284 dev_err(&pdev->dev, "Failed to add gpio irq_chip %d\n", ret); 285 return ret; 286 } 287 288 return 0; 289 } 290 291 static const struct platform_device_id max77620_gpio_devtype[] = { 292 { .name = "max77620-gpio", }, 293 { .name = "max20024-gpio", }, 294 {}, 295 }; 296 MODULE_DEVICE_TABLE(platform, max77620_gpio_devtype); 297 298 static struct platform_driver max77620_gpio_driver = { 299 .driver.name = "max77620-gpio", 300 .probe = max77620_gpio_probe, 301 .id_table = max77620_gpio_devtype, 302 }; 303 304 module_platform_driver(max77620_gpio_driver); 305 306 MODULE_DESCRIPTION("GPIO interface for MAX77620 and MAX20024 PMIC"); 307 MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); 308 MODULE_AUTHOR("Chaitanya Bandi <bandik@nvidia.com>"); 309 MODULE_ALIAS("platform:max77620-gpio"); 310 MODULE_LICENSE("GPL v2"); 311