summaryrefslogtreecommitdiff
path: root/drivers/mfd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig2
-rw-r--r--drivers/mfd/twl-core.c6
-rw-r--r--drivers/mfd/twl4030-power.c20
-rw-r--r--drivers/mfd/wm831x-core.c20
-rw-r--r--drivers/mfd/wm831x-i2c.c2
-rw-r--r--drivers/mfd/wm831x-spi.c2
-rw-r--r--drivers/mfd/wm8400-core.c7
-rw-r--r--drivers/mfd/wm8994-core.c92
8 files changed, 104 insertions, 47 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index cd13e9f2f5e6..f147395bac9a 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -200,7 +200,7 @@ config MENELAUS
config TWL4030_CORE
bool "Texas Instruments TWL4030/TWL5030/TWL6030/TPS659x0 Support"
- depends on I2C=y && GENERIC_HARDIRQS && IRQ_DOMAIN
+ depends on I2C=y && GENERIC_HARDIRQS
help
Say yes here if you have TWL4030 / TWL6030 family chip on your board.
This core driver provides register access and IRQ handling
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index e04e04ddc15e..8ce3959c6919 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -263,7 +263,9 @@ struct twl_client {
static struct twl_client twl_modules[TWL_NUM_SLAVES];
+#ifdef CONFIG_IRQ_DOMAIN
static struct irq_domain domain;
+#endif
/* mapping the module id to slave id and base address */
struct twl_mapping {
@@ -1226,13 +1228,13 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
pdata->irq_base = status;
pdata->irq_end = pdata->irq_base + nr_irqs;
+#ifdef CONFIG_IRQ_DOMAIN
domain.irq_base = pdata->irq_base;
domain.nr_irq = nr_irqs;
-#ifdef CONFIG_OF_IRQ
domain.of_node = of_node_get(node);
domain.ops = &irq_domain_simple_ops;
-#endif
irq_domain_add(&domain);
+#endif
if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
dev_dbg(&client->dev, "can't talk I2C?\n");
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
index d905f5171153..79ca33dfacca 100644
--- a/drivers/mfd/twl4030-power.c
+++ b/drivers/mfd/twl4030-power.c
@@ -124,7 +124,7 @@ static u8 res_config_addrs[] = {
[RES_MAIN_REF] = 0x94,
};
-static int __init twl4030_write_script_byte(u8 address, u8 byte)
+static int __devinit twl4030_write_script_byte(u8 address, u8 byte)
{
int err;
@@ -138,7 +138,7 @@ out:
return err;
}
-static int __init twl4030_write_script_ins(u8 address, u16 pmb_message,
+static int __devinit twl4030_write_script_ins(u8 address, u16 pmb_message,
u8 delay, u8 next)
{
int err;
@@ -158,7 +158,7 @@ out:
return err;
}
-static int __init twl4030_write_script(u8 address, struct twl4030_ins *script,
+static int __devinit twl4030_write_script(u8 address, struct twl4030_ins *script,
int len)
{
int err;
@@ -183,7 +183,7 @@ static int __init twl4030_write_script(u8 address, struct twl4030_ins *script,
return err;
}
-static int __init twl4030_config_wakeup3_sequence(u8 address)
+static int __devinit twl4030_config_wakeup3_sequence(u8 address)
{
int err;
u8 data;
@@ -208,7 +208,7 @@ out:
return err;
}
-static int __init twl4030_config_wakeup12_sequence(u8 address)
+static int __devinit twl4030_config_wakeup12_sequence(u8 address)
{
int err = 0;
u8 data;
@@ -262,7 +262,7 @@ out:
return err;
}
-static int __init twl4030_config_sleep_sequence(u8 address)
+static int __devinit twl4030_config_sleep_sequence(u8 address)
{
int err;
@@ -276,7 +276,7 @@ static int __init twl4030_config_sleep_sequence(u8 address)
return err;
}
-static int __init twl4030_config_warmreset_sequence(u8 address)
+static int __devinit twl4030_config_warmreset_sequence(u8 address)
{
int err;
u8 rd_data;
@@ -324,7 +324,7 @@ out:
return err;
}
-static int __init twl4030_configure_resource(struct twl4030_resconfig *rconfig)
+static int __devinit twl4030_configure_resource(struct twl4030_resconfig *rconfig)
{
int rconfig_addr;
int err;
@@ -416,7 +416,7 @@ static int __init twl4030_configure_resource(struct twl4030_resconfig *rconfig)
return 0;
}
-static int __init load_twl4030_script(struct twl4030_script *tscript,
+static int __devinit load_twl4030_script(struct twl4030_script *tscript,
u8 address)
{
int err;
@@ -527,7 +527,7 @@ void twl4030_power_off(void)
pr_err("TWL4030 Unable to power off\n");
}
-void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
+void __devinit twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
{
int err = 0;
int i;
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index f5e54fae8ada..838056c3493a 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -1631,7 +1631,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
if (ret < 0) {
dev_err(wm831x->dev, "Failed to read parent ID: %d\n", ret);
- goto err_regmap;
+ goto err;
}
switch (ret) {
case 0x6204:
@@ -1640,20 +1640,20 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
default:
dev_err(wm831x->dev, "Device is not a WM831x: ID %x\n", ret);
ret = -EINVAL;
- goto err_regmap;
+ goto err;
}
ret = wm831x_reg_read(wm831x, WM831X_REVISION);
if (ret < 0) {
dev_err(wm831x->dev, "Failed to read revision: %d\n", ret);
- goto err_regmap;
+ goto err;
}
rev = (ret & WM831X_PARENT_REV_MASK) >> WM831X_PARENT_REV_SHIFT;
ret = wm831x_reg_read(wm831x, WM831X_RESET_ID);
if (ret < 0) {
dev_err(wm831x->dev, "Failed to read device ID: %d\n", ret);
- goto err_regmap;
+ goto err;
}
/* Some engineering samples do not have the ID set, rely on
@@ -1728,7 +1728,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
default:
dev_err(wm831x->dev, "Unknown WM831x device %04x\n", ret);
ret = -EINVAL;
- goto err_regmap;
+ goto err;
}
/* This will need revisiting in future but is OK for all
@@ -1742,7 +1742,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
ret = wm831x_reg_read(wm831x, WM831X_SECURITY_KEY);
if (ret < 0) {
dev_err(wm831x->dev, "Failed to read security key: %d\n", ret);
- goto err_regmap;
+ goto err;
}
if (ret != 0) {
dev_warn(wm831x->dev, "Security key had non-zero value %x\n",
@@ -1755,7 +1755,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
ret = pdata->pre_init(wm831x);
if (ret != 0) {
dev_err(wm831x->dev, "pre_init() failed: %d\n", ret);
- goto err_regmap;
+ goto err;
}
}
@@ -1778,7 +1778,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
ret = wm831x_irq_init(wm831x, irq);
if (ret != 0)
- goto err_regmap;
+ goto err;
wm831x_auxadc_init(wm831x);
@@ -1874,9 +1874,8 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
err_irq:
wm831x_irq_exit(wm831x);
-err_regmap:
+err:
mfd_remove_devices(wm831x->dev);
- regmap_exit(wm831x->regmap);
return ret;
}
@@ -1887,7 +1886,6 @@ void wm831x_device_exit(struct wm831x *wm831x)
if (wm831x->irq_base)
free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x);
wm831x_irq_exit(wm831x);
- regmap_exit(wm831x->regmap);
}
int wm831x_device_suspend(struct wm831x *wm831x)
diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c
index cb15609b0a48..2b29caebc9cf 100644
--- a/drivers/mfd/wm831x-i2c.c
+++ b/drivers/mfd/wm831x-i2c.c
@@ -37,7 +37,7 @@ static int wm831x_i2c_probe(struct i2c_client *i2c,
i2c_set_clientdata(i2c, wm831x);
wm831x->dev = &i2c->dev;
- wm831x->regmap = regmap_init_i2c(i2c, &wm831x_regmap_config);
+ wm831x->regmap = devm_regmap_init_i2c(i2c, &wm831x_regmap_config);
if (IS_ERR(wm831x->regmap)) {
ret = PTR_ERR(wm831x->regmap);
dev_err(wm831x->dev, "Failed to allocate register map: %d\n",
diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c
index 62ef3254105f..745c87945664 100644
--- a/drivers/mfd/wm831x-spi.c
+++ b/drivers/mfd/wm831x-spi.c
@@ -40,7 +40,7 @@ static int __devinit wm831x_spi_probe(struct spi_device *spi)
dev_set_drvdata(&spi->dev, wm831x);
wm831x->dev = &spi->dev;
- wm831x->regmap = regmap_init_spi(spi, &wm831x_regmap_config);
+ wm831x->regmap = devm_regmap_init_spi(spi, &wm831x_regmap_config);
if (IS_ERR(wm831x->regmap)) {
ret = PTR_ERR(wm831x->regmap);
dev_err(wm831x->dev, "Failed to allocate register map: %d\n",
diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c
index 2204893444a6..237764ae5f9b 100644
--- a/drivers/mfd/wm8400-core.c
+++ b/drivers/mfd/wm8400-core.c
@@ -350,7 +350,7 @@ static int wm8400_i2c_probe(struct i2c_client *i2c,
goto err;
}
- wm8400->regmap = regmap_init_i2c(i2c, &wm8400_regmap_config);
+ wm8400->regmap = devm_regmap_init_i2c(i2c, &wm8400_regmap_config);
if (IS_ERR(wm8400->regmap)) {
ret = PTR_ERR(wm8400->regmap);
goto err;
@@ -361,12 +361,10 @@ static int wm8400_i2c_probe(struct i2c_client *i2c,
ret = wm8400_init(wm8400, i2c->dev.platform_data);
if (ret != 0)
- goto map_err;
+ goto err;
return 0;
-map_err:
- regmap_exit(wm8400->regmap);
err:
return ret;
}
@@ -376,7 +374,6 @@ static int wm8400_i2c_remove(struct i2c_client *i2c)
struct wm8400 *wm8400 = i2c_get_clientdata(i2c);
wm8400_release(wm8400);
- regmap_exit(wm8400->regmap);
return 0;
}
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index f117e7fb9321..4b8b78c39767 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -345,15 +345,38 @@ static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
}
#endif
+static const __devinitdata struct reg_default wm8994_revc_patch[] = {
+ { 0x102, 0x3 },
+ { 0x56, 0x3 },
+ { 0x817, 0x0 },
+ { 0x102, 0x0 },
+};
+
+static const __devinitdata struct reg_default wm8958_reva_patch[] = {
+ { 0x102, 0x3 },
+ { 0xcb, 0x81 },
+ { 0x817, 0x0 },
+ { 0x102, 0x0 },
+};
+
+static const __devinitdata struct reg_default wm1811_reva_patch[] = {
+ { 0x102, 0x3 },
+ { 0x56, 0x7 },
+ { 0x5d, 0x7e },
+ { 0x5e, 0x0 },
+ { 0x102, 0x0 },
+};
+
/*
* Instantiate the generic non-control parts of the device.
*/
-static int wm8994_device_init(struct wm8994 *wm8994, int irq)
+static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq)
{
struct wm8994_pdata *pdata = wm8994->dev->platform_data;
struct regmap_config *regmap_config;
+ const struct reg_default *regmap_patch = NULL;
const char *devname;
- int ret, i;
+ int ret, i, patch_regs;
int pulls = 0;
dev_set_drvdata(wm8994->dev, wm8994);
@@ -365,7 +388,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
NULL, 0);
if (ret != 0) {
dev_err(wm8994->dev, "Failed to add children: %d\n", ret);
- goto err_regmap;
+ goto err;
}
switch (wm8994->type) {
@@ -380,7 +403,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
break;
default:
BUG();
- goto err_regmap;
+ goto err;
}
wm8994->supplies = devm_kzalloc(wm8994->dev,
@@ -388,7 +411,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
wm8994->num_supplies, GFP_KERNEL);
if (!wm8994->supplies) {
ret = -ENOMEM;
- goto err_regmap;
+ goto err;
}
switch (wm8994->type) {
@@ -406,14 +429,14 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
break;
default:
BUG();
- goto err_regmap;
+ goto err;
}
ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies,
wm8994->supplies);
if (ret != 0) {
dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret);
- goto err_regmap;
+ goto err;
}
ret = regulator_bulk_enable(wm8994->num_supplies,
@@ -474,15 +497,44 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
"revision %c not fully supported\n",
'A' + wm8994->revision);
break;
+ case 2:
+ case 3:
+ regmap_patch = wm8994_revc_patch;
+ patch_regs = ARRAY_SIZE(wm8994_revc_patch);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case WM8958:
+ switch (wm8994->revision) {
+ case 0:
+ regmap_patch = wm8958_reva_patch;
+ patch_regs = ARRAY_SIZE(wm8958_reva_patch);
+ break;
default:
break;
}
break;
+
case WM1811:
/* Revision C did not change the relevant layer */
if (wm8994->revision > 1)
wm8994->revision++;
+ switch (wm8994->revision) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ regmap_patch = wm1811_reva_patch;
+ patch_regs = ARRAY_SIZE(wm1811_reva_patch);
+ break;
+ default:
+ break;
+ }
break;
+
default:
break;
}
@@ -512,6 +564,16 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
return ret;
}
+ if (regmap_patch) {
+ ret = regmap_register_patch(wm8994->regmap, regmap_patch,
+ patch_regs);
+ if (ret != 0) {
+ dev_err(wm8994->dev, "Failed to register patch: %d\n",
+ ret);
+ goto err;
+ }
+ }
+
if (pdata) {
wm8994->irq_base = pdata->irq_base;
wm8994->gpio_base = pdata->gpio_base;
@@ -574,13 +636,12 @@ err_enable:
wm8994->supplies);
err_get:
regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
-err_regmap:
- regmap_exit(wm8994->regmap);
+err:
mfd_remove_devices(wm8994->dev);
return ret;
}
-static void wm8994_device_exit(struct wm8994 *wm8994)
+static __devexit void wm8994_device_exit(struct wm8994 *wm8994)
{
pm_runtime_disable(wm8994->dev);
mfd_remove_devices(wm8994->dev);
@@ -588,7 +649,6 @@ static void wm8994_device_exit(struct wm8994 *wm8994)
regulator_bulk_disable(wm8994->num_supplies,
wm8994->supplies);
regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
- regmap_exit(wm8994->regmap);
}
static const struct of_device_id wm8994_of_match[] = {
@@ -599,8 +659,8 @@ static const struct of_device_id wm8994_of_match[] = {
};
MODULE_DEVICE_TABLE(of, wm8994_of_match);
-static int wm8994_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static __devinit int wm8994_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
{
struct wm8994 *wm8994;
int ret;
@@ -614,7 +674,7 @@ static int wm8994_i2c_probe(struct i2c_client *i2c,
wm8994->irq = i2c->irq;
wm8994->type = id->driver_data;
- wm8994->regmap = regmap_init_i2c(i2c, &wm8994_base_regmap_config);
+ wm8994->regmap = devm_regmap_init_i2c(i2c, &wm8994_base_regmap_config);
if (IS_ERR(wm8994->regmap)) {
ret = PTR_ERR(wm8994->regmap);
dev_err(wm8994->dev, "Failed to allocate register map: %d\n",
@@ -625,7 +685,7 @@ static int wm8994_i2c_probe(struct i2c_client *i2c,
return wm8994_device_init(wm8994, i2c->irq);
}
-static int wm8994_i2c_remove(struct i2c_client *i2c)
+static __devexit int wm8994_i2c_remove(struct i2c_client *i2c)
{
struct wm8994 *wm8994 = i2c_get_clientdata(i2c);
@@ -654,7 +714,7 @@ static struct i2c_driver wm8994_i2c_driver = {
.of_match_table = wm8994_of_match,
},
.probe = wm8994_i2c_probe,
- .remove = wm8994_i2c_remove,
+ .remove = __devexit_p(wm8994_i2c_remove),
.id_table = wm8994_i2c_id,
};