summaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 20:33:14 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 20:33:14 -0700
commit9586c959bfc917695893bef0102433a7d0675691 (patch)
treec8b89e40b7a04c3150e50785e7c48b67df360c83 /drivers/mfd
parent34699403e9916060af8ae23f5e4705a6c078e79d (diff)
parentaddfd8a09e1f434a73b3d87d36ef050c73511d2b (diff)
downloadlinux-9586c959bfc917695893bef0102433a7d0675691.tar.bz2
Merge tag 'regmap-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap
Pull regmap updates from Mark Brown: "Things are really quieting down with the regmap API, while we're still seeing a trickle of new features coming in they're getting much smaller than they were. It's also nice to have some features which support other subsystems building infrastructure on top of regmap. Highlights include: - Support for padding between the register and the value when interacting with the device, sometimes needed for fast interfaces. - Support for applying register updates to the device when restoring the register state. This is intended to be used to apply updates supplied by manufacturers for tuning the performance of the device (many of which are to undocumented registers which aren't otherwise covered). - Support for multi-register operations on cached registers. - Support for syncing only part of the register cache. - Stubs and parameter query functions intended to make it easier for other subsystems to build infrastructure on top of the regmap API. plus a few driver updates making use of the new features which it was easier to merge via this tree." * tag 'regmap-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap: (41 commits) regmap: Fix future missing prototype of devres_alloc() and friends regmap: Rejig struct declarations for stubbed API regmap: Fix rbtree block base in sync regcache: Make sure we sync register 0 in an rbtree cache regmap: delete unused module.h from drivers/base/regmap files regmap: Add stub for regcache_sync_region() mfd: Improve performance of later WM1811 revisions regmap: Fix x86_64 breakage regmap: Allow drivers to sync only part of the register cache regmap: Supply ranges to the sync operations regmap: Add tracepoints for cache only and cache bypass regmap: Mark the cache as clean after a successful sync regmap: Remove default cache sync implementation regmap: Skip hardware defaults for LZO caches regmap: Expose the driver name in debugfs mfd: wm8400: Convert to devm_regmap_init_i2c() mfd: wm831x: Convert to devm_regmap_init() mfd: wm8994: Convert to devm_regmap_init() mfd/ASoC: Convert WM8994 driver to use regmap patches mfd: Add __devinit and __devexit annotations in wm8994 ...
Diffstat (limited to 'drivers/mfd')
-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
5 files changed, 89 insertions, 34 deletions
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 a04b3c108c8c..98733d408fee 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -359,15 +359,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);
@@ -379,7 +402,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) {
@@ -394,7 +417,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,
@@ -402,7 +425,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) {
@@ -420,14 +443,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,
@@ -488,15 +511,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;
}
@@ -526,6 +578,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;
@@ -588,13 +650,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);
@@ -602,7 +663,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[] = {
@@ -613,8 +673,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;
@@ -628,7 +688,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",
@@ -639,7 +699,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);
@@ -668,7 +728,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,
};