13 #include <linux/module.h>
18 #include <linux/i2c.h>
21 #include <linux/slab.h>
31 static const struct reg_default wm8983_defaults[] = {
87 static const struct wm8983_reg_access {
91 [0x00] = { 0x0000, 0x01FF },
92 [0x01] = { 0x0000, 0x01FF },
93 [0x02] = { 0x0000, 0x01FF },
94 [0x03] = { 0x0000, 0x01EF },
95 [0x04] = { 0x0000, 0x01FF },
96 [0x05] = { 0x0000, 0x003F },
97 [0x06] = { 0x0000, 0x01FD },
98 [0x07] = { 0x0000, 0x000F },
99 [0x08] = { 0x0000, 0x003F },
100 [0x09] = { 0x0000, 0x0070 },
101 [0x0A] = { 0x0000, 0x004F },
102 [0x0B] = { 0x0000, 0x01FF },
103 [0x0C] = { 0x0000, 0x01FF },
104 [0x0D] = { 0x0000, 0x00FF },
105 [0x0E] = { 0x0000, 0x01FB },
106 [0x0F] = { 0x0000, 0x01FF },
107 [0x10] = { 0x0000, 0x01FF },
108 [0x12] = { 0x0000, 0x017F },
109 [0x13] = { 0x0000, 0x017F },
110 [0x14] = { 0x0000, 0x017F },
111 [0x15] = { 0x0000, 0x017F },
112 [0x16] = { 0x0000, 0x007F },
113 [0x18] = { 0x0000, 0x01FF },
114 [0x19] = { 0x0000, 0x007F },
115 [0x1B] = { 0x0000, 0x01FF },
116 [0x1C] = { 0x0000, 0x017F },
117 [0x1D] = { 0x0000, 0x017F },
118 [0x1E] = { 0x0000, 0x017F },
119 [0x20] = { 0x0000, 0x01BF },
120 [0x21] = { 0x0000, 0x00FF },
121 [0x22] = { 0x0000, 0x01FF },
122 [0x23] = { 0x0000, 0x000F },
123 [0x24] = { 0x0000, 0x001F },
124 [0x25] = { 0x0000, 0x003F },
125 [0x26] = { 0x0000, 0x01FF },
126 [0x27] = { 0x0000, 0x01FF },
127 [0x29] = { 0x0000, 0x000F },
128 [0x2A] = { 0x0000, 0x01E7 },
129 [0x2B] = { 0x0000, 0x01BF },
130 [0x2C] = { 0x0000, 0x0177 },
131 [0x2D] = { 0x0000, 0x01FF },
132 [0x2E] = { 0x0000, 0x01FF },
133 [0x2F] = { 0x0000, 0x0177 },
134 [0x30] = { 0x0000, 0x0177 },
135 [0x31] = { 0x0000, 0x007F },
136 [0x32] = { 0x0000, 0x01FF },
137 [0x33] = { 0x0000, 0x01FF },
138 [0x34] = { 0x0000, 0x01FF },
139 [0x35] = { 0x0000, 0x01FF },
140 [0x36] = { 0x0000, 0x01FF },
141 [0x37] = { 0x0000, 0x01FF },
142 [0x38] = { 0x0000, 0x004F },
143 [0x39] = { 0x0000, 0x00FF },
144 [0x3D] = { 0x0000, 0x0100 }
148 static const int vol_update_regs[] = {
167 static const struct {
181 static const int srates[] = { 48000, 32000, 24000, 16000, 12000, 8000 };
183 static const int bclk_divs[] = {
207 static const char *alc_sel_text[] = {
"Off",
"Right",
"Left",
"Stereo" };
211 static const char *alc_mode_text[] = {
"ALC",
"Limiter" };
215 static const char *filter_mode_text[] = {
"Audio",
"Application" };
219 static const char *eq_bw_text[] = {
"Narrow",
"Wide" };
220 static const char *eqmode_text[] = {
"Capture",
"Playback" };
223 static const char *eq1_cutoff_text[] = {
224 "80Hz",
"105Hz",
"135Hz",
"175Hz"
228 static const char *eq2_cutoff_text[] = {
229 "230Hz",
"300Hz",
"385Hz",
"500Hz"
234 static const char *eq3_cutoff_text[] = {
235 "650Hz",
"850Hz",
"1.1kHz",
"1.4kHz"
240 static const char *eq4_cutoff_text[] = {
241 "1.8kHz",
"2.4kHz",
"3.2kHz",
"4.1kHz"
246 static const char *eq5_cutoff_text[] = {
247 "5.3kHz",
"6.9kHz",
"9kHz",
"11.7kHz"
252 static const char *depth_3d_text[] = {
277 SOC_ENUM(
"ALC Capture Function", alc_sel),
279 3, 7, 0, alc_max_tlv),
281 0, 7, 0, alc_min_tlv),
283 0, 15, 0, alc_tar_tlv),
302 8, 1, 0, pga_boost_tlv),
314 4, 7, 1, lim_thresh_tlv),
316 0, 12, 0, lim_boost_tlv),
342 SOC_ENUM(
"High Pass Filter Mode", filter_mode),
353 SOC_ENUM_EXT(
"Equalizer Function", eqmode, eqmode_get, eqmode_put),
438 2, 0, left_out_mixer,
ARRAY_SIZE(left_out_mixer)),
440 3, 0, right_out_mixer,
ARRAY_SIZE(right_out_mixer)),
443 2, 0, left_input_mixer,
ARRAY_SIZE(left_input_mixer)),
445 3, 0, right_input_mixer,
ARRAY_SIZE(right_input_mixer)),
448 4, 0, left_boost_mixer,
ARRAY_SIZE(left_boost_mixer)),
450 5, 0, right_boost_mixer,
ARRAY_SIZE(right_boost_mixer)),
499 {
"OUT3 Mixer",
"LMIX2OUT3 Switch",
"Left Output Mixer" },
500 {
"OUT3 Mixer",
"LDAC2OUT3 Switch",
"Left DAC" },
502 {
"OUT3 Out",
NULL,
"OUT3 Mixer" },
503 {
"OUT3",
NULL,
"OUT3 Out" },
505 {
"OUT4 Mixer",
"LMIX2OUT4 Switch",
"Left Output Mixer" },
506 {
"OUT4 Mixer",
"RMIX2OUT4 Switch",
"Right Output Mixer" },
507 {
"OUT4 Mixer",
"LDAC2OUT4 Switch",
"Left DAC" },
508 {
"OUT4 Mixer",
"RDAC2OUT4 Switch",
"Right DAC" },
510 {
"OUT4 Out",
NULL,
"OUT4 Mixer" },
511 {
"OUT4",
NULL,
"OUT4 Out" },
513 {
"Right Output Mixer",
"PCM Switch",
"Right DAC" },
514 {
"Right Output Mixer",
"Aux Switch",
"AUXR" },
515 {
"Right Output Mixer",
"Line Switch",
"Right Boost Mixer" },
517 {
"Left Output Mixer",
"PCM Switch",
"Left DAC" },
518 {
"Left Output Mixer",
"Aux Switch",
"AUXL" },
519 {
"Left Output Mixer",
"Line Switch",
"Left Boost Mixer" },
521 {
"Right Headphone Out",
NULL,
"Right Output Mixer" },
522 {
"HPR",
NULL,
"Right Headphone Out" },
524 {
"Left Headphone Out",
NULL,
"Left Output Mixer" },
525 {
"HPL",
NULL,
"Left Headphone Out" },
527 {
"Right Speaker Out",
NULL,
"Right Output Mixer" },
528 {
"SPKR",
NULL,
"Right Speaker Out" },
530 {
"Left Speaker Out",
NULL,
"Left Output Mixer" },
531 {
"SPKL",
NULL,
"Left Speaker Out" },
533 {
"Right ADC",
NULL,
"Right Boost Mixer" },
535 {
"Right Boost Mixer",
"AUXR Volume",
"AUXR" },
536 {
"Right Boost Mixer",
NULL,
"Right Capture PGA" },
537 {
"Right Boost Mixer",
"R2 Volume",
"R2" },
539 {
"Left ADC",
NULL,
"Left Boost Mixer" },
541 {
"Left Boost Mixer",
"AUXL Volume",
"AUXL" },
542 {
"Left Boost Mixer",
NULL,
"Left Capture PGA" },
543 {
"Left Boost Mixer",
"L2 Volume",
"L2" },
545 {
"Right Capture PGA",
NULL,
"Right Input Mixer" },
546 {
"Left Capture PGA",
NULL,
"Left Input Mixer" },
548 {
"Right Input Mixer",
"R2 Switch",
"R2" },
549 {
"Right Input Mixer",
"MicN Switch",
"RIN" },
550 {
"Right Input Mixer",
"MicP Switch",
"RIP" },
552 {
"Left Input Mixer",
"L2 Switch",
"L2" },
553 {
"Left Input Mixer",
"MicN Switch",
"LIN" },
554 {
"Left Input Mixer",
"MicP Switch",
"LIP" },
565 ucontrol->
value.integer.value[0] = 1;
567 ucontrol->
value.integer.value[0] = 0;
576 unsigned int regpwr2, regpwr3;
579 if (ucontrol->
value.integer.value[0] != 0
580 && ucontrol->
value.integer.value[0] != 1)
586 if (!ucontrol->
value.integer.value[0])
590 if (ucontrol->
value.integer.value[0])
605 ucontrol->
value.integer.value[0]
613 static bool wm8983_readable(
struct device *
dev,
unsigned int reg)
618 return wm8983_access_masks[
reg].read != 0;
665 dev_err(dai->
dev,
"Unknown master/slave configuration\n");
673 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
676 dev_err(dai->
dev,
"DSP A/B modes are not supported\n");
696 dev_err(dai->
dev,
"Unknown polarity configuration\n");
713 struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec);
721 dev_err(codec->
dev,
"Failed to convert params to bclk: %d\n", ret);
741 dev_err(dai->
dev,
"Unsupported word length %u\n",
762 dev_dbg(dai->
dev,
"Selected SRATE = %d\n", srates[srate_idx]);
771 == fs_ratios[
i].ratio)
776 dev_err(dai->
dev,
"Unable to configure MCLK ratio %u/%u\n",
781 dev_dbg(dai->
dev,
"MCLK ratio = %dfs\n", fs_ratios[i].ratio);
786 tmp = (wm8983->
sysclk / fs_ratios[
i].div) * 10;
788 if (wm8983->
bclk == tmp / bclk_divs[i])
793 dev_err(dai->
dev,
"No matching BCLK divider found\n");
810 #define FIXED_PLL_SIZE ((1ULL << 24) * 10)
815 unsigned long int K, Ndiv, Nmod;
825 if (Ndiv < 6 || Ndiv > 12) {
827 " the recommended range: %lu\n", __func__, Ndiv);
837 K = Kpart & 0xffffffff;
845 static int wm8983_set_pll(
struct snd_soc_dai *dai,
int pll_id,
846 int source,
unsigned int freq_in,
847 unsigned int freq_out)
854 if (freq_in && freq_out) {
864 if (!freq_in || !freq_out)
881 static int wm8983_set_sysclk(
struct snd_soc_dai *dai,
882 int clk_id,
unsigned int freq,
int dir)
885 struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec);
897 dev_err(dai->
dev,
"Unknown clock source: %d\n", clk_id);
905 static int wm8983_set_bias_level(
struct snd_soc_codec *codec,
908 struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec);
923 dev_err(codec->
dev,
"Failed to sync cache: %d\n", ret);
985 #define wm8983_suspend NULL
986 #define wm8983_resume NULL
1002 dev_err(codec->
dev,
"Failed to set cache i/o: %d\n", ret);
1008 dev_err(codec->
dev,
"Failed to issue reset: %d\n", ret);
1034 .digital_mute = wm8983_dac_mute,
1035 .hw_params = wm8983_hw_params,
1036 .set_fmt = wm8983_set_fmt,
1037 .set_sysclk = wm8983_set_sysclk,
1038 .set_pll = wm8983_set_pll
1041 #define WM8983_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1042 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1045 .name =
"wm8983-hifi",
1047 .stream_name =
"Playback",
1054 .stream_name =
"Capture",
1060 .ops = &wm8983_dai_ops,
1061 .symmetric_rates = 1
1065 .probe = wm8983_probe,
1066 .remove = wm8983_remove,
1069 .set_bias_level = wm8983_set_bias_level,
1070 .controls = wm8983_snd_controls,
1071 .num_controls =
ARRAY_SIZE(wm8983_snd_controls),
1072 .dapm_widgets = wm8983_dapm_widgets,
1073 .num_dapm_widgets =
ARRAY_SIZE(wm8983_dapm_widgets),
1074 .dapm_routes = wm8983_audio_map,
1075 .num_dapm_routes =
ARRAY_SIZE(wm8983_audio_map),
1078 static const struct regmap_config wm8983_regmap = {
1082 .reg_defaults = wm8983_defaults,
1083 .num_reg_defaults =
ARRAY_SIZE(wm8983_defaults),
1086 .readable_reg = wm8983_readable,
1089 #if defined(CONFIG_SPI_MASTER)
1100 if (IS_ERR(wm8983->
regmap)) {
1101 ret = PTR_ERR(wm8983->
regmap);
1102 dev_err(&spi->
dev,
"Failed to init regmap: %d\n", ret);
1106 spi_set_drvdata(spi, wm8983);
1109 &soc_codec_dev_wm8983, &wm8983_dai, 1);
1119 static struct spi_driver wm8983_spi_driver = {
1124 .probe = wm8983_spi_probe,
1129 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1141 if (IS_ERR(wm8983->
regmap)) {
1142 ret = PTR_ERR(wm8983->
regmap);
1143 dev_err(&i2c->
dev,
"Failed to init regmap: %d\n", ret);
1147 i2c_set_clientdata(i2c, wm8983);
1150 &soc_codec_dev_wm8983, &wm8983_dai, 1);
1167 static struct i2c_driver wm8983_i2c_driver = {
1172 .probe = wm8983_i2c_probe,
1174 .id_table = wm8983_i2c_id
1178 static int __init wm8983_modinit(
void)
1182 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1183 ret = i2c_add_driver(&wm8983_i2c_driver);
1189 #if defined(CONFIG_SPI_MASTER)
1200 static void __exit wm8983_exit(
void)
1202 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1205 #if defined(CONFIG_SPI_MASTER)
1206 spi_unregister_driver(&wm8983_spi_driver);
1212 MODULE_AUTHOR(
"Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");