@@ -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");