16 #include <linux/module.h>
21 #include <linux/i2c.h>
22 #include <linux/slab.h>
31 #define WM8971_REG_COUNT 43
46 static const u16 wm8971_reg[] = {
47 0x0097, 0x0097, 0x0079, 0x0079,
48 0x0000, 0x0008, 0x0000, 0x000a,
49 0x0000, 0x0000, 0x00ff, 0x00ff,
50 0x000f, 0x000f, 0x0000, 0x0000,
51 0x0000, 0x007b, 0x0000, 0x0032,
52 0x0000, 0x00c3, 0x00c3, 0x00c0,
53 0x0000, 0x0000, 0x0000, 0x0000,
54 0x0000, 0x0000, 0x0000, 0x0000,
55 0x0000, 0x0000, 0x0050, 0x0050,
56 0x0050, 0x0050, 0x0050, 0x0050,
57 0x0079, 0x0079, 0x0079,
60 #define wm8971_reset(c) snd_soc_write(c, WM8971_RESET, 0)
63 static const char *wm8971_bass[] = {
"Linear Control",
"Adaptive Boost" };
64 static const char *wm8971_bass_filter[] = {
"130Hz @ 48kHz",
66 static const char *wm8971_treble[] = {
"8kHz",
"4kHz" };
67 static const char *wm8971_alc_func[] = {
"Off",
"Right",
"Left",
"Stereo" };
68 static const char *wm8971_ng_type[] = {
"Constant PGA Gain",
70 static const char *wm8971_deemp[] = {
"None",
"32kHz",
"44.1kHz",
"48kHz" };
71 static const char *wm8971_mono_mux[] = {
"Stereo",
"Mono (Left)",
72 "Mono (Right)",
"Digital Mono"};
73 static const char *wm8971_dac_phase[] = {
"Non Inverted",
"Inverted" };
74 static const char *wm8971_lline_mux[] = {
"Line",
"NC",
"NC",
"PGA",
76 static const char *wm8971_rline_mux[] = {
"Line",
"Mic",
"NC",
"PGA",
78 static const char *wm8971_lpga_sel[] = {
"Line",
"NC",
"NC",
"Differential"};
79 static const char *wm8971_rpga_sel[] = {
"Line",
"Mic",
"NC",
"Differential"};
80 static const char *wm8971_adcpol[] = {
"Normal",
"L Invert",
"R Invert",
83 static const struct soc_enum wm8971_enum[] = {
126 SOC_ENUM(
"Bass Boost", wm8971_enum[0]),
127 SOC_ENUM(
"Bass Filter", wm8971_enum[1]),
131 SOC_ENUM(
"Treble Cut-off", wm8971_enum[2]),
140 SOC_ENUM(
"ALC Capture Function", wm8971_enum[3]),
146 SOC_ENUM(
"ALC Capture NG Type", wm8971_enum[4]),
152 SOC_ENUM(
"Playback De-emphasis", wm8971_enum[5]),
153 SOC_ENUM(
"Playback Function", wm8971_enum[6]),
154 SOC_ENUM(
"Playback Phase", wm8971_enum[7]),
209 &wm8971_left_mixer_controls[0],
212 &wm8971_right_mixer_controls[0],
215 &wm8971_mono_mixer_controls[0],
231 &wm8971_left_pga_controls),
233 &wm8971_right_pga_controls),
235 &wm8971_left_line_controls),
237 &wm8971_right_line_controls),
240 &wm8971_monomux_controls),
242 &wm8971_monomux_controls),
257 {
"Left Mixer",
"Playback Switch",
"Left DAC"},
258 {
"Left Mixer",
"Left Bypass Switch",
"Left Line Mux"},
259 {
"Left Mixer",
"Right Playback Switch",
"Right DAC"},
260 {
"Left Mixer",
"Right Bypass Switch",
"Right Line Mux"},
263 {
"Right Mixer",
"Left Playback Switch",
"Left DAC"},
264 {
"Right Mixer",
"Left Bypass Switch",
"Left Line Mux"},
265 {
"Right Mixer",
"Playback Switch",
"Right DAC"},
266 {
"Right Mixer",
"Right Bypass Switch",
"Right Line Mux"},
269 {
"Left Out 1",
NULL,
"Left Mixer"},
270 {
"LOUT1",
NULL,
"Left Out 1"},
273 {
"Left Out 2",
NULL,
"Left Mixer"},
274 {
"LOUT2",
NULL,
"Left Out 2"},
277 {
"Right Out 1",
NULL,
"Right Mixer"},
278 {
"ROUT1",
NULL,
"Right Out 1"},
281 {
"Right Out 2",
NULL,
"Right Mixer"},
282 {
"ROUT2",
NULL,
"Right Out 2"},
285 {
"Mono Mixer",
"Left Playback Switch",
"Left DAC"},
286 {
"Mono Mixer",
"Left Bypass Switch",
"Left Line Mux"},
287 {
"Mono Mixer",
"Right Playback Switch",
"Right DAC"},
288 {
"Mono Mixer",
"Right Bypass Switch",
"Right Line Mux"},
291 {
"Mono Out",
NULL,
"Mono Mixer"},
292 {
"MONO1",
NULL,
"Mono Out"},
295 {
"Left Line Mux",
"Line",
"LINPUT1"},
296 {
"Left Line Mux",
"PGA",
"Left PGA Mux"},
297 {
"Left Line Mux",
"Differential",
"Differential Mux"},
300 {
"Right Line Mux",
"Line",
"RINPUT1"},
301 {
"Right Line Mux",
"Mic",
"MIC"},
302 {
"Right Line Mux",
"PGA",
"Right PGA Mux"},
303 {
"Right Line Mux",
"Differential",
"Differential Mux"},
306 {
"Left PGA Mux",
"Line",
"LINPUT1"},
307 {
"Left PGA Mux",
"Differential",
"Differential Mux"},
310 {
"Right PGA Mux",
"Line",
"RINPUT1"},
311 {
"Right PGA Mux",
"Differential",
"Differential Mux"},
314 {
"Differential Mux",
"Line",
"LINPUT1"},
315 {
"Differential Mux",
"Line",
"RINPUT1"},
318 {
"Left ADC Mux",
"Stereo",
"Left PGA Mux"},
319 {
"Left ADC Mux",
"Mono (Left)",
"Left PGA Mux"},
320 {
"Left ADC Mux",
"Digital Mono",
"Left PGA Mux"},
323 {
"Right ADC Mux",
"Stereo",
"Right PGA Mux"},
324 {
"Right ADC Mux",
"Mono (Right)",
"Right PGA Mux"},
325 {
"Right ADC Mux",
"Digital Mono",
"Right PGA Mux"},
328 {
"Left ADC",
NULL,
"Left ADC Mux"},
329 {
"Right ADC",
NULL,
"Right ADC Mux"},
341 static const struct _coeff_div coeff_div[] = {
343 {12288000, 8000, 1536, 0x6, 0x0},
344 {11289600, 8000, 1408, 0x16, 0x0},
345 {18432000, 8000, 2304, 0x7, 0x0},
346 {16934400, 8000, 2112, 0x17, 0x0},
347 {12000000, 8000, 1500, 0x6, 0x1},
350 {11289600, 11025, 1024, 0x18, 0x0},
351 {16934400, 11025, 1536, 0x19, 0x0},
352 {12000000, 11025, 1088, 0x19, 0x1},
355 {12288000, 16000, 768, 0xa, 0x0},
356 {18432000, 16000, 1152, 0xb, 0x0},
357 {12000000, 16000, 750, 0xa, 0x1},
360 {11289600, 22050, 512, 0x1a, 0x0},
361 {16934400, 22050, 768, 0x1b, 0x0},
362 {12000000, 22050, 544, 0x1b, 0x1},
365 {12288000, 32000, 384, 0xc, 0x0},
366 {18432000, 32000, 576, 0xd, 0x0},
367 {12000000, 32000, 375, 0xa, 0x1},
370 {11289600, 44100, 256, 0x10, 0x0},
371 {16934400, 44100, 384, 0x11, 0x0},
372 {12000000, 44100, 272, 0x11, 0x1},
375 {12288000, 48000, 256, 0x0, 0x0},
376 {18432000, 48000, 384, 0x1, 0x0},
377 {12000000, 48000, 250, 0x0, 0x1},
380 {11289600, 88200, 128, 0x1e, 0x0},
381 {16934400, 88200, 192, 0x1f, 0x0},
382 {12000000, 88200, 136, 0x1f, 0x1},
385 {12288000, 96000, 128, 0xe, 0x0},
386 {18432000, 96000, 192, 0xf, 0x0},
387 {12000000, 96000, 125, 0xe, 0x1},
390 static int get_coeff(
int mclk,
int rate)
395 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
401 static int wm8971_set_dai_sysclk(
struct snd_soc_dai *codec_dai,
402 int clk_id,
unsigned int freq,
int dir)
405 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
419 static int wm8971_set_dai_fmt(
struct snd_soc_dai *codec_dai,
482 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
506 (coeff_div[coeff].
sr << 1) | coeff_div[coeff].
usb);
523 static int wm8971_set_bias_level(
struct snd_soc_codec *codec,
550 #define WM8971_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
551 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
552 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
554 #define WM8971_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
555 SNDRV_PCM_FMTBIT_S24_LE)
558 .hw_params = wm8971_pcm_hw_params,
559 .digital_mute = wm8971_mute,
560 .set_fmt = wm8971_set_dai_fmt,
561 .set_sysclk = wm8971_set_dai_sysclk,
565 .name =
"wm8971-hifi",
567 .stream_name =
"Playback",
573 .stream_name =
"Capture",
578 .ops = &wm8971_dai_ops,
587 wm8971_set_bias_level(codec, codec->
dapm.bias_level);
616 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
628 if (wm8971_workq ==
NULL)
665 .probe = wm8971_probe,
666 .remove = wm8971_remove,
667 .suspend = wm8971_suspend,
668 .resume = wm8971_resume,
669 .set_bias_level = wm8971_set_bias_level,
671 .reg_word_size =
sizeof(
u16),
676 .dapm_widgets = wm8971_dapm_widgets,
677 .num_dapm_widgets =
ARRAY_SIZE(wm8971_dapm_widgets),
678 .dapm_routes = wm8971_dapm_routes,
679 .num_dapm_routes =
ARRAY_SIZE(wm8971_dapm_routes),
694 i2c_set_clientdata(i2c, wm8971);
697 &soc_codec_dev_wm8971, &wm8971_dai, 1);
714 static struct i2c_driver wm8971_i2c_driver = {
719 .probe = wm8971_i2c_probe,
721 .id_table = wm8971_i2c_id,