Skip to content

Commit

Permalink
pinctrl: bcm281xx: Provide pinctrl device info as OF platform data
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Artur Weber authored and Linus Walleij committed Mar 5, 2025
1 parent 07b5a2a commit 596c185
Showing 1 changed file with 78 additions and 41 deletions.
119 changes: 78 additions & 41 deletions drivers/pinctrl/bcm/pinctrl-bcm281xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

/*
Expand Down Expand Up @@ -933,22 +953,33 @@ 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,
unsigned int pin)
{
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) \
Expand All @@ -970,26 +1001,19 @@ 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,
unsigned int group)
{
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,
Expand All @@ -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;
Expand All @@ -1025,15 +1049,15 @@ 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,
unsigned int function)
{
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,
Expand All @@ -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;
}
Expand All @@ -1054,22 +1078,23 @@ 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,
function << BCM281XX_PIN_REG_F_SEL_SHIFT);
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;
}
Expand Down Expand Up @@ -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,
Expand All @@ -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 */
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
Expand All @@ -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;
}

Expand All @@ -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)) {
Expand All @@ -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)) {
Expand All @@ -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 },
{ },
};

Expand Down

0 comments on commit 596c185

Please sign in to comment.