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