Lines Matching +full:4 +full:- +full:switch

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * wm8753.c -- WM8753 ALSA Soc Audio driver
5 * Copyright 2003-11 Wolfson Microelectronics PLC.
12 * Dual DAI:-
23 * Fast DAI switching:-
25 * The driver can now fast switch between the DAI configurations via a
157 static const char *wm8753_treble[] = {"8kHz", "4kHz"};
166 static const char *wm8753_line_mix[] = {"Line 1 + 2", "Line 1 - 2",
171 static const char *wm8753_rxmsel[] = {"RXP - RXN", "RXP + RXN", "RXP", "RXN"};
178 static const char *wm8753_radcsel[] = {"PGA", "Line or RXP-RXN", "Sidetone"};
179 static const char *wm8753_ladcsel[] = {"PGA", "Line or RXP-RXN", "Line"};
193 SOC_ENUM_SINGLE(WM8753_BASS, 4, 6, wm8753_base_filter),
195 SOC_ENUM_SINGLE(WM8753_ALC1, 7, 4, wm8753_alc_func),
200 SOC_ENUM_SINGLE(WM8753_DAC, 1, 4, wm8753_deemp),
201 SOC_ENUM_SINGLE(WM8753_DAC, 4, 4, wm8753_mono_mix),
203 SOC_ENUM_SINGLE(WM8753_INCTL1, 3, 4, wm8753_line_mix),
207 SOC_ENUM_SINGLE(WM8753_INCTL2, 6, 4, wm8753_rxmsel),
208 SOC_ENUM_SINGLE(WM8753_INCTL2, 4, 4, wm8753_sidetone_mux),
209 SOC_ENUM_SINGLE(WM8753_OUTCTL, 7, 4, wm8753_mono2_src),
214 SOC_ENUM_SINGLE(WM8753_ADCIN, 4, 4, wm8753_mono_adc),
215 SOC_ENUM_SINGLE(WM8753_ADC, 2, 4, wm8753_adc_hp),
216 SOC_ENUM_SINGLE(WM8753_ADC, 4, 2, wm8753_adc_filter),
218 SOC_ENUM_SINGLE(WM8753_IOCTL, 2, 4, wm8753_dai_mode),
219 SOC_ENUM_SINGLE(WM8753_ADC, 7, 4, wm8753_dat_sel),
230 ucontrol->value.enumerated.item[0] = wm8753->dai_func; in wm8753_get_dai()
241 if (wm8753->dai_func == ucontrol->value.enumerated.item[0]) in wm8753_set_dai()
245 return -EBUSY; in wm8753_set_dai()
249 wm8753->dai_func = ucontrol->value.enumerated.item[0]; in wm8753_set_dai()
251 if (((ioctl >> 2) & 0x3) == wm8753->dai_func) in wm8753_set_dai()
254 ioctl = (ioctl & 0x1f3) | (wm8753->dai_func << 2); in wm8753_set_dai()
258 wm8753_hifi_write_dai_fmt(component, wm8753->hifi_fmt); in wm8753_set_dai()
259 wm8753_voice_write_dai_fmt(component, wm8753->voice_fmt); in wm8753_set_dai()
264 static const DECLARE_TLV_DB_SCALE(rec_mix_tlv, -1500, 300, 0);
266 static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1);
267 static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
269 /* 0000000 - 0101111 = "Analogue mute" */
270 0, 48, TLV_DB_SCALE_ITEM(-25500, 0, 0),
271 48, 127, TLV_DB_SCALE_ITEM(-7300, 100, 0)
273 static const DECLARE_TLV_DB_SCALE(mix_tlv, -1500, 300, 0);
274 static const DECLARE_TLV_DB_SCALE(voice_mix_tlv, -1200, 300, 0);
275 static const DECLARE_TLV_DB_SCALE(pga_tlv, -1725, 75, 0);
278 SOC_SINGLE("Hi-Fi DAC Left/Right channel Swap", WM8753_HIFI, 5, 1, 0),
291 SOC_DOUBLE_R_TLV("Bypass Playback Volume", WM8753_LOUTM1, WM8753_ROUTM1, 4, 7,
293 SOC_DOUBLE_R_TLV("Sidetone Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 4,
298 SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8753_LOUT1V, WM8753_ROUT1V, 7,
300 SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8753_LOUT2V, WM8753_ROUT2V, 7,
303 SOC_SINGLE_TLV("Mono Bypass Playback Volume", WM8753_MOUTM1, 4, 7, 1, mix_tlv),
304 SOC_SINGLE_TLV("Mono Sidetone Playback Volume", WM8753_MOUTM2, 4, 7, 1,
308 SOC_SINGLE("Mono Playback ZC Switch", WM8753_MOUTV, 7, 1, 0),
315 SOC_ENUM("Treble Cut-off", wm8753_enum[2]),
317 SOC_DOUBLE_TLV("Sidetone Capture Volume", WM8753_RECMIX1, 0, 4, 7, 1,
324 SOC_DOUBLE_R("Capture ZC Switch", WM8753_LINVOL, WM8753_RINVOL, 6, 1, 0),
325 SOC_DOUBLE_R("Capture Switch", WM8753_LINVOL, WM8753_RINVOL, 7, 1, 1),
328 SOC_ENUM("Capture Filter Cut-off", wm8753_enum[24]),
329 SOC_SINGLE("Capture Filter Switch", WM8753_ADC, 0, 1, 1),
332 SOC_SINGLE("ALC Capture Max Volume", WM8753_ALC1, 4, 7, 0),
334 SOC_SINGLE("ALC Capture ZC Switch", WM8753_ALC2, 8, 1, 0),
336 SOC_SINGLE("ALC Capture Decay Time", WM8753_ALC3, 4, 15, 1),
339 SOC_ENUM("ALC Capture NG Type", wm8753_enum[4]),
340 SOC_SINGLE("ALC Capture NG Switch", WM8753_NGATE, 0, 1, 0),
343 SOC_ENUM("3D Upper Cut-off", wm8753_enum[6]),
344 SOC_ENUM("3D Lower Cut-off", wm8753_enum[7]),
346 SOC_SINGLE("3D Switch", WM8753_3D, 0, 1, 0),
351 SOC_ENUM("De-emphasis", wm8753_enum[8]),
370 SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_LOUTM2, 8, 1, 0),
371 SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_LOUTM2, 7, 1, 0),
372 SOC_DAPM_SINGLE("Left Playback Switch", WM8753_LOUTM1, 8, 1, 0),
373 SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_LOUTM1, 7, 1, 0),
378 SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_ROUTM2, 8, 1, 0),
379 SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_ROUTM2, 7, 1, 0),
380 SOC_DAPM_SINGLE("Right Playback Switch", WM8753_ROUTM1, 8, 1, 0),
381 SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_ROUTM1, 7, 1, 0),
386 SOC_DAPM_SINGLE("Left Playback Switch", WM8753_MOUTM1, 8, 1, 0),
387 SOC_DAPM_SINGLE("Right Playback Switch", WM8753_MOUTM2, 8, 1, 0),
388 SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_MOUTM2, 3, 1, 0),
389 SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_MOUTM2, 7, 1, 0),
390 SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_MOUTM1, 7, 1, 0),
401 /* Out 4 Mux */
411 SOC_DAPM_SINGLE("Voice Capture Switch", WM8753_RECMIX2, 3, 1, 0),
412 SOC_DAPM_SINGLE("Left Capture Switch", WM8753_RECMIX1, 3, 1, 0),
413 SOC_DAPM_SINGLE("Right Capture Switch", WM8753_RECMIX1, 7, 1, 0),
430 SOC_DAPM_SINGLE("Line Capture Switch", WM8753_INCTL2, 3, 1, 0),
431 SOC_DAPM_SINGLE("Mic2 Capture Switch", WM8753_INCTL2, 2, 1, 0),
432 SOC_DAPM_SINGLE("Mic1 Capture Switch", WM8753_INCTL2, 1, 1, 0),
433 SOC_DAPM_SINGLE("Rx Capture Switch", WM8753_INCTL2, 0, 1, 0),
480 SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", WM8753_PWR1, 4, 0),
486 SND_SOC_DAPM_PGA("Out 3", WM8753_PWR3, 4, 0, NULL, 0),
489 SND_SOC_DAPM_PGA("Out 4", WM8753_PWR3, 3, 0, NULL, 0),
507 SND_SOC_DAPM_PGA("Right Capture Volume", WM8753_PWR2, 4, 0, NULL, 0),
539 {"Left Mixer", "Left Playback Switch", "Left DAC"},
540 {"Left Mixer", "Voice Playback Switch", "Voice DAC"},
541 {"Left Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
542 {"Left Mixer", "Bypass Playback Switch", "Line Left Mux"},
545 {"Right Mixer", "Right Playback Switch", "Right DAC"},
546 {"Right Mixer", "Voice Playback Switch", "Voice DAC"},
547 {"Right Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
548 {"Right Mixer", "Bypass Playback Switch", "Line Right Mux"},
551 {"Mono Mixer", "Voice Playback Switch", "Voice DAC"},
552 {"Mono Mixer", "Left Playback Switch", "Left DAC"},
553 {"Mono Mixer", "Right Playback Switch", "Right DAC"},
554 {"Mono Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
555 {"Mono Mixer", "Bypass Playback Switch", "Line Mono Mux"},
590 /* out 4 */
594 {"Out 4", NULL, "Out4 Mux"},
595 {"OUT4", NULL, "Out 4"},
598 {"Playback Mixer", "Left Capture Switch", "Left Mixer"},
599 {"Playback Mixer", "Voice Capture Switch", "Mono Mixer"},
600 {"Playback Mixer", "Right Capture Switch", "Right Mixer"},
610 {"Capture Left Mux", "Line or RXP-RXN", "Line Left Mux"},
615 {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"},
618 /* Mono Capture mixer-mux */
641 {"ALC Mixer", "Line Capture Switch", "Line Mixer"},
642 {"ALC Mixer", "Mic2 Capture Switch", "Mic 2 Volume"},
643 {"ALC Mixer", "Mic1 Capture Switch", "Mic 1 Volume"},
644 {"ALC Mixer", "Rx Capture Switch", "Rx Mixer"},
660 {"Line Mixer", "Line 1 - 2", "LINE1"},
662 {"Line Mixer", "Line 1 - 2", "LINE2"},
667 {"Rx Mixer", "RXP - RXN", "RXP"},
669 {"Rx Mixer", "RXP - RXN", "RXN"},
694 u32 n:4;
711 pll_div->div2 = 1; in pll_factors()
714 pll_div->div2 = 0; in pll_factors()
720 pll_div->n = Ndiv; in pll_factors()
735 pll_div->k = K; in pll_factors()
743 struct snd_soc_component *component = codec_dai->component; in wm8753_set_dai_pll()
746 return -ENODEV; in wm8753_set_dai_pll()
753 offset = 4; in wm8753_set_dai_pll()
855 return -EINVAL; in get_coeff()
864 struct snd_soc_component *component = codec_dai->component; in wm8753_set_dai_sysclk()
867 switch (freq) { in wm8753_set_dai_sysclk()
874 wm8753->sysclk = freq; in wm8753_set_dai_sysclk()
877 wm8753->pcmclk = freq; in wm8753_set_dai_sysclk()
882 return -EINVAL; in wm8753_set_dai_sysclk()
894 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { in wm8753_vdac_adc_set_dai_fmt()
910 return -EINVAL; in wm8753_vdac_adc_set_dai_fmt()
924 struct snd_soc_component *component = dai->component; in wm8753_pcm_hw_params()
930 switch (params_width(params)) { in wm8753_pcm_hw_params()
945 if (params_rate(params) * 384 == wm8753->pcmclk) in wm8753_pcm_hw_params()
965 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { in wm8753_pcm_set_dai_fmt()
975 return -EINVAL; in wm8753_pcm_set_dai_fmt()
979 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { in wm8753_pcm_set_dai_fmt()
983 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { in wm8753_pcm_set_dai_fmt()
990 return -EINVAL; in wm8753_pcm_set_dai_fmt()
997 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { in wm8753_pcm_set_dai_fmt()
1010 return -EINVAL; in wm8753_pcm_set_dai_fmt()
1014 return -EINVAL; in wm8753_pcm_set_dai_fmt()
1025 struct snd_soc_component *component = codec_dai->component; in wm8753_set_dai_clkdiv()
1028 switch (div_id) { in wm8753_set_dai_clkdiv()
1042 return -EINVAL; in wm8753_set_dai_clkdiv()
1056 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { in wm8753_hdac_set_dai_fmt()
1072 return -EINVAL; in wm8753_hdac_set_dai_fmt()
1091 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { in wm8753_i2s_set_dai_fmt()
1101 return -EINVAL; in wm8753_i2s_set_dai_fmt()
1105 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { in wm8753_i2s_set_dai_fmt()
1109 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { in wm8753_i2s_set_dai_fmt()
1116 return -EINVAL; in wm8753_i2s_set_dai_fmt()
1123 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { in wm8753_i2s_set_dai_fmt()
1136 return -EINVAL; in wm8753_i2s_set_dai_fmt()
1140 return -EINVAL; in wm8753_i2s_set_dai_fmt()
1155 struct snd_soc_component *component = dai->component; in wm8753_i2s_hw_params()
1162 coeff = get_coeff(wm8753->sysclk, params_rate(params)); in wm8753_i2s_hw_params()
1171 switch (params_width(params)) { in wm8753_i2s_hw_params()
1229 return -EINVAL; in wm8753_mode3_4_set_dai_fmt()
1239 switch (wm8753->dai_func) { in wm8753_hifi_write_dai_fmt()
1262 struct snd_soc_component *component = codec_dai->component; in wm8753_hifi_set_dai_fmt()
1265 wm8753->hifi_fmt = fmt; in wm8753_hifi_set_dai_fmt()
1276 if (wm8753->dai_func != 0) in wm8753_voice_write_dai_fmt()
1292 struct snd_soc_component *component = codec_dai->component; in wm8753_voice_set_dai_fmt()
1295 wm8753->voice_fmt = fmt; in wm8753_voice_set_dai_fmt()
1302 struct snd_soc_component *component = dai->component; in wm8753_mute()
1308 if (mute && wm8753->dai_func == 1) { in wm8753_mute()
1327 regmap_update_bits(wm8753->regmap, WM8753_PWR1, 0x0180, 0x0100); in wm8753_charge_work()
1336 switch (level) { in wm8753_set_bias_level()
1343 flush_delayed_work(&wm8753->charge_work); in wm8753_set_bias_level()
1349 schedule_delayed_work(&wm8753->charge_work, in wm8753_set_bias_level()
1357 cancel_delayed_work_sync(&wm8753->charge_work); in wm8753_set_bias_level()
1373 * The WM8753 supports up to 4 different and mutually exclusive DAI
1378 * 1. Voice over PCM DAI - HIFI DAC over HIFI DAI
1379 * 2. Voice over HIFI DAI - HIFI disabled
1380 * 3. Voice disabled - HIFI over HIFI
1381 * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture
1405 { .name = "wm8753-hifi",
1423 { .name = "wm8753-voice",
1446 regcache_sync(wm8753->regmap); in wm8753_resume()
1456 INIT_DELAYED_WORK(&wm8753->charge_work, wm8753_charge_work); in wm8753_probe()
1460 dev_err(component->dev, "Failed to issue reset: %d\n", ret); in wm8753_probe()
1464 wm8753->dai_func = 0; in wm8753_probe()
1521 wm8753 = devm_kzalloc(&spi->dev, sizeof(struct wm8753_priv), in wm8753_spi_probe()
1524 return -ENOMEM; in wm8753_spi_probe()
1528 wm8753->regmap = devm_regmap_init_spi(spi, &wm8753_regmap); in wm8753_spi_probe()
1529 if (IS_ERR(wm8753->regmap)) { in wm8753_spi_probe()
1530 ret = PTR_ERR(wm8753->regmap); in wm8753_spi_probe()
1531 dev_err(&spi->dev, "Failed to allocate register map: %d\n", in wm8753_spi_probe()
1536 ret = devm_snd_soc_register_component(&spi->dev, &soc_component_dev_wm8753, in wm8753_spi_probe()
1539 dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret); in wm8753_spi_probe()
1559 wm8753 = devm_kzalloc(&i2c->dev, sizeof(struct wm8753_priv), in wm8753_i2c_probe()
1562 return -ENOMEM; in wm8753_i2c_probe()
1566 wm8753->regmap = devm_regmap_init_i2c(i2c, &wm8753_regmap); in wm8753_i2c_probe()
1567 if (IS_ERR(wm8753->regmap)) { in wm8753_i2c_probe()
1568 ret = PTR_ERR(wm8753->regmap); in wm8753_i2c_probe()
1569 dev_err(&i2c->dev, "Failed to allocate register map: %d\n", in wm8753_i2c_probe()
1574 ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_dev_wm8753, in wm8753_i2c_probe()
1577 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); in wm8753_i2c_probe()