13 #include <linux/module.h>
21 #include <linux/slab.h>
31 #define WM8770_NUM_SUPPLIES 3
39 0x7f, 0x7f, 0x7f, 0x7f,
40 0x7f, 0x7f, 0x7f, 0x7f,
41 0x7f, 0xff, 0xff, 0xff,
42 0xff, 0xff, 0xff, 0xff,
43 0xff, 0xff, 0, 0x90, 0,
45 0xc, 0xc, 0x100, 0x189,
67 #define WM8770_REGULATOR_EVENT(n) \
68 static int wm8770_regulator_event_##n(struct notifier_block *nb, \
69 unsigned long event, void *data) \
71 struct wm8770_priv *wm8770 = container_of(nb, struct wm8770_priv, \
73 if (event & REGULATOR_EVENT_DISABLE) { \
74 wm8770->codec->cache_sync = 1; \
87 static
const char *dac_phase_text[][2] = {
88 {
"DAC1 Normal",
"DAC1 Inverted" },
89 {
"DAC2 Normal",
"DAC2 Inverted" },
90 {
"DAC3 Normal",
"DAC3 Inverted" },
91 {
"DAC4 Normal",
"DAC4 Inverted" },
94 static const struct soc_enum dac_phase[] = {
135 SOC_ENUM(
"DAC1 Phase", dac_phase[0]),
139 SOC_ENUM(
"DAC2 Phase", dac_phase[1]),
143 SOC_ENUM(
"DAC3 Phase", dac_phase[2]),
147 SOC_ENUM(
"DAC4 Phase", dac_phase[3]),
160 static const char *ain_text[] = {
161 "AIN1",
"AIN2",
"AIN3",
"AIN4",
162 "AIN5",
"AIN6",
"AIN7",
"AIN8"
165 static const struct soc_enum ain_enum =
223 vout1_mix_controls,
ARRAY_SIZE(vout1_mix_controls)),
225 vout2_mix_controls,
ARRAY_SIZE(vout2_mix_controls)),
227 vout3_mix_controls,
ARRAY_SIZE(vout3_mix_controls)),
229 vout4_mix_controls,
ARRAY_SIZE(vout4_mix_controls)),
238 {
"Capture Mux",
"AIN1",
"AIN1" },
239 {
"Capture Mux",
"AIN2",
"AIN2" },
240 {
"Capture Mux",
"AIN3",
"AIN3" },
241 {
"Capture Mux",
"AIN4",
"AIN4" },
242 {
"Capture Mux",
"AIN5",
"AIN5" },
243 {
"Capture Mux",
"AIN6",
"AIN6" },
244 {
"Capture Mux",
"AIN7",
"AIN7" },
245 {
"Capture Mux",
"AIN8",
"AIN8" },
247 {
"ADC",
NULL,
"Capture Mux" },
249 {
"VOUT1 Mixer",
NULL,
"VOUT12 Supply" },
250 {
"VOUT1 Mixer",
"DAC1 Switch",
"DAC1" },
251 {
"VOUT1 Mixer",
"AUX1 Switch",
"AUX1" },
252 {
"VOUT1 Mixer",
"Bypass Switch",
"Capture Mux" },
254 {
"VOUT2 Mixer",
NULL,
"VOUT12 Supply" },
255 {
"VOUT2 Mixer",
"DAC2 Switch",
"DAC2" },
256 {
"VOUT2 Mixer",
"AUX2 Switch",
"AUX2" },
257 {
"VOUT2 Mixer",
"Bypass Switch",
"Capture Mux" },
259 {
"VOUT3 Mixer",
NULL,
"VOUT34 Supply" },
260 {
"VOUT3 Mixer",
"DAC3 Switch",
"DAC3" },
261 {
"VOUT3 Mixer",
"AUX3 Switch",
"AUX3" },
262 {
"VOUT3 Mixer",
"Bypass Switch",
"Capture Mux" },
264 {
"VOUT4 Mixer",
NULL,
"VOUT34 Supply" },
265 {
"VOUT4 Mixer",
"DAC4 Switch",
"DAC4" },
266 {
"VOUT4 Mixer",
"Bypass Switch",
"Capture Mux" },
268 {
"VOUT1",
NULL,
"VOUT1 Mixer" },
269 {
"VOUT2",
NULL,
"VOUT2 Mixer" },
270 {
"VOUT3",
NULL,
"VOUT3 Mixer" },
271 {
"VOUT4",
NULL,
"VOUT4 Mixer" }
371 static const int mclk_ratios[] = {
392 wm8770 = snd_soc_codec_get_drvdata(codec);
409 switch (substream->
stream) {
426 if (ratio == mclk_ratios[i])
432 "Unable to configure MCLK ratio %d/%d\n",
437 dev_dbg(codec->
dev,
"MCLK is %dfs\n", mclk_ratios[i]);
457 static int wm8770_set_sysclk(
struct snd_soc_dai *dai,
458 int clk_id,
unsigned int freq,
int dir)
464 wm8770 = snd_soc_codec_get_drvdata(codec);
479 for (i = 0; i < codec->
driver->reg_cache_size; i++) {
480 if (i ==
WM8770_RESET || cache[i] == wm8770_reg_defs[i])
487 static int wm8770_set_bias_level(
struct snd_soc_codec *codec,
493 wm8770 = snd_soc_codec_get_drvdata(codec);
506 "Failed to enable supplies: %d\n",
510 wm8770_sync_cache(codec);
527 #define WM8770_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
528 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
531 .digital_mute = wm8770_mute,
532 .hw_params = wm8770_hw_params,
533 .set_fmt = wm8770_set_fmt,
534 .set_sysclk = wm8770_set_sysclk,
538 .name =
"wm8770-hifi",
540 .stream_name =
"Playback",
547 .stream_name =
"Capture",
553 .ops = &wm8770_dai_ops,
570 #define wm8770_suspend NULL
571 #define wm8770_resume NULL
580 wm8770 = snd_soc_codec_get_drvdata(codec);
585 dev_err(codec->
dev,
"Failed to set cache I/O: %d\n", ret);
590 wm8770->
supplies[i].supply = wm8770_supply_names[i];
595 dev_err(codec->
dev,
"Failed to request supplies: %d\n", ret);
599 wm8770->
disable_nb[0].notifier_call = wm8770_regulator_event_0;
600 wm8770->
disable_nb[1].notifier_call = wm8770_regulator_event_1;
601 wm8770->
disable_nb[2].notifier_call = wm8770_regulator_event_2;
609 "Failed to register regulator notifier: %d\n",
617 dev_err(codec->
dev,
"Failed to enable supplies: %d\n", ret);
621 ret = wm8770_reset(codec);
623 dev_err(codec->
dev,
"Failed to issue reset: %d\n", ret);
647 ARRAY_SIZE(wm8770_dapm_widgets));
649 ARRAY_SIZE(wm8770_intercon));
664 wm8770 = snd_soc_codec_get_drvdata(codec);
675 .probe = wm8770_probe,
676 .remove = wm8770_remove,
679 .set_bias_level = wm8770_set_bias_level,
680 .idle_bias_off =
true,
681 .reg_cache_size =
ARRAY_SIZE(wm8770_reg_defs),
682 .reg_word_size =
sizeof (
u16),
687 { .compatible =
"wlf,wm8770", },
703 spi_set_drvdata(spi, wm8770);
706 &soc_codec_dev_wm8770, &wm8770_dai, 1);
717 static struct spi_driver wm8770_spi_driver = {
721 .of_match_table = wm8770_of_match,
723 .probe = wm8770_spi_probe,