1 // SPDX-License-Identifier: GPL-2.0+
3 * Driver for BCM63xx GPIO unit (pinctrl + GPIO)
5 * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
6 * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
9 #include <linux/gpio/regmap.h>
10 #include <linux/mfd/syscon.h>
11 #include <linux/mod_devicetable.h>
13 #include <linux/platform_device.h>
15 #include "pinctrl-bcm63xx.h"
17 #define BCM63XX_BANK_SIZE 4
19 #define BCM63XX_DIROUT_REG 0x04
20 #define BCM63XX_DATA_REG 0x0c
22 static int bcm63xx_reg_mask_xlate(struct gpio_regmap
*gpio
,
23 unsigned int base
, unsigned int offset
,
24 unsigned int *reg
, unsigned int *mask
)
26 unsigned int line
= offset
% BCM63XX_BANK_GPIOS
;
27 unsigned int stride
= offset
/ BCM63XX_BANK_GPIOS
;
29 *reg
= base
- stride
* BCM63XX_BANK_SIZE
;
35 static const struct of_device_id bcm63xx_gpio_of_match
[] = {
36 { .compatible
= "brcm,bcm6318-gpio", },
37 { .compatible
= "brcm,bcm6328-gpio", },
38 { .compatible
= "brcm,bcm6358-gpio", },
39 { .compatible
= "brcm,bcm6362-gpio", },
40 { .compatible
= "brcm,bcm6368-gpio", },
41 { .compatible
= "brcm,bcm63268-gpio", },
45 static int bcm63xx_gpio_probe(struct device
*dev
, struct device_node
*node
,
46 const struct bcm63xx_pinctrl_soc
*soc
,
47 struct bcm63xx_pinctrl
*pc
)
49 struct gpio_regmap_config grc
= {0};
52 grc
.fwnode
= &node
->fwnode
;
53 grc
.ngpio
= soc
->ngpios
;
54 grc
.ngpio_per_reg
= BCM63XX_BANK_GPIOS
;
55 grc
.regmap
= pc
->regs
;
56 grc
.reg_dat_base
= BCM63XX_DATA_REG
;
57 grc
.reg_dir_out_base
= BCM63XX_DIROUT_REG
;
58 grc
.reg_set_base
= BCM63XX_DATA_REG
;
59 grc
.reg_mask_xlate
= bcm63xx_reg_mask_xlate
;
61 return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev
, &grc
));
64 int bcm63xx_pinctrl_probe(struct platform_device
*pdev
,
65 const struct bcm63xx_pinctrl_soc
*soc
,
68 struct device
*dev
= &pdev
->dev
;
69 struct bcm63xx_pinctrl
*pc
;
72 pc
= devm_kzalloc(dev
, sizeof(*pc
), GFP_KERNEL
);
76 platform_set_drvdata(pdev
, pc
);
79 pc
->driver_data
= driver_data
;
81 pc
->regs
= syscon_node_to_regmap(dev
->parent
->of_node
);
83 return PTR_ERR(pc
->regs
);
85 pc
->pctl_desc
.name
= dev_name(dev
);
86 pc
->pctl_desc
.pins
= soc
->pins
;
87 pc
->pctl_desc
.npins
= soc
->npins
;
88 pc
->pctl_desc
.pctlops
= soc
->pctl_ops
;
89 pc
->pctl_desc
.pmxops
= soc
->pmx_ops
;
90 pc
->pctl_desc
.owner
= THIS_MODULE
;
92 pc
->pctl_dev
= devm_pinctrl_register(dev
, &pc
->pctl_desc
, pc
);
93 if (IS_ERR(pc
->pctl_dev
))
94 return PTR_ERR(pc
->pctl_dev
);
96 for_each_child_of_node_scoped(dev
->parent
->of_node
, node
) {
97 if (of_match_node(bcm63xx_gpio_of_match
, node
)) {
98 err
= bcm63xx_gpio_probe(dev
, node
, soc
, pc
);
100 dev_err(dev
, "could not add GPIO chip\n");