aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8750.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8750.c')
-rw-r--r--sound/soc/codecs/wm8750.c87
1 files changed, 30 insertions, 57 deletions
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 16cd5d4d5ad9..e23cb09f0d14 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -31,25 +31,6 @@
31#define AUDIO_NAME "WM8750" 31#define AUDIO_NAME "WM8750"
32#define WM8750_VERSION "0.12" 32#define WM8750_VERSION "0.12"
33 33
34/*
35 * Debug
36 */
37
38#define WM8750_DEBUG 0
39
40#ifdef WM8750_DEBUG
41#define dbg(format, arg...) \
42 printk(KERN_DEBUG AUDIO_NAME ": " format "\n" , ## arg)
43#else
44#define dbg(format, arg...) do {} while (0)
45#endif
46#define err(format, arg...) \
47 printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg)
48#define info(format, arg...) \
49 printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
50#define warn(format, arg...) \
51 printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg)
52
53/* codec private data */ 34/* codec private data */
54struct wm8750_priv { 35struct wm8750_priv {
55 unsigned int sysclk; 36 unsigned int sysclk;
@@ -378,7 +359,7 @@ static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = {
378 SND_SOC_DAPM_INPUT("RINPUT3"), 359 SND_SOC_DAPM_INPUT("RINPUT3"),
379}; 360};
380 361
381static const char *audio_map[][3] = { 362static const struct snd_soc_dapm_route audio_map[] = {
382 /* left mixer */ 363 /* left mixer */
383 {"Left Mixer", "Playback Switch", "Left DAC"}, 364 {"Left Mixer", "Playback Switch", "Left DAC"},
384 {"Left Mixer", "Left Bypass Switch", "Left Line Mux"}, 365 {"Left Mixer", "Left Bypass Switch", "Left Line Mux"},
@@ -470,22 +451,14 @@ static const char *audio_map[][3] = {
470 /* ADC */ 451 /* ADC */
471 {"Left ADC", NULL, "Left ADC Mux"}, 452 {"Left ADC", NULL, "Left ADC Mux"},
472 {"Right ADC", NULL, "Right ADC Mux"}, 453 {"Right ADC", NULL, "Right ADC Mux"},
473
474 /* terminator */
475 {NULL, NULL, NULL},
476}; 454};
477 455
478static int wm8750_add_widgets(struct snd_soc_codec *codec) 456static int wm8750_add_widgets(struct snd_soc_codec *codec)
479{ 457{
480 int i; 458 snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets,
481 459 ARRAY_SIZE(wm8750_dapm_widgets));
482 for (i = 0; i < ARRAY_SIZE(wm8750_dapm_widgets); i++)
483 snd_soc_dapm_new_control(codec, &wm8750_dapm_widgets[i]);
484 460
485 /* set up audio path audio_mapnects */ 461 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
486 for (i = 0; audio_map[i][0] != NULL; i++)
487 snd_soc_dapm_connect_input(codec, audio_map[i][0],
488 audio_map[i][1], audio_map[i][2]);
489 462
490 snd_soc_dapm_new_widgets(codec); 463 snd_soc_dapm_new_widgets(codec);
491 return 0; 464 return 0;
@@ -563,7 +536,7 @@ static inline int get_coeff(int mclk, int rate)
563 return -EINVAL; 536 return -EINVAL;
564} 537}
565 538
566static int wm8750_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, 539static int wm8750_set_dai_sysclk(struct snd_soc_dai *codec_dai,
567 int clk_id, unsigned int freq, int dir) 540 int clk_id, unsigned int freq, int dir)
568{ 541{
569 struct snd_soc_codec *codec = codec_dai->codec; 542 struct snd_soc_codec *codec = codec_dai->codec;
@@ -581,7 +554,7 @@ static int wm8750_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai,
581 return -EINVAL; 554 return -EINVAL;
582} 555}
583 556
584static int wm8750_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, 557static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai,
585 unsigned int fmt) 558 unsigned int fmt)
586{ 559{
587 struct snd_soc_codec *codec = codec_dai->codec; 560 struct snd_soc_codec *codec = codec_dai->codec;
@@ -674,7 +647,7 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
674 return 0; 647 return 0;
675} 648}
676 649
677static int wm8750_mute(struct snd_soc_codec_dai *dai, int mute) 650static int wm8750_mute(struct snd_soc_dai *dai, int mute)
678{ 651{
679 struct snd_soc_codec *codec = dai->codec; 652 struct snd_soc_codec *codec = dai->codec;
680 u16 mute_reg = wm8750_read_reg_cache(codec, WM8750_ADCDAC) & 0xfff7; 653 u16 mute_reg = wm8750_read_reg_cache(codec, WM8750_ADCDAC) & 0xfff7;
@@ -686,29 +659,29 @@ static int wm8750_mute(struct snd_soc_codec_dai *dai, int mute)
686 return 0; 659 return 0;
687} 660}
688 661
689static int wm8750_dapm_event(struct snd_soc_codec *codec, int event) 662static int wm8750_set_bias_level(struct snd_soc_codec *codec,
663 enum snd_soc_bias_level level)
690{ 664{
691 u16 pwr_reg = wm8750_read_reg_cache(codec, WM8750_PWR1) & 0xfe3e; 665 u16 pwr_reg = wm8750_read_reg_cache(codec, WM8750_PWR1) & 0xfe3e;
692 666
693 switch (event) { 667 switch (level) {
694 case SNDRV_CTL_POWER_D0: /* full On */ 668 case SND_SOC_BIAS_ON:
695 /* set vmid to 50k and unmute dac */ 669 /* set vmid to 50k and unmute dac */
696 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x00c0); 670 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x00c0);
697 break; 671 break;
698 case SNDRV_CTL_POWER_D1: /* partial On */ 672 case SND_SOC_BIAS_PREPARE:
699 case SNDRV_CTL_POWER_D2: /* partial On */
700 /* set vmid to 5k for quick power up */ 673 /* set vmid to 5k for quick power up */
701 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); 674 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
702 break; 675 break;
703 case SNDRV_CTL_POWER_D3hot: /* Off, with power */ 676 case SND_SOC_BIAS_STANDBY:
704 /* mute dac and set vmid to 500k, enable VREF */ 677 /* mute dac and set vmid to 500k, enable VREF */
705 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x0141); 678 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x0141);
706 break; 679 break;
707 case SNDRV_CTL_POWER_D3cold: /* Off, without power */ 680 case SND_SOC_BIAS_OFF:
708 wm8750_write(codec, WM8750_PWR1, 0x0001); 681 wm8750_write(codec, WM8750_PWR1, 0x0001);
709 break; 682 break;
710 } 683 }
711 codec->dapm_state = event; 684 codec->bias_level = level;
712 return 0; 685 return 0;
713} 686}
714 687
@@ -719,7 +692,7 @@ static int wm8750_dapm_event(struct snd_soc_codec *codec, int event)
719#define WM8750_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 692#define WM8750_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
720 SNDRV_PCM_FMTBIT_S24_LE) 693 SNDRV_PCM_FMTBIT_S24_LE)
721 694
722struct snd_soc_codec_dai wm8750_dai = { 695struct snd_soc_dai wm8750_dai = {
723 .name = "WM8750", 696 .name = "WM8750",
724 .playback = { 697 .playback = {
725 .stream_name = "Playback", 698 .stream_name = "Playback",
@@ -748,7 +721,7 @@ static void wm8750_work(struct work_struct *work)
748{ 721{
749 struct snd_soc_codec *codec = 722 struct snd_soc_codec *codec =
750 container_of(work, struct snd_soc_codec, delayed_work.work); 723 container_of(work, struct snd_soc_codec, delayed_work.work);
751 wm8750_dapm_event(codec, codec->dapm_state); 724 wm8750_set_bias_level(codec, codec->bias_level);
752} 725}
753 726
754static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) 727static int wm8750_suspend(struct platform_device *pdev, pm_message_t state)
@@ -756,7 +729,7 @@ static int wm8750_suspend(struct platform_device *pdev, pm_message_t state)
756 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 729 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
757 struct snd_soc_codec *codec = socdev->codec; 730 struct snd_soc_codec *codec = socdev->codec;
758 731
759 wm8750_dapm_event(codec, SNDRV_CTL_POWER_D3cold); 732 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
760 return 0; 733 return 0;
761} 734}
762 735
@@ -777,12 +750,12 @@ static int wm8750_resume(struct platform_device *pdev)
777 codec->hw_write(codec->control_data, data, 2); 750 codec->hw_write(codec->control_data, data, 2);
778 } 751 }
779 752
780 wm8750_dapm_event(codec, SNDRV_CTL_POWER_D3hot); 753 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
781 754
782 /* charge wm8750 caps */ 755 /* charge wm8750 caps */
783 if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0) { 756 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) {
784 wm8750_dapm_event(codec, SNDRV_CTL_POWER_D2); 757 wm8750_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
785 codec->dapm_state = SNDRV_CTL_POWER_D0; 758 codec->bias_level = SND_SOC_BIAS_ON;
786 schedule_delayed_work(&codec->delayed_work, 759 schedule_delayed_work(&codec->delayed_work,
787 msecs_to_jiffies(1000)); 760 msecs_to_jiffies(1000));
788 } 761 }
@@ -803,10 +776,10 @@ static int wm8750_init(struct snd_soc_device *socdev)
803 codec->owner = THIS_MODULE; 776 codec->owner = THIS_MODULE;
804 codec->read = wm8750_read_reg_cache; 777 codec->read = wm8750_read_reg_cache;
805 codec->write = wm8750_write; 778 codec->write = wm8750_write;
806 codec->dapm_event = wm8750_dapm_event; 779 codec->set_bias_level = wm8750_set_bias_level;
807 codec->dai = &wm8750_dai; 780 codec->dai = &wm8750_dai;
808 codec->num_dai = 1; 781 codec->num_dai = 1;
809 codec->reg_cache_size = sizeof(wm8750_reg); 782 codec->reg_cache_size = ARRAY_SIZE(wm8750_reg);
810 codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KERNEL); 783 codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KERNEL);
811 if (codec->reg_cache == NULL) 784 if (codec->reg_cache == NULL)
812 return -ENOMEM; 785 return -ENOMEM;
@@ -821,8 +794,8 @@ static int wm8750_init(struct snd_soc_device *socdev)
821 } 794 }
822 795
823 /* charge output caps */ 796 /* charge output caps */
824 wm8750_dapm_event(codec, SNDRV_CTL_POWER_D2); 797 wm8750_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
825 codec->dapm_state = SNDRV_CTL_POWER_D3hot; 798 codec->bias_level = SND_SOC_BIAS_STANDBY;
826 schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000)); 799 schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000));
827 800
828 /* set the update bits */ 801 /* set the update bits */
@@ -904,13 +877,13 @@ static int wm8750_codec_probe(struct i2c_adapter *adap, int addr, int kind)
904 877
905 ret = i2c_attach_client(i2c); 878 ret = i2c_attach_client(i2c);
906 if (ret < 0) { 879 if (ret < 0) {
907 err("failed to attach codec at addr %x\n", addr); 880 pr_err("failed to attach codec at addr %x\n", addr);
908 goto err; 881 goto err;
909 } 882 }
910 883
911 ret = wm8750_init(socdev); 884 ret = wm8750_init(socdev);
912 if (ret < 0) { 885 if (ret < 0) {
913 err("failed to initialise WM8750\n"); 886 pr_err("failed to initialise WM8750\n");
914 goto err; 887 goto err;
915 } 888 }
916 return ret; 889 return ret;
@@ -961,7 +934,7 @@ static int wm8750_probe(struct platform_device *pdev)
961 struct wm8750_priv *wm8750; 934 struct wm8750_priv *wm8750;
962 int ret = 0; 935 int ret = 0;
963 936
964 info("WM8750 Audio Codec %s", WM8750_VERSION); 937 pr_info("WM8750 Audio Codec %s", WM8750_VERSION);
965 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 938 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
966 if (codec == NULL) 939 if (codec == NULL)
967 return -ENOMEM; 940 return -ENOMEM;
@@ -1021,7 +994,7 @@ static int wm8750_remove(struct platform_device *pdev)
1021 struct snd_soc_codec *codec = socdev->codec; 994 struct snd_soc_codec *codec = socdev->codec;
1022 995
1023 if (codec->control_data) 996 if (codec->control_data)
1024 wm8750_dapm_event(codec, SNDRV_CTL_POWER_D3cold); 997 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
1025 run_delayed_work(&codec->delayed_work); 998 run_delayed_work(&codec->delayed_work);
1026 snd_soc_free_pcms(socdev); 999 snd_soc_free_pcms(socdev);
1027 snd_soc_dapm_free(socdev); 1000 snd_soc_dapm_free(socdev);