diff options
Diffstat (limited to 'sound/soc/codecs/wm8900.c')
-rw-r--r-- | sound/soc/codecs/wm8900.c | 115 |
1 files changed, 45 insertions, 70 deletions
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index 082040eda8a2..3d0dc1591ecc 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c | |||
@@ -110,8 +110,8 @@ | |||
110 | 110 | ||
111 | #define WM8900_REG_CLOCKING1_BCLK_DIR 0x1 | 111 | #define WM8900_REG_CLOCKING1_BCLK_DIR 0x1 |
112 | #define WM8900_REG_CLOCKING1_MCLK_SRC 0x100 | 112 | #define WM8900_REG_CLOCKING1_MCLK_SRC 0x100 |
113 | #define WM8900_REG_CLOCKING1_BCLK_MASK (~0x01e) | 113 | #define WM8900_REG_CLOCKING1_BCLK_MASK 0x01e |
114 | #define WM8900_REG_CLOCKING1_OPCLK_MASK (~0x7000) | 114 | #define WM8900_REG_CLOCKING1_OPCLK_MASK 0x7000 |
115 | 115 | ||
116 | #define WM8900_REG_CLOCKING2_ADC_CLKDIV 0xe0 | 116 | #define WM8900_REG_CLOCKING2_ADC_CLKDIV 0xe0 |
117 | #define WM8900_REG_CLOCKING2_DAC_CLKDIV 0x1c | 117 | #define WM8900_REG_CLOCKING2_DAC_CLKDIV 0x1c |
@@ -135,7 +135,7 @@ | |||
135 | #define WM8900_REG_HPCTL1_HP_SHORT 0x08 | 135 | #define WM8900_REG_HPCTL1_HP_SHORT 0x08 |
136 | #define WM8900_REG_HPCTL1_HP_SHORT2 0x04 | 136 | #define WM8900_REG_HPCTL1_HP_SHORT2 0x04 |
137 | 137 | ||
138 | #define WM8900_LRC_MASK 0xfc00 | 138 | #define WM8900_LRC_MASK 0x03ff |
139 | 139 | ||
140 | struct wm8900_priv { | 140 | struct wm8900_priv { |
141 | enum snd_soc_control_type control_type; | 141 | enum snd_soc_control_type control_type; |
@@ -742,26 +742,20 @@ static int wm8900_set_fll(struct snd_soc_codec *codec, | |||
742 | { | 742 | { |
743 | struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec); | 743 | struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec); |
744 | struct _fll_div fll_div; | 744 | struct _fll_div fll_div; |
745 | unsigned int reg; | ||
746 | 745 | ||
747 | if (wm8900->fll_in == freq_in && wm8900->fll_out == freq_out) | 746 | if (wm8900->fll_in == freq_in && wm8900->fll_out == freq_out) |
748 | return 0; | 747 | return 0; |
749 | 748 | ||
750 | /* The digital side should be disabled during any change. */ | 749 | /* The digital side should be disabled during any change. */ |
751 | reg = snd_soc_read(codec, WM8900_REG_POWER1); | 750 | snd_soc_update_bits(codec, WM8900_REG_POWER1, |
752 | snd_soc_write(codec, WM8900_REG_POWER1, | 751 | WM8900_REG_POWER1_FLL_ENA, 0); |
753 | reg & (~WM8900_REG_POWER1_FLL_ENA)); | ||
754 | 752 | ||
755 | /* Disable the FLL? */ | 753 | /* Disable the FLL? */ |
756 | if (!freq_in || !freq_out) { | 754 | if (!freq_in || !freq_out) { |
757 | reg = snd_soc_read(codec, WM8900_REG_CLOCKING1); | 755 | snd_soc_update_bits(codec, WM8900_REG_CLOCKING1, |
758 | snd_soc_write(codec, WM8900_REG_CLOCKING1, | 756 | WM8900_REG_CLOCKING1_MCLK_SRC, 0); |
759 | reg & (~WM8900_REG_CLOCKING1_MCLK_SRC)); | 757 | snd_soc_update_bits(codec, WM8900_REG_FLLCTL1, |
760 | 758 | WM8900_REG_FLLCTL1_OSC_ENA, 0); | |
761 | reg = snd_soc_read(codec, WM8900_REG_FLLCTL1); | ||
762 | snd_soc_write(codec, WM8900_REG_FLLCTL1, | ||
763 | reg & (~WM8900_REG_FLLCTL1_OSC_ENA)); | ||
764 | |||
765 | wm8900->fll_in = freq_in; | 759 | wm8900->fll_in = freq_in; |
766 | wm8900->fll_out = freq_out; | 760 | wm8900->fll_out = freq_out; |
767 | 761 | ||
@@ -796,15 +790,14 @@ static int wm8900_set_fll(struct snd_soc_codec *codec, | |||
796 | else | 790 | else |
797 | snd_soc_write(codec, WM8900_REG_FLLCTL6, 0); | 791 | snd_soc_write(codec, WM8900_REG_FLLCTL6, 0); |
798 | 792 | ||
799 | reg = snd_soc_read(codec, WM8900_REG_POWER1); | 793 | snd_soc_update_bits(codec, WM8900_REG_POWER1, |
800 | snd_soc_write(codec, WM8900_REG_POWER1, | 794 | WM8900_REG_POWER1_FLL_ENA, |
801 | reg | WM8900_REG_POWER1_FLL_ENA); | 795 | WM8900_REG_POWER1_FLL_ENA); |
802 | 796 | ||
803 | reenable: | 797 | reenable: |
804 | reg = snd_soc_read(codec, WM8900_REG_CLOCKING1); | 798 | snd_soc_update_bits(codec, WM8900_REG_CLOCKING1, |
805 | snd_soc_write(codec, WM8900_REG_CLOCKING1, | 799 | WM8900_REG_CLOCKING1_MCLK_SRC, |
806 | reg | WM8900_REG_CLOCKING1_MCLK_SRC); | 800 | WM8900_REG_CLOCKING1_MCLK_SRC); |
807 | |||
808 | return 0; | 801 | return 0; |
809 | } | 802 | } |
810 | 803 | ||
@@ -818,43 +811,35 @@ static int wm8900_set_dai_clkdiv(struct snd_soc_dai *codec_dai, | |||
818 | int div_id, int div) | 811 | int div_id, int div) |
819 | { | 812 | { |
820 | struct snd_soc_codec *codec = codec_dai->codec; | 813 | struct snd_soc_codec *codec = codec_dai->codec; |
821 | unsigned int reg; | ||
822 | 814 | ||
823 | switch (div_id) { | 815 | switch (div_id) { |
824 | case WM8900_BCLK_DIV: | 816 | case WM8900_BCLK_DIV: |
825 | reg = snd_soc_read(codec, WM8900_REG_CLOCKING1); | 817 | snd_soc_update_bits(codec, WM8900_REG_CLOCKING1, |
826 | snd_soc_write(codec, WM8900_REG_CLOCKING1, | 818 | WM8900_REG_CLOCKING1_BCLK_MASK, div); |
827 | div | (reg & WM8900_REG_CLOCKING1_BCLK_MASK)); | ||
828 | break; | 819 | break; |
829 | case WM8900_OPCLK_DIV: | 820 | case WM8900_OPCLK_DIV: |
830 | reg = snd_soc_read(codec, WM8900_REG_CLOCKING1); | 821 | snd_soc_update_bits(codec, WM8900_REG_CLOCKING1, |
831 | snd_soc_write(codec, WM8900_REG_CLOCKING1, | 822 | WM8900_REG_CLOCKING1_OPCLK_MASK, div); |
832 | div | (reg & WM8900_REG_CLOCKING1_OPCLK_MASK)); | ||
833 | break; | 823 | break; |
834 | case WM8900_DAC_LRCLK: | 824 | case WM8900_DAC_LRCLK: |
835 | reg = snd_soc_read(codec, WM8900_REG_AUDIO4); | 825 | snd_soc_update_bits(codec, WM8900_REG_AUDIO4, |
836 | snd_soc_write(codec, WM8900_REG_AUDIO4, | 826 | WM8900_LRC_MASK, div); |
837 | div | (reg & WM8900_LRC_MASK)); | ||
838 | break; | 827 | break; |
839 | case WM8900_ADC_LRCLK: | 828 | case WM8900_ADC_LRCLK: |
840 | reg = snd_soc_read(codec, WM8900_REG_AUDIO3); | 829 | snd_soc_update_bits(codec, WM8900_REG_AUDIO3, |
841 | snd_soc_write(codec, WM8900_REG_AUDIO3, | 830 | WM8900_LRC_MASK, div); |
842 | div | (reg & WM8900_LRC_MASK)); | ||
843 | break; | 831 | break; |
844 | case WM8900_DAC_CLKDIV: | 832 | case WM8900_DAC_CLKDIV: |
845 | reg = snd_soc_read(codec, WM8900_REG_CLOCKING2); | 833 | snd_soc_update_bits(codec, WM8900_REG_CLOCKING2, |
846 | snd_soc_write(codec, WM8900_REG_CLOCKING2, | 834 | WM8900_REG_CLOCKING2_DAC_CLKDIV, div); |
847 | div | (reg & WM8900_REG_CLOCKING2_DAC_CLKDIV)); | ||
848 | break; | 835 | break; |
849 | case WM8900_ADC_CLKDIV: | 836 | case WM8900_ADC_CLKDIV: |
850 | reg = snd_soc_read(codec, WM8900_REG_CLOCKING2); | 837 | snd_soc_update_bits(codec, WM8900_REG_CLOCKING2, |
851 | snd_soc_write(codec, WM8900_REG_CLOCKING2, | 838 | WM8900_REG_CLOCKING2_ADC_CLKDIV, div); |
852 | div | (reg & WM8900_REG_CLOCKING2_ADC_CLKDIV)); | ||
853 | break; | 839 | break; |
854 | case WM8900_LRCLK_MODE: | 840 | case WM8900_LRCLK_MODE: |
855 | reg = snd_soc_read(codec, WM8900_REG_DACCTRL); | 841 | snd_soc_update_bits(codec, WM8900_REG_DACCTRL, |
856 | snd_soc_write(codec, WM8900_REG_DACCTRL, | 842 | WM8900_REG_DACCTRL_AIF_LRCLKRATE, div); |
857 | div | (reg & WM8900_REG_DACCTRL_AIF_LRCLKRATE)); | ||
858 | break; | 843 | break; |
859 | default: | 844 | default: |
860 | return -EINVAL; | 845 | return -EINVAL; |
@@ -1037,12 +1022,12 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec, | |||
1037 | switch (level) { | 1022 | switch (level) { |
1038 | case SND_SOC_BIAS_ON: | 1023 | case SND_SOC_BIAS_ON: |
1039 | /* Enable thermal shutdown */ | 1024 | /* Enable thermal shutdown */ |
1040 | reg = snd_soc_read(codec, WM8900_REG_GPIO); | 1025 | snd_soc_update_bits(codec, WM8900_REG_GPIO, |
1041 | snd_soc_write(codec, WM8900_REG_GPIO, | 1026 | WM8900_REG_GPIO_TEMP_ENA, |
1042 | reg | WM8900_REG_GPIO_TEMP_ENA); | 1027 | WM8900_REG_GPIO_TEMP_ENA); |
1043 | reg = snd_soc_read(codec, WM8900_REG_ADDCTL); | 1028 | snd_soc_update_bits(codec, WM8900_REG_ADDCTL, |
1044 | snd_soc_write(codec, WM8900_REG_ADDCTL, | 1029 | WM8900_REG_ADDCTL_TEMP_SD, |
1045 | reg | WM8900_REG_ADDCTL_TEMP_SD); | 1030 | WM8900_REG_ADDCTL_TEMP_SD); |
1046 | break; | 1031 | break; |
1047 | 1032 | ||
1048 | case SND_SOC_BIAS_PREPARE: | 1033 | case SND_SOC_BIAS_PREPARE: |
@@ -1205,26 +1190,16 @@ static int wm8900_probe(struct snd_soc_codec *codec) | |||
1205 | wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1190 | wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1206 | 1191 | ||
1207 | /* Latch the volume update bits */ | 1192 | /* Latch the volume update bits */ |
1208 | snd_soc_write(codec, WM8900_REG_LINVOL, | 1193 | snd_soc_update_bits(codec, WM8900_REG_LINVOL, 0x100, 0x100); |
1209 | snd_soc_read(codec, WM8900_REG_LINVOL) | 0x100); | 1194 | snd_soc_update_bits(codec, WM8900_REG_RINVOL, 0x100, 0x100); |
1210 | snd_soc_write(codec, WM8900_REG_RINVOL, | 1195 | snd_soc_update_bits(codec, WM8900_REG_LOUT1CTL, 0x100, 0x100); |
1211 | snd_soc_read(codec, WM8900_REG_RINVOL) | 0x100); | 1196 | snd_soc_update_bits(codec, WM8900_REG_ROUT1CTL, 0x100, 0x100); |
1212 | snd_soc_write(codec, WM8900_REG_LOUT1CTL, | 1197 | snd_soc_update_bits(codec, WM8900_REG_LOUT2CTL, 0x100, 0x100); |
1213 | snd_soc_read(codec, WM8900_REG_LOUT1CTL) | 0x100); | 1198 | snd_soc_update_bits(codec, WM8900_REG_ROUT2CTL, 0x100, 0x100); |
1214 | snd_soc_write(codec, WM8900_REG_ROUT1CTL, | 1199 | snd_soc_update_bits(codec, WM8900_REG_LDAC_DV, 0x100, 0x100); |
1215 | snd_soc_read(codec, WM8900_REG_ROUT1CTL) | 0x100); | 1200 | snd_soc_update_bits(codec, WM8900_REG_RDAC_DV, 0x100, 0x100); |
1216 | snd_soc_write(codec, WM8900_REG_LOUT2CTL, | 1201 | snd_soc_update_bits(codec, WM8900_REG_LADC_DV, 0x100, 0x100); |
1217 | snd_soc_read(codec, WM8900_REG_LOUT2CTL) | 0x100); | 1202 | snd_soc_update_bits(codec, WM8900_REG_RADC_DV, 0x100, 0x100); |
1218 | snd_soc_write(codec, WM8900_REG_ROUT2CTL, | ||
1219 | snd_soc_read(codec, WM8900_REG_ROUT2CTL) | 0x100); | ||
1220 | snd_soc_write(codec, WM8900_REG_LDAC_DV, | ||
1221 | snd_soc_read(codec, WM8900_REG_LDAC_DV) | 0x100); | ||
1222 | snd_soc_write(codec, WM8900_REG_RDAC_DV, | ||
1223 | snd_soc_read(codec, WM8900_REG_RDAC_DV) | 0x100); | ||
1224 | snd_soc_write(codec, WM8900_REG_LADC_DV, | ||
1225 | snd_soc_read(codec, WM8900_REG_LADC_DV) | 0x100); | ||
1226 | snd_soc_write(codec, WM8900_REG_RADC_DV, | ||
1227 | snd_soc_read(codec, WM8900_REG_RADC_DV) | 0x100); | ||
1228 | 1203 | ||
1229 | /* Set the DAC and mixer output bias */ | 1204 | /* Set the DAC and mixer output bias */ |
1230 | snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81); | 1205 | snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81); |