diff options
Diffstat (limited to 'sound/soc/codecs/wm8750.c')
-rw-r--r-- | sound/soc/codecs/wm8750.c | 87 |
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 */ |
54 | struct wm8750_priv { | 35 | struct 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 | ||
381 | static const char *audio_map[][3] = { | 362 | static 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 | ||
478 | static int wm8750_add_widgets(struct snd_soc_codec *codec) | 456 | static 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 | ||
566 | static int wm8750_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, | 539 | static 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 | ||
584 | static int wm8750_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, | 557 | static 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 | ||
677 | static int wm8750_mute(struct snd_soc_codec_dai *dai, int mute) | 650 | static 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 | ||
689 | static int wm8750_dapm_event(struct snd_soc_codec *codec, int event) | 662 | static 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 | ||
722 | struct snd_soc_codec_dai wm8750_dai = { | 695 | struct 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 | ||
754 | static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) | 727 | static 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); |