Re: [PATCH 4/6] pinctrl: bcm: Add pinconf/pinmux controller driver for BCM2712

From: Christophe JAILLET
Date: Sun Apr 14 2024 - 03:21:25 EST


Le 14/04/2024 à 00:14, Andrea della Porta a écrit :
Add a pincontrol driver for BCM2712. BCM2712 allows muxing GPIOs
and setting configuration on pads.

Originally-by: Jonathan Bell <jonathan@xxxxxxxxxxxxxxx>
Originally-by: Phil Elwell <phil@xxxxxxxxxxxxxxx>
Signed-off-by: Andrea della Porta <andrea.porta@xxxxxxxx>
---
drivers/pinctrl/bcm/Kconfig | 9 +
drivers/pinctrl/bcm/Makefile | 1 +
drivers/pinctrl/bcm/pinctrl-bcm2712.c | 1247 +++++++++++++++++++++++++
3 files changed, 1257 insertions(+)
create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm2712.c

..

+static int bcm2712_pmx_get_function_groups(struct pinctrl_dev *pctldev,
+ unsigned selector,
+ const char * const **groups,
+ unsigned * const num_groups)
+{
+ struct bcm2712_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);

Missing empty new line.

+ /* every pin can do every function */
+ *groups = pc->gpio_groups;
+ *num_groups = pc->pctl_desc.npins;
+
+ return 0;
+}

..

+static int bcm2712_pinconf_get(struct pinctrl_dev *pctldev,
+ unsigned pin, unsigned long *config)
+{
+ struct bcm2712_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+ enum pin_config_param param = pinconf_to_config_param(*config);
+ u32 arg;
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ arg = (bcm2712_pull_config_get(pc, pin) == BCM2712_PULL_NONE);
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ arg = (bcm2712_pull_config_get(pc, pin) == BCM2712_PULL_DOWN);
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ arg = (bcm2712_pull_config_get(pc, pin) == BCM2712_PULL_UP);
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ *config = pinconf_to_config_packed(param, arg);
+
+ return -ENOTSUPP;

Strange.

return 0;
?

+}
+
+static int bcm2712_pinconf_set(struct pinctrl_dev *pctldev,
+ unsigned int pin, unsigned long *configs,
+ unsigned int num_configs)
+{
+ struct bcm2712_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+ u32 param, arg;
+ int i;
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ bcm2712_pull_config_set(pc, pin, BCM2712_PULL_NONE);
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ bcm2712_pull_config_set(pc, pin, BCM2712_PULL_DOWN);
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ bcm2712_pull_config_set(pc, pin, BCM2712_PULL_UP);
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+ } /* for each config */

This comment is not really usefull, IMHO.

+
+ return 0;
+}

..

+static int bcm2712_pinctrl_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ //struct device_node *np = dev->of_node;
+ const struct bcm_plat_data *pdata;
+ //const struct of_device_id *match;
+ struct bcm2712_pinctrl *pc;
+ const char **names;
+ int num_pins, i;
+
+ pdata = device_get_match_data(&pdev->dev);
+ if (!pdata)
+ return -EINVAL;
+
+ pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
+ if (!pc)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, pc);
+ pc->dev = dev;
+ spin_lock_init(&pc->lock);
+
+ //pc->base = devm_of_iomap(dev, np, 0, NULL);

Any use for this commented code? (and variable declarations above)

CJ

+ pc->base = devm_platform_ioremap_resource(pdev, 0);
+ if (WARN_ON(IS_ERR(pc->base))) {
+ //dev_err(dev, "could not get IO memory\n");
+ return PTR_ERR(pc->base);
+ }
+
+ pc->pctl_desc = *pdata->pctl_desc;
+ num_pins = pc->pctl_desc.npins;
+ names = devm_kmalloc_array(dev, num_pins, sizeof(const char *),
+ GFP_KERNEL);
+ if (!names)
+ return -ENOMEM;
+ for (i = 0; i < num_pins; i++)
+ names[i] = pc->pctl_desc.pins[i].name;
+ pc->gpio_groups = names;
+ pc->pin_regs = pdata->pin_regs;
+ pc->pin_funcs = pdata->pin_funcs;
+ pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
+ if (IS_ERR(pc->pctl_dev))
+ return PTR_ERR(pc->pctl_dev);
+
+ pc->gpio_range = *pdata->gpio_range;
+ pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
+
+ return 0;
+}

..