]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
pinctrl: bcm281xx: Provide pinctrl device info as OF platform data
authorArtur Weber <aweber.kernel@gmail.com>
Mon, 3 Mar 2025 20:54:48 +0000 (21:54 +0100)
committerLinus Walleij <linus.walleij@linaro.org>
Wed, 5 Mar 2025 08:00:47 +0000 (09:00 +0100)
Introduce a new struct type, "bcm281xx_pinctrl_info", that holds
information about the pins, pin functions and regmap config for a pin
control chip. Create such a struct for the BCM218xx and pass it as
device data for the OF compatible match.

This is done in preparation for introducing additional chip types
to the driver.

Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
Link: https://lore.kernel.org/20250303-bcm21664-pinctrl-v3-3-5f8b80e4ab51@gmail.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/pinctrl/bcm/pinctrl-bcm281xx.c

index 3d774ee97aac064174843a07258f23b82527ca5a..f5aeb8a56e6ffa1204423ddc22204a4f0f4e8f84 100644 (file)
@@ -76,20 +76,40 @@ struct bcm281xx_pin_function {
 };
 
 /*
- * bcm281xx_pinctrl_data - Broadcom-specific pinctrl data
- * @reg_base - base of pinctrl registers
+ * Device types (used in bcm281xx_pinctrl_desc to differentiate
+ * the two device types from each other)
  */
-struct bcm281xx_pinctrl_data {
-       void __iomem *reg_base;
+enum bcm281xx_pinctrl_type {
+       BCM281XX_PINCTRL_TYPE,
+};
+
+/*
+ * bcm281xx_pinctrl_info - description of a pinctrl device supported
+ * by this driver, intended to be used as a provider of OF match data.
+ */
+struct bcm281xx_pinctrl_info {
+       enum bcm281xx_pinctrl_type device_type;
 
        /* List of all pins */
        const struct pinctrl_pin_desc *pins;
-       const unsigned int npins;
+       unsigned int npins;
 
        const struct bcm281xx_pin_function *functions;
-       const unsigned int nfunctions;
+       unsigned int nfunctions;
+
+       const struct regmap_config *regmap_config;
+};
+
+/*
+ * bcm281xx_pinctrl_data - Broadcom-specific pinctrl data
+ * @reg_base - base of pinctrl registers
+ */
+struct bcm281xx_pinctrl_data {
+       struct device *dev;
+       void __iomem *reg_base;
 
        struct regmap *regmap;
+       const struct bcm281xx_pinctrl_info *info;
 };
 
 /*
@@ -933,11 +953,22 @@ static const struct bcm281xx_pin_function bcm281xx_functions[] = {
        BCM281XX_PIN_FUNCTION(alt4),
 };
 
-static struct bcm281xx_pinctrl_data bcm281xx_pinctrl = {
+static const struct regmap_config bcm281xx_pinctrl_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .max_register = BCM281XX_PIN_VC_CAM3_SDA * 4,
+};
+
+static const struct bcm281xx_pinctrl_info bcm281xx_pinctrl = {
+       .device_type = BCM281XX_PINCTRL_TYPE,
+
        .pins = bcm281xx_pinctrl_pins,
        .npins = ARRAY_SIZE(bcm281xx_pinctrl_pins),
        .functions = bcm281xx_functions,
        .nfunctions = ARRAY_SIZE(bcm281xx_functions),
+
+       .regmap_config = &bcm281xx_pinctrl_regmap_config,
 };
 
 static inline enum bcm281xx_pin_type pin_type_get(struct pinctrl_dev *pctldev,
@@ -945,10 +976,10 @@ static inline enum bcm281xx_pin_type pin_type_get(struct pinctrl_dev *pctldev,
 {
        struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
 
-       if (pin >= pdata->npins)
+       if (pin >= pdata->info->npins)
                return BCM281XX_PIN_TYPE_UNKNOWN;
 
-       return *(enum bcm281xx_pin_type *)(pdata->pins[pin].drv_data);
+       return *(enum bcm281xx_pin_type *)(pdata->info->pins[pin].drv_data);
 }
 
 #define BCM281XX_PIN_SHIFT(type, param) \
@@ -970,18 +1001,11 @@ static inline void bcm281xx_pin_update(u32 *reg_val, u32 *reg_mask,
        *reg_mask |= param_mask;
 }
 
-static const struct regmap_config bcm281xx_pinctrl_regmap_config = {
-       .reg_bits = 32,
-       .reg_stride = 4,
-       .val_bits = 32,
-       .max_register = BCM281XX_PIN_VC_CAM3_SDA,
-};
-
 static int bcm281xx_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
 {
        struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
 
-       return pdata->npins;
+       return pdata->info->npins;
 }
 
 static const char *bcm281xx_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
@@ -989,7 +1013,7 @@ static const char *bcm281xx_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
 {
        struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
 
-       return pdata->pins[group].name;
+       return pdata->info->pins[group].name;
 }
 
 static int bcm281xx_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
@@ -999,7 +1023,7 @@ static int bcm281xx_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
 {
        struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
 
-       *pins = &pdata->pins[group].number;
+       *pins = &pdata->info->pins[group].number;
        *num_pins = 1;
 
        return 0;
@@ -1025,7 +1049,7 @@ static int bcm281xx_pinctrl_get_fcns_count(struct pinctrl_dev *pctldev)
 {
        struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
 
-       return pdata->nfunctions;
+       return pdata->info->nfunctions;
 }
 
 static const char *bcm281xx_pinctrl_get_fcn_name(struct pinctrl_dev *pctldev,
@@ -1033,7 +1057,7 @@ static const char *bcm281xx_pinctrl_get_fcn_name(struct pinctrl_dev *pctldev,
 {
        struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
 
-       return pdata->functions[function].name;
+       return pdata->info->functions[function].name;
 }
 
 static int bcm281xx_pinctrl_get_fcn_groups(struct pinctrl_dev *pctldev,
@@ -1043,8 +1067,8 @@ static int bcm281xx_pinctrl_get_fcn_groups(struct pinctrl_dev *pctldev,
 {
        struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
 
-       *groups = pdata->functions[function].groups;
-       *num_groups = pdata->functions[function].ngroups;
+       *groups = pdata->info->functions[function].groups;
+       *num_groups = pdata->info->functions[function].ngroups;
 
        return 0;
 }
@@ -1054,14 +1078,15 @@ static int bcm281xx_pinmux_set(struct pinctrl_dev *pctldev,
                               unsigned int group)
 {
        struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-       const struct bcm281xx_pin_function *f = &pdata->functions[function];
-       u32 offset = 4 * pdata->pins[group].number;
+       const struct bcm281xx_pin_function *f = &pdata->info->functions[function];
+       unsigned int pin = pdata->info->pins[group].number;
+       u32 offset = 4 * pin;
        int rc = 0;
 
        dev_dbg(pctldev->dev,
                "%s(): Enable function %s (%d) of pin %s (%d) @offset 0x%x.\n",
-               __func__, f->name, function, pdata->pins[group].name,
-               pdata->pins[group].number, offset);
+               __func__, f->name, function, pdata->info->pins[group].name,
+               pin, offset);
 
        rc = regmap_update_bits(pdata->regmap, offset,
                BCM281XX_PIN_REG_F_SEL_MASK,
@@ -1069,7 +1094,7 @@ static int bcm281xx_pinmux_set(struct pinctrl_dev *pctldev,
        if (rc)
                dev_err(pctldev->dev,
                        "Error updating register for pin %s (%d).\n",
-                       pdata->pins[group].name, pdata->pins[group].number);
+                       pdata->info->pins[group].name, pin);
 
        return rc;
 }
@@ -1168,7 +1193,7 @@ static int bcm281xx_std_pin_update(struct pinctrl_dev *pctldev,
                                        "Invalid Drive Strength value (%d) for "
                                        "pin %s (%d). Valid values are "
                                        "(2..16) mA, even numbers only.\n",
-                                       arg, pdata->pins[pin].name, pin);
+                                       arg, pdata->info->pins[pin].name, pin);
                                return -EINVAL;
                        }
                        bcm281xx_pin_update(val, mask, (arg/2)-1,
@@ -1179,7 +1204,7 @@ static int bcm281xx_std_pin_update(struct pinctrl_dev *pctldev,
                default:
                        dev_err(pctldev->dev,
                                "Unrecognized pin config %d for pin %s (%d).\n",
-                               param, pdata->pins[pin].name, pin);
+                               param, pdata->info->pins[pin].name, pin);
                        return -EINVAL;
 
                } /* switch config */
@@ -1233,7 +1258,7 @@ static int bcm281xx_i2c_pin_update(struct pinctrl_dev *pctldev,
                                        "Invalid pull-up value (%d) for pin %s "
                                        "(%d). Valid values are 568, 720, 831, "
                                        "1080, 1200, 1800, 2700 Ohms.\n",
-                                       arg, pdata->pins[pin].name, pin);
+                                       arg, pdata->info->pins[pin].name, pin);
                                return -EINVAL;
                        }
 
@@ -1266,7 +1291,7 @@ static int bcm281xx_i2c_pin_update(struct pinctrl_dev *pctldev,
                default:
                        dev_err(pctldev->dev,
                                "Unrecognized pin config %d for pin %s (%d).\n",
-                               param, pdata->pins[pin].name, pin);
+                               param, pdata->info->pins[pin].name, pin);
                        return -EINVAL;
 
                } /* switch config */
@@ -1311,7 +1336,7 @@ static int bcm281xx_hdmi_pin_update(struct pinctrl_dev *pctldev,
                default:
                        dev_err(pctldev->dev,
                                "Unrecognized pin config %d for pin %s (%d).\n",
-                               param, pdata->pins[pin].name, pin);
+                               param, pdata->info->pins[pin].name, pin);
                        return -EINVAL;
 
                } /* switch config */
@@ -1354,7 +1379,7 @@ static int bcm281xx_pinctrl_pin_config_set(struct pinctrl_dev *pctldev,
 
        default:
                dev_err(pctldev->dev, "Unknown pin type for pin %s (%d).\n",
-                       pdata->pins[pin].name, pin);
+                       pdata->info->pins[pin].name, pin);
                return -EINVAL;
 
        } /* switch pin type */
@@ -1364,13 +1389,13 @@ static int bcm281xx_pinctrl_pin_config_set(struct pinctrl_dev *pctldev,
 
        dev_dbg(pctldev->dev,
                "%s(): Set pin %s (%d) with config 0x%x, mask 0x%x\n",
-               __func__, pdata->pins[pin].name, pin, cfg_val, cfg_mask);
+               __func__, pdata->info->pins[pin].name, pin, cfg_val, cfg_mask);
 
        rc = regmap_update_bits(pdata->regmap, offset, cfg_mask, cfg_val);
        if (rc) {
                dev_err(pctldev->dev,
                        "Error updating register for pin %s (%d).\n",
-                       pdata->pins[pin].name, pin);
+                       pdata->info->pins[pin].name, pin);
                return rc;
        }
 
@@ -1390,11 +1415,23 @@ static struct pinctrl_desc bcm281xx_pinctrl_desc = {
        .owner = THIS_MODULE,
 };
 
+static struct bcm281xx_pinctrl_data bcm281xx_pinctrl_pdata;
+
 static int __init bcm281xx_pinctrl_probe(struct platform_device *pdev)
 {
-       struct bcm281xx_pinctrl_data *pdata = &bcm281xx_pinctrl;
+       struct bcm281xx_pinctrl_data *pdata = &bcm281xx_pinctrl_pdata;
        struct pinctrl_dev *pctl;
 
+       /* Set device pointer in platform data */
+       pdata->dev = &pdev->dev;
+
+       /* Get the data to use from OF match */
+       pdata->info = of_device_get_match_data(&pdev->dev);
+       if (!pdata->info) {
+               dev_err(&pdev->dev, "Failed to get data from OF match\n");
+               return -ENODEV;
+       }
+
        /* So far We can assume there is only 1 bank of registers */
        pdata->reg_base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(pdata->reg_base)) {
@@ -1404,15 +1441,15 @@ static int __init bcm281xx_pinctrl_probe(struct platform_device *pdev)
 
        /* Initialize the dynamic part of pinctrl_desc */
        pdata->regmap = devm_regmap_init_mmio(&pdev->dev, pdata->reg_base,
-               &bcm281xx_pinctrl_regmap_config);
+               pdata->info->regmap_config);
        if (IS_ERR(pdata->regmap)) {
                dev_err(&pdev->dev, "Regmap MMIO init failed.\n");
                return -ENODEV;
        }
 
        bcm281xx_pinctrl_desc.name = dev_name(&pdev->dev);
-       bcm281xx_pinctrl_desc.pins = bcm281xx_pinctrl.pins;
-       bcm281xx_pinctrl_desc.npins = bcm281xx_pinctrl.npins;
+       bcm281xx_pinctrl_desc.pins = pdata->info->pins;
+       bcm281xx_pinctrl_desc.npins = pdata->info->npins;
 
        pctl = devm_pinctrl_register(&pdev->dev, &bcm281xx_pinctrl_desc, pdata);
        if (IS_ERR(pctl)) {
@@ -1426,7 +1463,7 @@ static int __init bcm281xx_pinctrl_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id bcm281xx_pinctrl_of_match[] = {
-       { .compatible = "brcm,bcm11351-pinctrl", },
+       { .compatible = "brcm,bcm11351-pinctrl", .data = &bcm281xx_pinctrl },
        { },
 };