diff mbox series

[v3,02/22] mfd: adp5585: only add devices given in FW

Message ID 20250512-dev-adp5589-fw-v3-2-092b14b79a88@analog.com
State New
Headers show
Series mfd: adp5585: support keymap events and drop legacy Input driver | expand

Commit Message

Nuno Sá via B4 Relay May 12, 2025, 12:38 p.m. UTC
From: Nuno Sá <nuno.sa@analog.com>

Not all devices (features) of the adp5585 device are mandatory to be
used in all platforms. Hence, check what's given in FW and dynamically
create the mfd_cell array to be given to devm_mfd_add_devices().

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
---
 drivers/mfd/adp5585.c | 45 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 41 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/drivers/mfd/adp5585.c b/drivers/mfd/adp5585.c
index 160e0b38106a6d78f7d4b7c866cb603d96ea673e..02f9e8c1c6a1d8b9516c060e0024d69886e9fb7a 100644
--- a/drivers/mfd/adp5585.c
+++ b/drivers/mfd/adp5585.c
@@ -17,7 +17,13 @@ 
 #include <linux/regmap.h>
 #include <linux/types.h>
 
-static const struct mfd_cell adp5585_devs[] = {
+enum {
+	ADP5585_DEV_GPIO,
+	ADP5585_DEV_PWM,
+	ADP5585_DEV_MAX
+};
+
+static const struct mfd_cell adp5585_devs[ADP5585_DEV_MAX] = {
 	{ .name = "adp5585-gpio", },
 	{ .name = "adp5585-pwm", },
 };
@@ -110,12 +116,40 @@  static const struct regmap_config adp5585_regmap_configs[] = {
 	},
 };
 
+static int adp5585_parse_fw(struct device *dev, struct adp5585_dev *adp5585,
+			    struct mfd_cell **devs)
+{
+	unsigned int has_pwm = 0, has_gpio = 0, rc = 0;
+
+	if (device_property_present(dev, "#pwm-cells"))
+		has_pwm = 1;
+
+	if (device_property_present(dev, "#gpio-cells"))
+		has_gpio = 1;
+
+	if (!has_pwm && !has_gpio)
+		return -ENODEV;
+
+	*devs = devm_kcalloc(dev, has_pwm + has_gpio, sizeof(struct mfd_cell),
+			     GFP_KERNEL);
+	if (!*devs)
+		return -ENOMEM;
+
+	if (has_pwm)
+		(*devs)[rc++] = adp5585_devs[ADP5585_DEV_PWM];
+	if (has_gpio)
+		(*devs)[rc++] = adp5585_devs[ADP5585_DEV_GPIO];
+
+	return rc;
+}
+
 static int adp5585_i2c_probe(struct i2c_client *i2c)
 {
 	const struct regmap_config *regmap_config;
 	struct adp5585_dev *adp5585;
+	struct mfd_cell *devs;
 	unsigned int id;
-	int ret;
+	int ret, n_devs;
 
 	adp5585 = devm_kzalloc(&i2c->dev, sizeof(*adp5585), GFP_KERNEL);
 	if (!adp5585)
@@ -138,9 +172,12 @@  static int adp5585_i2c_probe(struct i2c_client *i2c)
 		return dev_err_probe(&i2c->dev, -ENODEV,
 				     "Invalid device ID 0x%02x\n", id);
 
+	n_devs = adp5585_parse_fw(&i2c->dev, adp5585, &devs);
+	if (n_devs < 0)
+		return n_devs;
+
 	ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO,
-				   adp5585_devs, ARRAY_SIZE(adp5585_devs),
-				   NULL, 0, NULL);
+				   devs, n_devs, NULL, 0, NULL);
 	if (ret)
 		return dev_err_probe(&i2c->dev, ret,
 				     "Failed to add child devices\n");