aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/wm8994-core.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 23:33:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 23:33:14 -0400
commit9586c959bfc917695893bef0102433a7d0675691 (patch)
treec8b89e40b7a04c3150e50785e7c48b67df360c83 /drivers/mfd/wm8994-core.c
parent34699403e9916060af8ae23f5e4705a6c078e79d (diff)
parentaddfd8a09e1f434a73b3d87d36ef050c73511d2b (diff)
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/wm8994-core.c')
-rw-r--r--drivers/mfd/wm8994-core.c92
1 files changed, 76 insertions, 16 deletions
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)
359} 359}
360#endif 360#endif
361 361
362static const __devinitdata struct reg_default wm8994_revc_patch[] = {
363 { 0x102, 0x3 },
364 { 0x56, 0x3 },
365 { 0x817, 0x0 },
366 { 0x102, 0x0 },
367};
368
369static const __devinitdata struct reg_default wm8958_reva_patch[] = {
370 { 0x102, 0x3 },
371 { 0xcb, 0x81 },
372 { 0x817, 0x0 },
373 { 0x102, 0x0 },
374};
375
376static const __devinitdata struct reg_default wm1811_reva_patch[] = {
377 { 0x102, 0x3 },
378 { 0x56, 0x7 },
379 { 0x5d, 0x7e },
380 { 0x5e, 0x0 },
381 { 0x102, 0x0 },
382};
383
362/* 384/*
363 * Instantiate the generic non-control parts of the device. 385 * Instantiate the generic non-control parts of the device.
364 */ 386 */
365static int wm8994_device_init(struct wm8994 *wm8994, int irq) 387static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq)
366{ 388{
367 struct wm8994_pdata *pdata = wm8994->dev->platform_data; 389 struct wm8994_pdata *pdata = wm8994->dev->platform_data;
368 struct regmap_config *regmap_config; 390 struct regmap_config *regmap_config;
391 const struct reg_default *regmap_patch = NULL;
369 const char *devname; 392 const char *devname;
370 int ret, i; 393 int ret, i, patch_regs;
371 int pulls = 0; 394 int pulls = 0;
372 395
373 dev_set_drvdata(wm8994->dev, wm8994); 396 dev_set_drvdata(wm8994->dev, wm8994);
@@ -379,7 +402,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
379 NULL, 0); 402 NULL, 0);
380 if (ret != 0) { 403 if (ret != 0) {
381 dev_err(wm8994->dev, "Failed to add children: %d\n", ret); 404 dev_err(wm8994->dev, "Failed to add children: %d\n", ret);
382 goto err_regmap; 405 goto err;
383 } 406 }
384 407
385 switch (wm8994->type) { 408 switch (wm8994->type) {
@@ -394,7 +417,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
394 break; 417 break;
395 default: 418 default:
396 BUG(); 419 BUG();
397 goto err_regmap; 420 goto err;
398 } 421 }
399 422
400 wm8994->supplies = devm_kzalloc(wm8994->dev, 423 wm8994->supplies = devm_kzalloc(wm8994->dev,
@@ -402,7 +425,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
402 wm8994->num_supplies, GFP_KERNEL); 425 wm8994->num_supplies, GFP_KERNEL);
403 if (!wm8994->supplies) { 426 if (!wm8994->supplies) {
404 ret = -ENOMEM; 427 ret = -ENOMEM;
405 goto err_regmap; 428 goto err;
406 } 429 }
407 430
408 switch (wm8994->type) { 431 switch (wm8994->type) {
@@ -420,14 +443,14 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
420 break; 443 break;
421 default: 444 default:
422 BUG(); 445 BUG();
423 goto err_regmap; 446 goto err;
424 } 447 }
425 448
426 ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies, 449 ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies,
427 wm8994->supplies); 450 wm8994->supplies);
428 if (ret != 0) { 451 if (ret != 0) {
429 dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret); 452 dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret);
430 goto err_regmap; 453 goto err;
431 } 454 }
432 455
433 ret = regulator_bulk_enable(wm8994->num_supplies, 456 ret = regulator_bulk_enable(wm8994->num_supplies,
@@ -488,15 +511,44 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
488 "revision %c not fully supported\n", 511 "revision %c not fully supported\n",
489 'A' + wm8994->revision); 512 'A' + wm8994->revision);
490 break; 513 break;
514 case 2:
515 case 3:
516 regmap_patch = wm8994_revc_patch;
517 patch_regs = ARRAY_SIZE(wm8994_revc_patch);
518 break;
519 default:
520 break;
521 }
522 break;
523
524 case WM8958:
525 switch (wm8994->revision) {
526 case 0:
527 regmap_patch = wm8958_reva_patch;
528 patch_regs = ARRAY_SIZE(wm8958_reva_patch);
529 break;
491 default: 530 default:
492 break; 531 break;
493 } 532 }
494 break; 533 break;
534
495 case WM1811: 535 case WM1811:
496 /* Revision C did not change the relevant layer */ 536 /* Revision C did not change the relevant layer */
497 if (wm8994->revision > 1) 537 if (wm8994->revision > 1)
498 wm8994->revision++; 538 wm8994->revision++;
539 switch (wm8994->revision) {
540 case 0:
541 case 1:
542 case 2:
543 case 3:
544 regmap_patch = wm1811_reva_patch;
545 patch_regs = ARRAY_SIZE(wm1811_reva_patch);
546 break;
547 default:
548 break;
549 }
499 break; 550 break;
551
500 default: 552 default:
501 break; 553 break;
502 } 554 }
@@ -526,6 +578,16 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
526 return ret; 578 return ret;
527 } 579 }
528 580
581 if (regmap_patch) {
582 ret = regmap_register_patch(wm8994->regmap, regmap_patch,
583 patch_regs);
584 if (ret != 0) {
585 dev_err(wm8994->dev, "Failed to register patch: %d\n",
586 ret);
587 goto err;
588 }
589 }
590
529 if (pdata) { 591 if (pdata) {
530 wm8994->irq_base = pdata->irq_base; 592 wm8994->irq_base = pdata->irq_base;
531 wm8994->gpio_base = pdata->gpio_base; 593 wm8994->gpio_base = pdata->gpio_base;
@@ -588,13 +650,12 @@ err_enable:
588 wm8994->supplies); 650 wm8994->supplies);
589err_get: 651err_get:
590 regulator_bulk_free(wm8994->num_supplies, wm8994->supplies); 652 regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
591err_regmap: 653err:
592 regmap_exit(wm8994->regmap);
593 mfd_remove_devices(wm8994->dev); 654 mfd_remove_devices(wm8994->dev);
594 return ret; 655 return ret;
595} 656}
596 657
597static void wm8994_device_exit(struct wm8994 *wm8994) 658static __devexit void wm8994_device_exit(struct wm8994 *wm8994)
598{ 659{
599 pm_runtime_disable(wm8994->dev); 660 pm_runtime_disable(wm8994->dev);
600 mfd_remove_devices(wm8994->dev); 661 mfd_remove_devices(wm8994->dev);
@@ -602,7 +663,6 @@ static void wm8994_device_exit(struct wm8994 *wm8994)
602 regulator_bulk_disable(wm8994->num_supplies, 663 regulator_bulk_disable(wm8994->num_supplies,
603 wm8994->supplies); 664 wm8994->supplies);
604 regulator_bulk_free(wm8994->num_supplies, wm8994->supplies); 665 regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
605 regmap_exit(wm8994->regmap);
606} 666}
607 667
608static const struct of_device_id wm8994_of_match[] = { 668static const struct of_device_id wm8994_of_match[] = {
@@ -613,8 +673,8 @@ static const struct of_device_id wm8994_of_match[] = {
613}; 673};
614MODULE_DEVICE_TABLE(of, wm8994_of_match); 674MODULE_DEVICE_TABLE(of, wm8994_of_match);
615 675
616static int wm8994_i2c_probe(struct i2c_client *i2c, 676static __devinit int wm8994_i2c_probe(struct i2c_client *i2c,
617 const struct i2c_device_id *id) 677 const struct i2c_device_id *id)
618{ 678{
619 struct wm8994 *wm8994; 679 struct wm8994 *wm8994;
620 int ret; 680 int ret;
@@ -628,7 +688,7 @@ static int wm8994_i2c_probe(struct i2c_client *i2c,
628 wm8994->irq = i2c->irq; 688 wm8994->irq = i2c->irq;
629 wm8994->type = id->driver_data; 689 wm8994->type = id->driver_data;
630 690
631 wm8994->regmap = regmap_init_i2c(i2c, &wm8994_base_regmap_config); 691 wm8994->regmap = devm_regmap_init_i2c(i2c, &wm8994_base_regmap_config);
632 if (IS_ERR(wm8994->regmap)) { 692 if (IS_ERR(wm8994->regmap)) {
633 ret = PTR_ERR(wm8994->regmap); 693 ret = PTR_ERR(wm8994->regmap);
634 dev_err(wm8994->dev, "Failed to allocate register map: %d\n", 694 dev_err(wm8994->dev, "Failed to allocate register map: %d\n",
@@ -639,7 +699,7 @@ static int wm8994_i2c_probe(struct i2c_client *i2c,
639 return wm8994_device_init(wm8994, i2c->irq); 699 return wm8994_device_init(wm8994, i2c->irq);
640} 700}
641 701
642static int wm8994_i2c_remove(struct i2c_client *i2c) 702static __devexit int wm8994_i2c_remove(struct i2c_client *i2c)
643{ 703{
644 struct wm8994 *wm8994 = i2c_get_clientdata(i2c); 704 struct wm8994 *wm8994 = i2c_get_clientdata(i2c);
645 705
@@ -668,7 +728,7 @@ static struct i2c_driver wm8994_i2c_driver = {
668 .of_match_table = wm8994_of_match, 728 .of_match_table = wm8994_of_match,
669 }, 729 },
670 .probe = wm8994_i2c_probe, 730 .probe = wm8994_i2c_probe,
671 .remove = wm8994_i2c_remove, 731 .remove = __devexit_p(wm8994_i2c_remove),
672 .id_table = wm8994_i2c_id, 732 .id_table = wm8994_i2c_id,
673}; 733};
674 734