1 // SPDX-License-Identifier: GPL-2.0-only
3 * MAXIM MAX77620 GPIO driver
5 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
8 #include <linux/gpio/driver.h>
9 #include <linux/interrupt.h>
10 #include <linux/mfd/max77620.h>
11 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <linux/regmap.h>
15 #define GPIO_REG_ADDR(offset) (MAX77620_REG_GPIO0 + offset)
17 struct max77620_gpio
{
18 struct gpio_chip gpio_chip
;
23 static const struct regmap_irq max77620_gpio_irqs
[] = {
26 .mask
= MAX77620_IRQ_LVL2_GPIO_EDGE0
,
28 .type_rising_val
= MAX77620_CNFG_GPIO_INT_RISING
,
29 .type_falling_val
= MAX77620_CNFG_GPIO_INT_FALLING
,
30 .type_reg_mask
= MAX77620_CNFG_GPIO_INT_MASK
,
32 .types_supported
= IRQ_TYPE_EDGE_BOTH
,
37 .mask
= MAX77620_IRQ_LVL2_GPIO_EDGE1
,
39 .type_rising_val
= MAX77620_CNFG_GPIO_INT_RISING
,
40 .type_falling_val
= MAX77620_CNFG_GPIO_INT_FALLING
,
41 .type_reg_mask
= MAX77620_CNFG_GPIO_INT_MASK
,
43 .types_supported
= IRQ_TYPE_EDGE_BOTH
,
48 .mask
= MAX77620_IRQ_LVL2_GPIO_EDGE2
,
50 .type_rising_val
= MAX77620_CNFG_GPIO_INT_RISING
,
51 .type_falling_val
= MAX77620_CNFG_GPIO_INT_FALLING
,
52 .type_reg_mask
= MAX77620_CNFG_GPIO_INT_MASK
,
54 .types_supported
= IRQ_TYPE_EDGE_BOTH
,
59 .mask
= MAX77620_IRQ_LVL2_GPIO_EDGE3
,
61 .type_rising_val
= MAX77620_CNFG_GPIO_INT_RISING
,
62 .type_falling_val
= MAX77620_CNFG_GPIO_INT_FALLING
,
63 .type_reg_mask
= MAX77620_CNFG_GPIO_INT_MASK
,
65 .types_supported
= IRQ_TYPE_EDGE_BOTH
,
70 .mask
= MAX77620_IRQ_LVL2_GPIO_EDGE4
,
72 .type_rising_val
= MAX77620_CNFG_GPIO_INT_RISING
,
73 .type_falling_val
= MAX77620_CNFG_GPIO_INT_FALLING
,
74 .type_reg_mask
= MAX77620_CNFG_GPIO_INT_MASK
,
76 .types_supported
= IRQ_TYPE_EDGE_BOTH
,
81 .mask
= MAX77620_IRQ_LVL2_GPIO_EDGE5
,
83 .type_rising_val
= MAX77620_CNFG_GPIO_INT_RISING
,
84 .type_falling_val
= MAX77620_CNFG_GPIO_INT_FALLING
,
85 .type_reg_mask
= MAX77620_CNFG_GPIO_INT_MASK
,
87 .types_supported
= IRQ_TYPE_EDGE_BOTH
,
92 .mask
= MAX77620_IRQ_LVL2_GPIO_EDGE6
,
94 .type_rising_val
= MAX77620_CNFG_GPIO_INT_RISING
,
95 .type_falling_val
= MAX77620_CNFG_GPIO_INT_FALLING
,
96 .type_reg_mask
= MAX77620_CNFG_GPIO_INT_MASK
,
98 .types_supported
= IRQ_TYPE_EDGE_BOTH
,
103 .mask
= MAX77620_IRQ_LVL2_GPIO_EDGE7
,
105 .type_rising_val
= MAX77620_CNFG_GPIO_INT_RISING
,
106 .type_falling_val
= MAX77620_CNFG_GPIO_INT_FALLING
,
107 .type_reg_mask
= MAX77620_CNFG_GPIO_INT_MASK
,
108 .type_reg_offset
= 7,
109 .types_supported
= IRQ_TYPE_EDGE_BOTH
,
114 static const struct regmap_irq_chip max77620_gpio_irq_chip
= {
115 .name
= "max77620-gpio",
116 .irqs
= max77620_gpio_irqs
,
117 .num_irqs
= ARRAY_SIZE(max77620_gpio_irqs
),
121 .type_reg_stride
= 1,
122 .status_base
= MAX77620_REG_IRQ_LVL2_GPIO
,
123 .type_base
= MAX77620_REG_GPIO0
,
126 static int max77620_gpio_dir_input(struct gpio_chip
*gc
, unsigned int offset
)
128 struct max77620_gpio
*mgpio
= gpiochip_get_data(gc
);
131 ret
= regmap_update_bits(mgpio
->rmap
, GPIO_REG_ADDR(offset
),
132 MAX77620_CNFG_GPIO_DIR_MASK
,
133 MAX77620_CNFG_GPIO_DIR_INPUT
);
135 dev_err(mgpio
->dev
, "CNFG_GPIOx dir update failed: %d\n", ret
);
140 static int max77620_gpio_get(struct gpio_chip
*gc
, unsigned int offset
)
142 struct max77620_gpio
*mgpio
= gpiochip_get_data(gc
);
146 ret
= regmap_read(mgpio
->rmap
, GPIO_REG_ADDR(offset
), &val
);
148 dev_err(mgpio
->dev
, "CNFG_GPIOx read failed: %d\n", ret
);
152 if (val
& MAX77620_CNFG_GPIO_DIR_MASK
)
153 return !!(val
& MAX77620_CNFG_GPIO_INPUT_VAL_MASK
);
155 return !!(val
& MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK
);
158 static int max77620_gpio_dir_output(struct gpio_chip
*gc
, unsigned int offset
,
161 struct max77620_gpio
*mgpio
= gpiochip_get_data(gc
);
165 val
= (value
) ? MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH
:
166 MAX77620_CNFG_GPIO_OUTPUT_VAL_LOW
;
168 ret
= regmap_update_bits(mgpio
->rmap
, GPIO_REG_ADDR(offset
),
169 MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK
, val
);
171 dev_err(mgpio
->dev
, "CNFG_GPIOx val update failed: %d\n", ret
);
175 ret
= regmap_update_bits(mgpio
->rmap
, GPIO_REG_ADDR(offset
),
176 MAX77620_CNFG_GPIO_DIR_MASK
,
177 MAX77620_CNFG_GPIO_DIR_OUTPUT
);
179 dev_err(mgpio
->dev
, "CNFG_GPIOx dir update failed: %d\n", ret
);
184 static int max77620_gpio_set_debounce(struct max77620_gpio
*mgpio
,
186 unsigned int debounce
)
193 val
= MAX77620_CNFG_GPIO_DBNC_None
;
196 val
= MAX77620_CNFG_GPIO_DBNC_8ms
;
199 val
= MAX77620_CNFG_GPIO_DBNC_16ms
;
202 val
= MAX77620_CNFG_GPIO_DBNC_32ms
;
205 dev_err(mgpio
->dev
, "Illegal value %u\n", debounce
);
209 ret
= regmap_update_bits(mgpio
->rmap
, GPIO_REG_ADDR(offset
),
210 MAX77620_CNFG_GPIO_DBNC_MASK
, val
);
212 dev_err(mgpio
->dev
, "CNFG_GPIOx_DBNC update failed: %d\n", ret
);
217 static void max77620_gpio_set(struct gpio_chip
*gc
, unsigned int offset
,
220 struct max77620_gpio
*mgpio
= gpiochip_get_data(gc
);
224 val
= (value
) ? MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH
:
225 MAX77620_CNFG_GPIO_OUTPUT_VAL_LOW
;
227 ret
= regmap_update_bits(mgpio
->rmap
, GPIO_REG_ADDR(offset
),
228 MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK
, val
);
230 dev_err(mgpio
->dev
, "CNFG_GPIO_OUT update failed: %d\n", ret
);
233 static int max77620_gpio_set_config(struct gpio_chip
*gc
, unsigned int offset
,
234 unsigned long config
)
236 struct max77620_gpio
*mgpio
= gpiochip_get_data(gc
);
238 switch (pinconf_to_config_param(config
)) {
239 case PIN_CONFIG_DRIVE_OPEN_DRAIN
:
240 return regmap_update_bits(mgpio
->rmap
, GPIO_REG_ADDR(offset
),
241 MAX77620_CNFG_GPIO_DRV_MASK
,
242 MAX77620_CNFG_GPIO_DRV_OPENDRAIN
);
243 case PIN_CONFIG_DRIVE_PUSH_PULL
:
244 return regmap_update_bits(mgpio
->rmap
, GPIO_REG_ADDR(offset
),
245 MAX77620_CNFG_GPIO_DRV_MASK
,
246 MAX77620_CNFG_GPIO_DRV_PUSHPULL
);
247 case PIN_CONFIG_INPUT_DEBOUNCE
:
248 return max77620_gpio_set_debounce(mgpio
, offset
,
249 pinconf_to_config_argument(config
));
257 static int max77620_gpio_to_irq(struct gpio_chip
*gc
, unsigned int offset
)
259 struct max77620_gpio
*mgpio
= gpiochip_get_data(gc
);
260 struct max77620_chip
*chip
= dev_get_drvdata(mgpio
->dev
->parent
);
262 return regmap_irq_get_virq(chip
->gpio_irq_data
, offset
);
265 static int max77620_gpio_probe(struct platform_device
*pdev
)
267 struct max77620_chip
*chip
= dev_get_drvdata(pdev
->dev
.parent
);
268 struct max77620_gpio
*mgpio
;
272 gpio_irq
= platform_get_irq(pdev
, 0);
274 dev_err(&pdev
->dev
, "GPIO irq not available %d\n", gpio_irq
);
278 mgpio
= devm_kzalloc(&pdev
->dev
, sizeof(*mgpio
), GFP_KERNEL
);
282 mgpio
->rmap
= chip
->rmap
;
283 mgpio
->dev
= &pdev
->dev
;
285 mgpio
->gpio_chip
.label
= pdev
->name
;
286 mgpio
->gpio_chip
.parent
= &pdev
->dev
;
287 mgpio
->gpio_chip
.direction_input
= max77620_gpio_dir_input
;
288 mgpio
->gpio_chip
.get
= max77620_gpio_get
;
289 mgpio
->gpio_chip
.direction_output
= max77620_gpio_dir_output
;
290 mgpio
->gpio_chip
.set
= max77620_gpio_set
;
291 mgpio
->gpio_chip
.set_config
= max77620_gpio_set_config
;
292 mgpio
->gpio_chip
.to_irq
= max77620_gpio_to_irq
;
293 mgpio
->gpio_chip
.ngpio
= MAX77620_GPIO_NR
;
294 mgpio
->gpio_chip
.can_sleep
= 1;
295 mgpio
->gpio_chip
.base
= -1;
296 #ifdef CONFIG_OF_GPIO
297 mgpio
->gpio_chip
.of_node
= pdev
->dev
.parent
->of_node
;
300 platform_set_drvdata(pdev
, mgpio
);
302 ret
= devm_gpiochip_add_data(&pdev
->dev
, &mgpio
->gpio_chip
, mgpio
);
304 dev_err(&pdev
->dev
, "gpio_init: Failed to add max77620_gpio\n");
308 ret
= devm_regmap_add_irq_chip(&pdev
->dev
, chip
->rmap
, gpio_irq
,
310 &max77620_gpio_irq_chip
,
311 &chip
->gpio_irq_data
);
313 dev_err(&pdev
->dev
, "Failed to add gpio irq_chip %d\n", ret
);
320 static const struct platform_device_id max77620_gpio_devtype
[] = {
321 { .name
= "max77620-gpio", },
322 { .name
= "max20024-gpio", },
325 MODULE_DEVICE_TABLE(platform
, max77620_gpio_devtype
);
327 static struct platform_driver max77620_gpio_driver
= {
328 .driver
.name
= "max77620-gpio",
329 .probe
= max77620_gpio_probe
,
330 .id_table
= max77620_gpio_devtype
,
333 module_platform_driver(max77620_gpio_driver
);
335 MODULE_DESCRIPTION("GPIO interface for MAX77620 and MAX20024 PMIC");
336 MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
337 MODULE_AUTHOR("Chaitanya Bandi <bandik@nvidia.com>");
338 MODULE_ALIAS("platform:max77620-gpio");
339 MODULE_LICENSE("GPL v2");