aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-08-31 14:25:12 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-11-26 10:16:19 -0500
commit559e0df6b3ffbc218a11bb9dada5320a217cb7a6 (patch)
tree5f42260e7bb90657215eb7daa3faceb52d2b9256
parentccf1fa403e44c4107ef4d73f73cafe81b5148d40 (diff)
mfd: Add initial WM8958 support
The WM8958 is a derivative of the WM8994 which is register compatible with the addition of some extra features, mostly in the CODEC side. The major change visible at the MFD level is that rather than a single DBVDD supply we now have three separate DBVDDs so we must request and enable a different set of supplies. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Samuel Ortiz <sameo@linux.intel.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
-rw-r--r--drivers/mfd/wm8994-core.c93
-rw-r--r--include/linux/mfd/wm8994/core.h8
2 files changed, 82 insertions, 19 deletions
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index b3b2aaf89dbe..8d221ba5e38d 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -218,6 +218,18 @@ static const char *wm8994_main_supplies[] = {
218 "SPKVDD2", 218 "SPKVDD2",
219}; 219};
220 220
221static const char *wm8958_main_supplies[] = {
222 "DBVDD1",
223 "DBVDD2",
224 "DBVDD3",
225 "DCVDD",
226 "AVDD1",
227 "AVDD2",
228 "CPVDD",
229 "SPKVDD1",
230 "SPKVDD2",
231};
232
221#ifdef CONFIG_PM 233#ifdef CONFIG_PM
222static int wm8994_device_suspend(struct device *dev) 234static int wm8994_device_suspend(struct device *dev)
223{ 235{
@@ -239,7 +251,7 @@ static int wm8994_device_suspend(struct device *dev)
239 if (ret < 0) 251 if (ret < 0)
240 dev_err(dev, "Failed to save LDO registers: %d\n", ret); 252 dev_err(dev, "Failed to save LDO registers: %d\n", ret);
241 253
242 ret = regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies), 254 ret = regulator_bulk_disable(wm8994->num_supplies,
243 wm8994->supplies); 255 wm8994->supplies);
244 if (ret != 0) { 256 if (ret != 0) {
245 dev_err(dev, "Failed to disable supplies: %d\n", ret); 257 dev_err(dev, "Failed to disable supplies: %d\n", ret);
@@ -254,7 +266,7 @@ static int wm8994_device_resume(struct device *dev)
254 struct wm8994 *wm8994 = dev_get_drvdata(dev); 266 struct wm8994 *wm8994 = dev_get_drvdata(dev);
255 int ret; 267 int ret;
256 268
257 ret = regulator_bulk_enable(ARRAY_SIZE(wm8994_main_supplies), 269 ret = regulator_bulk_enable(wm8994->num_supplies,
258 wm8994->supplies); 270 wm8994->supplies);
259 if (ret != 0) { 271 if (ret != 0) {
260 dev_err(dev, "Failed to enable supplies: %d\n", ret); 272 dev_err(dev, "Failed to enable supplies: %d\n", ret);
@@ -305,9 +317,10 @@ static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
305/* 317/*
306 * Instantiate the generic non-control parts of the device. 318 * Instantiate the generic non-control parts of the device.
307 */ 319 */
308static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq) 320static int wm8994_device_init(struct wm8994 *wm8994, int irq)
309{ 321{
310 struct wm8994_pdata *pdata = wm8994->dev->platform_data; 322 struct wm8994_pdata *pdata = wm8994->dev->platform_data;
323 const char *devname;
311 int ret, i; 324 int ret, i;
312 325
313 mutex_init(&wm8994->io_lock); 326 mutex_init(&wm8994->io_lock);
@@ -323,25 +336,48 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
323 goto err; 336 goto err;
324 } 337 }
325 338
339 switch (wm8994->type) {
340 case WM8994:
341 wm8994->num_supplies = ARRAY_SIZE(wm8994_main_supplies);
342 break;
343 case WM8958:
344 wm8994->num_supplies = ARRAY_SIZE(wm8958_main_supplies);
345 break;
346 default:
347 BUG();
348 return -EINVAL;
349 }
350
326 wm8994->supplies = kzalloc(sizeof(struct regulator_bulk_data) * 351 wm8994->supplies = kzalloc(sizeof(struct regulator_bulk_data) *
327 ARRAY_SIZE(wm8994_main_supplies), 352 wm8994->num_supplies,
328 GFP_KERNEL); 353 GFP_KERNEL);
329 if (!wm8994->supplies) { 354 if (!wm8994->supplies) {
330 ret = -ENOMEM; 355 ret = -ENOMEM;
331 goto err; 356 goto err;
332 } 357 }
333 358
334 for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++) 359 switch (wm8994->type) {
335 wm8994->supplies[i].supply = wm8994_main_supplies[i]; 360 case WM8994:
336 361 for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++)
337 ret = regulator_bulk_get(wm8994->dev, ARRAY_SIZE(wm8994_main_supplies), 362 wm8994->supplies[i].supply = wm8994_main_supplies[i];
363 break;
364 case WM8958:
365 for (i = 0; i < ARRAY_SIZE(wm8958_main_supplies); i++)
366 wm8994->supplies[i].supply = wm8958_main_supplies[i];
367 break;
368 default:
369 BUG();
370 return -EINVAL;
371 }
372
373 ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies,
338 wm8994->supplies); 374 wm8994->supplies);
339 if (ret != 0) { 375 if (ret != 0) {
340 dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret); 376 dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret);
341 goto err_supplies; 377 goto err_supplies;
342 } 378 }
343 379
344 ret = regulator_bulk_enable(ARRAY_SIZE(wm8994_main_supplies), 380 ret = regulator_bulk_enable(wm8994->num_supplies,
345 wm8994->supplies); 381 wm8994->supplies);
346 if (ret != 0) { 382 if (ret != 0) {
347 dev_err(wm8994->dev, "Failed to enable supplies: %d\n", ret); 383 dev_err(wm8994->dev, "Failed to enable supplies: %d\n", ret);
@@ -353,7 +389,22 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
353 dev_err(wm8994->dev, "Failed to read ID register\n"); 389 dev_err(wm8994->dev, "Failed to read ID register\n");
354 goto err_enable; 390 goto err_enable;
355 } 391 }
356 if (ret != 0x8994) { 392 switch (ret) {
393 case 0x8994:
394 devname = "WM8994";
395 if (wm8994->type != WM8994)
396 dev_warn(wm8994->dev, "Device registered as type %d\n",
397 wm8994->type);
398 wm8994->type = WM8994;
399 break;
400 case 0x8958:
401 devname = "WM8958";
402 if (wm8994->type != WM8958)
403 dev_warn(wm8994->dev, "Device registered as type %d\n",
404 wm8994->type);
405 wm8994->type = WM8958;
406 break;
407 default:
357 dev_err(wm8994->dev, "Device is not a WM8994, ID is %x\n", 408 dev_err(wm8994->dev, "Device is not a WM8994, ID is %x\n",
358 ret); 409 ret);
359 ret = -EINVAL; 410 ret = -EINVAL;
@@ -370,14 +421,16 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
370 switch (ret) { 421 switch (ret) {
371 case 0: 422 case 0:
372 case 1: 423 case 1:
373 dev_warn(wm8994->dev, "revision %c not fully supported\n", 424 if (wm8994->type == WM8994)
374 'A' + ret); 425 dev_warn(wm8994->dev,
426 "revision %c not fully supported\n",
427 'A' + ret);
375 break; 428 break;
376 default: 429 default:
377 dev_info(wm8994->dev, "revision %c\n", 'A' + ret);
378 break; 430 break;
379 } 431 }
380 432
433 dev_info(wm8994->dev, "%s revision %c\n", devname, 'A' + ret);
381 434
382 if (pdata) { 435 if (pdata) {
383 wm8994->irq_base = pdata->irq_base; 436 wm8994->irq_base = pdata->irq_base;
@@ -423,10 +476,10 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
423err_irq: 476err_irq:
424 wm8994_irq_exit(wm8994); 477 wm8994_irq_exit(wm8994);
425err_enable: 478err_enable:
426 regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies), 479 regulator_bulk_disable(wm8994->num_supplies,
427 wm8994->supplies); 480 wm8994->supplies);
428err_get: 481err_get:
429 regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies); 482 regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
430err_supplies: 483err_supplies:
431 kfree(wm8994->supplies); 484 kfree(wm8994->supplies);
432err: 485err:
@@ -439,9 +492,9 @@ static void wm8994_device_exit(struct wm8994 *wm8994)
439{ 492{
440 mfd_remove_devices(wm8994->dev); 493 mfd_remove_devices(wm8994->dev);
441 wm8994_irq_exit(wm8994); 494 wm8994_irq_exit(wm8994);
442 regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies), 495 regulator_bulk_disable(wm8994->num_supplies,
443 wm8994->supplies); 496 wm8994->supplies);
444 regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies); 497 regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
445 kfree(wm8994->supplies); 498 kfree(wm8994->supplies);
446 kfree(wm8994); 499 kfree(wm8994);
447} 500}
@@ -506,8 +559,9 @@ static int wm8994_i2c_probe(struct i2c_client *i2c,
506 wm8994->read_dev = wm8994_i2c_read_device; 559 wm8994->read_dev = wm8994_i2c_read_device;
507 wm8994->write_dev = wm8994_i2c_write_device; 560 wm8994->write_dev = wm8994_i2c_write_device;
508 wm8994->irq = i2c->irq; 561 wm8994->irq = i2c->irq;
562 wm8994->type = id->driver_data;
509 563
510 return wm8994_device_init(wm8994, id->driver_data, i2c->irq); 564 return wm8994_device_init(wm8994, i2c->irq);
511} 565}
512 566
513static int wm8994_i2c_remove(struct i2c_client *i2c) 567static int wm8994_i2c_remove(struct i2c_client *i2c)
@@ -535,7 +589,8 @@ static int wm8994_i2c_resume(struct i2c_client *i2c)
535#endif 589#endif
536 590
537static const struct i2c_device_id wm8994_i2c_id[] = { 591static const struct i2c_device_id wm8994_i2c_id[] = {
538 { "wm8994", 0 }, 592 { "wm8994", WM8994 },
593 { "wm8958", WM8958 },
539 { } 594 { }
540}; 595};
541MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id); 596MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id);
diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h
index de79baee4925..3fd36845ca45 100644
--- a/include/linux/mfd/wm8994/core.h
+++ b/include/linux/mfd/wm8994/core.h
@@ -17,6 +17,11 @@
17 17
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19 19
20enum wm8994_type {
21 WM8994 = 0,
22 WM8958 = 1,
23};
24
20struct regulator_dev; 25struct regulator_dev;
21struct regulator_bulk_data; 26struct regulator_bulk_data;
22 27
@@ -48,6 +53,8 @@ struct wm8994 {
48 struct mutex io_lock; 53 struct mutex io_lock;
49 struct mutex irq_lock; 54 struct mutex irq_lock;
50 55
56 enum wm8994_type type;
57
51 struct device *dev; 58 struct device *dev;
52 int (*read_dev)(struct wm8994 *wm8994, unsigned short reg, 59 int (*read_dev)(struct wm8994 *wm8994, unsigned short reg,
53 int bytes, void *dest); 60 int bytes, void *dest);
@@ -68,6 +75,7 @@ struct wm8994 {
68 u16 gpio_regs[WM8994_NUM_GPIO_REGS]; 75 u16 gpio_regs[WM8994_NUM_GPIO_REGS];
69 76
70 struct regulator_dev *dbvdd; 77 struct regulator_dev *dbvdd;
78 int num_supplies;
71 struct regulator_bulk_data *supplies; 79 struct regulator_bulk_data *supplies;
72}; 80};
73 81