1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * AXP20x pinctrl and GPIO driver
5 * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com>
6 * Copyright (C) 2017 Quentin Schulz <quentin.schulz@free-electrons.com>
9 #include <linux/bitops.h>
10 #include <linux/device.h>
11 #include <linux/gpio/driver.h>
12 #include <linux/init.h>
13 #include <linux/interrupt.h>
14 #include <linux/kernel.h>
15 #include <linux/mfd/axp20x.h>
16 #include <linux/module.h>
18 #include <linux/platform_device.h>
19 #include <linux/regmap.h>
20 #include <linux/slab.h>
22 #include <linux/pinctrl/consumer.h>
23 #include <linux/pinctrl/pinconf-generic.h>
24 #include <linux/pinctrl/pinctrl.h>
25 #include <linux/pinctrl/pinmux.h>
27 #define AXP20X_GPIO_FUNCTIONS 0x7
28 #define AXP20X_GPIO_FUNCTION_OUT_LOW 0
29 #define AXP20X_GPIO_FUNCTION_OUT_HIGH 1
30 #define AXP20X_GPIO_FUNCTION_INPUT 2
32 #define AXP20X_GPIO3_FUNCTIONS GENMASK(2, 1)
33 #define AXP20X_GPIO3_FUNCTION_OUT_LOW 0
34 #define AXP20X_GPIO3_FUNCTION_OUT_HIGH 2
35 #define AXP20X_GPIO3_FUNCTION_INPUT 4
37 #define AXP20X_FUNC_GPIO_OUT 0
38 #define AXP20X_FUNC_GPIO_IN 1
39 #define AXP20X_FUNC_LDO 2
40 #define AXP20X_FUNC_ADC 3
41 #define AXP20X_FUNCS_NB 4
43 #define AXP20X_MUX_GPIO_OUT 0
44 #define AXP20X_MUX_GPIO_IN BIT(1)
45 #define AXP20X_MUX_ADC BIT(2)
47 #define AXP813_MUX_ADC (BIT(2) | BIT(0))
49 struct axp20x_pctrl_desc
{
50 const struct pinctrl_pin_desc
*pins
;
52 /* Stores the pins supporting LDO function. Bit offset is pin number. */
54 /* Stores the pins supporting ADC function. Bit offset is pin number. */
56 u8 gpio_status_offset
;
60 struct axp20x_pinctrl_function
{
68 struct gpio_chip chip
;
69 struct regmap
*regmap
;
70 struct pinctrl_dev
*pctl_dev
;
72 const struct axp20x_pctrl_desc
*desc
;
73 struct axp20x_pinctrl_function funcs
[AXP20X_FUNCS_NB
];
76 static const struct pinctrl_pin_desc axp209_pins
[] = {
77 PINCTRL_PIN(0, "GPIO0"),
78 PINCTRL_PIN(1, "GPIO1"),
79 PINCTRL_PIN(2, "GPIO2"),
80 PINCTRL_PIN(3, "GPIO3"),
83 static const struct pinctrl_pin_desc axp22x_pins
[] = {
84 PINCTRL_PIN(0, "GPIO0"),
85 PINCTRL_PIN(1, "GPIO1"),
88 static const struct axp20x_pctrl_desc axp20x_data
= {
90 .npins
= ARRAY_SIZE(axp209_pins
),
91 .ldo_mask
= BIT(0) | BIT(1),
92 .adc_mask
= BIT(0) | BIT(1),
93 .gpio_status_offset
= 4,
94 .adc_mux
= AXP20X_MUX_ADC
,
97 static const struct axp20x_pctrl_desc axp22x_data
= {
99 .npins
= ARRAY_SIZE(axp22x_pins
),
100 .ldo_mask
= BIT(0) | BIT(1),
101 .gpio_status_offset
= 0,
104 static const struct axp20x_pctrl_desc axp813_data
= {
106 .npins
= ARRAY_SIZE(axp22x_pins
),
107 .ldo_mask
= BIT(0) | BIT(1),
109 .gpio_status_offset
= 0,
110 .adc_mux
= AXP813_MUX_ADC
,
113 static int axp20x_gpio_get_reg(unsigned int offset
)
117 return AXP20X_GPIO0_CTRL
;
119 return AXP20X_GPIO1_CTRL
;
121 return AXP20X_GPIO2_CTRL
;
127 static int axp20x_gpio_get(struct gpio_chip
*chip
, unsigned int offset
)
129 struct axp20x_pctl
*pctl
= gpiochip_get_data(chip
);
133 /* AXP209 has GPIO3 status sharing the settings register */
135 ret
= regmap_read(pctl
->regmap
, AXP20X_GPIO3_CTRL
, &val
);
138 return !!(val
& BIT(0));
141 ret
= regmap_read(pctl
->regmap
, AXP20X_GPIO20_SS
, &val
);
145 return !!(val
& BIT(offset
+ pctl
->desc
->gpio_status_offset
));
148 static int axp20x_gpio_get_direction(struct gpio_chip
*chip
,
151 struct axp20x_pctl
*pctl
= gpiochip_get_data(chip
);
155 /* AXP209 GPIO3 settings have a different layout */
157 ret
= regmap_read(pctl
->regmap
, AXP20X_GPIO3_CTRL
, &val
);
160 if (val
& AXP20X_GPIO3_FUNCTION_INPUT
)
161 return GPIO_LINE_DIRECTION_IN
;
163 return GPIO_LINE_DIRECTION_OUT
;
166 reg
= axp20x_gpio_get_reg(offset
);
170 ret
= regmap_read(pctl
->regmap
, reg
, &val
);
175 * This shouldn't really happen if the pin is in use already,
176 * or if it's not in use yet, it doesn't matter since we're
177 * going to change the value soon anyway. Default to output.
179 if ((val
& AXP20X_GPIO_FUNCTIONS
) > 2)
180 return GPIO_LINE_DIRECTION_OUT
;
183 * The GPIO directions are the three lowest values.
184 * 2 is input, 0 and 1 are output
187 return GPIO_LINE_DIRECTION_IN
;
189 return GPIO_LINE_DIRECTION_OUT
;
192 static int axp20x_gpio_output(struct gpio_chip
*chip
, unsigned int offset
,
195 chip
->set(chip
, offset
, value
);
200 static void axp20x_gpio_set(struct gpio_chip
*chip
, unsigned int offset
,
203 struct axp20x_pctl
*pctl
= gpiochip_get_data(chip
);
206 /* AXP209 has GPIO3 status sharing the settings register */
208 regmap_update_bits(pctl
->regmap
, AXP20X_GPIO3_CTRL
,
209 AXP20X_GPIO3_FUNCTIONS
,
210 value
? AXP20X_GPIO3_FUNCTION_OUT_HIGH
:
211 AXP20X_GPIO3_FUNCTION_OUT_LOW
);
215 reg
= axp20x_gpio_get_reg(offset
);
219 regmap_update_bits(pctl
->regmap
, reg
,
220 AXP20X_GPIO_FUNCTIONS
,
221 value
? AXP20X_GPIO_FUNCTION_OUT_HIGH
:
222 AXP20X_GPIO_FUNCTION_OUT_LOW
);
225 static int axp20x_pmx_set(struct pinctrl_dev
*pctldev
, unsigned int offset
,
228 struct axp20x_pctl
*pctl
= pinctrl_dev_get_drvdata(pctldev
);
231 /* AXP209 GPIO3 settings have a different layout */
233 return regmap_update_bits(pctl
->regmap
, AXP20X_GPIO3_CTRL
,
234 AXP20X_GPIO3_FUNCTIONS
,
235 config
== AXP20X_MUX_GPIO_OUT
? AXP20X_GPIO3_FUNCTION_OUT_LOW
:
236 AXP20X_GPIO3_FUNCTION_INPUT
);
239 reg
= axp20x_gpio_get_reg(offset
);
243 return regmap_update_bits(pctl
->regmap
, reg
, AXP20X_GPIO_FUNCTIONS
,
247 static int axp20x_pmx_func_cnt(struct pinctrl_dev
*pctldev
)
249 struct axp20x_pctl
*pctl
= pinctrl_dev_get_drvdata(pctldev
);
251 return ARRAY_SIZE(pctl
->funcs
);
254 static const char *axp20x_pmx_func_name(struct pinctrl_dev
*pctldev
,
255 unsigned int selector
)
257 struct axp20x_pctl
*pctl
= pinctrl_dev_get_drvdata(pctldev
);
259 return pctl
->funcs
[selector
].name
;
262 static int axp20x_pmx_func_groups(struct pinctrl_dev
*pctldev
,
263 unsigned int selector
,
264 const char * const **groups
,
265 unsigned int *num_groups
)
267 struct axp20x_pctl
*pctl
= pinctrl_dev_get_drvdata(pctldev
);
269 *groups
= pctl
->funcs
[selector
].groups
;
270 *num_groups
= pctl
->funcs
[selector
].ngroups
;
275 static int axp20x_pmx_set_mux(struct pinctrl_dev
*pctldev
,
276 unsigned int function
, unsigned int group
)
278 struct axp20x_pctl
*pctl
= pinctrl_dev_get_drvdata(pctldev
);
281 /* Every pin supports GPIO_OUT and GPIO_IN functions */
282 if (function
<= AXP20X_FUNC_GPIO_IN
)
283 return axp20x_pmx_set(pctldev
, group
,
284 pctl
->funcs
[function
].muxval
);
286 if (function
== AXP20X_FUNC_LDO
)
287 mask
= pctl
->desc
->ldo_mask
;
289 mask
= pctl
->desc
->adc_mask
;
291 if (!(BIT(group
) & mask
))
295 * We let the regulator framework handle the LDO muxing as muxing bits
296 * are basically also regulators on/off bits. It's better not to enforce
297 * any state of the regulator when selecting LDO mux so that we don't
298 * interfere with the regulator driver.
300 if (function
== AXP20X_FUNC_LDO
)
303 return axp20x_pmx_set(pctldev
, group
, pctl
->funcs
[function
].muxval
);
306 static int axp20x_pmx_gpio_set_direction(struct pinctrl_dev
*pctldev
,
307 struct pinctrl_gpio_range
*range
,
308 unsigned int offset
, bool input
)
310 struct axp20x_pctl
*pctl
= pinctrl_dev_get_drvdata(pctldev
);
313 return axp20x_pmx_set(pctldev
, offset
,
314 pctl
->funcs
[AXP20X_FUNC_GPIO_IN
].muxval
);
316 return axp20x_pmx_set(pctldev
, offset
,
317 pctl
->funcs
[AXP20X_FUNC_GPIO_OUT
].muxval
);
320 static const struct pinmux_ops axp20x_pmx_ops
= {
321 .get_functions_count
= axp20x_pmx_func_cnt
,
322 .get_function_name
= axp20x_pmx_func_name
,
323 .get_function_groups
= axp20x_pmx_func_groups
,
324 .set_mux
= axp20x_pmx_set_mux
,
325 .gpio_set_direction
= axp20x_pmx_gpio_set_direction
,
329 static int axp20x_groups_cnt(struct pinctrl_dev
*pctldev
)
331 struct axp20x_pctl
*pctl
= pinctrl_dev_get_drvdata(pctldev
);
333 return pctl
->desc
->npins
;
336 static int axp20x_group_pins(struct pinctrl_dev
*pctldev
, unsigned int selector
,
337 const unsigned int **pins
, unsigned int *num_pins
)
339 struct axp20x_pctl
*pctl
= pinctrl_dev_get_drvdata(pctldev
);
341 *pins
= (unsigned int *)&pctl
->desc
->pins
[selector
];
347 static const char *axp20x_group_name(struct pinctrl_dev
*pctldev
,
348 unsigned int selector
)
350 struct axp20x_pctl
*pctl
= pinctrl_dev_get_drvdata(pctldev
);
352 return pctl
->desc
->pins
[selector
].name
;
355 static const struct pinctrl_ops axp20x_pctrl_ops
= {
356 .dt_node_to_map
= pinconf_generic_dt_node_to_map_group
,
357 .dt_free_map
= pinconf_generic_dt_free_map
,
358 .get_groups_count
= axp20x_groups_cnt
,
359 .get_group_name
= axp20x_group_name
,
360 .get_group_pins
= axp20x_group_pins
,
363 static int axp20x_funcs_groups_from_mask(struct device
*dev
, unsigned int mask
,
364 unsigned int mask_len
,
365 struct axp20x_pinctrl_function
*func
,
366 const struct pinctrl_pin_desc
*pins
)
368 unsigned long int mask_cpy
= mask
;
370 unsigned int ngroups
= hweight8(mask
);
373 func
->ngroups
= ngroups
;
374 if (func
->ngroups
> 0) {
375 func
->groups
= devm_kcalloc(dev
,
376 ngroups
, sizeof(const char *),
380 group
= func
->groups
;
381 for_each_set_bit(bit
, &mask_cpy
, mask_len
) {
382 *group
= pins
[bit
].name
;
390 static int axp20x_build_funcs_groups(struct platform_device
*pdev
)
392 struct axp20x_pctl
*pctl
= platform_get_drvdata(pdev
);
393 int i
, ret
, pin
, npins
= pctl
->desc
->npins
;
395 pctl
->funcs
[AXP20X_FUNC_GPIO_OUT
].name
= "gpio_out";
396 pctl
->funcs
[AXP20X_FUNC_GPIO_OUT
].muxval
= AXP20X_MUX_GPIO_OUT
;
397 pctl
->funcs
[AXP20X_FUNC_GPIO_IN
].name
= "gpio_in";
398 pctl
->funcs
[AXP20X_FUNC_GPIO_IN
].muxval
= AXP20X_MUX_GPIO_IN
;
399 pctl
->funcs
[AXP20X_FUNC_LDO
].name
= "ldo";
401 * Muxval for LDO is useless as we won't use it.
402 * See comment in axp20x_pmx_set_mux.
404 pctl
->funcs
[AXP20X_FUNC_ADC
].name
= "adc";
405 pctl
->funcs
[AXP20X_FUNC_ADC
].muxval
= pctl
->desc
->adc_mux
;
407 /* Every pin supports GPIO_OUT and GPIO_IN functions */
408 for (i
= 0; i
<= AXP20X_FUNC_GPIO_IN
; i
++) {
409 pctl
->funcs
[i
].ngroups
= npins
;
410 pctl
->funcs
[i
].groups
= devm_kcalloc(&pdev
->dev
,
411 npins
, sizeof(char *),
413 if (!pctl
->funcs
[i
].groups
)
415 for (pin
= 0; pin
< npins
; pin
++)
416 pctl
->funcs
[i
].groups
[pin
] = pctl
->desc
->pins
[pin
].name
;
419 ret
= axp20x_funcs_groups_from_mask(&pdev
->dev
, pctl
->desc
->ldo_mask
,
420 npins
, &pctl
->funcs
[AXP20X_FUNC_LDO
],
425 ret
= axp20x_funcs_groups_from_mask(&pdev
->dev
, pctl
->desc
->adc_mask
,
426 npins
, &pctl
->funcs
[AXP20X_FUNC_ADC
],
434 static const struct of_device_id axp20x_pctl_match
[] = {
435 { .compatible
= "x-powers,axp209-gpio", .data
= &axp20x_data
, },
436 { .compatible
= "x-powers,axp221-gpio", .data
= &axp22x_data
, },
437 { .compatible
= "x-powers,axp813-gpio", .data
= &axp813_data
, },
440 MODULE_DEVICE_TABLE(of
, axp20x_pctl_match
);
442 static int axp20x_pctl_probe(struct platform_device
*pdev
)
444 struct axp20x_dev
*axp20x
= dev_get_drvdata(pdev
->dev
.parent
);
445 struct axp20x_pctl
*pctl
;
446 struct device
*dev
= &pdev
->dev
;
447 struct pinctrl_desc
*pctrl_desc
;
450 if (!of_device_is_available(pdev
->dev
.of_node
))
454 dev_err(&pdev
->dev
, "Parent drvdata not set\n");
458 pctl
= devm_kzalloc(&pdev
->dev
, sizeof(*pctl
), GFP_KERNEL
);
462 pctl
->chip
.base
= -1;
463 pctl
->chip
.can_sleep
= true;
464 pctl
->chip
.request
= gpiochip_generic_request
;
465 pctl
->chip
.free
= gpiochip_generic_free
;
466 pctl
->chip
.parent
= &pdev
->dev
;
467 pctl
->chip
.label
= dev_name(&pdev
->dev
);
468 pctl
->chip
.owner
= THIS_MODULE
;
469 pctl
->chip
.get
= axp20x_gpio_get
;
470 pctl
->chip
.get_direction
= axp20x_gpio_get_direction
;
471 pctl
->chip
.set
= axp20x_gpio_set
;
472 pctl
->chip
.direction_input
= pinctrl_gpio_direction_input
;
473 pctl
->chip
.direction_output
= axp20x_gpio_output
;
475 pctl
->desc
= of_device_get_match_data(dev
);
477 pctl
->chip
.ngpio
= pctl
->desc
->npins
;
479 pctl
->regmap
= axp20x
->regmap
;
480 pctl
->dev
= &pdev
->dev
;
482 platform_set_drvdata(pdev
, pctl
);
484 ret
= axp20x_build_funcs_groups(pdev
);
486 dev_err(&pdev
->dev
, "failed to build groups\n");
490 pctrl_desc
= devm_kzalloc(&pdev
->dev
, sizeof(*pctrl_desc
), GFP_KERNEL
);
494 pctrl_desc
->name
= dev_name(&pdev
->dev
);
495 pctrl_desc
->owner
= THIS_MODULE
;
496 pctrl_desc
->pins
= pctl
->desc
->pins
;
497 pctrl_desc
->npins
= pctl
->desc
->npins
;
498 pctrl_desc
->pctlops
= &axp20x_pctrl_ops
;
499 pctrl_desc
->pmxops
= &axp20x_pmx_ops
;
501 pctl
->pctl_dev
= devm_pinctrl_register(&pdev
->dev
, pctrl_desc
, pctl
);
502 if (IS_ERR(pctl
->pctl_dev
)) {
503 dev_err(&pdev
->dev
, "couldn't register pinctrl driver\n");
504 return PTR_ERR(pctl
->pctl_dev
);
507 ret
= devm_gpiochip_add_data(&pdev
->dev
, &pctl
->chip
, pctl
);
509 dev_err(&pdev
->dev
, "Failed to register GPIO chip\n");
513 ret
= gpiochip_add_pin_range(&pctl
->chip
, dev_name(&pdev
->dev
),
514 pctl
->desc
->pins
->number
,
515 pctl
->desc
->pins
->number
,
518 dev_err(&pdev
->dev
, "failed to add pin range\n");
522 dev_info(&pdev
->dev
, "AXP209 pinctrl and GPIO driver loaded\n");
527 static struct platform_driver axp20x_pctl_driver
= {
528 .probe
= axp20x_pctl_probe
,
530 .name
= "axp20x-gpio",
531 .of_match_table
= axp20x_pctl_match
,
535 module_platform_driver(axp20x_pctl_driver
);
537 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
538 MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
539 MODULE_DESCRIPTION("AXP20x PMIC pinctrl and GPIO driver");
540 MODULE_LICENSE("GPL");