aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm9090.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm9090.c')
-rw-r--r--sound/soc/codecs/wm9090.c183
1 files changed, 59 insertions, 124 deletions
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 1592250daec0..7a1825418ee4 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -34,8 +34,6 @@
34 34
35#include "wm9090.h" 35#include "wm9090.h"
36 36
37static struct snd_soc_codec *wm9090_codec;
38
39static const u16 wm9090_reg_defaults[] = { 37static const u16 wm9090_reg_defaults[] = {
40 0x9093, /* R0 - Software Reset */ 38 0x9093, /* R0 - Software Reset */
41 0x0006, /* R1 - Power Management (1) */ 39 0x0006, /* R1 - Power Management (1) */
@@ -142,15 +140,10 @@ static const u16 wm9090_reg_defaults[] = {
142 140
143/* This struct is used to save the context */ 141/* This struct is used to save the context */
144struct wm9090_priv { 142struct wm9090_priv {
145 /* We're not really registering as a CODEC since ASoC core
146 * does not yet support multiple CODECs but having the CODEC
147 * structure means we can reuse some of the ASoC core
148 * features.
149 */
150 struct snd_soc_codec codec;
151 struct mutex mutex; 143 struct mutex mutex;
152 u16 reg_cache[WM9090_MAX_REGISTER + 1]; 144 u16 reg_cache[WM9090_MAX_REGISTER + 1];
153 struct wm9090_platform_data pdata; 145 struct wm9090_platform_data pdata;
146 void *control_data;
154}; 147};
155 148
156static int wm9090_volatile(unsigned int reg) 149static int wm9090_volatile(unsigned int reg)
@@ -523,7 +516,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
523 case SND_SOC_BIAS_STANDBY: 516 case SND_SOC_BIAS_STANDBY:
524 if (codec->bias_level == SND_SOC_BIAS_OFF) { 517 if (codec->bias_level == SND_SOC_BIAS_OFF) {
525 /* Restore the register cache */ 518 /* Restore the register cache */
526 for (i = 1; i < codec->reg_cache_size; i++) { 519 for (i = 1; i < codec->driver->reg_cache_size; i++) {
527 if (reg_cache[i] == wm9090_reg_defaults[i]) 520 if (reg_cache[i] == wm9090_reg_defaults[i])
528 continue; 521 continue;
529 if (wm9090_volatile(i)) 522 if (wm9090_volatile(i))
@@ -556,51 +549,67 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
556 return 0; 549 return 0;
557} 550}
558 551
559static int wm9090_probe(struct platform_device *pdev) 552static int wm9090_probe(struct snd_soc_codec *codec)
560{ 553{
561 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 554 struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
562 struct snd_soc_codec *codec; 555 int ret;
563 int ret = 0;
564 556
565 if (wm9090_codec == NULL) { 557 codec->control_data = wm9090->control_data;
566 dev_err(&pdev->dev, "Codec device not registered\n"); 558 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
567 return -ENODEV; 559 if (ret != 0) {
560 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
561 return ret;
568 } 562 }
569 563
570 socdev->card->codec = wm9090_codec; 564 ret = snd_soc_read(codec, WM9090_SOFTWARE_RESET);
571 codec = wm9090_codec; 565 if (ret < 0)
572 566 return ret;
573 /* register pcms */ 567 if (ret != wm9090_reg_defaults[WM9090_SOFTWARE_RESET]) {
574 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 568 dev_err(codec->dev, "Device is not a WM9090, ID=%x\n", ret);
575 if (ret < 0) { 569 return -EINVAL;
576 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
577 goto pcm_err;
578 } 570 }
579 571
572 ret = snd_soc_write(codec, WM9090_SOFTWARE_RESET, 0);
573 if (ret < 0)
574 return ret;
575
576 /* Configure some defaults; they will be written out when we
577 * bring the bias up.
578 */
579 wm9090->reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU
580 | WM9090_IN1A_ZC;
581 wm9090->reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU
582 | WM9090_IN1B_ZC;
583 wm9090->reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU
584 | WM9090_IN2A_ZC;
585 wm9090->reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU
586 | WM9090_IN2B_ZC;
587 wm9090->reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |=
588 WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC;
589 wm9090->reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |=
590 WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC;
591 wm9090->reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |=
592 WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC;
593
594 wm9090->reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA;
595
596 wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
597
580 wm9090_add_controls(codec); 598 wm9090_add_controls(codec);
581 599
582 return 0; 600 return 0;
583
584pcm_err:
585 return ret;
586} 601}
587 602
588#ifdef CONFIG_PM 603#ifdef CONFIG_PM
589static int wm9090_suspend(struct platform_device *pdev, pm_message_t state) 604static int wm9090_suspend(struct snd_soc_codec *codec, pm_message_t state)
590{ 605{
591 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
592 struct snd_soc_codec *codec = socdev->card->codec;
593
594 wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF); 606 wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
595 607
596 return 0; 608 return 0;
597} 609}
598 610
599static int wm9090_resume(struct platform_device *pdev) 611static int wm9090_resume(struct snd_soc_codec *codec)
600{ 612{
601 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
602 struct snd_soc_codec *codec = socdev->card->codec;
603
604 wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 613 wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
605 614
606 return 0; 615 return 0;
@@ -610,29 +619,29 @@ static int wm9090_resume(struct platform_device *pdev)
610#define wm9090_resume NULL 619#define wm9090_resume NULL
611#endif 620#endif
612 621
613static int wm9090_remove(struct platform_device *pdev) 622static int wm9090_remove(struct snd_soc_codec *codec)
614{ 623{
615 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 624 wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
616
617 snd_soc_free_pcms(socdev);
618 snd_soc_dapm_free(socdev);
619 625
620 return 0; 626 return 0;
621} 627}
622 628
623struct snd_soc_codec_device soc_codec_dev_wm9090 = { 629static struct snd_soc_codec_driver soc_codec_dev_wm9090 = {
624 .probe = wm9090_probe, 630 .probe = wm9090_probe,
625 .remove = wm9090_remove, 631 .remove = wm9090_remove,
626 .suspend = wm9090_suspend, 632 .suspend = wm9090_suspend,
627 .resume = wm9090_resume, 633 .resume = wm9090_resume,
634 .set_bias_level = wm9090_set_bias_level,
635 .reg_cache_size = (WM9090_MAX_REGISTER + 1),
636 .reg_word_size = sizeof(u16),
637 .reg_cache_default = wm9090_reg_defaults,
638 .volatile_register = wm9090_volatile,
628}; 639};
629EXPORT_SYMBOL_GPL(soc_codec_dev_wm9090);
630 640
631static int wm9090_i2c_probe(struct i2c_client *i2c, 641static int wm9090_i2c_probe(struct i2c_client *i2c,
632 const struct i2c_device_id *id) 642 const struct i2c_device_id *id)
633{ 643{
634 struct wm9090_priv *wm9090; 644 struct wm9090_priv *wm9090;
635 struct snd_soc_codec *codec;
636 int ret; 645 int ret;
637 646
638 wm9090 = kzalloc(sizeof(*wm9090), GFP_KERNEL); 647 wm9090 = kzalloc(sizeof(*wm9090), GFP_KERNEL);
@@ -640,102 +649,28 @@ static int wm9090_i2c_probe(struct i2c_client *i2c,
640 dev_err(&i2c->dev, "Can not allocate memory\n"); 649 dev_err(&i2c->dev, "Can not allocate memory\n");
641 return -ENOMEM; 650 return -ENOMEM;
642 } 651 }
643 codec = &wm9090->codec;
644 652
645 if (i2c->dev.platform_data) 653 if (i2c->dev.platform_data)
646 memcpy(&wm9090->pdata, i2c->dev.platform_data, 654 memcpy(&wm9090->pdata, i2c->dev.platform_data,
647 sizeof(wm9090->pdata)); 655 sizeof(wm9090->pdata));
648 656
649 wm9090_codec = codec;
650
651 i2c_set_clientdata(i2c, wm9090); 657 i2c_set_clientdata(i2c, wm9090);
658 wm9090->control_data = i2c;
659 mutex_init(&wm9090->mutex);
652 660
653 mutex_init(&codec->mutex); 661 ret = snd_soc_register_codec(&i2c->dev,
654 INIT_LIST_HEAD(&codec->dapm_widgets); 662 &soc_codec_dev_wm9090, NULL, 0);
655 INIT_LIST_HEAD(&codec->dapm_paths);
656
657 codec->control_data = i2c;
658 snd_soc_codec_set_drvdata(codec, wm9090);
659 codec->dev = &i2c->dev;
660 codec->name = "WM9090";
661 codec->owner = THIS_MODULE;
662 codec->bias_level = SND_SOC_BIAS_OFF;
663 codec->set_bias_level = wm9090_set_bias_level,
664 codec->reg_cache_size = WM9090_MAX_REGISTER + 1;
665 codec->reg_cache = &wm9090->reg_cache;
666 codec->volatile_register = wm9090_volatile;
667
668 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
669 if (ret != 0) {
670 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
671 goto err;
672 }
673
674 memcpy(&wm9090->reg_cache, wm9090_reg_defaults,
675 sizeof(wm9090->reg_cache));
676
677 ret = snd_soc_read(codec, WM9090_SOFTWARE_RESET);
678 if (ret < 0)
679 goto err;
680 if (ret != wm9090_reg_defaults[WM9090_SOFTWARE_RESET]) {
681 dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", ret);
682 ret = -EINVAL;
683 goto err;
684 }
685
686 ret = snd_soc_write(codec, WM9090_SOFTWARE_RESET, 0);
687 if (ret < 0) 663 if (ret < 0)
688 goto err; 664 kfree(wm9090);
689
690 /* Configure some defaults; they will be written out when we
691 * bring the bias up.
692 */
693 wm9090->reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU
694 | WM9090_IN1A_ZC;
695 wm9090->reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU
696 | WM9090_IN1B_ZC;
697 wm9090->reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU
698 | WM9090_IN2A_ZC;
699 wm9090->reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU
700 | WM9090_IN2B_ZC;
701 wm9090->reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |=
702 WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC;
703 wm9090->reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |=
704 WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC;
705 wm9090->reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |=
706 WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC;
707
708 wm9090->reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA;
709
710 wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
711
712 ret = snd_soc_register_codec(codec);
713 if (ret != 0) {
714 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
715 goto err_bias;
716 }
717
718 return 0;
719
720err_bias:
721 wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
722err:
723 kfree(wm9090);
724 i2c_set_clientdata(i2c, NULL);
725 wm9090_codec = NULL;
726
727 return ret; 665 return ret;
728} 666}
729 667
730static int wm9090_i2c_remove(struct i2c_client *i2c) 668static int wm9090_i2c_remove(struct i2c_client *i2c)
731{ 669{
732 struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c); 670 struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c);
733 struct snd_soc_codec *codec = &wm9090->codec;
734 671
735 snd_soc_unregister_codec(codec); 672 snd_soc_unregister_codec(&i2c->dev);
736 wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
737 kfree(wm9090); 673 kfree(wm9090);
738 wm9090_codec = NULL;
739 674
740 return 0; 675 return 0;
741} 676}
@@ -748,7 +683,7 @@ MODULE_DEVICE_TABLE(i2c, wm9090_id);
748 683
749static struct i2c_driver wm9090_i2c_driver = { 684static struct i2c_driver wm9090_i2c_driver = {
750 .driver = { 685 .driver = {
751 .name = "wm9090", 686 .name = "wm9090-codec",
752 .owner = THIS_MODULE, 687 .owner = THIS_MODULE,
753 }, 688 },
754 .probe = wm9090_i2c_probe, 689 .probe = wm9090_i2c_probe,