14 #include <linux/module.h>
16 #include <linux/kernel.h>
20 #include <linux/i2c.h>
21 #include <linux/slab.h>
29 #include <asm/div64.h>
38 static const u16 wm8991_reg_defs[] = {
104 #define wm8991_reset(c) snd_soc_write(c, WM8991_RESET, 0)
106 static const unsigned int rec_mix_tlv[] = {
111 static const unsigned int in_pga_tlv[] = {
116 static const unsigned int out_mix_tlv[] = {
121 static const unsigned int out_pga_tlv[] = {
126 static const unsigned int out_omix_tlv[] = {
131 static const unsigned int out_dac_tlv[] = {
136 static const unsigned int in_adc_tlv[] = {
141 static const unsigned int out_sidetone_tlv[] = {
146 static int wm899x_outpga_put_volsw_vu(
struct snd_kcontrol *kcontrol,
163 static const char *wm8991_digital_sidetone[] =
164 {
"None",
"Left ADC",
"Right ADC",
"Reserved"};
166 static const struct soc_enum wm8991_left_digital_sidetone_enum =
170 wm8991_digital_sidetone);
172 static const struct soc_enum wm8991_right_digital_sidetone_enum =
176 wm8991_digital_sidetone);
178 static const char *wm8991_adcmode[] =
179 {
"Hi-fi mode",
"Voice mode 1",
"Voice mode 2",
"Voice mode 3"};
181 static const struct soc_enum wm8991_right_adcmode_enum =
292 SOC_ENUM(
"Left Digital Sidetone", wm8991_left_digital_sidetone_enum),
293 SOC_ENUM(
"Right Digital Sidetone", wm8991_right_digital_sidetone_enum),
305 SOC_ENUM(
"ADC HPF Mode", wm8991_right_adcmode_enum),
413 "Cannot set as Output Mixer 1 LDLO Set\n");
422 "Cannot set as Output Mixer 2 RDRO Set\n");
431 "Cannot set as Speaker Mixer LDSPK Set\n");
440 "Cannot set as Speaker Mixer RDSPK Set\n");
450 static const unsigned int in_mix_tlv[] = {
502 static const char *wm8991_ainlmux[] =
503 {
"INMIXL Mix",
"RXVOICE Mix",
"DIFFINL Mix"};
505 static const struct soc_enum wm8991_ainlmux_enum =
515 static const char *wm8991_ainrmux[] =
516 {
"INMIXR Mix",
"RXVOICE Mix",
"DIFFINR Mix"};
518 static const struct soc_enum wm8991_ainrmux_enum =
666 0, &wm8991_dapm_lin12_pga_controls[0],
669 0, &wm8991_dapm_lin34_pga_controls[0],
672 0, &wm8991_dapm_rin12_pga_controls[0],
675 0, &wm8991_dapm_rin34_pga_controls[0],
680 &wm8991_dapm_inmixl_controls[0],
686 &wm8991_dapm_ainlmux_controls, inmixer_event,
691 &wm8991_dapm_inmixr_controls[0],
697 &wm8991_dapm_ainrmux_controls, inmixer_event,
709 0, &wm8991_dapm_lomix_controls[0],
715 &wm8991_dapm_lonmix_controls[0],
720 &wm8991_dapm_lopmix_controls[0],
725 &wm8991_dapm_out3mix_controls[0],
730 &wm8991_dapm_spkmix_controls[0],
731 ARRAY_SIZE(wm8991_dapm_spkmix_controls), outmixer_event,
736 &wm8991_dapm_out4mix_controls[0],
741 &wm8991_dapm_ropmix_controls[0],
746 &wm8991_dapm_ronmix_controls[0],
751 0, &wm8991_dapm_romix_controls[0],
792 {
"Internal DAC Sink",
NULL,
"Left DAC"},
793 {
"Internal DAC Sink",
NULL,
"Right DAC"},
796 {
"Left ADC",
NULL,
"Internal ADC Source"},
797 {
"Right ADC",
NULL,
"Internal ADC Source"},
801 {
"LIN12 PGA",
"LIN1 Switch",
"LIN1"},
802 {
"LIN12 PGA",
"LIN2 Switch",
"LIN2"},
804 {
"LIN34 PGA",
"LIN3 Switch",
"LIN3"},
805 {
"LIN34 PGA",
"LIN4 Switch",
"LIN4RXN"},
807 {
"INMIXL",
"Record Left Volume",
"LOMIX"},
808 {
"INMIXL",
"LIN2 Volume",
"LIN2"},
809 {
"INMIXL",
"LINPGA12 Switch",
"LIN12 PGA"},
810 {
"INMIXL",
"LINPGA34 Switch",
"LIN34 PGA"},
812 {
"AINLMUX",
"INMIXL Mix",
"INMIXL"},
813 {
"AINLMUX",
"DIFFINL Mix",
"LIN12 PGA"},
814 {
"AINLMUX",
"DIFFINL Mix",
"LIN34 PGA"},
815 {
"AINLMUX",
"RXVOICE Mix",
"LIN4RXN"},
816 {
"AINLMUX",
"RXVOICE Mix",
"RIN4RXP"},
818 {
"Left ADC",
NULL,
"AINLMUX"},
821 {
"RIN12 PGA",
"RIN1 Switch",
"RIN1"},
822 {
"RIN12 PGA",
"RIN2 Switch",
"RIN2"},
824 {
"RIN34 PGA",
"RIN3 Switch",
"RIN3"},
825 {
"RIN34 PGA",
"RIN4 Switch",
"RIN4RXP"},
827 {
"INMIXR",
"Record Right Volume",
"ROMIX"},
828 {
"INMIXR",
"RIN2 Volume",
"RIN2"},
829 {
"INMIXR",
"RINPGA12 Switch",
"RIN12 PGA"},
830 {
"INMIXR",
"RINPGA34 Switch",
"RIN34 PGA"},
832 {
"AINRMUX",
"INMIXR Mix",
"INMIXR"},
833 {
"AINRMUX",
"DIFFINR Mix",
"RIN12 PGA"},
834 {
"AINRMUX",
"DIFFINR Mix",
"RIN34 PGA"},
835 {
"AINRMUX",
"RXVOICE Mix",
"LIN4RXN"},
836 {
"AINRMUX",
"RXVOICE Mix",
"RIN4RXP"},
838 {
"Right ADC",
NULL,
"AINRMUX"},
841 {
"LOMIX",
"LOMIX RIN3 Bypass Switch",
"RIN3"},
842 {
"LOMIX",
"LOMIX LIN3 Bypass Switch",
"LIN3"},
843 {
"LOMIX",
"LOMIX LIN12 PGA Bypass Switch",
"LIN12 PGA"},
844 {
"LOMIX",
"LOMIX RIN12 PGA Bypass Switch",
"RIN12 PGA"},
845 {
"LOMIX",
"LOMIX Right ADC Bypass Switch",
"AINRMUX"},
846 {
"LOMIX",
"LOMIX Left ADC Bypass Switch",
"AINLMUX"},
847 {
"LOMIX",
"LOMIX Left DAC Switch",
"Left DAC"},
850 {
"ROMIX",
"ROMIX RIN3 Bypass Switch",
"RIN3"},
851 {
"ROMIX",
"ROMIX LIN3 Bypass Switch",
"LIN3"},
852 {
"ROMIX",
"ROMIX LIN12 PGA Bypass Switch",
"LIN12 PGA"},
853 {
"ROMIX",
"ROMIX RIN12 PGA Bypass Switch",
"RIN12 PGA"},
854 {
"ROMIX",
"ROMIX Right ADC Bypass Switch",
"AINRMUX"},
855 {
"ROMIX",
"ROMIX Left ADC Bypass Switch",
"AINLMUX"},
856 {
"ROMIX",
"ROMIX Right DAC Switch",
"Right DAC"},
859 {
"SPKMIX",
"SPKMIX LIN2 Bypass Switch",
"LIN2"},
860 {
"SPKMIX",
"SPKMIX RIN2 Bypass Switch",
"RIN2"},
861 {
"SPKMIX",
"SPKMIX LADC Bypass Switch",
"AINLMUX"},
862 {
"SPKMIX",
"SPKMIX RADC Bypass Switch",
"AINRMUX"},
863 {
"SPKMIX",
"SPKMIX Left Mixer PGA Switch",
"LOPGA"},
864 {
"SPKMIX",
"SPKMIX Right Mixer PGA Switch",
"ROPGA"},
865 {
"SPKMIX",
"SPKMIX Right DAC Switch",
"Right DAC"},
866 {
"SPKMIX",
"SPKMIX Left DAC Switch",
"Right DAC"},
869 {
"LONMIX",
"LONMIX Left Mixer PGA Switch",
"LOPGA"},
870 {
"LONMIX",
"LONMIX Right Mixer PGA Switch",
"ROPGA"},
871 {
"LONMIX",
"LONMIX Inverted LOP Switch",
"LOPMIX"},
874 {
"LOPMIX",
"LOPMIX Right Mic Bypass Switch",
"RIN12 PGA"},
875 {
"LOPMIX",
"LOPMIX Left Mic Bypass Switch",
"LIN12 PGA"},
876 {
"LOPMIX",
"LOPMIX Left Mixer PGA Switch",
"LOPGA"},
879 {
"OUT3MIX",
"OUT3MIX LIN4RXN Bypass Switch",
"LIN4RXN"},
880 {
"OUT3MIX",
"OUT3MIX Left Out PGA Switch",
"LOPGA"},
883 {
"OUT4MIX",
"OUT4MIX Right Out PGA Switch",
"ROPGA"},
884 {
"OUT4MIX",
"OUT4MIX RIN4RXP Bypass Switch",
"RIN4RXP"},
887 {
"RONMIX",
"RONMIX Right Mixer PGA Switch",
"ROPGA"},
888 {
"RONMIX",
"RONMIX Left Mixer PGA Switch",
"LOPGA"},
889 {
"RONMIX",
"RONMIX Inverted ROP Switch",
"ROPMIX"},
892 {
"ROPMIX",
"ROPMIX Left Mic Bypass Switch",
"LIN12 PGA"},
893 {
"ROPMIX",
"ROPMIX Right Mic Bypass Switch",
"RIN12 PGA"},
894 {
"ROPMIX",
"ROPMIX Right Mixer PGA Switch",
"ROPGA"},
897 {
"LOPGA",
NULL,
"LOMIX"},
898 {
"ROPGA",
NULL,
"ROMIX"},
900 {
"LOUT PGA",
NULL,
"LOMIX"},
901 {
"ROUT PGA",
NULL,
"ROMIX"},
904 {
"LON",
NULL,
"LONMIX"},
905 {
"LOP",
NULL,
"LOPMIX"},
906 {
"OUT",
NULL,
"OUT3MIX"},
907 {
"LOUT",
NULL,
"LOUT PGA"},
908 {
"SPKN",
NULL,
"SPKMIX"},
909 {
"ROUT",
NULL,
"ROUT PGA"},
910 {
"OUT4",
NULL,
"OUT4MIX"},
911 {
"ROP",
NULL,
"ROPMIX"},
912 {
"RON",
NULL,
"RONMIX"},
924 #define FIXED_PLL_SIZE ((1 << 16) * 10)
930 unsigned int K, Ndiv, Nmod;
941 if ((Ndiv < 6) || (Ndiv > 12))
943 "WM8991 N value outwith recommended range! N = %d\n", Ndiv);
951 K = Kpart & 0xFFFFFFFF;
963 static int wm8991_set_dai_pll(
struct snd_soc_dai *codec_dai,
964 int pll_id,
int src,
unsigned int freq_in,
unsigned int freq_out)
970 if (freq_in && freq_out) {
999 static int wm8991_set_dai_fmt(
struct snd_soc_dai *codec_dai,
1052 static int wm8991_set_dai_clkdiv(
struct snd_soc_dai *codec_dai,
1053 int div_id,
int div)
1129 static int wm8991_set_bias_level(
struct snd_soc_codec *codec,
1267 wm8991 = snd_soc_codec_get_drvdata(codec);
1271 dev_err(codec->
dev,
"Failed to set cache i/o: %d\n", ret);
1277 dev_err(codec->
dev,
"Failed to issue reset\n");
1310 #define WM8991_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1311 SNDRV_PCM_FMTBIT_S24_LE)
1314 .hw_params = wm8991_hw_params,
1315 .digital_mute = wm8991_mute,
1316 .set_fmt = wm8991_set_dai_fmt,
1317 .set_clkdiv = wm8991_set_dai_clkdiv,
1318 .set_pll = wm8991_set_dai_pll
1333 .stream_name =
"Playback",
1340 .stream_name =
"Capture",
1350 .probe = wm8991_probe,
1351 .remove = wm8991_remove,
1352 .suspend = wm8991_suspend,
1353 .resume = wm8991_resume,
1354 .set_bias_level = wm8991_set_bias_level,
1356 .reg_word_size =
sizeof(
u16),
1371 i2c_set_clientdata(i2c, wm8991);
1374 &soc_codec_dev_wm8991, &wm8991_dai, 1);
1392 static struct i2c_driver wm8991_i2c_driver = {
1397 .probe = wm8991_i2c_probe,
1399 .id_table = wm8991_i2c_id,