diff options
Diffstat (limited to 'drivers/mfd/palmas.c')
-rw-r--r-- | drivers/mfd/palmas.c | 146 |
1 files changed, 32 insertions, 114 deletions
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c index 53e9fe638d32..e4d1c706df8b 100644 --- a/drivers/mfd/palmas.c +++ b/drivers/mfd/palmas.c @@ -23,78 +23,7 @@ #include <linux/err.h> #include <linux/mfd/core.h> #include <linux/mfd/palmas.h> -#include <linux/of_platform.h> - -enum palmas_ids { - PALMAS_PMIC_ID, - PALMAS_GPIO_ID, - PALMAS_LEDS_ID, - PALMAS_WDT_ID, - PALMAS_RTC_ID, - PALMAS_PWRBUTTON_ID, - PALMAS_GPADC_ID, - PALMAS_RESOURCE_ID, - PALMAS_CLK_ID, - PALMAS_PWM_ID, - PALMAS_USB_ID, -}; - -static struct resource palmas_rtc_resources[] = { - { - .start = PALMAS_RTC_ALARM_IRQ, - .end = PALMAS_RTC_ALARM_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -static const struct mfd_cell palmas_children[] = { - { - .name = "palmas-pmic", - .id = PALMAS_PMIC_ID, - }, - { - .name = "palmas-gpio", - .id = PALMAS_GPIO_ID, - }, - { - .name = "palmas-leds", - .id = PALMAS_LEDS_ID, - }, - { - .name = "palmas-wdt", - .id = PALMAS_WDT_ID, - }, - { - .name = "palmas-rtc", - .id = PALMAS_RTC_ID, - .resources = &palmas_rtc_resources[0], - .num_resources = ARRAY_SIZE(palmas_rtc_resources), - }, - { - .name = "palmas-pwrbutton", - .id = PALMAS_PWRBUTTON_ID, - }, - { - .name = "palmas-gpadc", - .id = PALMAS_GPADC_ID, - }, - { - .name = "palmas-resource", - .id = PALMAS_RESOURCE_ID, - }, - { - .name = "palmas-clk", - .id = PALMAS_CLK_ID, - }, - { - .name = "palmas-pwm", - .id = PALMAS_PWM_ID, - }, - { - .name = "palmas-usb", - .id = PALMAS_USB_ID, - } -}; +#include <linux/of_device.h> static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = { { @@ -302,6 +231,21 @@ static void palmas_dt_to_pdata(struct i2c_client *i2c, palmas_set_pdata_irq_flag(i2c, pdata); } +static unsigned int palmas_features = PALMAS_PMIC_FEATURE_SMPS10_BOOST; +static unsigned int tps659038_features; + +static const struct of_device_id of_palmas_match_tbl[] = { + { + .compatible = "ti,palmas", + .data = &palmas_features, + }, + { + .compatible = "ti,tps659038", + .data = &tps659038_features, + }, + { }, +}; + static int palmas_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -309,9 +253,9 @@ static int palmas_i2c_probe(struct i2c_client *i2c, struct palmas_platform_data *pdata; struct device_node *node = i2c->dev.of_node; int ret = 0, i; - unsigned int reg, addr; + unsigned int reg, addr, *features; int slave; - struct mfd_cell *children; + const struct of_device_id *match; pdata = dev_get_platdata(&i2c->dev); @@ -333,9 +277,16 @@ static int palmas_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, palmas); palmas->dev = &i2c->dev; - palmas->id = id->driver_data; palmas->irq = i2c->irq; + match = of_match_device(of_match_ptr(of_palmas_match_tbl), &i2c->dev); + + if (!match) + return -ENODATA; + + features = (unsigned int *)match->data; + palmas->features = *features; + for (i = 0; i < PALMAS_NUM_CLIENTS; i++) { if (i == 0) palmas->i2c_clients[i] = i2c; @@ -362,6 +313,11 @@ static int palmas_i2c_probe(struct i2c_client *i2c, } } + if (!palmas->irq) { + dev_warn(palmas->dev, "IRQ missing: skipping irq request\n"); + goto no_irq; + } + /* Change interrupt line output polarity */ if (pdata->irq_flags & IRQ_TYPE_LEVEL_HIGH) reg = PALMAS_POLARITY_CTRL_INT_POLARITY; @@ -388,6 +344,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c, if (ret < 0) goto err; +no_irq: slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, PALMAS_PRIMARY_SECONDARY_PAD1); @@ -472,42 +429,8 @@ static int palmas_i2c_probe(struct i2c_client *i2c, return ret; } - children = kmemdup(palmas_children, sizeof(palmas_children), - GFP_KERNEL); - if (!children) { - ret = -ENOMEM; - goto err_irq; - } - - children[PALMAS_PMIC_ID].platform_data = pdata->pmic_pdata; - children[PALMAS_PMIC_ID].pdata_size = sizeof(*pdata->pmic_pdata); - - children[PALMAS_GPADC_ID].platform_data = pdata->gpadc_pdata; - children[PALMAS_GPADC_ID].pdata_size = sizeof(*pdata->gpadc_pdata); - - children[PALMAS_RESOURCE_ID].platform_data = pdata->resource_pdata; - children[PALMAS_RESOURCE_ID].pdata_size = - sizeof(*pdata->resource_pdata); - - children[PALMAS_USB_ID].platform_data = pdata->usb_pdata; - children[PALMAS_USB_ID].pdata_size = sizeof(*pdata->usb_pdata); - - children[PALMAS_CLK_ID].platform_data = pdata->clk_pdata; - children[PALMAS_CLK_ID].pdata_size = sizeof(*pdata->clk_pdata); - - ret = mfd_add_devices(palmas->dev, -1, - children, ARRAY_SIZE(palmas_children), - NULL, 0, - regmap_irq_get_domain(palmas->irq_data)); - kfree(children); - - if (ret < 0) - goto err_devices; - return ret; -err_devices: - mfd_remove_devices(palmas->dev); err_irq: regmap_del_irq_chip(palmas->irq, palmas->irq_data); err: @@ -533,11 +456,6 @@ static const struct i2c_device_id palmas_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, palmas_i2c_id); -static struct of_device_id of_palmas_match_tbl[] = { - { .compatible = "ti,palmas", }, - { /* end */ } -}; - static struct i2c_driver palmas_i2c_driver = { .driver = { .name = "palmas", |