Lines Matching +full:enable +full:- +full:charge +full:- +full:control
1 // SPDX-License-Identifier: GPL-2.0-only
3 * wm8961.c -- WM8961 ALSA SoC Audio driver
5 * Copyright 2009-10 Wolfson Microelectronics, plc
10 * - ALC
33 { 0, 0x009F }, /* R0 - Left Input volume */
34 { 1, 0x009F }, /* R1 - Right Input volume */
35 { 2, 0x0000 }, /* R2 - LOUT1 volume */
36 { 3, 0x0000 }, /* R3 - ROUT1 volume */
37 { 4, 0x0020 }, /* R4 - Clocking1 */
38 { 5, 0x0008 }, /* R5 - ADC & DAC Control 1 */
39 { 6, 0x0000 }, /* R6 - ADC & DAC Control 2 */
40 { 7, 0x000A }, /* R7 - Audio Interface 0 */
41 { 8, 0x01F4 }, /* R8 - Clocking2 */
42 { 9, 0x0000 }, /* R9 - Audio Interface 1 */
43 { 10, 0x00FF }, /* R10 - Left DAC volume */
44 { 11, 0x00FF }, /* R11 - Right DAC volume */
46 { 14, 0x0040 }, /* R14 - Audio Interface 2 */
48 { 17, 0x007B }, /* R17 - ALC1 */
49 { 18, 0x0000 }, /* R18 - ALC2 */
50 { 19, 0x0032 }, /* R19 - ALC3 */
51 { 20, 0x0000 }, /* R20 - Noise Gate */
52 { 21, 0x00C0 }, /* R21 - Left ADC volume */
53 { 22, 0x00C0 }, /* R22 - Right ADC volume */
54 { 23, 0x0120 }, /* R23 - Additional control(1) */
55 { 24, 0x0000 }, /* R24 - Additional control(2) */
56 { 25, 0x0000 }, /* R25 - Pwr Mgmt (1) */
57 { 26, 0x0000 }, /* R26 - Pwr Mgmt (2) */
58 { 27, 0x0000 }, /* R27 - Additional Control (3) */
59 { 28, 0x0000 }, /* R28 - Anti-pop */
61 { 30, 0x005F }, /* R30 - Clocking 3 */
63 { 32, 0x0000 }, /* R32 - ADCL signal path */
64 { 33, 0x0000 }, /* R33 - ADCR signal path */
66 { 40, 0x0000 }, /* R40 - LOUT2 volume */
67 { 41, 0x0000 }, /* R41 - ROUT2 volume */
69 { 47, 0x0000 }, /* R47 - Pwr Mgmt (3) */
70 { 48, 0x0023 }, /* R48 - Additional Control (4) */
71 { 49, 0x0000 }, /* R49 - Class D Control 1 */
73 { 51, 0x0003 }, /* R51 - Class D Control 2 */
75 { 56, 0x0106 }, /* R56 - Clocking 4 */
76 { 57, 0x0000 }, /* R57 - DSP Sidetone 0 */
77 { 58, 0x0000 }, /* R58 - DSP Sidetone 1 */
79 { 60, 0x0000 }, /* R60 - DC Servo 0 */
80 { 61, 0x0000 }, /* R61 - DC Servo 1 */
82 { 63, 0x015E }, /* R63 - DC Servo 3 */
84 { 65, 0x0010 }, /* R65 - DC Servo 5 */
86 { 68, 0x0003 }, /* R68 - Analogue PGA Bias */
87 { 69, 0x0000 }, /* R69 - Analogue HP 0 */
89 { 71, 0x01FB }, /* R71 - Analogue HP 2 */
90 { 72, 0x0000 }, /* R72 - Charge Pump 1 */
92 { 82, 0x0000 }, /* R82 - Charge Pump B */
94 { 87, 0x0000 }, /* R87 - Write Sequencer 1 */
95 { 88, 0x0000 }, /* R88 - Write Sequencer 2 */
96 { 89, 0x0000 }, /* R89 - Write Sequencer 3 */
97 { 90, 0x0000 }, /* R90 - Write Sequencer 4 */
98 { 91, 0x0000 }, /* R91 - Write Sequencer 5 */
99 { 92, 0x0000 }, /* R92 - Write Sequencer 6 */
100 { 93, 0x0000 }, /* R93 - Write Sequencer 7 */
102 { 252, 0x0001 }, /* R252 - General test 1 */
188 * The headphone output supports special anti-pop sequences giving
194 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wm8961_hp_event()
206 /* Enable the charge pump */ in wm8961_hp_event()
211 /* Enable the PGA */ in wm8961_hp_event()
215 /* Enable the amplifier */ in wm8961_hp_event()
219 /* Second stage enable */ in wm8961_hp_event()
223 /* Enable the DC servo & trigger startup */ in wm8961_hp_event()
227 dev_dbg(component->dev, "Enabling DC servo\n"); in wm8961_hp_event()
233 } while (--timeout && in wm8961_hp_event()
238 dev_err(component->dev, "DC servo timed out\n"); in wm8961_hp_event()
240 dev_dbg(component->dev, "DC servo startup complete\n"); in wm8961_hp_event()
242 /* Enable the output stage */ in wm8961_hp_event()
274 /* Disable the charge pump */ in wm8961_hp_event()
275 dev_dbg(component->dev, "Disabling charge pump\n"); in wm8961_hp_event()
286 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wm8961_spk_event()
291 /* Enable the PGA */ in wm8961_spk_event()
295 /* Enable the amplifier */ in wm8961_spk_event()
314 "Hi-fi", "Voice 1", "Voice 2", "Voice 3",
327 static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
328 static const DECLARE_TLV_DB_SCALE(hp_sec_tlv, -700, 100, 0);
329 static const DECLARE_TLV_DB_SCALE(adc_tlv, -7200, 75, 1);
330 static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0);
337 static const DECLARE_TLV_DB_SCALE(pga_tlv, -2325, 75, 0);
505 struct snd_soc_component *component = dai->component; in wm8961_hw_params()
512 if (!wm8961->sysclk) { in wm8961_hw_params()
513 dev_err(component->dev, "MCLK has not been specified\n"); in wm8961_hw_params()
514 return -EINVAL; in wm8961_hw_params()
520 if (abs(wm8961_srate[i].rate - fs) < in wm8961_hw_params()
521 abs(wm8961_srate[best].rate - fs)) in wm8961_hw_params()
528 dev_dbg(component->dev, "Selected SRATE %dHz for %dHz\n", in wm8961_hw_params()
532 target = wm8961->sysclk / fs; in wm8961_hw_params()
534 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && target < 64) { in wm8961_hw_params()
535 dev_err(component->dev, in wm8961_hw_params()
537 return -EINVAL; in wm8961_hw_params()
539 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE && target < 256) { in wm8961_hw_params()
540 dev_err(component->dev, in wm8961_hw_params()
542 return -EINVAL; in wm8961_hw_params()
550 dev_err(component->dev, "Unable to generate CLK_SYS_RATE\n"); in wm8961_hw_params()
551 return -EINVAL; in wm8961_hw_params()
553 dev_dbg(component->dev, "Selected CLK_SYS_RATE of %d for %d/%d=%d\n", in wm8961_hw_params()
554 wm8961_clk_sys_ratio[i].ratio, wm8961->sysclk, fs, in wm8961_hw_params()
555 wm8961->sysclk / fs); in wm8961_hw_params()
577 return -EINVAL; in wm8961_hw_params()
581 /* Sloping stop-band filter is recommended for <= 24kHz */ in wm8961_hw_params()
596 struct snd_soc_component *component = dai->component; in wm8961_set_sysclk()
601 dev_err(component->dev, "MCLK must be <33MHz\n"); in wm8961_set_sysclk()
602 return -EINVAL; in wm8961_set_sysclk()
606 dev_dbg(component->dev, "Using MCLK/2 for %dHz MCLK\n", freq); in wm8961_set_sysclk()
610 dev_dbg(component->dev, "Using MCLK/1 for %dHz MCLK\n", freq); in wm8961_set_sysclk()
616 wm8961->sysclk = freq; in wm8961_set_sysclk()
623 struct snd_soc_component *component = dai->component; in wm8961_set_fmt()
636 return -EINVAL; in wm8961_set_fmt()
661 return -EINVAL; in wm8961_set_fmt()
666 return -EINVAL; in wm8961_set_fmt()
682 return -EINVAL; in wm8961_set_fmt()
690 struct snd_soc_component *component = dai->component; in wm8961_set_tristate()
703 struct snd_soc_component *component = dai->component; in wm8961_mute()
718 struct snd_soc_component *component = dai->component; in wm8961_set_clkdiv()
737 return -EINVAL; in wm8961_set_clkdiv()
759 /* Enable bias generation */ in wm8961_set_bias_level()
816 .name = "wm8961-hifi",
836 /* Enable class W */ in wm8961_probe()
919 wm8961 = devm_kzalloc(&i2c->dev, sizeof(struct wm8961_priv), in wm8961_i2c_probe()
922 return -ENOMEM; in wm8961_i2c_probe()
924 wm8961->regmap = devm_regmap_init_i2c(i2c, &wm8961_regmap); in wm8961_i2c_probe()
925 if (IS_ERR(wm8961->regmap)) in wm8961_i2c_probe()
926 return PTR_ERR(wm8961->regmap); in wm8961_i2c_probe()
928 ret = regmap_read(wm8961->regmap, WM8961_SOFTWARE_RESET, &val); in wm8961_i2c_probe()
930 dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); in wm8961_i2c_probe()
935 dev_err(&i2c->dev, "Device is not a WM8961: ID=0x%x\n", val); in wm8961_i2c_probe()
936 return -EINVAL; in wm8961_i2c_probe()
939 /* This isn't volatile - readback doesn't correspond to write */ in wm8961_i2c_probe()
940 regcache_cache_bypass(wm8961->regmap, true); in wm8961_i2c_probe()
941 ret = regmap_read(wm8961->regmap, WM8961_RIGHT_INPUT_VOLUME, &val); in wm8961_i2c_probe()
942 regcache_cache_bypass(wm8961->regmap, false); in wm8961_i2c_probe()
945 dev_err(&i2c->dev, "Failed to read chip revision: %d\n", ret); in wm8961_i2c_probe()
949 dev_info(&i2c->dev, "WM8961 family %d revision %c\n", in wm8961_i2c_probe()
954 ret = regmap_write(wm8961->regmap, WM8961_SOFTWARE_RESET, 0x1801); in wm8961_i2c_probe()
956 dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret); in wm8961_i2c_probe()
962 ret = devm_snd_soc_register_component(&i2c->dev, in wm8961_i2c_probe()