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@xxxxxxxxx> --- drivers/pinctrl/bcm/pinctrl-bcm281xx.c | 120 ++++++++++++++++++++++----------- 1 file changed, 79 insertions(+), 41 deletions(-) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm281xx.c b/drivers/pinctrl/bcm/pinctrl-bcm281xx.c index a039b490cdb8e6c41169bfd48abb371447c150a0..6ed9bbed71f2d660a2c38d28788c1b0ca8f052c3 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm281xx.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm281xx.c @@ -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 * 4, -}; - 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,10 +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; + int rc; + + /* 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); @@ -1404,15 +1442,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 +1464,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 }, { }, }; -- 2.48.1