Lines Matching +full:codec +full:- +full:aif3 +full:- +full:lrclk
1 // SPDX-License-Identifier: GPL-2.0-only
3 * wm9081.c -- WM9081 ALSA SoC Audio driver
7 * Copyright 2009-12 Wolfson Microelectronics plc
30 { 2, 0x00B9 }, /* R2 - Analogue Lineout */
31 { 3, 0x00B9 }, /* R3 - Analogue Speaker PGA */
32 { 4, 0x0001 }, /* R4 - VMID Control */
33 { 5, 0x0068 }, /* R5 - Bias Control 1 */
34 { 7, 0x0000 }, /* R7 - Analogue Mixer */
35 { 8, 0x0000 }, /* R8 - Anti Pop Control */
36 { 9, 0x01DB }, /* R9 - Analogue Speaker 1 */
37 { 10, 0x0018 }, /* R10 - Analogue Speaker 2 */
38 { 11, 0x0180 }, /* R11 - Power Management */
39 { 12, 0x0000 }, /* R12 - Clock Control 1 */
40 { 13, 0x0038 }, /* R13 - Clock Control 2 */
41 { 14, 0x4000 }, /* R14 - Clock Control 3 */
42 { 16, 0x0000 }, /* R16 - FLL Control 1 */
43 { 17, 0x0200 }, /* R17 - FLL Control 2 */
44 { 18, 0x0000 }, /* R18 - FLL Control 3 */
45 { 19, 0x0204 }, /* R19 - FLL Control 4 */
46 { 20, 0x0000 }, /* R20 - FLL Control 5 */
47 { 22, 0x0000 }, /* R22 - Audio Interface 1 */
48 { 23, 0x0002 }, /* R23 - Audio Interface 2 */
49 { 24, 0x0008 }, /* R24 - Audio Interface 3 */
50 { 25, 0x0022 }, /* R25 - Audio Interface 4 */
51 { 27, 0x0006 }, /* R27 - Interrupt Status Mask */
52 { 28, 0x0000 }, /* R28 - Interrupt Polarity */
53 { 29, 0x0000 }, /* R29 - Interrupt Control */
54 { 30, 0x00C0 }, /* R30 - DAC Digital 1 */
55 { 31, 0x0008 }, /* R31 - DAC Digital 2 */
56 { 32, 0x09AF }, /* R32 - DRC 1 */
57 { 33, 0x4201 }, /* R33 - DRC 2 */
58 { 34, 0x0000 }, /* R34 - DRC 3 */
59 { 35, 0x0000 }, /* R35 - DRC 4 */
60 { 38, 0x0000 }, /* R38 - Write Sequencer 1 */
61 { 39, 0x0000 }, /* R39 - Write Sequencer 2 */
62 { 40, 0x0002 }, /* R40 - MW Slave 1 */
63 { 42, 0x0000 }, /* R42 - EQ 1 */
64 { 43, 0x0000 }, /* R43 - EQ 2 */
65 { 44, 0x0FCA }, /* R44 - EQ 3 */
66 { 45, 0x0400 }, /* R45 - EQ 4 */
67 { 46, 0x00B8 }, /* R46 - EQ 5 */
68 { 47, 0x1EB5 }, /* R47 - EQ 6 */
69 { 48, 0xF145 }, /* R48 - EQ 7 */
70 { 49, 0x0B75 }, /* R49 - EQ 8 */
71 { 50, 0x01C5 }, /* R50 - EQ 9 */
72 { 51, 0x169E }, /* R51 - EQ 10 */
73 { 52, 0xF829 }, /* R52 - EQ 11 */
74 { 53, 0x07AD }, /* R53 - EQ 12 */
75 { 54, 0x1103 }, /* R54 - EQ 13 */
76 { 55, 0x1C58 }, /* R55 - EQ 14 */
77 { 56, 0xF373 }, /* R56 - EQ 15 */
78 { 57, 0x0A54 }, /* R57 - EQ 16 */
79 { 58, 0x0558 }, /* R58 - EQ 17 */
80 { 59, 0x0564 }, /* R59 - EQ 18 */
81 { 60, 0x0559 }, /* R60 - EQ 19 */
82 { 61, 0x4000 }, /* R61 - EQ 20 */
239 static const DECLARE_TLV_DB_SCALE(drc_in_tlv, -4500, 75, 0);
240 static const DECLARE_TLV_DB_SCALE(drc_out_tlv, -2250, 75, 0);
241 static const DECLARE_TLV_DB_SCALE(drc_min_tlv, -1800, 600, 0);
249 static const DECLARE_TLV_DB_SCALE(drc_startup_tlv, -300, 50, 0);
251 static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
253 static const DECLARE_TLV_DB_SCALE(in_tlv, -600, 600, 0);
254 static const DECLARE_TLV_DB_SCALE(dac_tlv, -7200, 75, 1);
255 static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
343 ucontrol->value.enumerated.item[0] = 1; in speaker_mode_get()
345 ucontrol->value.enumerated.item[0] = 0; in speaker_mode_get()
353 * We also have some special anti-pop controls dependent on speaker
364 if (ucontrol->value.enumerated.item[0] == in speaker_mode_put()
370 return -EINVAL; in speaker_mode_put()
372 if (ucontrol->value.enumerated.item[0]) { in speaker_mode_put()
478 return -EINVAL; in fll_factors()
481 fll_div->fll_clk_ref_div = div / 2; in fll_factors()
488 /* Fvco should be 90-100MHz; don't check the upper bound */ in fll_factors()
497 return -EINVAL; in fll_factors()
500 fll_div->fll_outdiv = div; in fll_factors()
507 fll_div->fll_fratio = fll_fratios[i].fll_fratio; in fll_factors()
514 return -EINVAL; in fll_factors()
520 fll_div->n = Ndiv; in fll_factors()
524 /* Calculate fractional part - scale up so we can round. */ in fll_factors()
535 fll_div->k = K / 10; in fll_factors()
538 fll_div->n, fll_div->k, in fll_factors()
539 fll_div->fll_fratio, fll_div->fll_outdiv, in fll_factors()
540 fll_div->fll_clk_ref_div); in fll_factors()
555 if (Fref == wm9081->fll_fref && Fout == wm9081->fll_fout) in wm9081_set_fll()
560 dev_dbg(component->dev, "FLL disabled\n"); in wm9081_set_fll()
561 wm9081->fll_fref = 0; in wm9081_set_fll()
562 wm9081->fll_fout = 0; in wm9081_set_fll()
580 dev_err(component->dev, "Unknown FLL ID %d\n", fll_id); in wm9081_set_fll()
581 return -EINVAL; in wm9081_set_fll()
628 dev_dbg(component->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout); in wm9081_set_fll()
630 wm9081->fll_fref = Fref; in wm9081_set_fll()
631 wm9081->fll_fout = Fout; in wm9081_set_fll()
645 switch (wm9081->sysclk_source) { in configure_clock()
647 if (wm9081->mclk_rate > 12225000) { in configure_clock()
649 wm9081->sysclk_rate = wm9081->mclk_rate / 2; in configure_clock()
651 wm9081->sysclk_rate = wm9081->mclk_rate; in configure_clock()
664 if (wm9081->master && wm9081->bclk) { in configure_clock()
669 target = wm9081->fs * clk_sys_rates[i].ratio; in configure_clock()
671 if (target >= wm9081->bclk && in configure_clock()
677 return -EINVAL; in configure_clock()
679 } else if (wm9081->fs) { in configure_clock()
682 * wm9081->fs; in configure_clock()
688 return -EINVAL; in configure_clock()
695 wm9081->mclk_rate, new_sysclk); in configure_clock()
697 wm9081->sysclk_rate = new_sysclk; in configure_clock()
702 wm9081->sysclk_rate = wm9081->mclk_rate; in configure_clock()
707 return -EINVAL; in configure_clock()
724 dev_dbg(component->dev, "CLK_SYS is %dHz\n", wm9081->sysclk_rate); in configure_clock()
732 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in clk_sys_event()
736 switch (wm9081->sysclk_source) { in clk_sys_event()
738 dev_dbg(component->dev, "Using %dHz MCLK\n", wm9081->mclk_rate); in clk_sys_event()
741 dev_dbg(component->dev, "Using %dHz MCLK with FLL\n", in clk_sys_event()
742 wm9081->mclk_rate); in clk_sys_event()
745 dev_err(component->dev, "System clock not configured\n"); in clk_sys_event()
746 return -EINVAL; in clk_sys_event()
837 regcache_cache_only(wm9081->regmap, false); in wm9081_set_bias_level()
838 regcache_sync(wm9081->regmap); in wm9081_set_bias_level()
892 regcache_cache_only(wm9081->regmap, true); in wm9081_set_bias_level()
902 struct snd_soc_component *component = dai->component; in wm9081_set_dai_fmt()
911 wm9081->master = 0; in wm9081_set_dai_fmt()
915 wm9081->master = 1; in wm9081_set_dai_fmt()
919 wm9081->master = 1; in wm9081_set_dai_fmt()
923 wm9081->master = 1; in wm9081_set_dai_fmt()
926 return -EINVAL; in wm9081_set_dai_fmt()
945 return -EINVAL; in wm9081_set_dai_fmt()
959 return -EINVAL; in wm9081_set_dai_fmt()
979 return -EINVAL; in wm9081_set_dai_fmt()
983 return -EINVAL; in wm9081_set_dai_fmt()
995 struct snd_soc_component *component = dai->component; in wm9081_hw_params()
998 unsigned int clk_ctrl2, aif1, aif2, aif3, aif4; in wm9081_hw_params() local
1008 aif3 = snd_soc_component_read(component, WM9081_AUDIO_INTERFACE_3); in wm9081_hw_params()
1009 aif3 &= ~WM9081_BCLK_DIV_MASK; in wm9081_hw_params()
1014 wm9081->fs = params_rate(params); in wm9081_hw_params()
1016 if (wm9081->tdm_width) { in wm9081_hw_params()
1021 wm9081->bclk = wm9081->fs * wm9081->tdm_width * slots; in wm9081_hw_params()
1024 wm9081->bclk = 2 * wm9081->fs; in wm9081_hw_params()
1028 wm9081->bclk *= 16; in wm9081_hw_params()
1031 wm9081->bclk *= 20; in wm9081_hw_params()
1035 wm9081->bclk *= 24; in wm9081_hw_params()
1039 wm9081->bclk *= 32; in wm9081_hw_params()
1043 return -EINVAL; in wm9081_hw_params()
1047 dev_dbg(component->dev, "Target BCLK is %dHz\n", wm9081->bclk); in wm9081_hw_params()
1055 best_val = abs((wm9081->sysclk_rate / clk_sys_rates[0].ratio) in wm9081_hw_params()
1056 - wm9081->fs); in wm9081_hw_params()
1058 cur_val = abs((wm9081->sysclk_rate / in wm9081_hw_params()
1059 clk_sys_rates[i].ratio) - wm9081->fs); in wm9081_hw_params()
1065 dev_dbg(component->dev, "Selected CLK_SYS_RATIO of %d\n", in wm9081_hw_params()
1072 best_val = abs(wm9081->fs - sample_rates[0].rate); in wm9081_hw_params()
1075 cur_val = abs(wm9081->fs - sample_rates[i].rate); in wm9081_hw_params()
1081 dev_dbg(component->dev, "Selected SAMPLE_RATE of %dHz\n", in wm9081_hw_params()
1090 cur_val = ((wm9081->sysclk_rate * 10) / bclk_divs[i].div) in wm9081_hw_params()
1091 - wm9081->bclk; in wm9081_hw_params()
1099 wm9081->bclk = (wm9081->sysclk_rate * 10) / bclk_divs[best].div; in wm9081_hw_params()
1100 dev_dbg(component->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n", in wm9081_hw_params()
1101 bclk_divs[best].div, wm9081->bclk); in wm9081_hw_params()
1102 aif3 |= bclk_divs[best].bclk_div; in wm9081_hw_params()
1104 /* LRCLK is a simple fraction of BCLK */ in wm9081_hw_params()
1105 dev_dbg(component->dev, "LRCLK_RATE is %d\n", wm9081->bclk / wm9081->fs); in wm9081_hw_params()
1106 aif4 |= wm9081->bclk / wm9081->fs; in wm9081_hw_params()
1109 if (wm9081->pdata.num_retune_configs) { in wm9081_hw_params()
1110 struct wm9081_pdata *pdata = &wm9081->pdata; in wm9081_hw_params()
1115 best_val = abs(pdata->retune_configs[0].rate - wm9081->fs); in wm9081_hw_params()
1116 for (i = 0; i < pdata->num_retune_configs; i++) { in wm9081_hw_params()
1117 cur_val = abs(pdata->retune_configs[i].rate - in wm9081_hw_params()
1118 wm9081->fs); in wm9081_hw_params()
1124 s = &pdata->retune_configs[best]; in wm9081_hw_params()
1126 dev_dbg(component->dev, "ReTune Mobile %s tuned for %dHz\n", in wm9081_hw_params()
1127 s->name, s->rate); in wm9081_hw_params()
1135 for (i = 1; i < ARRAY_SIZE(s->config); i++) in wm9081_hw_params()
1136 snd_soc_component_write(component, WM9081_EQ_1 + i, s->config[i]); in wm9081_hw_params()
1138 eq1 |= (s->config[0] & ~WM9081_EQ_ENA); in wm9081_hw_params()
1144 snd_soc_component_write(component, WM9081_AUDIO_INTERFACE_3, aif3); in wm9081_hw_params()
1152 struct snd_soc_component *component = codec_dai->component; in wm9081_mute()
1175 wm9081->sysclk_source = clk_id; in wm9081_set_sysclk()
1176 wm9081->mclk_rate = freq; in wm9081_set_sysclk()
1180 return -EINVAL; in wm9081_set_sysclk()
1189 struct snd_soc_component *component = dai->component; in wm9081_set_tdm_slot()
1196 return -EINVAL; in wm9081_set_tdm_slot()
1198 wm9081->tdm_width = slot_width; in wm9081_set_tdm_slot()
1203 aif1 |= (slots - 1) << WM9081_AIFDAC_TDM_MODE_SHIFT; in wm9081_set_tdm_slot()
1218 return -EINVAL; in wm9081_set_tdm_slot()
1240 /* We report two channels because the CODEC processes a stereo signal, even
1244 .name = "wm9081-hifi",
1265 if (!wm9081->pdata.num_retune_configs) { in wm9081_probe()
1266 dev_dbg(component->dev, in wm9081_probe()
1307 wm9081 = devm_kzalloc(&i2c->dev, sizeof(struct wm9081_priv), in wm9081_i2c_probe()
1310 return -ENOMEM; in wm9081_i2c_probe()
1314 wm9081->regmap = devm_regmap_init_i2c(i2c, &wm9081_regmap); in wm9081_i2c_probe()
1315 if (IS_ERR(wm9081->regmap)) { in wm9081_i2c_probe()
1316 ret = PTR_ERR(wm9081->regmap); in wm9081_i2c_probe()
1317 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); in wm9081_i2c_probe()
1321 ret = regmap_read(wm9081->regmap, WM9081_SOFTWARE_RESET, ®); in wm9081_i2c_probe()
1323 dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); in wm9081_i2c_probe()
1327 dev_err(&i2c->dev, "Device is not a WM9081: ID=0x%x\n", reg); in wm9081_i2c_probe()
1328 return -EINVAL; in wm9081_i2c_probe()
1331 ret = wm9081_reset(wm9081->regmap); in wm9081_i2c_probe()
1333 dev_err(&i2c->dev, "Failed to issue reset\n"); in wm9081_i2c_probe()
1337 if (dev_get_platdata(&i2c->dev)) in wm9081_i2c_probe()
1338 memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev), in wm9081_i2c_probe()
1339 sizeof(wm9081->pdata)); in wm9081_i2c_probe()
1342 if (wm9081->pdata.irq_high) in wm9081_i2c_probe()
1344 if (!wm9081->pdata.irq_cmos) in wm9081_i2c_probe()
1346 regmap_update_bits(wm9081->regmap, WM9081_INTERRUPT_CONTROL, in wm9081_i2c_probe()
1349 regcache_cache_only(wm9081->regmap, true); in wm9081_i2c_probe()
1351 ret = devm_snd_soc_register_component(&i2c->dev, in wm9081_i2c_probe()