Commit 596c1852 authored by Artur Weber's avatar Artur Weber Committed by Linus Walleij
Browse files

pinctrl: bcm281xx: Provide pinctrl device info as OF platform data



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: default avatarArtur Weber <aweber.kernel@gmail.com>
Link: https://lore.kernel.org/20250303-bcm21664-pinctrl-v3-3-5f8b80e4ab51@gmail.com


Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 07b5a2a1
Loading
Loading
Loading
Loading
+78 −41
Original line number Diff line number Diff line
@@ -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 },
	{ },
};