14 #include <linux/module.h>
16 #include <linux/kernel.h>
17 #include <linux/slab.h>
36 #define WM8400_INTDRIVBITS (WM8400_REGISTER_COUNT + 1)
37 #define WM8400_INMIXL_PWR 0
38 #define WM8400_AINLMUX_PWR 1
39 #define WM8400_INMIXR_PWR 2
40 #define WM8400_AINRMUX_PWR 3
100 return wm8400_set_bits(wm8400->
wm8400, reg, 0xffff, value);
105 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
126 static int wm8400_outpga_put_volsw_vu(
struct snd_kcontrol *kcontrol,
145 #define WM8400_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert, tlv_array) \
146 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
147 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
148 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
149 .tlv.p = (tlv_array), \
150 .info = snd_soc_info_volsw, \
151 .get = snd_soc_get_volsw, .put = wm8400_outpga_put_volsw_vu, \
152 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
155 static const char *wm8400_digital_sidetone[] =
156 {
"None",
"Left ADC",
"Right ADC",
"Reserved"};
158 static const struct soc_enum wm8400_left_digital_sidetone_enum =
162 static const struct soc_enum wm8400_right_digital_sidetone_enum =
166 static const char *wm8400_adcmode[] =
167 {
"Hi-fi mode",
"Voice mode 1",
"Voice mode 2",
"Voice mode 3"};
169 static const struct soc_enum wm8400_right_adcmode_enum =
269 127, 0, out_dac_tlv),
273 127, 0, out_dac_tlv),
275 SOC_ENUM(
"Left Digital Sidetone", wm8400_left_digital_sidetone_enum),
276 SOC_ENUM(
"Right Digital Sidetone", wm8400_right_digital_sidetone_enum),
286 SOC_ENUM(
"ADC HPF Mode", wm8400_right_adcmode_enum),
400 "Cannot set as Output Mixer 1 LDLO Set\n");
408 "Cannot set as Output Mixer 2 RDRO Set\n");
416 "Cannot set as Speaker Mixer LDSPK Set\n");
424 "Cannot set as Speaker Mixer RDSPK Set\n");
434 static const unsigned int in_mix_tlv[] = {
486 static const char *wm8400_ainlmux[] =
487 {
"INMIXL Mix",
"RXVOICE Mix",
"DIFFINL Mix"};
489 static const struct soc_enum wm8400_ainlmux_enum =
499 static const char *wm8400_ainrmux[] =
500 {
"INMIXR Mix",
"RXVOICE Mix",
"DIFFINR Mix"};
502 static const struct soc_enum wm8400_ainrmux_enum =
651 0, &wm8400_dapm_lin12_pga_controls[0],
655 0, &wm8400_dapm_lin34_pga_controls[0],
659 0, &wm8400_dapm_rin12_pga_controls[0],
663 0, &wm8400_dapm_rin34_pga_controls[0],
668 &wm8400_dapm_inmixl_controls[0],
674 &wm8400_dapm_ainlmux_controls, inmixer_event,
679 &wm8400_dapm_inmixr_controls[0],
685 &wm8400_dapm_ainrmux_controls, inmixer_event,
698 0, &wm8400_dapm_lomix_controls[0],
704 0, &wm8400_dapm_lonmix_controls[0],
709 0, &wm8400_dapm_lopmix_controls[0],
714 0, &wm8400_dapm_out3mix_controls[0],
719 0, &wm8400_dapm_spkmix_controls[0],
720 ARRAY_SIZE(wm8400_dapm_spkmix_controls), outmixer_event,
725 0, &wm8400_dapm_out4mix_controls[0],
730 0, &wm8400_dapm_ropmix_controls[0],
735 0, &wm8400_dapm_ronmix_controls[0],
741 0, &wm8400_dapm_romix_controls[0],
781 {
"Internal DAC Sink",
NULL,
"Left DAC"},
782 {
"Internal DAC Sink",
NULL,
"Right DAC"},
786 {
"Left ADC",
NULL,
"Internal ADC Source"},
787 {
"Right ADC",
NULL,
"Internal ADC Source"},
791 {
"LIN12 PGA",
"LIN1 Switch",
"LIN1"},
792 {
"LIN12 PGA",
"LIN2 Switch",
"LIN2"},
794 {
"LIN34 PGA",
"LIN3 Switch",
"LIN3"},
795 {
"LIN34 PGA",
"LIN4 Switch",
"LIN4/RXN"},
797 {
"INMIXL",
"Record Left Volume",
"LOMIX"},
798 {
"INMIXL",
"LIN2 Volume",
"LIN2"},
799 {
"INMIXL",
"LINPGA12 Switch",
"LIN12 PGA"},
800 {
"INMIXL",
"LINPGA34 Switch",
"LIN34 PGA"},
802 {
"AILNMUX",
"INMIXL Mix",
"INMIXL"},
803 {
"AILNMUX",
"DIFFINL Mix",
"LIN12 PGA"},
804 {
"AILNMUX",
"DIFFINL Mix",
"LIN34 PGA"},
805 {
"AILNMUX",
"RXVOICE Mix",
"LIN4/RXN"},
806 {
"AILNMUX",
"RXVOICE Mix",
"RIN4/RXP"},
808 {
"Left ADC",
NULL,
"AILNMUX"},
811 {
"RIN12 PGA",
"RIN1 Switch",
"RIN1"},
812 {
"RIN12 PGA",
"RIN2 Switch",
"RIN2"},
814 {
"RIN34 PGA",
"RIN3 Switch",
"RIN3"},
815 {
"RIN34 PGA",
"RIN4 Switch",
"RIN4/RXP"},
817 {
"INMIXR",
"Record Right Volume",
"ROMIX"},
818 {
"INMIXR",
"RIN2 Volume",
"RIN2"},
819 {
"INMIXR",
"RINPGA12 Switch",
"RIN12 PGA"},
820 {
"INMIXR",
"RINPGA34 Switch",
"RIN34 PGA"},
822 {
"AIRNMUX",
"INMIXR Mix",
"INMIXR"},
823 {
"AIRNMUX",
"DIFFINR Mix",
"RIN12 PGA"},
824 {
"AIRNMUX",
"DIFFINR Mix",
"RIN34 PGA"},
825 {
"AIRNMUX",
"RXVOICE Mix",
"LIN4/RXN"},
826 {
"AIRNMUX",
"RXVOICE Mix",
"RIN4/RXP"},
828 {
"Right ADC",
NULL,
"AIRNMUX"},
831 {
"LOMIX",
"LOMIX RIN3 Bypass Switch",
"RIN3"},
832 {
"LOMIX",
"LOMIX LIN3 Bypass Switch",
"LIN3"},
833 {
"LOMIX",
"LOMIX LIN12 PGA Bypass Switch",
"LIN12 PGA"},
834 {
"LOMIX",
"LOMIX RIN12 PGA Bypass Switch",
"RIN12 PGA"},
835 {
"LOMIX",
"LOMIX Right ADC Bypass Switch",
"AIRNMUX"},
836 {
"LOMIX",
"LOMIX Left ADC Bypass Switch",
"AILNMUX"},
837 {
"LOMIX",
"LOMIX Left DAC Switch",
"Left DAC"},
840 {
"ROMIX",
"ROMIX RIN3 Bypass Switch",
"RIN3"},
841 {
"ROMIX",
"ROMIX LIN3 Bypass Switch",
"LIN3"},
842 {
"ROMIX",
"ROMIX LIN12 PGA Bypass Switch",
"LIN12 PGA"},
843 {
"ROMIX",
"ROMIX RIN12 PGA Bypass Switch",
"RIN12 PGA"},
844 {
"ROMIX",
"ROMIX Right ADC Bypass Switch",
"AIRNMUX"},
845 {
"ROMIX",
"ROMIX Left ADC Bypass Switch",
"AILNMUX"},
846 {
"ROMIX",
"ROMIX Right DAC Switch",
"Right DAC"},
849 {
"SPKMIX",
"SPKMIX LIN2 Bypass Switch",
"LIN2"},
850 {
"SPKMIX",
"SPKMIX RIN2 Bypass Switch",
"RIN2"},
851 {
"SPKMIX",
"SPKMIX LADC Bypass Switch",
"AILNMUX"},
852 {
"SPKMIX",
"SPKMIX RADC Bypass Switch",
"AIRNMUX"},
853 {
"SPKMIX",
"SPKMIX Left Mixer PGA Switch",
"LOPGA"},
854 {
"SPKMIX",
"SPKMIX Right Mixer PGA Switch",
"ROPGA"},
855 {
"SPKMIX",
"SPKMIX Right DAC Switch",
"Right DAC"},
856 {
"SPKMIX",
"SPKMIX Left DAC Switch",
"Right DAC"},
859 {
"LONMIX",
"LONMIX Left Mixer PGA Switch",
"LOPGA"},
860 {
"LONMIX",
"LONMIX Right Mixer PGA Switch",
"ROPGA"},
861 {
"LONMIX",
"LONMIX Inverted LOP Switch",
"LOPMIX"},
864 {
"LOPMIX",
"LOPMIX Right Mic Bypass Switch",
"RIN12 PGA"},
865 {
"LOPMIX",
"LOPMIX Left Mic Bypass Switch",
"LIN12 PGA"},
866 {
"LOPMIX",
"LOPMIX Left Mixer PGA Switch",
"LOPGA"},
869 {
"OUT3MIX",
"OUT3MIX LIN4/RXP Bypass Switch",
"LIN4/RXN"},
870 {
"OUT3MIX",
"OUT3MIX Left Out PGA Switch",
"LOPGA"},
873 {
"OUT4MIX",
"OUT4MIX Right Out PGA Switch",
"ROPGA"},
874 {
"OUT4MIX",
"OUT4MIX RIN4/RXP Bypass Switch",
"RIN4/RXP"},
877 {
"RONMIX",
"RONMIX Right Mixer PGA Switch",
"ROPGA"},
878 {
"RONMIX",
"RONMIX Left Mixer PGA Switch",
"LOPGA"},
879 {
"RONMIX",
"RONMIX Inverted ROP Switch",
"ROPMIX"},
882 {
"ROPMIX",
"ROPMIX Left Mic Bypass Switch",
"LIN12 PGA"},
883 {
"ROPMIX",
"ROPMIX Right Mic Bypass Switch",
"RIN12 PGA"},
884 {
"ROPMIX",
"ROPMIX Right Mixer PGA Switch",
"ROPGA"},
887 {
"LOPGA",
NULL,
"LOMIX"},
888 {
"ROPGA",
NULL,
"ROMIX"},
890 {
"LOUT PGA",
NULL,
"LOMIX"},
891 {
"ROUT PGA",
NULL,
"ROMIX"},
894 {
"LON",
NULL,
"LONMIX"},
895 {
"LOP",
NULL,
"LOPMIX"},
896 {
"OUT3",
NULL,
"OUT3MIX"},
897 {
"LOUT",
NULL,
"LOUT PGA"},
898 {
"SPKN",
NULL,
"SPKMIX"},
899 {
"ROUT",
NULL,
"ROUT PGA"},
900 {
"OUT4",
NULL,
"OUT4MIX"},
901 {
"ROP",
NULL,
"ROPMIX"},
902 {
"RON",
NULL,
"RONMIX"},
908 static int wm8400_set_dai_sysclk(
struct snd_soc_dai *codec_dai,
909 int clk_id,
unsigned int freq,
int dir)
912 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
926 #define FIXED_FLL_SIZE ((1 << 16) * 10)
929 unsigned int Fref,
unsigned int Fout)
935 while (Fout * factors->
outdiv < 90000000 ||
936 Fout * factors->
outdiv > 100000000) {
938 if (factors->
outdiv > 32) {
940 "Unsupported FLL output frequency %uHz\n",
945 target = Fout * factors->
outdiv;
967 "Unable to calculate FRATIO\n");
971 factors->
n = target / (Fref * factors->
fratio);
972 Nmod = target % (Fref * factors->
fratio);
980 K = Kpart & 0xFFFFFFFF;
989 "FLL: Fref=%u Fout=%u N=%x K=%x, FRATIO=%x OUTDIV=%x\n",
996 static int wm8400_set_dai_pll(
struct snd_soc_dai *codec_dai,
int pll_id,
997 int source,
unsigned int freq_in,
998 unsigned int freq_out)
1001 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
1006 if (freq_in == wm8400->
fll_in && freq_out == wm8400->
fll_out)
1010 ret =
fll_factors(wm8400, &factors, freq_in, freq_out);
1017 memset(&factors, 0,
sizeof(factors));
1021 wm8400->
fll_in = freq_in;
1045 reg |= factors.outdiv;
1054 static int wm8400_set_dai_fmt(
struct snd_soc_dai *codec_dai,
1107 static int wm8400_set_dai_clkdiv(
struct snd_soc_dai *codec_dai,
1108 int div_id,
int div)
1185 static int wm8400_set_bias_level(
struct snd_soc_codec *codec,
1188 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
1209 "Failed to enable regulators: %d\n",
1295 #define WM8400_RATES SNDRV_PCM_RATE_8000_96000
1297 #define WM8400_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1298 SNDRV_PCM_FMTBIT_S24_LE)
1301 .hw_params = wm8400_hw_params,
1302 .digital_mute = wm8400_mute,
1303 .set_fmt = wm8400_set_dai_fmt,
1304 .set_clkdiv = wm8400_set_dai_clkdiv,
1305 .set_sysclk = wm8400_set_dai_sysclk,
1306 .set_pll = wm8400_set_dai_pll,
1318 .name =
"wm8400-hifi",
1320 .stream_name =
"Playback",
1327 .stream_name =
"Capture",
1333 .ops = &wm8400_dai_ops,
1362 struct wm8400 *wm8400 = dev_get_platdata(codec->
dev);
1372 snd_soc_codec_set_drvdata(codec, priv);
1379 dev_err(codec->
dev,
"Failed to get regulators: %d\n", ret);
1385 wm8400_codec_reset(codec);
1426 .probe = wm8400_codec_probe,
1427 .remove = wm8400_codec_remove,
1428 .suspend = wm8400_suspend,
1429 .resume = wm8400_resume,
1431 .write = wm8400_write,
1432 .set_bias_level = wm8400_set_bias_level,
1434 .controls = wm8400_snd_controls,
1435 .num_controls =
ARRAY_SIZE(wm8400_snd_controls),
1436 .dapm_widgets = wm8400_dapm_widgets,
1437 .num_dapm_widgets =
ARRAY_SIZE(wm8400_dapm_widgets),
1438 .dapm_routes = wm8400_dapm_routes,
1439 .num_dapm_routes =
ARRAY_SIZE(wm8400_dapm_routes),
1456 .name =
"wm8400-codec",
1459 .probe = wm8400_probe,