diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-12-15 09:56:44 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-12-15 09:56:44 -0500 |
commit | 20694ad278742ed982b24117d8525f0673529f63 (patch) | |
tree | efa288f95598b24cc1421df0ff9cbcae1c16b239 /sound | |
parent | 326b06a8a9b09d6d9a276fd550b6b6bb138e9a47 (diff) | |
parent | 7f3dd4a8e31cdaed5f80f24b798cedcab644830b (diff) |
Merge remote-tracking branch 'asoc/topic/cs42l73' into asoc-next
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/cs42l73.c | 116 |
1 files changed, 89 insertions, 27 deletions
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index a0791ecf6d95..6361dab48bd1 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c | |||
@@ -40,6 +40,7 @@ struct cs42l73_private { | |||
40 | u32 sysclk; | 40 | u32 sysclk; |
41 | u8 mclksel; | 41 | u8 mclksel; |
42 | u32 mclk; | 42 | u32 mclk; |
43 | int shutdwn_delay; | ||
43 | }; | 44 | }; |
44 | 45 | ||
45 | static const struct reg_default cs42l73_reg_defaults[] = { | 46 | static const struct reg_default cs42l73_reg_defaults[] = { |
@@ -588,7 +589,60 @@ static const struct snd_kcontrol_new cs42l73_snd_controls[] = { | |||
588 | SOC_ENUM("XSPOUT Mono/Stereo Select", xsp_output_mux_enum), | 589 | SOC_ENUM("XSPOUT Mono/Stereo Select", xsp_output_mux_enum), |
589 | }; | 590 | }; |
590 | 591 | ||
592 | static int cs42l73_spklo_spk_amp_event(struct snd_soc_dapm_widget *w, | ||
593 | struct snd_kcontrol *kcontrol, int event) | ||
594 | { | ||
595 | struct snd_soc_codec *codec = w->codec; | ||
596 | struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec); | ||
597 | switch (event) { | ||
598 | case SND_SOC_DAPM_POST_PMD: | ||
599 | /* 150 ms delay between setting PDN and MCLKDIS */ | ||
600 | priv->shutdwn_delay = 150; | ||
601 | break; | ||
602 | default: | ||
603 | pr_err("Invalid event = 0x%x\n", event); | ||
604 | } | ||
605 | return 0; | ||
606 | } | ||
607 | |||
608 | static int cs42l73_ear_amp_event(struct snd_soc_dapm_widget *w, | ||
609 | struct snd_kcontrol *kcontrol, int event) | ||
610 | { | ||
611 | struct snd_soc_codec *codec = w->codec; | ||
612 | struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec); | ||
613 | switch (event) { | ||
614 | case SND_SOC_DAPM_POST_PMD: | ||
615 | /* 50 ms delay between setting PDN and MCLKDIS */ | ||
616 | if (priv->shutdwn_delay < 50) | ||
617 | priv->shutdwn_delay = 50; | ||
618 | break; | ||
619 | default: | ||
620 | pr_err("Invalid event = 0x%x\n", event); | ||
621 | } | ||
622 | return 0; | ||
623 | } | ||
624 | |||
625 | |||
626 | static int cs42l73_hp_amp_event(struct snd_soc_dapm_widget *w, | ||
627 | struct snd_kcontrol *kcontrol, int event) | ||
628 | { | ||
629 | struct snd_soc_codec *codec = w->codec; | ||
630 | struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec); | ||
631 | switch (event) { | ||
632 | case SND_SOC_DAPM_POST_PMD: | ||
633 | /* 30 ms delay between setting PDN and MCLKDIS */ | ||
634 | if (priv->shutdwn_delay < 30) | ||
635 | priv->shutdwn_delay = 30; | ||
636 | break; | ||
637 | default: | ||
638 | pr_err("Invalid event = 0x%x\n", event); | ||
639 | } | ||
640 | return 0; | ||
641 | } | ||
642 | |||
591 | static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = { | 643 | static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = { |
644 | SND_SOC_DAPM_INPUT("DMICA"), | ||
645 | SND_SOC_DAPM_INPUT("DMICB"), | ||
592 | SND_SOC_DAPM_INPUT("LINEINA"), | 646 | SND_SOC_DAPM_INPUT("LINEINA"), |
593 | SND_SOC_DAPM_INPUT("LINEINB"), | 647 | SND_SOC_DAPM_INPUT("LINEINB"), |
594 | SND_SOC_DAPM_INPUT("MIC1"), | 648 | SND_SOC_DAPM_INPUT("MIC1"), |
@@ -604,9 +658,7 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = { | |||
604 | CS42L73_PWRCTL2, 3, 1), | 658 | CS42L73_PWRCTL2, 3, 1), |
605 | SND_SOC_DAPM_AIF_OUT("ASPOUTR", NULL, 0, | 659 | SND_SOC_DAPM_AIF_OUT("ASPOUTR", NULL, 0, |
606 | CS42L73_PWRCTL2, 3, 1), | 660 | CS42L73_PWRCTL2, 3, 1), |
607 | SND_SOC_DAPM_AIF_OUT("VSPOUTL", NULL, 0, | 661 | SND_SOC_DAPM_AIF_OUT("VSPINOUT", NULL, 0, |
608 | CS42L73_PWRCTL2, 4, 1), | ||
609 | SND_SOC_DAPM_AIF_OUT("VSPOUTR", NULL, 0, | ||
610 | CS42L73_PWRCTL2, 4, 1), | 662 | CS42L73_PWRCTL2, 4, 1), |
611 | 663 | ||
612 | SND_SOC_DAPM_PGA("PGA Left", SND_SOC_NOPM, 0, 0, NULL, 0), | 664 | SND_SOC_DAPM_PGA("PGA Left", SND_SOC_NOPM, 0, 0, NULL, 0), |
@@ -632,8 +684,7 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = { | |||
632 | SND_SOC_DAPM_MIXER("ASPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), | 684 | SND_SOC_DAPM_MIXER("ASPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), |
633 | SND_SOC_DAPM_MIXER("XSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), | 685 | SND_SOC_DAPM_MIXER("XSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), |
634 | SND_SOC_DAPM_MIXER("XSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), | 686 | SND_SOC_DAPM_MIXER("XSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), |
635 | SND_SOC_DAPM_MIXER("VSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), | 687 | SND_SOC_DAPM_MIXER("VSP Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), |
636 | SND_SOC_DAPM_MIXER("VSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
637 | 688 | ||
638 | SND_SOC_DAPM_AIF_IN("XSPINL", NULL, 0, | 689 | SND_SOC_DAPM_AIF_IN("XSPINL", NULL, 0, |
639 | CS42L73_PWRCTL2, 0, 1), | 690 | CS42L73_PWRCTL2, 0, 1), |
@@ -649,7 +700,7 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = { | |||
649 | SND_SOC_DAPM_AIF_IN("ASPINM", NULL, 0, | 700 | SND_SOC_DAPM_AIF_IN("ASPINM", NULL, 0, |
650 | CS42L73_PWRCTL2, 2, 1), | 701 | CS42L73_PWRCTL2, 2, 1), |
651 | 702 | ||
652 | SND_SOC_DAPM_AIF_IN("VSPIN", NULL, 0, | 703 | SND_SOC_DAPM_AIF_IN("VSPINOUT", NULL, 0, |
653 | CS42L73_PWRCTL2, 4, 1), | 704 | CS42L73_PWRCTL2, 4, 1), |
654 | 705 | ||
655 | SND_SOC_DAPM_MIXER("HL Left Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), | 706 | SND_SOC_DAPM_MIXER("HL Left Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), |
@@ -674,16 +725,20 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = { | |||
674 | SND_SOC_DAPM_PGA("SPK DAC", SND_SOC_NOPM, 0, 0, NULL, 0), | 725 | SND_SOC_DAPM_PGA("SPK DAC", SND_SOC_NOPM, 0, 0, NULL, 0), |
675 | SND_SOC_DAPM_PGA("ESL DAC", SND_SOC_NOPM, 0, 0, NULL, 0), | 726 | SND_SOC_DAPM_PGA("ESL DAC", SND_SOC_NOPM, 0, 0, NULL, 0), |
676 | 727 | ||
677 | SND_SOC_DAPM_SWITCH("HP Amp", CS42L73_PWRCTL3, 0, 1, | 728 | SND_SOC_DAPM_SWITCH_E("HP Amp", CS42L73_PWRCTL3, 0, 1, |
678 | &hp_amp_ctl), | 729 | &hp_amp_ctl, cs42l73_hp_amp_event, |
730 | SND_SOC_DAPM_POST_PMD), | ||
679 | SND_SOC_DAPM_SWITCH("LO Amp", CS42L73_PWRCTL3, 1, 1, | 731 | SND_SOC_DAPM_SWITCH("LO Amp", CS42L73_PWRCTL3, 1, 1, |
680 | &lo_amp_ctl), | 732 | &lo_amp_ctl), |
681 | SND_SOC_DAPM_SWITCH("SPK Amp", CS42L73_PWRCTL3, 2, 1, | 733 | SND_SOC_DAPM_SWITCH_E("SPK Amp", CS42L73_PWRCTL3, 2, 1, |
682 | &spk_amp_ctl), | 734 | &spk_amp_ctl, cs42l73_spklo_spk_amp_event, |
683 | SND_SOC_DAPM_SWITCH("EAR Amp", CS42L73_PWRCTL3, 3, 1, | 735 | SND_SOC_DAPM_POST_PMD), |
684 | &ear_amp_ctl), | 736 | SND_SOC_DAPM_SWITCH_E("EAR Amp", CS42L73_PWRCTL3, 3, 1, |
685 | SND_SOC_DAPM_SWITCH("SPKLO Amp", CS42L73_PWRCTL3, 4, 1, | 737 | &ear_amp_ctl, cs42l73_ear_amp_event, |
686 | &spklo_amp_ctl), | 738 | SND_SOC_DAPM_POST_PMD), |
739 | SND_SOC_DAPM_SWITCH_E("SPKLO Amp", CS42L73_PWRCTL3, 4, 1, | ||
740 | &spklo_amp_ctl, cs42l73_spklo_spk_amp_event, | ||
741 | SND_SOC_DAPM_POST_PMD), | ||
687 | 742 | ||
688 | SND_SOC_DAPM_OUTPUT("HPOUTA"), | 743 | SND_SOC_DAPM_OUTPUT("HPOUTA"), |
689 | SND_SOC_DAPM_OUTPUT("HPOUTB"), | 744 | SND_SOC_DAPM_OUTPUT("HPOUTB"), |
@@ -705,7 +760,7 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = { | |||
705 | 760 | ||
706 | {"ESL DAC", "ESL-ASP Mono Volume", "ESL Mixer"}, | 761 | {"ESL DAC", "ESL-ASP Mono Volume", "ESL Mixer"}, |
707 | {"ESL DAC", "ESL-XSP Mono Volume", "ESL Mixer"}, | 762 | {"ESL DAC", "ESL-XSP Mono Volume", "ESL Mixer"}, |
708 | {"ESL DAC", "ESL-VSP Mono Volume", "VSPIN"}, | 763 | {"ESL DAC", "ESL-VSP Mono Volume", "VSPINOUT"}, |
709 | /* Loopback */ | 764 | /* Loopback */ |
710 | {"ESL DAC", "ESL-IP Mono Volume", "Input Left Capture"}, | 765 | {"ESL DAC", "ESL-IP Mono Volume", "Input Left Capture"}, |
711 | {"ESL DAC", "ESL-IP Mono Volume", "Input Right Capture"}, | 766 | {"ESL DAC", "ESL-IP Mono Volume", "Input Right Capture"}, |
@@ -727,7 +782,7 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = { | |||
727 | 782 | ||
728 | {"SPK DAC", "SPK-ASP Mono Volume", "SPK Mixer"}, | 783 | {"SPK DAC", "SPK-ASP Mono Volume", "SPK Mixer"}, |
729 | {"SPK DAC", "SPK-XSP Mono Volume", "SPK Mixer"}, | 784 | {"SPK DAC", "SPK-XSP Mono Volume", "SPK Mixer"}, |
730 | {"SPK DAC", "SPK-VSP Mono Volume", "VSPIN"}, | 785 | {"SPK DAC", "SPK-VSP Mono Volume", "VSPINOUT"}, |
731 | /* Loopback */ | 786 | /* Loopback */ |
732 | {"SPK DAC", "SPK-IP Mono Volume", "Input Left Capture"}, | 787 | {"SPK DAC", "SPK-IP Mono Volume", "Input Left Capture"}, |
733 | {"SPK DAC", "SPK-IP Mono Volume", "Input Right Capture"}, | 788 | {"SPK DAC", "SPK-IP Mono Volume", "Input Right Capture"}, |
@@ -770,8 +825,8 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = { | |||
770 | {"HL Right Mixer", NULL, "ASPINR"}, | 825 | {"HL Right Mixer", NULL, "ASPINR"}, |
771 | {"HL Left Mixer", NULL, "XSPINL"}, | 826 | {"HL Left Mixer", NULL, "XSPINL"}, |
772 | {"HL Right Mixer", NULL, "XSPINR"}, | 827 | {"HL Right Mixer", NULL, "XSPINR"}, |
773 | {"HL Left Mixer", NULL, "VSPIN"}, | 828 | {"HL Left Mixer", NULL, "VSPINOUT"}, |
774 | {"HL Right Mixer", NULL, "VSPIN"}, | 829 | {"HL Right Mixer", NULL, "VSPINOUT"}, |
775 | 830 | ||
776 | {"ASPINL", NULL, "ASP Playback"}, | 831 | {"ASPINL", NULL, "ASP Playback"}, |
777 | {"ASPINM", NULL, "ASP Playback"}, | 832 | {"ASPINM", NULL, "ASP Playback"}, |
@@ -779,7 +834,7 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = { | |||
779 | {"XSPINL", NULL, "XSP Playback"}, | 834 | {"XSPINL", NULL, "XSP Playback"}, |
780 | {"XSPINM", NULL, "XSP Playback"}, | 835 | {"XSPINM", NULL, "XSP Playback"}, |
781 | {"XSPINR", NULL, "XSP Playback"}, | 836 | {"XSPINR", NULL, "XSP Playback"}, |
782 | {"VSPIN", NULL, "VSP Playback"}, | 837 | {"VSPINOUT", NULL, "VSP Playback"}, |
783 | 838 | ||
784 | /* Capture Paths */ | 839 | /* Capture Paths */ |
785 | {"MIC1", NULL, "MIC1 Bias"}, | 840 | {"MIC1", NULL, "MIC1 Bias"}, |
@@ -795,6 +850,8 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = { | |||
795 | 850 | ||
796 | {"ADC Left", NULL, "PGA Left"}, | 851 | {"ADC Left", NULL, "PGA Left"}, |
797 | {"ADC Right", NULL, "PGA Right"}, | 852 | {"ADC Right", NULL, "PGA Right"}, |
853 | {"DMIC Left", NULL, "DMICA"}, | ||
854 | {"DMIC Right", NULL, "DMICB"}, | ||
798 | 855 | ||
799 | {"Input Left Capture", "ADC Left Input", "ADC Left"}, | 856 | {"Input Left Capture", "ADC Left Input", "ADC Left"}, |
800 | {"Input Right Capture", "ADC Right Input", "ADC Right"}, | 857 | {"Input Right Capture", "ADC Right Input", "ADC Right"}, |
@@ -819,21 +876,18 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = { | |||
819 | {"XSPOUTR", NULL, "XSPR Output Mixer"}, | 876 | {"XSPOUTR", NULL, "XSPR Output Mixer"}, |
820 | 877 | ||
821 | /* Voice Capture */ | 878 | /* Voice Capture */ |
822 | {"VSPL Output Mixer", NULL, "Input Left Capture"}, | 879 | {"VSP Output Mixer", NULL, "Input Left Capture"}, |
823 | {"VSPR Output Mixer", NULL, "Input Left Capture"}, | 880 | {"VSP Output Mixer", NULL, "Input Right Capture"}, |
824 | 881 | ||
825 | {"VSPOUTL", "VSP-IP Volume", "VSPL Output Mixer"}, | 882 | {"VSPINOUT", "VSP-IP Volume", "VSP Output Mixer"}, |
826 | {"VSPOUTR", "VSP-IP Volume", "VSPR Output Mixer"}, | ||
827 | 883 | ||
828 | {"VSPOUTL", NULL, "VSPL Output Mixer"}, | 884 | {"VSPINOUT", NULL, "VSP Output Mixer"}, |
829 | {"VSPOUTR", NULL, "VSPR Output Mixer"}, | ||
830 | 885 | ||
831 | {"ASP Capture", NULL, "ASPOUTL"}, | 886 | {"ASP Capture", NULL, "ASPOUTL"}, |
832 | {"ASP Capture", NULL, "ASPOUTR"}, | 887 | {"ASP Capture", NULL, "ASPOUTR"}, |
833 | {"XSP Capture", NULL, "XSPOUTL"}, | 888 | {"XSP Capture", NULL, "XSPOUTL"}, |
834 | {"XSP Capture", NULL, "XSPOUTR"}, | 889 | {"XSP Capture", NULL, "XSPOUTR"}, |
835 | {"VSP Capture", NULL, "VSPOUTL"}, | 890 | {"VSP Capture", NULL, "VSPINOUT"}, |
836 | {"VSP Capture", NULL, "VSPOUTR"}, | ||
837 | }; | 891 | }; |
838 | 892 | ||
839 | struct cs42l73_mclk_div { | 893 | struct cs42l73_mclk_div { |
@@ -1167,6 +1221,14 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec, | |||
1167 | 1221 | ||
1168 | case SND_SOC_BIAS_OFF: | 1222 | case SND_SOC_BIAS_OFF: |
1169 | snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1); | 1223 | snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1); |
1224 | if (cs42l73->shutdwn_delay > 0) { | ||
1225 | mdelay(cs42l73->shutdwn_delay); | ||
1226 | cs42l73->shutdwn_delay = 0; | ||
1227 | } else { | ||
1228 | mdelay(15); /* Min amount of time requred to power | ||
1229 | * down. | ||
1230 | */ | ||
1231 | } | ||
1170 | snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 1); | 1232 | snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 1); |
1171 | break; | 1233 | break; |
1172 | } | 1234 | } |