14 #include <linux/module.h>
19 #include <linux/i2c.h>
21 #include <linux/slab.h>
36 static const struct reg_default wm8988_reg_defaults[] = {
72 static bool wm8988_writeable(
struct device *
dev,
unsigned int reg)
122 #define wm8988_reset(c) snd_soc_write(c, WM8988_RESET, 0)
128 static const char *bass_boost_txt[] = {
"Linear Control",
"Adaptive Boost"};
129 static const struct soc_enum bass_boost =
132 static const char *bass_filter_txt[] = {
"130Hz @ 48kHz",
"200Hz @ 48kHz" };
133 static const struct soc_enum bass_filter =
136 static const char *treble_txt[] = {
"8kHz",
"4kHz"};
137 static const struct soc_enum treble =
140 static const char *stereo_3d_lc_txt[] = {
"200Hz",
"500Hz"};
141 static const struct soc_enum stereo_3d_lc =
144 static const char *stereo_3d_uc_txt[] = {
"2.2kHz",
"1.5kHz"};
145 static const struct soc_enum stereo_3d_uc =
148 static const char *stereo_3d_func_txt[] = {
"Capture",
"Playback"};
149 static const struct soc_enum stereo_3d_func =
152 static const char *alc_func_txt[] = {
"Off",
"Right",
"Left",
"Stereo"};
153 static const struct soc_enum alc_func =
156 static const char *ng_type_txt[] = {
"Constant PGA Gain",
158 static const struct soc_enum ng_type =
161 static const char *deemph_txt[] = {
"None",
"32Khz",
"44.1Khz",
"48Khz"};
162 static const struct soc_enum deemph =
165 static const char *adcpol_txt[] = {
"Normal",
"L Invert",
"R Invert",
167 static const struct soc_enum adcpol =
179 SOC_ENUM(
"Bass Filter", bass_filter),
187 SOC_ENUM(
"3D Lower Cut-off", stereo_3d_lc),
188 SOC_ENUM(
"3D Upper Cut-off", stereo_3d_uc),
189 SOC_ENUM(
"3D Mode", stereo_3d_func),
193 SOC_ENUM(
"ALC Capture Function", alc_func),
199 SOC_ENUM(
"ALC Capture NG Type", ng_type),
211 SOC_ENUM(
"Playback De-emphasis", deemph),
213 SOC_ENUM(
"Capture Polarity", adcpol),
259 static const char *wm8988_line_texts[] = {
260 "Line 1",
"Line 2",
"PGA",
"Differential"};
262 static const unsigned int wm8988_line_values[] = {
265 static const struct soc_enum wm8988_lline_enum =
273 static const struct soc_enum wm8988_rline_enum =
297 static const char *wm8988_pga_sel[] = {
"Line 1",
"Line 2",
"Differential"};
298 static const unsigned int wm8988_pga_val[] = { 0, 1, 3 };
301 static const struct soc_enum wm8988_lpga_enum =
310 static const struct soc_enum wm8988_rpga_enum =
319 static const char *wm8988_diff_sel[] = {
"Line 1",
"Line 2"};
320 static const struct soc_enum diffmux =
326 static const char *wm8988_mono_mux[] = {
"Stereo",
"Mono (Left)",
327 "Mono (Right)",
"Digital Mono"};
328 static const struct soc_enum monomux =
337 &wm8988_diffmux_controls),
339 &wm8988_monomux_controls),
341 &wm8988_monomux_controls),
344 &wm8988_left_pga_controls),
346 &wm8988_right_pga_controls),
349 &wm8988_left_line_controls),
351 &wm8988_right_line_controls),
360 &wm8988_left_mixer_controls[0],
363 &wm8988_right_mixer_controls[0],
387 {
"Left Line Mux",
"Line 1",
"LINPUT1" },
388 {
"Left Line Mux",
"Line 2",
"LINPUT2" },
389 {
"Left Line Mux",
"PGA",
"Left PGA Mux" },
390 {
"Left Line Mux",
"Differential",
"Differential Mux" },
392 {
"Right Line Mux",
"Line 1",
"RINPUT1" },
393 {
"Right Line Mux",
"Line 2",
"RINPUT2" },
394 {
"Right Line Mux",
"PGA",
"Right PGA Mux" },
395 {
"Right Line Mux",
"Differential",
"Differential Mux" },
397 {
"Left PGA Mux",
"Line 1",
"LINPUT1" },
398 {
"Left PGA Mux",
"Line 2",
"LINPUT2" },
399 {
"Left PGA Mux",
"Differential",
"Differential Mux" },
401 {
"Right PGA Mux",
"Line 1",
"RINPUT1" },
402 {
"Right PGA Mux",
"Line 2",
"RINPUT2" },
403 {
"Right PGA Mux",
"Differential",
"Differential Mux" },
405 {
"Differential Mux",
"Line 1",
"LINPUT1" },
406 {
"Differential Mux",
"Line 1",
"RINPUT1" },
407 {
"Differential Mux",
"Line 2",
"LINPUT2" },
408 {
"Differential Mux",
"Line 2",
"RINPUT2" },
410 {
"Left ADC Mux",
"Stereo",
"Left PGA Mux" },
411 {
"Left ADC Mux",
"Mono (Left)",
"Left PGA Mux" },
412 {
"Left ADC Mux",
"Digital Mono",
"Left PGA Mux" },
414 {
"Right ADC Mux",
"Stereo",
"Right PGA Mux" },
415 {
"Right ADC Mux",
"Mono (Right)",
"Right PGA Mux" },
416 {
"Right ADC Mux",
"Digital Mono",
"Right PGA Mux" },
418 {
"Left ADC",
NULL,
"Left ADC Mux" },
419 {
"Right ADC",
NULL,
"Right ADC Mux" },
421 {
"Left Line Mux",
"Line 1",
"LINPUT1" },
422 {
"Left Line Mux",
"Line 2",
"LINPUT2" },
423 {
"Left Line Mux",
"PGA",
"Left PGA Mux" },
424 {
"Left Line Mux",
"Differential",
"Differential Mux" },
426 {
"Right Line Mux",
"Line 1",
"RINPUT1" },
427 {
"Right Line Mux",
"Line 2",
"RINPUT2" },
428 {
"Right Line Mux",
"PGA",
"Right PGA Mux" },
429 {
"Right Line Mux",
"Differential",
"Differential Mux" },
431 {
"Left Mixer",
"Playback Switch",
"Left DAC" },
432 {
"Left Mixer",
"Left Bypass Switch",
"Left Line Mux" },
433 {
"Left Mixer",
"Right Playback Switch",
"Right DAC" },
434 {
"Left Mixer",
"Right Bypass Switch",
"Right Line Mux" },
436 {
"Right Mixer",
"Left Playback Switch",
"Left DAC" },
437 {
"Right Mixer",
"Left Bypass Switch",
"Left Line Mux" },
438 {
"Right Mixer",
"Playback Switch",
"Right DAC" },
439 {
"Right Mixer",
"Right Bypass Switch",
"Right Line Mux" },
441 {
"Left Out 1",
NULL,
"Left Mixer" },
442 {
"LOUT1",
NULL,
"Left Out 1" },
443 {
"Right Out 1",
NULL,
"Right Mixer" },
444 {
"ROUT1",
NULL,
"Right Out 1" },
446 {
"Left Out 2",
NULL,
"Left Mixer" },
447 {
"LOUT2",
NULL,
"Left Out 2" },
448 {
"Right Out 2",
NULL,
"Right Mixer" },
449 {
"ROUT2",
NULL,
"Right Out 2" },
461 static const struct _coeff_div coeff_div[] = {
463 {12288000, 8000, 1536, 0x6, 0x0},
464 {11289600, 8000, 1408, 0x16, 0x0},
465 {18432000, 8000, 2304, 0x7, 0x0},
466 {16934400, 8000, 2112, 0x17, 0x0},
467 {12000000, 8000, 1500, 0x6, 0x1},
470 {11289600, 11025, 1024, 0x18, 0x0},
471 {16934400, 11025, 1536, 0x19, 0x0},
472 {12000000, 11025, 1088, 0x19, 0x1},
475 {12288000, 16000, 768, 0xa, 0x0},
476 {18432000, 16000, 1152, 0xb, 0x0},
477 {12000000, 16000, 750, 0xa, 0x1},
480 {11289600, 22050, 512, 0x1a, 0x0},
481 {16934400, 22050, 768, 0x1b, 0x0},
482 {12000000, 22050, 544, 0x1b, 0x1},
485 {12288000, 32000, 384, 0xc, 0x0},
486 {18432000, 32000, 576, 0xd, 0x0},
487 {12000000, 32000, 375, 0xa, 0x1},
490 {11289600, 44100, 256, 0x10, 0x0},
491 {16934400, 44100, 384, 0x11, 0x0},
492 {12000000, 44100, 272, 0x11, 0x1},
495 {12288000, 48000, 256, 0x0, 0x0},
496 {18432000, 48000, 384, 0x1, 0x0},
497 {12000000, 48000, 250, 0x0, 0x1},
500 {11289600, 88200, 128, 0x1e, 0x0},
501 {16934400, 88200, 192, 0x1f, 0x0},
502 {12000000, 88200, 136, 0x1f, 0x1},
505 {12288000, 96000, 128, 0xe, 0x0},
506 {18432000, 96000, 192, 0xf, 0x0},
507 {12000000, 96000, 125, 0xe, 0x1},
510 static inline int get_coeff(
int mclk,
int rate)
515 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
524 static unsigned int rates_12288[] = {
525 8000, 12000, 16000, 24000, 24000, 32000, 48000, 96000,
533 static unsigned int rates_112896[] = {
534 8000, 11025, 22050, 44100,
539 .list = rates_112896,
542 static unsigned int rates_12[] = {
543 8000, 11025, 12000, 16000, 22050, 2400, 32000, 41100, 48000,
555 static int wm8988_set_dai_sysclk(
struct snd_soc_dai *codec_dai,
556 int clk_id,
unsigned int freq,
int dir)
559 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
587 static int wm8988_set_dai_fmt(
struct snd_soc_dai *codec_dai,
649 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
656 "No MCLK configured, call set_sysclk() on init\n");
672 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
684 "Unable to configure sample rate %dHz with %dHz MCLK\n",
708 (coeff_div[coeff].
sr << 1) | coeff_div[coeff].
usb);
725 static int wm8988_set_bias_level(
struct snd_soc_codec *codec,
728 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
763 #define WM8988_RATES SNDRV_PCM_RATE_8000_96000
765 #define WM8988_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
766 SNDRV_PCM_FMTBIT_S24_LE)
769 .startup = wm8988_pcm_startup,
770 .hw_params = wm8988_pcm_hw_params,
771 .set_fmt = wm8988_set_dai_fmt,
772 .set_sysclk = wm8988_set_dai_sysclk,
773 .digital_mute = wm8988_mute,
777 .name =
"wm8988-hifi",
779 .stream_name =
"Playback",
786 .stream_name =
"Capture",
793 .symmetric_rates = 1,
798 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
813 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
819 dev_err(codec->
dev,
"Failed to set cache I/O: %d\n", ret);
825 dev_err(codec->
dev,
"Failed to issue reset\n");
848 .probe = wm8988_probe,
849 .remove = wm8988_remove,
850 .suspend = wm8988_suspend,
851 .resume = wm8988_resume,
852 .set_bias_level = wm8988_set_bias_level,
854 .controls = wm8988_snd_controls,
855 .num_controls =
ARRAY_SIZE(wm8988_snd_controls),
856 .dapm_widgets = wm8988_dapm_widgets,
857 .num_dapm_widgets =
ARRAY_SIZE(wm8988_dapm_widgets),
858 .dapm_routes = wm8988_dapm_routes,
859 .num_dapm_routes =
ARRAY_SIZE(wm8988_dapm_routes),
862 static struct regmap_config wm8988_regmap = {
867 .writeable_reg = wm8988_writeable,
870 .reg_defaults = wm8988_reg_defaults,
871 .num_reg_defaults =
ARRAY_SIZE(wm8988_reg_defaults),
874 #if defined(CONFIG_SPI_MASTER)
886 if (IS_ERR(wm8988->
regmap)) {
887 ret = PTR_ERR(wm8988->
regmap);
888 dev_err(&spi->
dev,
"Failed to init regmap: %d\n", ret);
892 spi_set_drvdata(spi, wm8988);
895 &soc_codec_dev_wm8988, &wm8988_dai, 1);
910 static struct spi_driver wm8988_spi_driver = {
915 .probe = wm8988_spi_probe,
920 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
932 i2c_set_clientdata(i2c, wm8988);
935 if (IS_ERR(wm8988->
regmap)) {
936 ret = PTR_ERR(wm8988->
regmap);
937 dev_err(&i2c->
dev,
"Failed to init regmap: %d\n", ret);
942 &soc_codec_dev_wm8988, &wm8988_dai, 1);
951 struct wm8988_priv *wm8988 = i2c_get_clientdata(client);
963 static struct i2c_driver wm8988_i2c_driver = {
968 .probe = wm8988_i2c_probe,
970 .id_table = wm8988_i2c_id,
974 static int __init wm8988_modinit(
void)
977 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
978 ret = i2c_add_driver(&wm8988_i2c_driver);
984 #if defined(CONFIG_SPI_MASTER)
995 static void __exit wm8988_exit(
void)
997 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1000 #if defined(CONFIG_SPI_MASTER)
1001 spi_unregister_driver(&wm8988_spi_driver);