14 #include <linux/module.h>
16 #include <linux/kernel.h>
20 #include <linux/i2c.h>
22 #include <linux/slab.h>
29 #include <asm/div64.h>
33 static const struct reg_default wm8978_reg_defaults[] = {
93 static bool wm8978_volatile(
struct device *
dev,
unsigned int reg)
109 static const char *wm8978_companding[] = {
"Off",
"NC",
"u-law",
"A-law"};
110 static const char *wm8978_eqmode[] = {
"Capture",
"Playback"};
111 static const char *wm8978_bw[] = {
"Narrow",
"Wide"};
112 static const char *wm8978_eq1[] = {
"80Hz",
"105Hz",
"135Hz",
"175Hz"};
113 static const char *wm8978_eq2[] = {
"230Hz",
"300Hz",
"385Hz",
"500Hz"};
114 static const char *wm8978_eq3[] = {
"650Hz",
"850Hz",
"1.1kHz",
"1.4kHz"};
115 static const char *wm8978_eq4[] = {
"1.8kHz",
"2.4kHz",
"3.2kHz",
"4.1kHz"};
116 static const char *wm8978_eq5[] = {
"5.3kHz",
"6.9kHz",
"9kHz",
"11.7kHz"};
117 static const char *wm8978_alc3[] = {
"ALC",
"Limiter"};
118 static const char *wm8978_alc1[] = {
"Off",
"Right",
"Left",
"Both"};
148 SOC_ENUM(
"ADC Companding", adc_compand),
149 SOC_ENUM(
"DAC Companding", dac_compand),
155 0, 255, 0, digital_tlv),
163 0, 255, 0, digital_tlv),
165 SOC_ENUM(
"Equaliser Function", eqmode),
169 SOC_ENUM(
"Equaliser EQ2 Bandwith", eq2bw),
173 SOC_ENUM(
"Equaliser EQ3 Bandwith", eq3bw),
177 SOC_ENUM(
"Equaliser EQ4 Bandwith", eq4bw),
196 SOC_ENUM(
"ALC Enable Switch", alc1),
208 SOC_SINGLE(
"ALC Capture Noise Gate Threshold",
249 0, 63, 0, inpga_tlv),
305 2, 0, wm8978_left_out_mixer),
307 3, 0, wm8978_right_out_mixer),
310 2, 0, wm8978_left_input_mixer),
312 3, 0, wm8978_right_input_mixer),
355 {
"Right Output Mixer",
"PCM Playback Switch",
"Right DAC"},
356 {
"Right Output Mixer",
"Aux Playback Switch",
"RAUX"},
357 {
"Right Output Mixer",
"Line Bypass Switch",
"Right Boost Mixer"},
359 {
"Left Output Mixer",
"PCM Playback Switch",
"Left DAC"},
360 {
"Left Output Mixer",
"Aux Playback Switch",
"LAUX"},
361 {
"Left Output Mixer",
"Line Bypass Switch",
"Left Boost Mixer"},
364 {
"Right Headphone Out",
NULL,
"Right Output Mixer"},
365 {
"RHP",
NULL,
"Right Headphone Out"},
367 {
"Left Headphone Out",
NULL,
"Left Output Mixer"},
368 {
"LHP",
NULL,
"Left Headphone Out"},
370 {
"Right Speaker Out",
NULL,
"Right Output Mixer"},
371 {
"RSPK",
NULL,
"Right Speaker Out"},
373 {
"Left Speaker Out",
NULL,
"Left Output Mixer"},
374 {
"LSPK",
NULL,
"Left Speaker Out"},
377 {
"Right ADC",
NULL,
"Right Boost Mixer"},
379 {
"Right Boost Mixer",
NULL,
"RAUX"},
380 {
"Right Boost Mixer",
NULL,
"Right Capture PGA"},
381 {
"Right Boost Mixer",
NULL,
"R2"},
383 {
"Left ADC",
NULL,
"Left Boost Mixer"},
385 {
"Left Boost Mixer",
NULL,
"LAUX"},
386 {
"Left Boost Mixer",
NULL,
"Left Capture PGA"},
387 {
"Left Boost Mixer",
NULL,
"L2"},
390 {
"Right Capture PGA",
NULL,
"Right Input Mixer"},
391 {
"Left Capture PGA",
NULL,
"Left Input Mixer"},
393 {
"Right Input Mixer",
"R2 Switch",
"R2"},
394 {
"Right Input Mixer",
"MicN Switch",
"RMICN"},
395 {
"Right Input Mixer",
"MicP Switch",
"RMICP"},
397 {
"Left Input Mixer",
"L2 Switch",
"L2"},
398 {
"Left Input Mixer",
"MicN Switch",
"LMICN"},
399 {
"Left Input Mixer",
"MicP Switch",
"LMICP"},
409 #define FIXED_PLL_SIZE (1 << 24)
415 unsigned int k, n_div, n_mod;
426 if (n_div < 6 || n_div > 12)
428 "WM8978 N value exceeds recommended range! N = %u\n",
432 n_mod = target - source * n_div;
437 k = k_part & 0xFFFFFFFF;
443 static const int mclk_numerator[] = {1, 3, 2, 3, 4, 6, 8, 12};
444 static const int mclk_denominator[] = {1, 2, 1, 1, 1, 1, 1, 1};
453 static int wm8978_enum_mclk(
unsigned int f_out,
unsigned int f_mclk,
454 unsigned int *f_pllout)
458 for (i = 0; i <
ARRAY_SIZE(mclk_numerator); i++) {
459 unsigned int f_pllout_x4 = 4 * f_out * mclk_numerator[
i] /
461 if (3 * f_mclk <= f_pllout_x4 && f_pllout_x4 < 13 * f_mclk) {
462 *f_pllout = f_pllout_x4 / 4;
476 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
478 unsigned int f_opclk = wm8978->
f_opclk, f_mclk = wm8978->
f_mclk,
486 unsigned int opclk_div;
499 if (16 * f_opclk < 3 * f_mclk || 4 * f_opclk >= 13 * f_mclk)
502 if (4 * f_opclk < 3 * f_mclk)
504 opclk_div = (3 * f_mclk / 4 + f_opclk - 1) / f_opclk;
508 dev_dbg(codec->
dev,
"%s: OPCLKDIV=%d\n", __func__, opclk_div);
511 (opclk_div - 1) << 4);
513 wm8978->
f_pllout = f_opclk * opclk_div;
514 }
else if (f_256fs) {
525 int idx = wm8978_enum_mclk(f_256fs, f_mclk, &wm8978->
f_pllout);
539 dev_dbg(codec->
dev,
"%s: f_MCLK=%uHz, f_PLLOUT=%uHz\n", __func__,
544 dev_dbg(codec->
dev,
"%s: calculated PLL N=0x%x, K=0x%x, div2=%d\n",
568 static int wm8978_set_dai_clkdiv(
struct snd_soc_dai *codec_dai,
572 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
594 ret = wm8978_configure_pll(codec);
605 dev_dbg(codec->
dev,
"%s: ID %d, value %u\n", __func__, div_id, div);
613 static int wm8978_set_dai_sysclk(
struct snd_soc_dai *codec_dai,
int clk_id,
614 unsigned int freq,
int dir)
617 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
620 dev_dbg(codec->
dev,
"%s: ID %d, freq %u\n", __func__, clk_id, freq);
627 ret = wm8978_configure_pll(codec);
655 static int wm8978_set_dai_fmt(
struct snd_soc_dai *codec_dai,
unsigned int fmt)
727 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
735 unsigned int f_sel, diff, diff_best =
INT_MAX;
787 int ret = wm8978_configure_pll(codec);
799 for (i = 0; i <
ARRAY_SIZE(mclk_numerator); i++) {
801 f_sel * 3 * mclk_denominator[i] / mclk_numerator[i]);
803 if (diff < diff_best) {
818 dev_warn(codec->
dev,
"Imprecise sampling rate: %uHz%s\n",
819 f_sel * mclk_denominator[best] / mclk_numerator[best] / 256,
821 ", consider using PLL" :
"");
823 dev_dbg(codec->
dev,
"%s: fmt %d, rate %u, MCLK divisor #%d\n", __func__,
832 if (wm8978->
sysclk != current_clk_id) {
849 dev_dbg(codec->
dev,
"%s: %d\n", __func__, mute);
859 static int wm8978_set_bias_level(
struct snd_soc_codec *codec,
892 dev_dbg(codec->
dev,
"%s: %d, %x\n", __func__, level, power1);
898 #define WM8978_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
899 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
902 .hw_params = wm8978_hw_params,
903 .digital_mute = wm8978_mute,
904 .set_fmt = wm8978_set_dai_fmt,
905 .set_clkdiv = wm8978_set_dai_clkdiv,
906 .set_sysclk = wm8978_set_dai_sysclk,
911 .name =
"wm8978-hifi",
913 .stream_name =
"Playback",
920 .stream_name =
"Capture",
926 .ops = &wm8978_dai_ops,
931 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
944 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
964 static const int update_reg[] = {
979 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
990 dev_err(codec->
dev,
"Failed to set cache I/O: %d\n", ret);
1015 .probe = wm8978_probe,
1016 .remove = wm8978_remove,
1017 .suspend = wm8978_suspend,
1018 .resume = wm8978_resume,
1019 .set_bias_level = wm8978_set_bias_level,
1021 .controls = wm8978_snd_controls,
1022 .num_controls =
ARRAY_SIZE(wm8978_snd_controls),
1023 .dapm_widgets = wm8978_dapm_widgets,
1024 .num_dapm_widgets =
ARRAY_SIZE(wm8978_dapm_widgets),
1025 .dapm_routes = wm8978_dapm_routes,
1026 .num_dapm_routes =
ARRAY_SIZE(wm8978_dapm_routes),
1029 static const struct regmap_config wm8978_regmap_config = {
1034 .volatile_reg = wm8978_volatile,
1037 .reg_defaults = wm8978_reg_defaults,
1038 .num_reg_defaults =
ARRAY_SIZE(wm8978_reg_defaults),
1053 if (IS_ERR(wm8978->
regmap)) {
1054 ret = PTR_ERR(wm8978->
regmap);
1055 dev_err(&i2c->
dev,
"Failed to allocate regmap: %d\n", ret);
1059 i2c_set_clientdata(i2c, wm8978);
1064 dev_err(&i2c->
dev,
"Failed to issue reset: %d\n", ret);
1069 &soc_codec_dev_wm8978, &wm8978_dai, 1);
1071 dev_err(&i2c->
dev,
"Failed to register CODEC: %d\n", ret);
1084 struct wm8978_priv *wm8978 = i2c_get_clientdata(client);
1098 static struct i2c_driver wm8978_i2c_driver = {
1103 .probe = wm8978_i2c_probe,
1105 .id_table = wm8978_i2c_id,