diff options
-rw-r--r-- | drivers/mfd/wm8994-core.c | 82 | ||||
-rw-r--r-- | include/linux/mfd/wm8994/core.h | 2 |
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 | ||
31 | static 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 | ||
71 | static 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) | |||
294 | static int wm8994_resume(struct device *dev) | 271 | static 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 | |||
302 | err_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 | ||
364 | static 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; |