aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2011-10-25 08:23:53 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-12-12 11:11:05 -0500
commitc3f1386171a100d27d9fb978f474a6a330888af5 (patch)
treeb8440eff5d99347f322b526ab1384eeb0153245a
parent4412823a0ac768679c0f31bd9585ebc23b317138 (diff)
mfd: Enable register cache for wm8994 devices
As part of this we provide information about the registers that exist in the device to the regmap core, drop the small amount of cache that the core had been using and let regmap do the sync. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r--drivers/mfd/wm8994-core.c82
-rw-r--r--include/linux/mfd/wm8994/core.h2
2 files changed, 30 insertions, 54 deletions
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index 016769475ffb..aafac5b5f3a5 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -28,11 +28,7 @@
28#include <linux/mfd/wm8994/pdata.h> 28#include <linux/mfd/wm8994/pdata.h>
29#include <linux/mfd/wm8994/registers.h> 29#include <linux/mfd/wm8994/registers.h>
30 30
31static int wm8994_read(struct wm8994 *wm8994, unsigned short reg, 31#include "wm8994.h"
32 int bytes, void *dest)
33{
34 return regmap_raw_read(wm8994->regmap, reg, dest, bytes);
35}
36 32
37/** 33/**
38 * wm8994_reg_read: Read a single WM8994 register. 34 * wm8994_reg_read: Read a single WM8994 register.
@@ -68,12 +64,6 @@ int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
68 return regmap_bulk_read(wm8994->regmap, reg, buf, count); 64 return regmap_bulk_read(wm8994->regmap, reg, buf, count);
69} 65}
70 66
71static int wm8994_write(struct wm8994 *wm8994, unsigned short reg,
72 int bytes, const void *src)
73{
74 return regmap_raw_write(wm8994->regmap, reg, src, bytes);
75}
76
77/** 67/**
78 * wm8994_reg_write: Write a single WM8994 register. 68 * wm8994_reg_write: Write a single WM8994 register.
79 * 69 *
@@ -258,27 +248,14 @@ static int wm8994_suspend(struct device *dev)
258 WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD, 248 WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
259 WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD); 249 WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD);
260 250
261 /* GPIO configuration state is saved here since we may be configuring
262 * the GPIO alternate functions even if we're not using the gpiolib
263 * driver for them.
264 */
265 ret = wm8994_read(wm8994, WM8994_GPIO_1, WM8994_NUM_GPIO_REGS * 2,
266 &wm8994->gpio_regs);
267 if (ret < 0)
268 dev_err(dev, "Failed to save GPIO registers: %d\n", ret);
269
270 /* For similar reasons we also stash the regulator states */
271 ret = wm8994_read(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2,
272 &wm8994->ldo_regs);
273 if (ret < 0)
274 dev_err(dev, "Failed to save LDO registers: %d\n", ret);
275
276 /* Explicitly put the device into reset in case regulators 251 /* Explicitly put the device into reset in case regulators
277 * don't get disabled in order to ensure consistent restart. 252 * don't get disabled in order to ensure consistent restart.
278 */ 253 */
279 wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET, 254 wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET,
280 wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET)); 255 wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET));
281 256
257 regcache_mark_dirty(wm8994->regmap);
258
282 wm8994->suspended = true; 259 wm8994->suspended = true;
283 260
284 ret = regulator_bulk_disable(wm8994->num_supplies, 261 ret = regulator_bulk_disable(wm8994->num_supplies,
@@ -294,7 +271,7 @@ static int wm8994_suspend(struct device *dev)
294static int wm8994_resume(struct device *dev) 271static int wm8994_resume(struct device *dev)
295{ 272{
296 struct wm8994 *wm8994 = dev_get_drvdata(dev); 273 struct wm8994 *wm8994 = dev_get_drvdata(dev);
297 int ret, i; 274 int ret;
298 275
299 /* We may have lied to the PM core about suspending */ 276 /* We may have lied to the PM core about suspending */
300 if (!wm8994->suspended) 277 if (!wm8994->suspended)
@@ -307,27 +284,12 @@ static int wm8994_resume(struct device *dev)
307 return ret; 284 return ret;
308 } 285 }
309 286
310 /* Write register at a time as we use the cache on the CPU so store 287 ret = regcache_sync(wm8994->regmap);
311 * it in native endian. 288 if (ret != 0) {
312 */ 289 dev_err(dev, "Failed to restore register map: %d\n", ret);
313 for (i = 0; i < ARRAY_SIZE(wm8994->irq_masks_cur); i++) { 290 goto err_enable;
314 ret = wm8994_reg_write(wm8994, WM8994_INTERRUPT_STATUS_1_MASK
315 + i, wm8994->irq_masks_cur[i]);
316 if (ret < 0)
317 dev_err(dev, "Failed to restore interrupt masks: %d\n",
318 ret);
319 } 291 }
320 292
321 ret = wm8994_write(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2,
322 &wm8994->ldo_regs);
323 if (ret < 0)
324 dev_err(dev, "Failed to restore LDO registers: %d\n", ret);
325
326 ret = wm8994_write(wm8994, WM8994_GPIO_1, WM8994_NUM_GPIO_REGS * 2,
327 &wm8994->gpio_regs);
328 if (ret < 0)
329 dev_err(dev, "Failed to restore GPIO registers: %d\n", ret);
330
331 /* Disable LDO pulldowns while the device is active */ 293 /* Disable LDO pulldowns while the device is active */
332 wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, 294 wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
333 WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD, 295 WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
@@ -336,6 +298,11 @@ static int wm8994_resume(struct device *dev)
336 wm8994->suspended = false; 298 wm8994->suspended = false;
337 299
338 return 0; 300 return 0;
301
302err_enable:
303 regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies);
304
305 return ret;
339} 306}
340#endif 307#endif
341 308
@@ -361,11 +328,6 @@ static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
361} 328}
362#endif 329#endif
363 330
364static struct regmap_config wm8994_regmap_config = {
365 .reg_bits = 16,
366 .val_bits = 16,
367};
368
369/* 331/*
370 * Instantiate the generic non-control parts of the device. 332 * Instantiate the generic non-control parts of the device.
371 */ 333 */
@@ -594,6 +556,7 @@ static int wm8994_i2c_probe(struct i2c_client *i2c,
594 const struct i2c_device_id *id) 556 const struct i2c_device_id *id)
595{ 557{
596 struct wm8994 *wm8994; 558 struct wm8994 *wm8994;
559 struct regmap_config *regmap_config;
597 int ret; 560 int ret;
598 561
599 wm8994 = devm_kzalloc(&i2c->dev, sizeof(struct wm8994), GFP_KERNEL); 562 wm8994 = devm_kzalloc(&i2c->dev, sizeof(struct wm8994), GFP_KERNEL);
@@ -605,7 +568,22 @@ static int wm8994_i2c_probe(struct i2c_client *i2c,
605 wm8994->irq = i2c->irq; 568 wm8994->irq = i2c->irq;
606 wm8994->type = id->driver_data; 569 wm8994->type = id->driver_data;
607 570
608 wm8994->regmap = regmap_init_i2c(i2c, &wm8994_regmap_config); 571 switch (wm8994->type) {
572 case WM1811:
573 regmap_config = &wm1811_regmap_config;
574 break;
575 case WM8994:
576 regmap_config = &wm8994_regmap_config;
577 break;
578 case WM8958:
579 regmap_config = &wm8958_regmap_config;
580 break;
581 default:
582 dev_err(wm8994->dev, "Unknown device type %d\n", wm8994->type);
583 return -EINVAL;
584 }
585
586 wm8994->regmap = regmap_init_i2c(i2c, regmap_config);
609 if (IS_ERR(wm8994->regmap)) { 587 if (IS_ERR(wm8994->regmap)) {
610 ret = PTR_ERR(wm8994->regmap); 588 ret = PTR_ERR(wm8994->regmap);
611 dev_err(wm8994->dev, "Failed to allocate register map: %d\n", 589 dev_err(wm8994->dev, "Failed to allocate register map: %d\n",
diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h
index f44bdb7273bd..d98593d52e7c 100644
--- a/include/linux/mfd/wm8994/core.h
+++ b/include/linux/mfd/wm8994/core.h
@@ -70,8 +70,6 @@ struct wm8994 {
70 70
71 /* Used over suspend/resume */ 71 /* Used over suspend/resume */
72 bool suspended; 72 bool suspended;
73 u16 ldo_regs[WM8994_NUM_LDO_REGS];
74 u16 gpio_regs[WM8994_NUM_GPIO_REGS];
75 73
76 struct regulator_dev *dbvdd; 74 struct regulator_dev *dbvdd;
77 int num_supplies; 75 int num_supplies;