1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
3 // Copyright (c) 2017-2018, Linaro Limited
4
5 #include <linux/module.h>
6 #include <linux/init.h>
7 #include <linux/platform_device.h>
8 #include <linux/cleanup.h>
9 #include <linux/device.h>
10 #include <linux/wait.h>
11 #include <linux/bitops.h>
12 #include <linux/regulator/consumer.h>
13 #include <linux/clk.h>
14 #include <linux/delay.h>
15 #include <linux/kernel.h>
16 #include <linux/slimbus.h>
17 #include <sound/soc.h>
18 #include <sound/pcm_params.h>
19 #include <sound/soc-dapm.h>
20 #include <linux/of_gpio.h>
21 #include <linux/of.h>
22 #include <linux/of_irq.h>
23 #include <sound/tlv.h>
24 #include <sound/info.h>
25 #include "wcd9335.h"
26 #include "wcd-clsh-v2.h"
27
28 #include <dt-bindings/sound/qcom,wcd9335.h>
29
30 #define WCD9335_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
31 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
32 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
33 /* Fractional Rates */
34 #define WCD9335_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100)
35 #define WCD9335_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \
36 SNDRV_PCM_FMTBIT_S24_LE)
37
38 /* slave port water mark level
39 * (0: 6bytes, 1: 9bytes, 2: 12 bytes, 3: 15 bytes)
40 */
41 #define SLAVE_PORT_WATER_MARK_6BYTES 0
42 #define SLAVE_PORT_WATER_MARK_9BYTES 1
43 #define SLAVE_PORT_WATER_MARK_12BYTES 2
44 #define SLAVE_PORT_WATER_MARK_15BYTES 3
45 #define SLAVE_PORT_WATER_MARK_SHIFT 1
46 #define SLAVE_PORT_ENABLE 1
47 #define SLAVE_PORT_DISABLE 0
48 #define WCD9335_SLIM_WATER_MARK_VAL \
49 ((SLAVE_PORT_WATER_MARK_12BYTES << SLAVE_PORT_WATER_MARK_SHIFT) | \
50 (SLAVE_PORT_ENABLE))
51
52 #define WCD9335_SLIM_NUM_PORT_REG 3
53 #define WCD9335_SLIM_PGD_PORT_INT_TX_EN0 (WCD9335_SLIM_PGD_PORT_INT_EN0 + 2)
54
55 #define WCD9335_MCLK_CLK_12P288MHZ 12288000
56 #define WCD9335_MCLK_CLK_9P6MHZ 9600000
57
58 #define WCD9335_SLIM_CLOSE_TIMEOUT 1000
59 #define WCD9335_SLIM_IRQ_OVERFLOW (1 << 0)
60 #define WCD9335_SLIM_IRQ_UNDERFLOW (1 << 1)
61 #define WCD9335_SLIM_IRQ_PORT_CLOSED (1 << 2)
62
63 #define WCD9335_NUM_INTERPOLATORS 9
64 #define WCD9335_RX_START 16
65 #define WCD9335_SLIM_CH_START 128
66 #define WCD9335_MAX_MICBIAS 4
67 #define WCD9335_MAX_VALID_ADC_MUX 13
68 #define WCD9335_INVALID_ADC_MUX 9
69
70 #define TX_HPF_CUT_OFF_FREQ_MASK 0x60
71 #define CF_MIN_3DB_4HZ 0x0
72 #define CF_MIN_3DB_75HZ 0x1
73 #define CF_MIN_3DB_150HZ 0x2
74 #define WCD9335_DMIC_CLK_DIV_2 0x0
75 #define WCD9335_DMIC_CLK_DIV_3 0x1
76 #define WCD9335_DMIC_CLK_DIV_4 0x2
77 #define WCD9335_DMIC_CLK_DIV_6 0x3
78 #define WCD9335_DMIC_CLK_DIV_8 0x4
79 #define WCD9335_DMIC_CLK_DIV_16 0x5
80 #define WCD9335_DMIC_CLK_DRIVE_DEFAULT 0x02
81 #define WCD9335_AMIC_PWR_LEVEL_LP 0
82 #define WCD9335_AMIC_PWR_LEVEL_DEFAULT 1
83 #define WCD9335_AMIC_PWR_LEVEL_HP 2
84 #define WCD9335_AMIC_PWR_LVL_MASK 0x60
85 #define WCD9335_AMIC_PWR_LVL_SHIFT 0x5
86
87 #define WCD9335_DEC_PWR_LVL_MASK 0x06
88 #define WCD9335_DEC_PWR_LVL_LP 0x02
89 #define WCD9335_DEC_PWR_LVL_HP 0x04
90 #define WCD9335_DEC_PWR_LVL_DF 0x00
91
92 #define WCD9335_SLIM_RX_CH(p) \
93 {.port = p + WCD9335_RX_START, .shift = p,}
94
95 #define WCD9335_SLIM_TX_CH(p) \
96 {.port = p, .shift = p,}
97
98 /* vout step value */
99 #define WCD9335_CALCULATE_VOUT_D(req_mv) (((req_mv - 650) * 10) / 25)
100
101 #define WCD9335_INTERPOLATOR_PATH(id) \
102 {"RX INT" #id "_1 MIX1 INP0", "RX0", "SLIM RX0"}, \
103 {"RX INT" #id "_1 MIX1 INP0", "RX1", "SLIM RX1"}, \
104 {"RX INT" #id "_1 MIX1 INP0", "RX2", "SLIM RX2"}, \
105 {"RX INT" #id "_1 MIX1 INP0", "RX3", "SLIM RX3"}, \
106 {"RX INT" #id "_1 MIX1 INP0", "RX4", "SLIM RX4"}, \
107 {"RX INT" #id "_1 MIX1 INP0", "RX5", "SLIM RX5"}, \
108 {"RX INT" #id "_1 MIX1 INP0", "RX6", "SLIM RX6"}, \
109 {"RX INT" #id "_1 MIX1 INP0", "RX7", "SLIM RX7"}, \
110 {"RX INT" #id "_1 MIX1 INP1", "RX0", "SLIM RX0"}, \
111 {"RX INT" #id "_1 MIX1 INP1", "RX1", "SLIM RX1"}, \
112 {"RX INT" #id "_1 MIX1 INP1", "RX2", "SLIM RX2"}, \
113 {"RX INT" #id "_1 MIX1 INP1", "RX3", "SLIM RX3"}, \
114 {"RX INT" #id "_1 MIX1 INP1", "RX4", "SLIM RX4"}, \
115 {"RX INT" #id "_1 MIX1 INP1", "RX5", "SLIM RX5"}, \
116 {"RX INT" #id "_1 MIX1 INP1", "RX6", "SLIM RX6"}, \
117 {"RX INT" #id "_1 MIX1 INP1", "RX7", "SLIM RX7"}, \
118 {"RX INT" #id "_1 MIX1 INP2", "RX0", "SLIM RX0"}, \
119 {"RX INT" #id "_1 MIX1 INP2", "RX1", "SLIM RX1"}, \
120 {"RX INT" #id "_1 MIX1 INP2", "RX2", "SLIM RX2"}, \
121 {"RX INT" #id "_1 MIX1 INP2", "RX3", "SLIM RX3"}, \
122 {"RX INT" #id "_1 MIX1 INP2", "RX4", "SLIM RX4"}, \
123 {"RX INT" #id "_1 MIX1 INP2", "RX5", "SLIM RX5"}, \
124 {"RX INT" #id "_1 MIX1 INP2", "RX6", "SLIM RX6"}, \
125 {"RX INT" #id "_1 MIX1 INP2", "RX7", "SLIM RX7"}, \
126 {"RX INT" #id "_2 MUX", "RX0", "SLIM RX0"}, \
127 {"RX INT" #id "_2 MUX", "RX1", "SLIM RX1"}, \
128 {"RX INT" #id "_2 MUX", "RX2", "SLIM RX2"}, \
129 {"RX INT" #id "_2 MUX", "RX3", "SLIM RX3"}, \
130 {"RX INT" #id "_2 MUX", "RX4", "SLIM RX4"}, \
131 {"RX INT" #id "_2 MUX", "RX5", "SLIM RX5"}, \
132 {"RX INT" #id "_2 MUX", "RX6", "SLIM RX6"}, \
133 {"RX INT" #id "_2 MUX", "RX7", "SLIM RX7"}, \
134 {"RX INT" #id "_1 MIX1", NULL, "RX INT" #id "_1 MIX1 INP0"}, \
135 {"RX INT" #id "_1 MIX1", NULL, "RX INT" #id "_1 MIX1 INP1"}, \
136 {"RX INT" #id "_1 MIX1", NULL, "RX INT" #id "_1 MIX1 INP2"}, \
137 {"RX INT" #id " SEC MIX", NULL, "RX INT" #id "_2 MUX"}, \
138 {"RX INT" #id " SEC MIX", NULL, "RX INT" #id "_1 MIX1"}, \
139 {"RX INT" #id " MIX2", NULL, "RX INT" #id " SEC MIX"}, \
140 {"RX INT" #id " INTERP", NULL, "RX INT" #id " MIX2"}
141
142 #define WCD9335_ADC_MUX_PATH(id) \
143 {"AIF1_CAP Mixer", "SLIM TX" #id, "SLIM TX" #id " MUX"}, \
144 {"AIF2_CAP Mixer", "SLIM TX" #id, "SLIM TX" #id " MUX"}, \
145 {"AIF3_CAP Mixer", "SLIM TX" #id, "SLIM TX" #id " MUX"}, \
146 {"SLIM TX" #id " MUX", "DEC" #id, "ADC MUX" #id}, \
147 {"ADC MUX" #id, "DMIC", "DMIC MUX" #id}, \
148 {"ADC MUX" #id, "AMIC", "AMIC MUX" #id}, \
149 {"DMIC MUX" #id, "DMIC0", "DMIC0"}, \
150 {"DMIC MUX" #id, "DMIC1", "DMIC1"}, \
151 {"DMIC MUX" #id, "DMIC2", "DMIC2"}, \
152 {"DMIC MUX" #id, "DMIC3", "DMIC3"}, \
153 {"DMIC MUX" #id, "DMIC4", "DMIC4"}, \
154 {"DMIC MUX" #id, "DMIC5", "DMIC5"}, \
155 {"AMIC MUX" #id, "ADC1", "ADC1"}, \
156 {"AMIC MUX" #id, "ADC2", "ADC2"}, \
157 {"AMIC MUX" #id, "ADC3", "ADC3"}, \
158 {"AMIC MUX" #id, "ADC4", "ADC4"}, \
159 {"AMIC MUX" #id, "ADC5", "ADC5"}, \
160 {"AMIC MUX" #id, "ADC6", "ADC6"}
161
162 enum {
163 WCD9335_RX0 = 0,
164 WCD9335_RX1,
165 WCD9335_RX2,
166 WCD9335_RX3,
167 WCD9335_RX4,
168 WCD9335_RX5,
169 WCD9335_RX6,
170 WCD9335_RX7,
171 WCD9335_RX8,
172 WCD9335_RX9,
173 WCD9335_RX10,
174 WCD9335_RX11,
175 WCD9335_RX12,
176 WCD9335_RX_MAX,
177 };
178
179 enum {
180 WCD9335_TX0 = 0,
181 WCD9335_TX1,
182 WCD9335_TX2,
183 WCD9335_TX3,
184 WCD9335_TX4,
185 WCD9335_TX5,
186 WCD9335_TX6,
187 WCD9335_TX7,
188 WCD9335_TX8,
189 WCD9335_TX9,
190 WCD9335_TX10,
191 WCD9335_TX11,
192 WCD9335_TX12,
193 WCD9335_TX13,
194 WCD9335_TX14,
195 WCD9335_TX15,
196 WCD9335_TX_MAX,
197 };
198
199 enum {
200 SIDO_SOURCE_INTERNAL = 0,
201 SIDO_SOURCE_RCO_BG,
202 };
203
204 enum wcd9335_sido_voltage {
205 SIDO_VOLTAGE_SVS_MV = 950,
206 SIDO_VOLTAGE_NOMINAL_MV = 1100,
207 };
208
209 enum {
210 COMPANDER_1, /* HPH_L */
211 COMPANDER_2, /* HPH_R */
212 COMPANDER_3, /* LO1_DIFF */
213 COMPANDER_4, /* LO2_DIFF */
214 COMPANDER_5, /* LO3_SE */
215 COMPANDER_6, /* LO4_SE */
216 COMPANDER_7, /* SWR SPK CH1 */
217 COMPANDER_8, /* SWR SPK CH2 */
218 COMPANDER_MAX,
219 };
220
221 enum {
222 INTn_2_INP_SEL_ZERO = 0,
223 INTn_2_INP_SEL_RX0,
224 INTn_2_INP_SEL_RX1,
225 INTn_2_INP_SEL_RX2,
226 INTn_2_INP_SEL_RX3,
227 INTn_2_INP_SEL_RX4,
228 INTn_2_INP_SEL_RX5,
229 INTn_2_INP_SEL_RX6,
230 INTn_2_INP_SEL_RX7,
231 INTn_2_INP_SEL_PROXIMITY,
232 };
233
234 enum {
235 INTn_1_MIX_INP_SEL_ZERO = 0,
236 INTn_1_MIX_INP_SEL_DEC0,
237 INTn_1_MIX_INP_SEL_DEC1,
238 INTn_1_MIX_INP_SEL_IIR0,
239 INTn_1_MIX_INP_SEL_IIR1,
240 INTn_1_MIX_INP_SEL_RX0,
241 INTn_1_MIX_INP_SEL_RX1,
242 INTn_1_MIX_INP_SEL_RX2,
243 INTn_1_MIX_INP_SEL_RX3,
244 INTn_1_MIX_INP_SEL_RX4,
245 INTn_1_MIX_INP_SEL_RX5,
246 INTn_1_MIX_INP_SEL_RX6,
247 INTn_1_MIX_INP_SEL_RX7,
248
249 };
250
251 enum {
252 INTERP_EAR = 0,
253 INTERP_HPHL,
254 INTERP_HPHR,
255 INTERP_LO1,
256 INTERP_LO2,
257 INTERP_LO3,
258 INTERP_LO4,
259 INTERP_SPKR1,
260 INTERP_SPKR2,
261 };
262
263 enum wcd_clock_type {
264 WCD_CLK_OFF,
265 WCD_CLK_RCO,
266 WCD_CLK_MCLK,
267 };
268
269 enum {
270 MIC_BIAS_1 = 1,
271 MIC_BIAS_2,
272 MIC_BIAS_3,
273 MIC_BIAS_4
274 };
275
276 enum {
277 MICB_PULLUP_ENABLE,
278 MICB_PULLUP_DISABLE,
279 MICB_ENABLE,
280 MICB_DISABLE,
281 };
282
283 struct wcd9335_slim_ch {
284 u32 ch_num;
285 u16 port;
286 u16 shift;
287 struct list_head list;
288 };
289
290 struct wcd_slim_codec_dai_data {
291 struct list_head slim_ch_list;
292 struct slim_stream_config sconfig;
293 struct slim_stream_runtime *sruntime;
294 };
295
296 struct wcd9335_codec {
297 struct device *dev;
298 struct clk *mclk;
299 struct clk *native_clk;
300 u32 mclk_rate;
301
302 struct slim_device *slim;
303 struct slim_device *slim_ifc_dev;
304 struct regmap *regmap;
305 struct regmap *if_regmap;
306 struct regmap_irq_chip_data *irq_data;
307
308 struct wcd9335_slim_ch rx_chs[WCD9335_RX_MAX];
309 struct wcd9335_slim_ch tx_chs[WCD9335_TX_MAX];
310 u32 num_rx_port;
311 u32 num_tx_port;
312
313 int sido_input_src;
314 enum wcd9335_sido_voltage sido_voltage;
315
316 struct wcd_slim_codec_dai_data dai[NUM_CODEC_DAIS];
317 struct snd_soc_component *component;
318
319 int master_bias_users;
320 int clk_mclk_users;
321 int clk_rco_users;
322 int sido_ccl_cnt;
323 enum wcd_clock_type clk_type;
324
325 struct wcd_clsh_ctrl *clsh_ctrl;
326 u32 hph_mode;
327 int prim_int_users[WCD9335_NUM_INTERPOLATORS];
328
329 int comp_enabled[COMPANDER_MAX];
330
331 int intr1;
332 int reset_gpio;
333 struct regulator_bulk_data supplies[WCD9335_MAX_SUPPLY];
334
335 unsigned int rx_port_value[WCD9335_RX_MAX];
336 unsigned int tx_port_value[WCD9335_TX_MAX];
337 int hph_l_gain;
338 int hph_r_gain;
339 u32 rx_bias_count;
340
341 /*TX*/
342 int micb_ref[WCD9335_MAX_MICBIAS];
343 int pullup_ref[WCD9335_MAX_MICBIAS];
344
345 int dmic_0_1_clk_cnt;
346 int dmic_2_3_clk_cnt;
347 int dmic_4_5_clk_cnt;
348 };
349
350 struct wcd9335_irq {
351 int irq;
352 irqreturn_t (*handler)(int irq, void *data);
353 char *name;
354 };
355
356 static const struct wcd9335_slim_ch wcd9335_tx_chs[WCD9335_TX_MAX] = {
357 WCD9335_SLIM_TX_CH(0),
358 WCD9335_SLIM_TX_CH(1),
359 WCD9335_SLIM_TX_CH(2),
360 WCD9335_SLIM_TX_CH(3),
361 WCD9335_SLIM_TX_CH(4),
362 WCD9335_SLIM_TX_CH(5),
363 WCD9335_SLIM_TX_CH(6),
364 WCD9335_SLIM_TX_CH(7),
365 WCD9335_SLIM_TX_CH(8),
366 WCD9335_SLIM_TX_CH(9),
367 WCD9335_SLIM_TX_CH(10),
368 WCD9335_SLIM_TX_CH(11),
369 WCD9335_SLIM_TX_CH(12),
370 WCD9335_SLIM_TX_CH(13),
371 WCD9335_SLIM_TX_CH(14),
372 WCD9335_SLIM_TX_CH(15),
373 };
374
375 static const struct wcd9335_slim_ch wcd9335_rx_chs[WCD9335_RX_MAX] = {
376 WCD9335_SLIM_RX_CH(0), /* 16 */
377 WCD9335_SLIM_RX_CH(1), /* 17 */
378 WCD9335_SLIM_RX_CH(2),
379 WCD9335_SLIM_RX_CH(3),
380 WCD9335_SLIM_RX_CH(4),
381 WCD9335_SLIM_RX_CH(5),
382 WCD9335_SLIM_RX_CH(6),
383 WCD9335_SLIM_RX_CH(7),
384 WCD9335_SLIM_RX_CH(8),
385 WCD9335_SLIM_RX_CH(9),
386 WCD9335_SLIM_RX_CH(10),
387 WCD9335_SLIM_RX_CH(11),
388 WCD9335_SLIM_RX_CH(12),
389 };
390
391 struct interp_sample_rate {
392 int rate;
393 int rate_val;
394 };
395
396 static const struct interp_sample_rate int_mix_rate_val[] = {
397 {48000, 0x4}, /* 48K */
398 {96000, 0x5}, /* 96K */
399 {192000, 0x6}, /* 192K */
400 };
401
402 static const struct interp_sample_rate int_prim_rate_val[] = {
403 {8000, 0x0}, /* 8K */
404 {16000, 0x1}, /* 16K */
405 {24000, -EINVAL},/* 24K */
406 {32000, 0x3}, /* 32K */
407 {48000, 0x4}, /* 48K */
408 {96000, 0x5}, /* 96K */
409 {192000, 0x6}, /* 192K */
410 {384000, 0x7}, /* 384K */
411 {44100, 0x8}, /* 44.1K */
412 };
413
414 struct wcd9335_reg_mask_val {
415 u16 reg;
416 u8 mask;
417 u8 val;
418 };
419
420 static const struct wcd9335_reg_mask_val wcd9335_codec_reg_init[] = {
421 /* Rbuckfly/R_EAR(32) */
422 {WCD9335_CDC_CLSH_K2_MSB, 0x0F, 0x00},
423 {WCD9335_CDC_CLSH_K2_LSB, 0xFF, 0x60},
424 {WCD9335_CPE_SS_DMIC_CFG, 0x80, 0x00},
425 {WCD9335_CDC_BOOST0_BOOST_CTL, 0x70, 0x50},
426 {WCD9335_CDC_BOOST1_BOOST_CTL, 0x70, 0x50},
427 {WCD9335_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08},
428 {WCD9335_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08},
429 {WCD9335_ANA_LO_1_2, 0x3C, 0X3C},
430 {WCD9335_DIFF_LO_COM_SWCAP_REFBUF_FREQ, 0x70, 0x00},
431 {WCD9335_DIFF_LO_COM_PA_FREQ, 0x70, 0x40},
432 {WCD9335_SOC_MAD_AUDIO_CTL_2, 0x03, 0x03},
433 {WCD9335_CDC_TOP_TOP_CFG1, 0x02, 0x02},
434 {WCD9335_CDC_TOP_TOP_CFG1, 0x01, 0x01},
435 {WCD9335_EAR_CMBUFF, 0x08, 0x00},
436 {WCD9335_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
437 {WCD9335_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
438 {WCD9335_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
439 {WCD9335_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
440 {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x80},
441 {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x80},
442 {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x01},
443 {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x01},
444 {WCD9335_CDC_RX0_RX_PATH_CFG0, 0x01, 0x01},
445 {WCD9335_CDC_RX1_RX_PATH_CFG0, 0x01, 0x01},
446 {WCD9335_CDC_RX2_RX_PATH_CFG0, 0x01, 0x01},
447 {WCD9335_CDC_RX3_RX_PATH_CFG0, 0x01, 0x01},
448 {WCD9335_CDC_RX4_RX_PATH_CFG0, 0x01, 0x01},
449 {WCD9335_CDC_RX5_RX_PATH_CFG0, 0x01, 0x01},
450 {WCD9335_CDC_RX6_RX_PATH_CFG0, 0x01, 0x01},
451 {WCD9335_CDC_RX7_RX_PATH_CFG0, 0x01, 0x01},
452 {WCD9335_CDC_RX8_RX_PATH_CFG0, 0x01, 0x01},
453 {WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
454 {WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
455 {WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 0x01, 0x01},
456 {WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 0x01, 0x01},
457 {WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 0x01, 0x01},
458 {WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 0x01, 0x01},
459 {WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 0x01, 0x01},
460 {WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 0x01, 0x01},
461 {WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 0x01, 0x01},
462 {WCD9335_VBADC_IBIAS_FE, 0x0C, 0x08},
463 {WCD9335_RCO_CTRL_2, 0x0F, 0x08},
464 {WCD9335_RX_BIAS_FLYB_MID_RST, 0xF0, 0x10},
465 {WCD9335_FLYBACK_CTRL_1, 0x20, 0x20},
466 {WCD9335_HPH_OCP_CTL, 0xFF, 0x5A},
467 {WCD9335_HPH_L_TEST, 0x01, 0x01},
468 {WCD9335_HPH_R_TEST, 0x01, 0x01},
469 {WCD9335_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12},
470 {WCD9335_CDC_BOOST0_BOOST_CFG2, 0x1C, 0x08},
471 {WCD9335_CDC_COMPANDER7_CTL7, 0x1E, 0x18},
472 {WCD9335_CDC_BOOST1_BOOST_CFG1, 0x3F, 0x12},
473 {WCD9335_CDC_BOOST1_BOOST_CFG2, 0x1C, 0x08},
474 {WCD9335_CDC_COMPANDER8_CTL7, 0x1E, 0x18},
475 {WCD9335_CDC_TX0_TX_PATH_SEC7, 0xFF, 0x45},
476 {WCD9335_CDC_RX0_RX_PATH_SEC0, 0xFC, 0xF4},
477 {WCD9335_HPH_REFBUFF_LP_CTL, 0x08, 0x08},
478 {WCD9335_HPH_REFBUFF_LP_CTL, 0x06, 0x02},
479 };
480
481 /* Cutoff frequency for high pass filter */
482 static const char * const cf_text[] = {
483 "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ"
484 };
485
486 static const char * const rx_cf_text[] = {
487 "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ",
488 "CF_NEG_3DB_0P48HZ"
489 };
490
491 static const char * const rx_int0_7_mix_mux_text[] = {
492 "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5",
493 "RX6", "RX7", "PROXIMITY"
494 };
495
496 static const char * const rx_int_mix_mux_text[] = {
497 "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5",
498 "RX6", "RX7"
499 };
500
501 static const char * const rx_prim_mix_text[] = {
502 "ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2",
503 "RX3", "RX4", "RX5", "RX6", "RX7"
504 };
505
506 static const char * const rx_int_dem_inp_mux_text[] = {
507 "NORMAL_DSM_OUT", "CLSH_DSM_OUT",
508 };
509
510 static const char * const rx_int0_interp_mux_text[] = {
511 "ZERO", "RX INT0 MIX2",
512 };
513
514 static const char * const rx_int1_interp_mux_text[] = {
515 "ZERO", "RX INT1 MIX2",
516 };
517
518 static const char * const rx_int2_interp_mux_text[] = {
519 "ZERO", "RX INT2 MIX2",
520 };
521
522 static const char * const rx_int3_interp_mux_text[] = {
523 "ZERO", "RX INT3 MIX2",
524 };
525
526 static const char * const rx_int4_interp_mux_text[] = {
527 "ZERO", "RX INT4 MIX2",
528 };
529
530 static const char * const rx_int5_interp_mux_text[] = {
531 "ZERO", "RX INT5 MIX2",
532 };
533
534 static const char * const rx_int6_interp_mux_text[] = {
535 "ZERO", "RX INT6 MIX2",
536 };
537
538 static const char * const rx_int7_interp_mux_text[] = {
539 "ZERO", "RX INT7 MIX2",
540 };
541
542 static const char * const rx_int8_interp_mux_text[] = {
543 "ZERO", "RX INT8 SEC MIX"
544 };
545
546 static const char * const rx_hph_mode_mux_text[] = {
547 "Class H Invalid", "Class-H Hi-Fi", "Class-H Low Power", "Class-AB",
548 "Class-H Hi-Fi Low Power"
549 };
550
551 static const char *const slim_rx_mux_text[] = {
552 "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB",
553 };
554
555 static const char * const adc_mux_text[] = {
556 "DMIC", "AMIC", "ANC_FB_TUNE1", "ANC_FB_TUNE2"
557 };
558
559 static const char * const dmic_mux_text[] = {
560 "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5",
561 "SMIC0", "SMIC1", "SMIC2", "SMIC3"
562 };
563
564 static const char * const dmic_mux_alt_text[] = {
565 "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5",
566 };
567
568 static const char * const amic_mux_text[] = {
569 "ZERO", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6"
570 };
571
572 static const char * const sb_tx0_mux_text[] = {
573 "ZERO", "RX_MIX_TX0", "DEC0", "DEC0_192"
574 };
575
576 static const char * const sb_tx1_mux_text[] = {
577 "ZERO", "RX_MIX_TX1", "DEC1", "DEC1_192"
578 };
579
580 static const char * const sb_tx2_mux_text[] = {
581 "ZERO", "RX_MIX_TX2", "DEC2", "DEC2_192"
582 };
583
584 static const char * const sb_tx3_mux_text[] = {
585 "ZERO", "RX_MIX_TX3", "DEC3", "DEC3_192"
586 };
587
588 static const char * const sb_tx4_mux_text[] = {
589 "ZERO", "RX_MIX_TX4", "DEC4", "DEC4_192"
590 };
591
592 static const char * const sb_tx5_mux_text[] = {
593 "ZERO", "RX_MIX_TX5", "DEC5", "DEC5_192"
594 };
595
596 static const char * const sb_tx6_mux_text[] = {
597 "ZERO", "RX_MIX_TX6", "DEC6", "DEC6_192"
598 };
599
600 static const char * const sb_tx7_mux_text[] = {
601 "ZERO", "RX_MIX_TX7", "DEC7", "DEC7_192"
602 };
603
604 static const char * const sb_tx8_mux_text[] = {
605 "ZERO", "RX_MIX_TX8", "DEC8", "DEC8_192"
606 };
607
608 static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400);
609 static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
610 static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
611 static const DECLARE_TLV_DB_SCALE(ear_pa_gain, 0, 150, 0);
612
613 static const struct soc_enum cf_dec0_enum =
614 SOC_ENUM_SINGLE(WCD9335_CDC_TX0_TX_PATH_CFG0, 5, 3, cf_text);
615
616 static const struct soc_enum cf_dec1_enum =
617 SOC_ENUM_SINGLE(WCD9335_CDC_TX1_TX_PATH_CFG0, 5, 3, cf_text);
618
619 static const struct soc_enum cf_dec2_enum =
620 SOC_ENUM_SINGLE(WCD9335_CDC_TX2_TX_PATH_CFG0, 5, 3, cf_text);
621
622 static const struct soc_enum cf_dec3_enum =
623 SOC_ENUM_SINGLE(WCD9335_CDC_TX3_TX_PATH_CFG0, 5, 3, cf_text);
624
625 static const struct soc_enum cf_dec4_enum =
626 SOC_ENUM_SINGLE(WCD9335_CDC_TX4_TX_PATH_CFG0, 5, 3, cf_text);
627
628 static const struct soc_enum cf_dec5_enum =
629 SOC_ENUM_SINGLE(WCD9335_CDC_TX5_TX_PATH_CFG0, 5, 3, cf_text);
630
631 static const struct soc_enum cf_dec6_enum =
632 SOC_ENUM_SINGLE(WCD9335_CDC_TX6_TX_PATH_CFG0, 5, 3, cf_text);
633
634 static const struct soc_enum cf_dec7_enum =
635 SOC_ENUM_SINGLE(WCD9335_CDC_TX7_TX_PATH_CFG0, 5, 3, cf_text);
636
637 static const struct soc_enum cf_dec8_enum =
638 SOC_ENUM_SINGLE(WCD9335_CDC_TX8_TX_PATH_CFG0, 5, 3, cf_text);
639
640 static const struct soc_enum cf_int0_1_enum =
641 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CFG2, 0, 4, rx_cf_text);
642
643 static SOC_ENUM_SINGLE_DECL(cf_int0_2_enum, WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 2,
644 rx_cf_text);
645
646 static const struct soc_enum cf_int1_1_enum =
647 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CFG2, 0, 4, rx_cf_text);
648
649 static SOC_ENUM_SINGLE_DECL(cf_int1_2_enum, WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 2,
650 rx_cf_text);
651
652 static const struct soc_enum cf_int2_1_enum =
653 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CFG2, 0, 4, rx_cf_text);
654
655 static SOC_ENUM_SINGLE_DECL(cf_int2_2_enum, WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 2,
656 rx_cf_text);
657
658 static const struct soc_enum cf_int3_1_enum =
659 SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CFG2, 0, 4, rx_cf_text);
660
661 static SOC_ENUM_SINGLE_DECL(cf_int3_2_enum, WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 2,
662 rx_cf_text);
663
664 static const struct soc_enum cf_int4_1_enum =
665 SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CFG2, 0, 4, rx_cf_text);
666
667 static SOC_ENUM_SINGLE_DECL(cf_int4_2_enum, WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 2,
668 rx_cf_text);
669
670 static const struct soc_enum cf_int5_1_enum =
671 SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CFG2, 0, 4, rx_cf_text);
672
673 static SOC_ENUM_SINGLE_DECL(cf_int5_2_enum, WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 2,
674 rx_cf_text);
675
676 static const struct soc_enum cf_int6_1_enum =
677 SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CFG2, 0, 4, rx_cf_text);
678
679 static SOC_ENUM_SINGLE_DECL(cf_int6_2_enum, WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 2,
680 rx_cf_text);
681
682 static const struct soc_enum cf_int7_1_enum =
683 SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CFG2, 0, 4, rx_cf_text);
684
685 static SOC_ENUM_SINGLE_DECL(cf_int7_2_enum, WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 2,
686 rx_cf_text);
687
688 static const struct soc_enum cf_int8_1_enum =
689 SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CFG2, 0, 4, rx_cf_text);
690
691 static SOC_ENUM_SINGLE_DECL(cf_int8_2_enum, WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 2,
692 rx_cf_text);
693
694 static const struct soc_enum rx_hph_mode_mux_enum =
695 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text),
696 rx_hph_mode_mux_text);
697
698 static const struct soc_enum slim_rx_mux_enum =
699 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text);
700
701 static const struct soc_enum rx_int0_2_mux_chain_enum =
702 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, 10,
703 rx_int0_7_mix_mux_text);
704
705 static const struct soc_enum rx_int1_2_mux_chain_enum =
706 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, 9,
707 rx_int_mix_mux_text);
708
709 static const struct soc_enum rx_int2_2_mux_chain_enum =
710 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 0, 9,
711 rx_int_mix_mux_text);
712
713 static const struct soc_enum rx_int3_2_mux_chain_enum =
714 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 0, 9,
715 rx_int_mix_mux_text);
716
717 static const struct soc_enum rx_int4_2_mux_chain_enum =
718 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 0, 9,
719 rx_int_mix_mux_text);
720
721 static const struct soc_enum rx_int5_2_mux_chain_enum =
722 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 0, 9,
723 rx_int_mix_mux_text);
724
725 static const struct soc_enum rx_int6_2_mux_chain_enum =
726 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 0, 9,
727 rx_int_mix_mux_text);
728
729 static const struct soc_enum rx_int7_2_mux_chain_enum =
730 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 0, 10,
731 rx_int0_7_mix_mux_text);
732
733 static const struct soc_enum rx_int8_2_mux_chain_enum =
734 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 0, 9,
735 rx_int_mix_mux_text);
736
737 static const struct soc_enum rx_int0_1_mix_inp0_chain_enum =
738 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 0, 13,
739 rx_prim_mix_text);
740
741 static const struct soc_enum rx_int0_1_mix_inp1_chain_enum =
742 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 4, 13,
743 rx_prim_mix_text);
744
745 static const struct soc_enum rx_int0_1_mix_inp2_chain_enum =
746 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 4, 13,
747 rx_prim_mix_text);
748
749 static const struct soc_enum rx_int1_1_mix_inp0_chain_enum =
750 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 0, 13,
751 rx_prim_mix_text);
752
753 static const struct soc_enum rx_int1_1_mix_inp1_chain_enum =
754 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 4, 13,
755 rx_prim_mix_text);
756
757 static const struct soc_enum rx_int1_1_mix_inp2_chain_enum =
758 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 4, 13,
759 rx_prim_mix_text);
760
761 static const struct soc_enum rx_int2_1_mix_inp0_chain_enum =
762 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 0, 13,
763 rx_prim_mix_text);
764
765 static const struct soc_enum rx_int2_1_mix_inp1_chain_enum =
766 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 4, 13,
767 rx_prim_mix_text);
768
769 static const struct soc_enum rx_int2_1_mix_inp2_chain_enum =
770 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 4, 13,
771 rx_prim_mix_text);
772
773 static const struct soc_enum rx_int3_1_mix_inp0_chain_enum =
774 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 0, 13,
775 rx_prim_mix_text);
776
777 static const struct soc_enum rx_int3_1_mix_inp1_chain_enum =
778 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 4, 13,
779 rx_prim_mix_text);
780
781 static const struct soc_enum rx_int3_1_mix_inp2_chain_enum =
782 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 4, 13,
783 rx_prim_mix_text);
784
785 static const struct soc_enum rx_int4_1_mix_inp0_chain_enum =
786 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 0, 13,
787 rx_prim_mix_text);
788
789 static const struct soc_enum rx_int4_1_mix_inp1_chain_enum =
790 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 4, 13,
791 rx_prim_mix_text);
792
793 static const struct soc_enum rx_int4_1_mix_inp2_chain_enum =
794 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 4, 13,
795 rx_prim_mix_text);
796
797 static const struct soc_enum rx_int5_1_mix_inp0_chain_enum =
798 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 0, 13,
799 rx_prim_mix_text);
800
801 static const struct soc_enum rx_int5_1_mix_inp1_chain_enum =
802 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 4, 13,
803 rx_prim_mix_text);
804
805 static const struct soc_enum rx_int5_1_mix_inp2_chain_enum =
806 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 4, 13,
807 rx_prim_mix_text);
808
809 static const struct soc_enum rx_int6_1_mix_inp0_chain_enum =
810 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 0, 13,
811 rx_prim_mix_text);
812
813 static const struct soc_enum rx_int6_1_mix_inp1_chain_enum =
814 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 4, 13,
815 rx_prim_mix_text);
816
817 static const struct soc_enum rx_int6_1_mix_inp2_chain_enum =
818 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 4, 13,
819 rx_prim_mix_text);
820
821 static const struct soc_enum rx_int7_1_mix_inp0_chain_enum =
822 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 0, 13,
823 rx_prim_mix_text);
824
825 static const struct soc_enum rx_int7_1_mix_inp1_chain_enum =
826 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 4, 13,
827 rx_prim_mix_text);
828
829 static const struct soc_enum rx_int7_1_mix_inp2_chain_enum =
830 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 4, 13,
831 rx_prim_mix_text);
832
833 static const struct soc_enum rx_int8_1_mix_inp0_chain_enum =
834 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 0, 13,
835 rx_prim_mix_text);
836
837 static const struct soc_enum rx_int8_1_mix_inp1_chain_enum =
838 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 4, 13,
839 rx_prim_mix_text);
840
841 static const struct soc_enum rx_int8_1_mix_inp2_chain_enum =
842 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 4, 13,
843 rx_prim_mix_text);
844
845 static const struct soc_enum rx_int0_dem_inp_mux_enum =
846 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_SEC0, 0,
847 ARRAY_SIZE(rx_int_dem_inp_mux_text),
848 rx_int_dem_inp_mux_text);
849
850 static const struct soc_enum rx_int1_dem_inp_mux_enum =
851 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_SEC0, 0,
852 ARRAY_SIZE(rx_int_dem_inp_mux_text),
853 rx_int_dem_inp_mux_text);
854
855 static const struct soc_enum rx_int2_dem_inp_mux_enum =
856 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_SEC0, 0,
857 ARRAY_SIZE(rx_int_dem_inp_mux_text),
858 rx_int_dem_inp_mux_text);
859
860 static const struct soc_enum rx_int0_interp_mux_enum =
861 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CTL, 5, 2,
862 rx_int0_interp_mux_text);
863
864 static const struct soc_enum rx_int1_interp_mux_enum =
865 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CTL, 5, 2,
866 rx_int1_interp_mux_text);
867
868 static const struct soc_enum rx_int2_interp_mux_enum =
869 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CTL, 5, 2,
870 rx_int2_interp_mux_text);
871
872 static const struct soc_enum rx_int3_interp_mux_enum =
873 SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CTL, 5, 2,
874 rx_int3_interp_mux_text);
875
876 static const struct soc_enum rx_int4_interp_mux_enum =
877 SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CTL, 5, 2,
878 rx_int4_interp_mux_text);
879
880 static const struct soc_enum rx_int5_interp_mux_enum =
881 SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CTL, 5, 2,
882 rx_int5_interp_mux_text);
883
884 static const struct soc_enum rx_int6_interp_mux_enum =
885 SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CTL, 5, 2,
886 rx_int6_interp_mux_text);
887
888 static const struct soc_enum rx_int7_interp_mux_enum =
889 SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CTL, 5, 2,
890 rx_int7_interp_mux_text);
891
892 static const struct soc_enum rx_int8_interp_mux_enum =
893 SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CTL, 5, 2,
894 rx_int8_interp_mux_text);
895
896 static const struct soc_enum tx_adc_mux0_chain_enum =
897 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0, 4,
898 adc_mux_text);
899
900 static const struct soc_enum tx_adc_mux1_chain_enum =
901 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0, 4,
902 adc_mux_text);
903
904 static const struct soc_enum tx_adc_mux2_chain_enum =
905 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0, 4,
906 adc_mux_text);
907
908 static const struct soc_enum tx_adc_mux3_chain_enum =
909 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0, 4,
910 adc_mux_text);
911
912 static const struct soc_enum tx_adc_mux4_chain_enum =
913 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 6, 4,
914 adc_mux_text);
915
916 static const struct soc_enum tx_adc_mux5_chain_enum =
917 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 6, 4,
918 adc_mux_text);
919
920 static const struct soc_enum tx_adc_mux6_chain_enum =
921 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 6, 4,
922 adc_mux_text);
923
924 static const struct soc_enum tx_adc_mux7_chain_enum =
925 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 6, 4,
926 adc_mux_text);
927
928 static const struct soc_enum tx_adc_mux8_chain_enum =
929 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 6, 4,
930 adc_mux_text);
931
932 static const struct soc_enum tx_dmic_mux0_enum =
933 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 3, 11,
934 dmic_mux_text);
935
936 static const struct soc_enum tx_dmic_mux1_enum =
937 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 3, 11,
938 dmic_mux_text);
939
940 static const struct soc_enum tx_dmic_mux2_enum =
941 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 3, 11,
942 dmic_mux_text);
943
944 static const struct soc_enum tx_dmic_mux3_enum =
945 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 3, 11,
946 dmic_mux_text);
947
948 static const struct soc_enum tx_dmic_mux4_enum =
949 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 3, 7,
950 dmic_mux_alt_text);
951
952 static const struct soc_enum tx_dmic_mux5_enum =
953 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 3, 7,
954 dmic_mux_alt_text);
955
956 static const struct soc_enum tx_dmic_mux6_enum =
957 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 3, 7,
958 dmic_mux_alt_text);
959
960 static const struct soc_enum tx_dmic_mux7_enum =
961 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 3, 7,
962 dmic_mux_alt_text);
963
964 static const struct soc_enum tx_dmic_mux8_enum =
965 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 3, 7,
966 dmic_mux_alt_text);
967
968 static const struct soc_enum tx_amic_mux0_enum =
969 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0, 7,
970 amic_mux_text);
971
972 static const struct soc_enum tx_amic_mux1_enum =
973 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0, 7,
974 amic_mux_text);
975
976 static const struct soc_enum tx_amic_mux2_enum =
977 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0, 7,
978 amic_mux_text);
979
980 static const struct soc_enum tx_amic_mux3_enum =
981 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0, 7,
982 amic_mux_text);
983
984 static const struct soc_enum tx_amic_mux4_enum =
985 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0, 7,
986 amic_mux_text);
987
988 static const struct soc_enum tx_amic_mux5_enum =
989 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0, 7,
990 amic_mux_text);
991
992 static const struct soc_enum tx_amic_mux6_enum =
993 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0, 7,
994 amic_mux_text);
995
996 static const struct soc_enum tx_amic_mux7_enum =
997 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0, 7,
998 amic_mux_text);
999
1000 static const struct soc_enum tx_amic_mux8_enum =
1001 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 0, 7,
1002 amic_mux_text);
1003
1004 static const struct soc_enum sb_tx0_mux_enum =
1005 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 0, 4,
1006 sb_tx0_mux_text);
1007
1008 static const struct soc_enum sb_tx1_mux_enum =
1009 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 2, 4,
1010 sb_tx1_mux_text);
1011
1012 static const struct soc_enum sb_tx2_mux_enum =
1013 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 4, 4,
1014 sb_tx2_mux_text);
1015
1016 static const struct soc_enum sb_tx3_mux_enum =
1017 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 6, 4,
1018 sb_tx3_mux_text);
1019
1020 static const struct soc_enum sb_tx4_mux_enum =
1021 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 0, 4,
1022 sb_tx4_mux_text);
1023
1024 static const struct soc_enum sb_tx5_mux_enum =
1025 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 2, 4,
1026 sb_tx5_mux_text);
1027
1028 static const struct soc_enum sb_tx6_mux_enum =
1029 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 4, 4,
1030 sb_tx6_mux_text);
1031
1032 static const struct soc_enum sb_tx7_mux_enum =
1033 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 6, 4,
1034 sb_tx7_mux_text);
1035
1036 static const struct soc_enum sb_tx8_mux_enum =
1037 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 0, 4,
1038 sb_tx8_mux_text);
1039
1040 static const struct snd_kcontrol_new rx_int0_2_mux =
1041 SOC_DAPM_ENUM("RX INT0_2 MUX Mux", rx_int0_2_mux_chain_enum);
1042
1043 static const struct snd_kcontrol_new rx_int1_2_mux =
1044 SOC_DAPM_ENUM("RX INT1_2 MUX Mux", rx_int1_2_mux_chain_enum);
1045
1046 static const struct snd_kcontrol_new rx_int2_2_mux =
1047 SOC_DAPM_ENUM("RX INT2_2 MUX Mux", rx_int2_2_mux_chain_enum);
1048
1049 static const struct snd_kcontrol_new rx_int3_2_mux =
1050 SOC_DAPM_ENUM("RX INT3_2 MUX Mux", rx_int3_2_mux_chain_enum);
1051
1052 static const struct snd_kcontrol_new rx_int4_2_mux =
1053 SOC_DAPM_ENUM("RX INT4_2 MUX Mux", rx_int4_2_mux_chain_enum);
1054
1055 static const struct snd_kcontrol_new rx_int5_2_mux =
1056 SOC_DAPM_ENUM("RX INT5_2 MUX Mux", rx_int5_2_mux_chain_enum);
1057
1058 static const struct snd_kcontrol_new rx_int6_2_mux =
1059 SOC_DAPM_ENUM("RX INT6_2 MUX Mux", rx_int6_2_mux_chain_enum);
1060
1061 static const struct snd_kcontrol_new rx_int7_2_mux =
1062 SOC_DAPM_ENUM("RX INT7_2 MUX Mux", rx_int7_2_mux_chain_enum);
1063
1064 static const struct snd_kcontrol_new rx_int8_2_mux =
1065 SOC_DAPM_ENUM("RX INT8_2 MUX Mux", rx_int8_2_mux_chain_enum);
1066
1067 static const struct snd_kcontrol_new rx_int0_1_mix_inp0_mux =
1068 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP0 Mux", rx_int0_1_mix_inp0_chain_enum);
1069
1070 static const struct snd_kcontrol_new rx_int0_1_mix_inp1_mux =
1071 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP1 Mux", rx_int0_1_mix_inp1_chain_enum);
1072
1073 static const struct snd_kcontrol_new rx_int0_1_mix_inp2_mux =
1074 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP2 Mux", rx_int0_1_mix_inp2_chain_enum);
1075
1076 static const struct snd_kcontrol_new rx_int1_1_mix_inp0_mux =
1077 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP0 Mux", rx_int1_1_mix_inp0_chain_enum);
1078
1079 static const struct snd_kcontrol_new rx_int1_1_mix_inp1_mux =
1080 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP1 Mux", rx_int1_1_mix_inp1_chain_enum);
1081
1082 static const struct snd_kcontrol_new rx_int1_1_mix_inp2_mux =
1083 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP2 Mux", rx_int1_1_mix_inp2_chain_enum);
1084
1085 static const struct snd_kcontrol_new rx_int2_1_mix_inp0_mux =
1086 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP0 Mux", rx_int2_1_mix_inp0_chain_enum);
1087
1088 static const struct snd_kcontrol_new rx_int2_1_mix_inp1_mux =
1089 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP1 Mux", rx_int2_1_mix_inp1_chain_enum);
1090
1091 static const struct snd_kcontrol_new rx_int2_1_mix_inp2_mux =
1092 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP2 Mux", rx_int2_1_mix_inp2_chain_enum);
1093
1094 static const struct snd_kcontrol_new rx_int3_1_mix_inp0_mux =
1095 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP0 Mux", rx_int3_1_mix_inp0_chain_enum);
1096
1097 static const struct snd_kcontrol_new rx_int3_1_mix_inp1_mux =
1098 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP1 Mux", rx_int3_1_mix_inp1_chain_enum);
1099
1100 static const struct snd_kcontrol_new rx_int3_1_mix_inp2_mux =
1101 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP2 Mux", rx_int3_1_mix_inp2_chain_enum);
1102
1103 static const struct snd_kcontrol_new rx_int4_1_mix_inp0_mux =
1104 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP0 Mux", rx_int4_1_mix_inp0_chain_enum);
1105
1106 static const struct snd_kcontrol_new rx_int4_1_mix_inp1_mux =
1107 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP1 Mux", rx_int4_1_mix_inp1_chain_enum);
1108
1109 static const struct snd_kcontrol_new rx_int4_1_mix_inp2_mux =
1110 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP2 Mux", rx_int4_1_mix_inp2_chain_enum);
1111
1112 static const struct snd_kcontrol_new rx_int5_1_mix_inp0_mux =
1113 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP0 Mux", rx_int5_1_mix_inp0_chain_enum);
1114
1115 static const struct snd_kcontrol_new rx_int5_1_mix_inp1_mux =
1116 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP1 Mux", rx_int5_1_mix_inp1_chain_enum);
1117
1118 static const struct snd_kcontrol_new rx_int5_1_mix_inp2_mux =
1119 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP2 Mux", rx_int5_1_mix_inp2_chain_enum);
1120
1121 static const struct snd_kcontrol_new rx_int6_1_mix_inp0_mux =
1122 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP0 Mux", rx_int6_1_mix_inp0_chain_enum);
1123
1124 static const struct snd_kcontrol_new rx_int6_1_mix_inp1_mux =
1125 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP1 Mux", rx_int6_1_mix_inp1_chain_enum);
1126
1127 static const struct snd_kcontrol_new rx_int6_1_mix_inp2_mux =
1128 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP2 Mux", rx_int6_1_mix_inp2_chain_enum);
1129
1130 static const struct snd_kcontrol_new rx_int7_1_mix_inp0_mux =
1131 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP0 Mux", rx_int7_1_mix_inp0_chain_enum);
1132
1133 static const struct snd_kcontrol_new rx_int7_1_mix_inp1_mux =
1134 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP1 Mux", rx_int7_1_mix_inp1_chain_enum);
1135
1136 static const struct snd_kcontrol_new rx_int7_1_mix_inp2_mux =
1137 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP2 Mux", rx_int7_1_mix_inp2_chain_enum);
1138
1139 static const struct snd_kcontrol_new rx_int8_1_mix_inp0_mux =
1140 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP0 Mux", rx_int8_1_mix_inp0_chain_enum);
1141
1142 static const struct snd_kcontrol_new rx_int8_1_mix_inp1_mux =
1143 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP1 Mux", rx_int8_1_mix_inp1_chain_enum);
1144
1145 static const struct snd_kcontrol_new rx_int8_1_mix_inp2_mux =
1146 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP2 Mux", rx_int8_1_mix_inp2_chain_enum);
1147
1148 static const struct snd_kcontrol_new rx_int0_interp_mux =
1149 SOC_DAPM_ENUM("RX INT0 INTERP Mux", rx_int0_interp_mux_enum);
1150
1151 static const struct snd_kcontrol_new rx_int1_interp_mux =
1152 SOC_DAPM_ENUM("RX INT1 INTERP Mux", rx_int1_interp_mux_enum);
1153
1154 static const struct snd_kcontrol_new rx_int2_interp_mux =
1155 SOC_DAPM_ENUM("RX INT2 INTERP Mux", rx_int2_interp_mux_enum);
1156
1157 static const struct snd_kcontrol_new rx_int3_interp_mux =
1158 SOC_DAPM_ENUM("RX INT3 INTERP Mux", rx_int3_interp_mux_enum);
1159
1160 static const struct snd_kcontrol_new rx_int4_interp_mux =
1161 SOC_DAPM_ENUM("RX INT4 INTERP Mux", rx_int4_interp_mux_enum);
1162
1163 static const struct snd_kcontrol_new rx_int5_interp_mux =
1164 SOC_DAPM_ENUM("RX INT5 INTERP Mux", rx_int5_interp_mux_enum);
1165
1166 static const struct snd_kcontrol_new rx_int6_interp_mux =
1167 SOC_DAPM_ENUM("RX INT6 INTERP Mux", rx_int6_interp_mux_enum);
1168
1169 static const struct snd_kcontrol_new rx_int7_interp_mux =
1170 SOC_DAPM_ENUM("RX INT7 INTERP Mux", rx_int7_interp_mux_enum);
1171
1172 static const struct snd_kcontrol_new rx_int8_interp_mux =
1173 SOC_DAPM_ENUM("RX INT8 INTERP Mux", rx_int8_interp_mux_enum);
1174
1175 static const struct snd_kcontrol_new tx_dmic_mux0 =
1176 SOC_DAPM_ENUM("DMIC MUX0 Mux", tx_dmic_mux0_enum);
1177
1178 static const struct snd_kcontrol_new tx_dmic_mux1 =
1179 SOC_DAPM_ENUM("DMIC MUX1 Mux", tx_dmic_mux1_enum);
1180
1181 static const struct snd_kcontrol_new tx_dmic_mux2 =
1182 SOC_DAPM_ENUM("DMIC MUX2 Mux", tx_dmic_mux2_enum);
1183
1184 static const struct snd_kcontrol_new tx_dmic_mux3 =
1185 SOC_DAPM_ENUM("DMIC MUX3 Mux", tx_dmic_mux3_enum);
1186
1187 static const struct snd_kcontrol_new tx_dmic_mux4 =
1188 SOC_DAPM_ENUM("DMIC MUX4 Mux", tx_dmic_mux4_enum);
1189
1190 static const struct snd_kcontrol_new tx_dmic_mux5 =
1191 SOC_DAPM_ENUM("DMIC MUX5 Mux", tx_dmic_mux5_enum);
1192
1193 static const struct snd_kcontrol_new tx_dmic_mux6 =
1194 SOC_DAPM_ENUM("DMIC MUX6 Mux", tx_dmic_mux6_enum);
1195
1196 static const struct snd_kcontrol_new tx_dmic_mux7 =
1197 SOC_DAPM_ENUM("DMIC MUX7 Mux", tx_dmic_mux7_enum);
1198
1199 static const struct snd_kcontrol_new tx_dmic_mux8 =
1200 SOC_DAPM_ENUM("DMIC MUX8 Mux", tx_dmic_mux8_enum);
1201
1202 static const struct snd_kcontrol_new tx_amic_mux0 =
1203 SOC_DAPM_ENUM("AMIC MUX0 Mux", tx_amic_mux0_enum);
1204
1205 static const struct snd_kcontrol_new tx_amic_mux1 =
1206 SOC_DAPM_ENUM("AMIC MUX1 Mux", tx_amic_mux1_enum);
1207
1208 static const struct snd_kcontrol_new tx_amic_mux2 =
1209 SOC_DAPM_ENUM("AMIC MUX2 Mux", tx_amic_mux2_enum);
1210
1211 static const struct snd_kcontrol_new tx_amic_mux3 =
1212 SOC_DAPM_ENUM("AMIC MUX3 Mux", tx_amic_mux3_enum);
1213
1214 static const struct snd_kcontrol_new tx_amic_mux4 =
1215 SOC_DAPM_ENUM("AMIC MUX4 Mux", tx_amic_mux4_enum);
1216
1217 static const struct snd_kcontrol_new tx_amic_mux5 =
1218 SOC_DAPM_ENUM("AMIC MUX5 Mux", tx_amic_mux5_enum);
1219
1220 static const struct snd_kcontrol_new tx_amic_mux6 =
1221 SOC_DAPM_ENUM("AMIC MUX6 Mux", tx_amic_mux6_enum);
1222
1223 static const struct snd_kcontrol_new tx_amic_mux7 =
1224 SOC_DAPM_ENUM("AMIC MUX7 Mux", tx_amic_mux7_enum);
1225
1226 static const struct snd_kcontrol_new tx_amic_mux8 =
1227 SOC_DAPM_ENUM("AMIC MUX8 Mux", tx_amic_mux8_enum);
1228
1229 static const struct snd_kcontrol_new sb_tx0_mux =
1230 SOC_DAPM_ENUM("SLIM TX0 MUX Mux", sb_tx0_mux_enum);
1231
1232 static const struct snd_kcontrol_new sb_tx1_mux =
1233 SOC_DAPM_ENUM("SLIM TX1 MUX Mux", sb_tx1_mux_enum);
1234
1235 static const struct snd_kcontrol_new sb_tx2_mux =
1236 SOC_DAPM_ENUM("SLIM TX2 MUX Mux", sb_tx2_mux_enum);
1237
1238 static const struct snd_kcontrol_new sb_tx3_mux =
1239 SOC_DAPM_ENUM("SLIM TX3 MUX Mux", sb_tx3_mux_enum);
1240
1241 static const struct snd_kcontrol_new sb_tx4_mux =
1242 SOC_DAPM_ENUM("SLIM TX4 MUX Mux", sb_tx4_mux_enum);
1243
1244 static const struct snd_kcontrol_new sb_tx5_mux =
1245 SOC_DAPM_ENUM("SLIM TX5 MUX Mux", sb_tx5_mux_enum);
1246
1247 static const struct snd_kcontrol_new sb_tx6_mux =
1248 SOC_DAPM_ENUM("SLIM TX6 MUX Mux", sb_tx6_mux_enum);
1249
1250 static const struct snd_kcontrol_new sb_tx7_mux =
1251 SOC_DAPM_ENUM("SLIM TX7 MUX Mux", sb_tx7_mux_enum);
1252
1253 static const struct snd_kcontrol_new sb_tx8_mux =
1254 SOC_DAPM_ENUM("SLIM TX8 MUX Mux", sb_tx8_mux_enum);
1255
slim_rx_mux_get(struct snd_kcontrol * kc,struct snd_ctl_elem_value * ucontrol)1256 static int slim_rx_mux_get(struct snd_kcontrol *kc,
1257 struct snd_ctl_elem_value *ucontrol)
1258 {
1259 struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kc);
1260 struct wcd9335_codec *wcd = dev_get_drvdata(w->dapm->dev);
1261 u32 port_id = w->shift;
1262
1263 ucontrol->value.enumerated.item[0] = wcd->rx_port_value[port_id];
1264
1265 return 0;
1266 }
1267
slim_rx_mux_put(struct snd_kcontrol * kc,struct snd_ctl_elem_value * ucontrol)1268 static int slim_rx_mux_put(struct snd_kcontrol *kc,
1269 struct snd_ctl_elem_value *ucontrol)
1270 {
1271 struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kc);
1272 struct wcd9335_codec *wcd = dev_get_drvdata(w->dapm->dev);
1273 struct soc_enum *e = (struct soc_enum *)kc->private_value;
1274 struct snd_soc_dapm_update *update = NULL;
1275 u32 port_id = w->shift;
1276
1277 if (wcd->rx_port_value[port_id] == ucontrol->value.enumerated.item[0])
1278 return 0;
1279
1280 wcd->rx_port_value[port_id] = ucontrol->value.enumerated.item[0];
1281
1282 /* Remove channel from any list it's in before adding it to a new one */
1283 list_del_init(&wcd->rx_chs[port_id].list);
1284
1285 switch (wcd->rx_port_value[port_id]) {
1286 case 0:
1287 /* Channel already removed from lists. Nothing to do here */
1288 break;
1289 case 1:
1290 list_add_tail(&wcd->rx_chs[port_id].list,
1291 &wcd->dai[AIF1_PB].slim_ch_list);
1292 break;
1293 case 2:
1294 list_add_tail(&wcd->rx_chs[port_id].list,
1295 &wcd->dai[AIF2_PB].slim_ch_list);
1296 break;
1297 case 3:
1298 list_add_tail(&wcd->rx_chs[port_id].list,
1299 &wcd->dai[AIF3_PB].slim_ch_list);
1300 break;
1301 case 4:
1302 list_add_tail(&wcd->rx_chs[port_id].list,
1303 &wcd->dai[AIF4_PB].slim_ch_list);
1304 break;
1305 default:
1306 dev_err(wcd->dev, "Unknown AIF %d\n", wcd->rx_port_value[port_id]);
1307 goto err;
1308 }
1309
1310 snd_soc_dapm_mux_update_power(w->dapm, kc, wcd->rx_port_value[port_id],
1311 e, update);
1312
1313 return 0;
1314 err:
1315 return -EINVAL;
1316 }
1317
slim_tx_mixer_get(struct snd_kcontrol * kc,struct snd_ctl_elem_value * ucontrol)1318 static int slim_tx_mixer_get(struct snd_kcontrol *kc,
1319 struct snd_ctl_elem_value *ucontrol)
1320 {
1321
1322 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kc);
1323 struct wcd9335_codec *wcd = dev_get_drvdata(dapm->dev);
1324 struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kc);
1325 struct soc_mixer_control *mixer =
1326 (struct soc_mixer_control *)kc->private_value;
1327 int dai_id = widget->shift;
1328 int port_id = mixer->shift;
1329
1330 ucontrol->value.integer.value[0] = wcd->tx_port_value[port_id] == dai_id;
1331
1332 return 0;
1333 }
1334
slim_tx_mixer_put(struct snd_kcontrol * kc,struct snd_ctl_elem_value * ucontrol)1335 static int slim_tx_mixer_put(struct snd_kcontrol *kc,
1336 struct snd_ctl_elem_value *ucontrol)
1337 {
1338
1339 struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kc);
1340 struct wcd9335_codec *wcd = dev_get_drvdata(widget->dapm->dev);
1341 struct snd_soc_dapm_update *update = NULL;
1342 struct soc_mixer_control *mixer =
1343 (struct soc_mixer_control *)kc->private_value;
1344 int enable = ucontrol->value.integer.value[0];
1345 int dai_id = widget->shift;
1346 int port_id = mixer->shift;
1347
1348 switch (dai_id) {
1349 case AIF1_CAP:
1350 case AIF2_CAP:
1351 case AIF3_CAP:
1352 /* only add to the list if value not set */
1353 if (enable && wcd->tx_port_value[port_id] != dai_id) {
1354 wcd->tx_port_value[port_id] = dai_id;
1355 list_add_tail(&wcd->tx_chs[port_id].list,
1356 &wcd->dai[dai_id].slim_ch_list);
1357 } else if (!enable && wcd->tx_port_value[port_id] == dai_id) {
1358 wcd->tx_port_value[port_id] = -1;
1359 list_del_init(&wcd->tx_chs[port_id].list);
1360 }
1361 break;
1362 default:
1363 dev_err(wcd->dev, "Unknown AIF %d\n", dai_id);
1364 return -EINVAL;
1365 }
1366
1367 snd_soc_dapm_mixer_update_power(widget->dapm, kc, enable, update);
1368
1369 return 0;
1370 }
1371
1372 static const struct snd_kcontrol_new slim_rx_mux[WCD9335_RX_MAX] = {
1373 SOC_DAPM_ENUM_EXT("SLIM RX0 Mux", slim_rx_mux_enum,
1374 slim_rx_mux_get, slim_rx_mux_put),
1375 SOC_DAPM_ENUM_EXT("SLIM RX1 Mux", slim_rx_mux_enum,
1376 slim_rx_mux_get, slim_rx_mux_put),
1377 SOC_DAPM_ENUM_EXT("SLIM RX2 Mux", slim_rx_mux_enum,
1378 slim_rx_mux_get, slim_rx_mux_put),
1379 SOC_DAPM_ENUM_EXT("SLIM RX3 Mux", slim_rx_mux_enum,
1380 slim_rx_mux_get, slim_rx_mux_put),
1381 SOC_DAPM_ENUM_EXT("SLIM RX4 Mux", slim_rx_mux_enum,
1382 slim_rx_mux_get, slim_rx_mux_put),
1383 SOC_DAPM_ENUM_EXT("SLIM RX5 Mux", slim_rx_mux_enum,
1384 slim_rx_mux_get, slim_rx_mux_put),
1385 SOC_DAPM_ENUM_EXT("SLIM RX6 Mux", slim_rx_mux_enum,
1386 slim_rx_mux_get, slim_rx_mux_put),
1387 SOC_DAPM_ENUM_EXT("SLIM RX7 Mux", slim_rx_mux_enum,
1388 slim_rx_mux_get, slim_rx_mux_put),
1389 };
1390
1391 static const struct snd_kcontrol_new aif1_cap_mixer[] = {
1392 SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD9335_TX0, 1, 0,
1393 slim_tx_mixer_get, slim_tx_mixer_put),
1394 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD9335_TX1, 1, 0,
1395 slim_tx_mixer_get, slim_tx_mixer_put),
1396 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD9335_TX2, 1, 0,
1397 slim_tx_mixer_get, slim_tx_mixer_put),
1398 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD9335_TX3, 1, 0,
1399 slim_tx_mixer_get, slim_tx_mixer_put),
1400 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD9335_TX4, 1, 0,
1401 slim_tx_mixer_get, slim_tx_mixer_put),
1402 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD9335_TX5, 1, 0,
1403 slim_tx_mixer_get, slim_tx_mixer_put),
1404 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD9335_TX6, 1, 0,
1405 slim_tx_mixer_get, slim_tx_mixer_put),
1406 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD9335_TX7, 1, 0,
1407 slim_tx_mixer_get, slim_tx_mixer_put),
1408 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD9335_TX8, 1, 0,
1409 slim_tx_mixer_get, slim_tx_mixer_put),
1410 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD9335_TX9, 1, 0,
1411 slim_tx_mixer_get, slim_tx_mixer_put),
1412 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD9335_TX10, 1, 0,
1413 slim_tx_mixer_get, slim_tx_mixer_put),
1414 SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD9335_TX11, 1, 0,
1415 slim_tx_mixer_get, slim_tx_mixer_put),
1416 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD9335_TX13, 1, 0,
1417 slim_tx_mixer_get, slim_tx_mixer_put),
1418 };
1419
1420 static const struct snd_kcontrol_new aif2_cap_mixer[] = {
1421 SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD9335_TX0, 1, 0,
1422 slim_tx_mixer_get, slim_tx_mixer_put),
1423 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD9335_TX1, 1, 0,
1424 slim_tx_mixer_get, slim_tx_mixer_put),
1425 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD9335_TX2, 1, 0,
1426 slim_tx_mixer_get, slim_tx_mixer_put),
1427 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD9335_TX3, 1, 0,
1428 slim_tx_mixer_get, slim_tx_mixer_put),
1429 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD9335_TX4, 1, 0,
1430 slim_tx_mixer_get, slim_tx_mixer_put),
1431 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD9335_TX5, 1, 0,
1432 slim_tx_mixer_get, slim_tx_mixer_put),
1433 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD9335_TX6, 1, 0,
1434 slim_tx_mixer_get, slim_tx_mixer_put),
1435 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD9335_TX7, 1, 0,
1436 slim_tx_mixer_get, slim_tx_mixer_put),
1437 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD9335_TX8, 1, 0,
1438 slim_tx_mixer_get, slim_tx_mixer_put),
1439 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD9335_TX9, 1, 0,
1440 slim_tx_mixer_get, slim_tx_mixer_put),
1441 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD9335_TX10, 1, 0,
1442 slim_tx_mixer_get, slim_tx_mixer_put),
1443 SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD9335_TX11, 1, 0,
1444 slim_tx_mixer_get, slim_tx_mixer_put),
1445 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD9335_TX13, 1, 0,
1446 slim_tx_mixer_get, slim_tx_mixer_put),
1447 };
1448
1449 static const struct snd_kcontrol_new aif3_cap_mixer[] = {
1450 SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD9335_TX0, 1, 0,
1451 slim_tx_mixer_get, slim_tx_mixer_put),
1452 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD9335_TX1, 1, 0,
1453 slim_tx_mixer_get, slim_tx_mixer_put),
1454 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD9335_TX2, 1, 0,
1455 slim_tx_mixer_get, slim_tx_mixer_put),
1456 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD9335_TX3, 1, 0,
1457 slim_tx_mixer_get, slim_tx_mixer_put),
1458 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD9335_TX4, 1, 0,
1459 slim_tx_mixer_get, slim_tx_mixer_put),
1460 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD9335_TX5, 1, 0,
1461 slim_tx_mixer_get, slim_tx_mixer_put),
1462 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD9335_TX6, 1, 0,
1463 slim_tx_mixer_get, slim_tx_mixer_put),
1464 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD9335_TX7, 1, 0,
1465 slim_tx_mixer_get, slim_tx_mixer_put),
1466 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD9335_TX8, 1, 0,
1467 slim_tx_mixer_get, slim_tx_mixer_put),
1468 };
1469
wcd9335_put_dec_enum(struct snd_kcontrol * kc,struct snd_ctl_elem_value * ucontrol)1470 static int wcd9335_put_dec_enum(struct snd_kcontrol *kc,
1471 struct snd_ctl_elem_value *ucontrol)
1472 {
1473 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kc);
1474 struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
1475 struct soc_enum *e = (struct soc_enum *)kc->private_value;
1476 unsigned int val, reg, sel;
1477
1478 val = ucontrol->value.enumerated.item[0];
1479
1480 switch (e->reg) {
1481 case WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1:
1482 reg = WCD9335_CDC_TX0_TX_PATH_CFG0;
1483 break;
1484 case WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1:
1485 reg = WCD9335_CDC_TX1_TX_PATH_CFG0;
1486 break;
1487 case WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1:
1488 reg = WCD9335_CDC_TX2_TX_PATH_CFG0;
1489 break;
1490 case WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1:
1491 reg = WCD9335_CDC_TX3_TX_PATH_CFG0;
1492 break;
1493 case WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0:
1494 reg = WCD9335_CDC_TX4_TX_PATH_CFG0;
1495 break;
1496 case WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0:
1497 reg = WCD9335_CDC_TX5_TX_PATH_CFG0;
1498 break;
1499 case WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0:
1500 reg = WCD9335_CDC_TX6_TX_PATH_CFG0;
1501 break;
1502 case WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0:
1503 reg = WCD9335_CDC_TX7_TX_PATH_CFG0;
1504 break;
1505 case WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0:
1506 reg = WCD9335_CDC_TX8_TX_PATH_CFG0;
1507 break;
1508 default:
1509 return -EINVAL;
1510 }
1511
1512 /* AMIC: 0, DMIC: 1 */
1513 sel = val ? WCD9335_CDC_TX_ADC_AMIC_SEL : WCD9335_CDC_TX_ADC_DMIC_SEL;
1514 snd_soc_component_update_bits(component, reg,
1515 WCD9335_CDC_TX_ADC_AMIC_DMIC_SEL_MASK,
1516 sel);
1517
1518 return snd_soc_dapm_put_enum_double(kc, ucontrol);
1519 }
1520
wcd9335_int_dem_inp_mux_put(struct snd_kcontrol * kc,struct snd_ctl_elem_value * ucontrol)1521 static int wcd9335_int_dem_inp_mux_put(struct snd_kcontrol *kc,
1522 struct snd_ctl_elem_value *ucontrol)
1523 {
1524 struct soc_enum *e = (struct soc_enum *)kc->private_value;
1525 struct snd_soc_component *component;
1526 int reg, val;
1527
1528 component = snd_soc_dapm_kcontrol_component(kc);
1529 val = ucontrol->value.enumerated.item[0];
1530
1531 if (e->reg == WCD9335_CDC_RX0_RX_PATH_SEC0)
1532 reg = WCD9335_CDC_RX0_RX_PATH_CFG0;
1533 else if (e->reg == WCD9335_CDC_RX1_RX_PATH_SEC0)
1534 reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
1535 else if (e->reg == WCD9335_CDC_RX2_RX_PATH_SEC0)
1536 reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
1537 else
1538 return -EINVAL;
1539
1540 /* Set Look Ahead Delay */
1541 snd_soc_component_update_bits(component, reg,
1542 WCD9335_CDC_RX_PATH_CFG0_DLY_ZN_EN_MASK,
1543 val ? WCD9335_CDC_RX_PATH_CFG0_DLY_ZN_EN : 0);
1544 /* Set DEM INP Select */
1545 return snd_soc_dapm_put_enum_double(kc, ucontrol);
1546 }
1547
1548 static const struct snd_kcontrol_new rx_int0_dem_inp_mux =
1549 SOC_DAPM_ENUM_EXT("RX INT0 DEM MUX Mux", rx_int0_dem_inp_mux_enum,
1550 snd_soc_dapm_get_enum_double,
1551 wcd9335_int_dem_inp_mux_put);
1552
1553 static const struct snd_kcontrol_new rx_int1_dem_inp_mux =
1554 SOC_DAPM_ENUM_EXT("RX INT1 DEM MUX Mux", rx_int1_dem_inp_mux_enum,
1555 snd_soc_dapm_get_enum_double,
1556 wcd9335_int_dem_inp_mux_put);
1557
1558 static const struct snd_kcontrol_new rx_int2_dem_inp_mux =
1559 SOC_DAPM_ENUM_EXT("RX INT2 DEM MUX Mux", rx_int2_dem_inp_mux_enum,
1560 snd_soc_dapm_get_enum_double,
1561 wcd9335_int_dem_inp_mux_put);
1562
1563 static const struct snd_kcontrol_new tx_adc_mux0 =
1564 SOC_DAPM_ENUM_EXT("ADC MUX0 Mux", tx_adc_mux0_chain_enum,
1565 snd_soc_dapm_get_enum_double,
1566 wcd9335_put_dec_enum);
1567
1568 static const struct snd_kcontrol_new tx_adc_mux1 =
1569 SOC_DAPM_ENUM_EXT("ADC MUX1 Mux", tx_adc_mux1_chain_enum,
1570 snd_soc_dapm_get_enum_double,
1571 wcd9335_put_dec_enum);
1572
1573 static const struct snd_kcontrol_new tx_adc_mux2 =
1574 SOC_DAPM_ENUM_EXT("ADC MUX2 Mux", tx_adc_mux2_chain_enum,
1575 snd_soc_dapm_get_enum_double,
1576 wcd9335_put_dec_enum);
1577
1578 static const struct snd_kcontrol_new tx_adc_mux3 =
1579 SOC_DAPM_ENUM_EXT("ADC MUX3 Mux", tx_adc_mux3_chain_enum,
1580 snd_soc_dapm_get_enum_double,
1581 wcd9335_put_dec_enum);
1582
1583 static const struct snd_kcontrol_new tx_adc_mux4 =
1584 SOC_DAPM_ENUM_EXT("ADC MUX4 Mux", tx_adc_mux4_chain_enum,
1585 snd_soc_dapm_get_enum_double,
1586 wcd9335_put_dec_enum);
1587
1588 static const struct snd_kcontrol_new tx_adc_mux5 =
1589 SOC_DAPM_ENUM_EXT("ADC MUX5 Mux", tx_adc_mux5_chain_enum,
1590 snd_soc_dapm_get_enum_double,
1591 wcd9335_put_dec_enum);
1592
1593 static const struct snd_kcontrol_new tx_adc_mux6 =
1594 SOC_DAPM_ENUM_EXT("ADC MUX6 Mux", tx_adc_mux6_chain_enum,
1595 snd_soc_dapm_get_enum_double,
1596 wcd9335_put_dec_enum);
1597
1598 static const struct snd_kcontrol_new tx_adc_mux7 =
1599 SOC_DAPM_ENUM_EXT("ADC MUX7 Mux", tx_adc_mux7_chain_enum,
1600 snd_soc_dapm_get_enum_double,
1601 wcd9335_put_dec_enum);
1602
1603 static const struct snd_kcontrol_new tx_adc_mux8 =
1604 SOC_DAPM_ENUM_EXT("ADC MUX8 Mux", tx_adc_mux8_chain_enum,
1605 snd_soc_dapm_get_enum_double,
1606 wcd9335_put_dec_enum);
1607
wcd9335_set_mix_interpolator_rate(struct snd_soc_dai * dai,int rate_val,u32 rate)1608 static int wcd9335_set_mix_interpolator_rate(struct snd_soc_dai *dai,
1609 int rate_val,
1610 u32 rate)
1611 {
1612 struct snd_soc_component *component = dai->component;
1613 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
1614 struct wcd9335_slim_ch *ch;
1615 int val, j;
1616
1617 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) {
1618 for (j = 0; j < WCD9335_NUM_INTERPOLATORS; j++) {
1619 val = snd_soc_component_read(component,
1620 WCD9335_CDC_RX_INP_MUX_RX_INT_CFG1(j)) &
1621 WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK;
1622
1623 if (val == (ch->shift + INTn_2_INP_SEL_RX0))
1624 snd_soc_component_update_bits(component,
1625 WCD9335_CDC_RX_PATH_MIX_CTL(j),
1626 WCD9335_CDC_MIX_PCM_RATE_MASK,
1627 rate_val);
1628 }
1629 }
1630
1631 return 0;
1632 }
1633
wcd9335_set_prim_interpolator_rate(struct snd_soc_dai * dai,u8 rate_val,u32 rate)1634 static int wcd9335_set_prim_interpolator_rate(struct snd_soc_dai *dai,
1635 u8 rate_val,
1636 u32 rate)
1637 {
1638 struct snd_soc_component *comp = dai->component;
1639 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
1640 struct wcd9335_slim_ch *ch;
1641 u8 cfg0, cfg1, inp0_sel, inp1_sel, inp2_sel;
1642 int inp, j;
1643
1644 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) {
1645 inp = ch->shift + INTn_1_MIX_INP_SEL_RX0;
1646 /*
1647 * Loop through all interpolator MUX inputs and find out
1648 * to which interpolator input, the slim rx port
1649 * is connected
1650 */
1651 for (j = 0; j < WCD9335_NUM_INTERPOLATORS; j++) {
1652 cfg0 = snd_soc_component_read(comp,
1653 WCD9335_CDC_RX_INP_MUX_RX_INT_CFG0(j));
1654 cfg1 = snd_soc_component_read(comp,
1655 WCD9335_CDC_RX_INP_MUX_RX_INT_CFG1(j));
1656
1657 inp0_sel = cfg0 &
1658 WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK;
1659 inp1_sel = (cfg0 >> 4) &
1660 WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK;
1661 inp2_sel = (cfg1 >> 4) &
1662 WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK;
1663
1664 if ((inp0_sel == inp) || (inp1_sel == inp) ||
1665 (inp2_sel == inp)) {
1666 /* rate is in Hz */
1667 if ((j == 0) && (rate == 44100))
1668 dev_info(wcd->dev,
1669 "Cannot set 44.1KHz on INT0\n");
1670 else
1671 snd_soc_component_update_bits(comp,
1672 WCD9335_CDC_RX_PATH_CTL(j),
1673 WCD9335_CDC_MIX_PCM_RATE_MASK,
1674 rate_val);
1675 }
1676 }
1677 }
1678
1679 return 0;
1680 }
1681
wcd9335_set_interpolator_rate(struct snd_soc_dai * dai,u32 rate)1682 static int wcd9335_set_interpolator_rate(struct snd_soc_dai *dai, u32 rate)
1683 {
1684 int i;
1685
1686 /* set mixing path rate */
1687 for (i = 0; i < ARRAY_SIZE(int_mix_rate_val); i++) {
1688 if (rate == int_mix_rate_val[i].rate) {
1689 wcd9335_set_mix_interpolator_rate(dai,
1690 int_mix_rate_val[i].rate_val, rate);
1691 break;
1692 }
1693 }
1694
1695 /* set primary path sample rate */
1696 for (i = 0; i < ARRAY_SIZE(int_prim_rate_val); i++) {
1697 if (rate == int_prim_rate_val[i].rate) {
1698 wcd9335_set_prim_interpolator_rate(dai,
1699 int_prim_rate_val[i].rate_val, rate);
1700 break;
1701 }
1702 }
1703
1704 return 0;
1705 }
1706
wcd9335_slim_set_hw_params(struct wcd9335_codec * wcd,struct wcd_slim_codec_dai_data * dai_data,int direction)1707 static int wcd9335_slim_set_hw_params(struct wcd9335_codec *wcd,
1708 struct wcd_slim_codec_dai_data *dai_data,
1709 int direction)
1710 {
1711 struct list_head *slim_ch_list = &dai_data->slim_ch_list;
1712 struct slim_stream_config *cfg = &dai_data->sconfig;
1713 struct wcd9335_slim_ch *ch;
1714 u16 payload = 0;
1715 int ret, i;
1716
1717 cfg->ch_count = 0;
1718 cfg->direction = direction;
1719 cfg->port_mask = 0;
1720
1721 /* Configure slave interface device */
1722 list_for_each_entry(ch, slim_ch_list, list) {
1723 cfg->ch_count++;
1724 payload |= 1 << ch->shift;
1725 cfg->port_mask |= BIT(ch->port);
1726 }
1727
1728 cfg->chs = kcalloc(cfg->ch_count, sizeof(unsigned int), GFP_KERNEL);
1729 if (!cfg->chs)
1730 return -ENOMEM;
1731
1732 i = 0;
1733 list_for_each_entry(ch, slim_ch_list, list) {
1734 cfg->chs[i++] = ch->ch_num;
1735 if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
1736 /* write to interface device */
1737 ret = regmap_write(wcd->if_regmap,
1738 WCD9335_SLIM_PGD_RX_PORT_MULTI_CHNL_0(ch->port),
1739 payload);
1740
1741 if (ret < 0)
1742 goto err;
1743
1744 /* configure the slave port for water mark and enable*/
1745 ret = regmap_write(wcd->if_regmap,
1746 WCD9335_SLIM_PGD_RX_PORT_CFG(ch->port),
1747 WCD9335_SLIM_WATER_MARK_VAL);
1748 if (ret < 0)
1749 goto err;
1750 } else {
1751 ret = regmap_write(wcd->if_regmap,
1752 WCD9335_SLIM_PGD_TX_PORT_MULTI_CHNL_0(ch->port),
1753 payload & 0x00FF);
1754 if (ret < 0)
1755 goto err;
1756
1757 /* ports 8,9 */
1758 ret = regmap_write(wcd->if_regmap,
1759 WCD9335_SLIM_PGD_TX_PORT_MULTI_CHNL_1(ch->port),
1760 (payload & 0xFF00)>>8);
1761 if (ret < 0)
1762 goto err;
1763
1764 /* configure the slave port for water mark and enable*/
1765 ret = regmap_write(wcd->if_regmap,
1766 WCD9335_SLIM_PGD_TX_PORT_CFG(ch->port),
1767 WCD9335_SLIM_WATER_MARK_VAL);
1768
1769 if (ret < 0)
1770 goto err;
1771 }
1772 }
1773
1774 dai_data->sruntime = slim_stream_allocate(wcd->slim, "WCD9335-SLIM");
1775
1776 return 0;
1777
1778 err:
1779 dev_err(wcd->dev, "Error Setting slim hw params\n");
1780 kfree(cfg->chs);
1781 cfg->chs = NULL;
1782
1783 return ret;
1784 }
1785
wcd9335_set_decimator_rate(struct snd_soc_dai * dai,u8 rate_val,u32 rate)1786 static int wcd9335_set_decimator_rate(struct snd_soc_dai *dai,
1787 u8 rate_val, u32 rate)
1788 {
1789 struct snd_soc_component *comp = dai->component;
1790 struct wcd9335_codec *wcd = snd_soc_component_get_drvdata(comp);
1791 u8 shift = 0, shift_val = 0, tx_mux_sel;
1792 struct wcd9335_slim_ch *ch;
1793 int tx_port, tx_port_reg;
1794 int decimator = -1;
1795
1796 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) {
1797 tx_port = ch->port;
1798 if ((tx_port == 12) || (tx_port >= 14)) {
1799 dev_err(wcd->dev, "Invalid SLIM TX%u port DAI ID:%d\n",
1800 tx_port, dai->id);
1801 return -EINVAL;
1802 }
1803 /* Find the SB TX MUX input - which decimator is connected */
1804 if (tx_port < 4) {
1805 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0;
1806 shift = (tx_port << 1);
1807 shift_val = 0x03;
1808 } else if (tx_port < 8) {
1809 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1;
1810 shift = ((tx_port - 4) << 1);
1811 shift_val = 0x03;
1812 } else if (tx_port < 11) {
1813 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2;
1814 shift = ((tx_port - 8) << 1);
1815 shift_val = 0x03;
1816 } else if (tx_port == 11) {
1817 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3;
1818 shift = 0;
1819 shift_val = 0x0F;
1820 } else /* (tx_port == 13) */ {
1821 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3;
1822 shift = 4;
1823 shift_val = 0x03;
1824 }
1825
1826 tx_mux_sel = snd_soc_component_read(comp, tx_port_reg) &
1827 (shift_val << shift);
1828
1829 tx_mux_sel = tx_mux_sel >> shift;
1830 if (tx_port <= 8) {
1831 if ((tx_mux_sel == 0x2) || (tx_mux_sel == 0x3))
1832 decimator = tx_port;
1833 } else if (tx_port <= 10) {
1834 if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2))
1835 decimator = ((tx_port == 9) ? 7 : 6);
1836 } else if (tx_port == 11) {
1837 if ((tx_mux_sel >= 1) && (tx_mux_sel < 7))
1838 decimator = tx_mux_sel - 1;
1839 } else if (tx_port == 13) {
1840 if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2))
1841 decimator = 5;
1842 }
1843
1844 if (decimator >= 0) {
1845 snd_soc_component_update_bits(comp,
1846 WCD9335_CDC_TX_PATH_CTL(decimator),
1847 WCD9335_CDC_TX_PATH_CTL_PCM_RATE_MASK,
1848 rate_val);
1849 } else if ((tx_port <= 8) && (tx_mux_sel == 0x01)) {
1850 /* Check if the TX Mux input is RX MIX TXn */
1851 dev_err(wcd->dev, "RX_MIX_TX%u going to SLIM TX%u\n",
1852 tx_port, tx_port);
1853 } else {
1854 dev_err(wcd->dev, "ERROR: Invalid decimator: %d\n",
1855 decimator);
1856 return -EINVAL;
1857 }
1858 }
1859
1860 return 0;
1861 }
1862
wcd9335_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)1863 static int wcd9335_hw_params(struct snd_pcm_substream *substream,
1864 struct snd_pcm_hw_params *params,
1865 struct snd_soc_dai *dai)
1866 {
1867 struct wcd9335_codec *wcd;
1868 int ret, tx_fs_rate = 0;
1869
1870 wcd = snd_soc_component_get_drvdata(dai->component);
1871
1872 switch (substream->stream) {
1873 case SNDRV_PCM_STREAM_PLAYBACK:
1874 ret = wcd9335_set_interpolator_rate(dai, params_rate(params));
1875 if (ret) {
1876 dev_err(wcd->dev, "cannot set sample rate: %u\n",
1877 params_rate(params));
1878 return ret;
1879 }
1880 switch (params_width(params)) {
1881 case 16 ... 24:
1882 wcd->dai[dai->id].sconfig.bps = params_width(params);
1883 break;
1884 default:
1885 dev_err(wcd->dev, "%s: Invalid format 0x%x\n",
1886 __func__, params_width(params));
1887 return -EINVAL;
1888 }
1889 break;
1890
1891 case SNDRV_PCM_STREAM_CAPTURE:
1892 switch (params_rate(params)) {
1893 case 8000:
1894 tx_fs_rate = 0;
1895 break;
1896 case 16000:
1897 tx_fs_rate = 1;
1898 break;
1899 case 32000:
1900 tx_fs_rate = 3;
1901 break;
1902 case 48000:
1903 tx_fs_rate = 4;
1904 break;
1905 case 96000:
1906 tx_fs_rate = 5;
1907 break;
1908 case 192000:
1909 tx_fs_rate = 6;
1910 break;
1911 case 384000:
1912 tx_fs_rate = 7;
1913 break;
1914 default:
1915 dev_err(wcd->dev, "%s: Invalid TX sample rate: %d\n",
1916 __func__, params_rate(params));
1917 return -EINVAL;
1918
1919 }
1920
1921 ret = wcd9335_set_decimator_rate(dai, tx_fs_rate,
1922 params_rate(params));
1923 if (ret < 0) {
1924 dev_err(wcd->dev, "Cannot set TX Decimator rate\n");
1925 return ret;
1926 }
1927 switch (params_width(params)) {
1928 case 16 ... 32:
1929 wcd->dai[dai->id].sconfig.bps = params_width(params);
1930 break;
1931 default:
1932 dev_err(wcd->dev, "%s: Invalid format 0x%x\n",
1933 __func__, params_width(params));
1934 return -EINVAL;
1935 }
1936 break;
1937 default:
1938 dev_err(wcd->dev, "Invalid stream type %d\n",
1939 substream->stream);
1940 return -EINVAL;
1941 }
1942
1943 wcd->dai[dai->id].sconfig.rate = params_rate(params);
1944 wcd9335_slim_set_hw_params(wcd, &wcd->dai[dai->id], substream->stream);
1945
1946 return 0;
1947 }
1948
wcd9335_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * dai)1949 static int wcd9335_trigger(struct snd_pcm_substream *substream, int cmd,
1950 struct snd_soc_dai *dai)
1951 {
1952 struct wcd_slim_codec_dai_data *dai_data;
1953 struct wcd9335_codec *wcd;
1954 struct slim_stream_config *cfg;
1955
1956 wcd = snd_soc_component_get_drvdata(dai->component);
1957
1958 dai_data = &wcd->dai[dai->id];
1959
1960 switch (cmd) {
1961 case SNDRV_PCM_TRIGGER_START:
1962 case SNDRV_PCM_TRIGGER_RESUME:
1963 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1964 cfg = &dai_data->sconfig;
1965 slim_stream_prepare(dai_data->sruntime, cfg);
1966 slim_stream_enable(dai_data->sruntime);
1967 break;
1968 case SNDRV_PCM_TRIGGER_STOP:
1969 case SNDRV_PCM_TRIGGER_SUSPEND:
1970 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1971 slim_stream_disable(dai_data->sruntime);
1972 slim_stream_unprepare(dai_data->sruntime);
1973 break;
1974 default:
1975 break;
1976 }
1977
1978 return 0;
1979 }
1980
wcd9335_set_channel_map(struct snd_soc_dai * dai,unsigned int tx_num,const unsigned int * tx_slot,unsigned int rx_num,const unsigned int * rx_slot)1981 static int wcd9335_set_channel_map(struct snd_soc_dai *dai,
1982 unsigned int tx_num,
1983 const unsigned int *tx_slot,
1984 unsigned int rx_num,
1985 const unsigned int *rx_slot)
1986 {
1987 struct wcd9335_codec *wcd;
1988 int i;
1989
1990 wcd = snd_soc_component_get_drvdata(dai->component);
1991
1992 if (!tx_slot || !rx_slot) {
1993 dev_err(wcd->dev, "Invalid tx_slot=%p, rx_slot=%p\n",
1994 tx_slot, rx_slot);
1995 return -EINVAL;
1996 }
1997
1998 wcd->num_rx_port = rx_num;
1999 for (i = 0; i < rx_num; i++) {
2000 wcd->rx_chs[i].ch_num = rx_slot[i];
2001 INIT_LIST_HEAD(&wcd->rx_chs[i].list);
2002 }
2003
2004 wcd->num_tx_port = tx_num;
2005 for (i = 0; i < tx_num; i++) {
2006 wcd->tx_chs[i].ch_num = tx_slot[i];
2007 INIT_LIST_HEAD(&wcd->tx_chs[i].list);
2008 }
2009
2010 return 0;
2011 }
2012
wcd9335_get_channel_map(const struct snd_soc_dai * dai,unsigned int * tx_num,unsigned int * tx_slot,unsigned int * rx_num,unsigned int * rx_slot)2013 static int wcd9335_get_channel_map(const struct snd_soc_dai *dai,
2014 unsigned int *tx_num, unsigned int *tx_slot,
2015 unsigned int *rx_num, unsigned int *rx_slot)
2016 {
2017 struct wcd9335_slim_ch *ch;
2018 struct wcd9335_codec *wcd;
2019 int i = 0;
2020
2021 wcd = snd_soc_component_get_drvdata(dai->component);
2022
2023 switch (dai->id) {
2024 case AIF1_PB:
2025 case AIF2_PB:
2026 case AIF3_PB:
2027 case AIF4_PB:
2028 if (!rx_slot || !rx_num) {
2029 dev_err(wcd->dev, "Invalid rx_slot %p or rx_num %p\n",
2030 rx_slot, rx_num);
2031 return -EINVAL;
2032 }
2033
2034 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list)
2035 rx_slot[i++] = ch->ch_num;
2036
2037 *rx_num = i;
2038 break;
2039 case AIF1_CAP:
2040 case AIF2_CAP:
2041 case AIF3_CAP:
2042 if (!tx_slot || !tx_num) {
2043 dev_err(wcd->dev, "Invalid tx_slot %p or tx_num %p\n",
2044 tx_slot, tx_num);
2045 return -EINVAL;
2046 }
2047 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list)
2048 tx_slot[i++] = ch->ch_num;
2049
2050 *tx_num = i;
2051 break;
2052 default:
2053 dev_err(wcd->dev, "Invalid DAI ID %x\n", dai->id);
2054 break;
2055 }
2056
2057 return 0;
2058 }
2059
2060 static const struct snd_soc_dai_ops wcd9335_dai_ops = {
2061 .hw_params = wcd9335_hw_params,
2062 .trigger = wcd9335_trigger,
2063 .set_channel_map = wcd9335_set_channel_map,
2064 .get_channel_map = wcd9335_get_channel_map,
2065 };
2066
2067 static struct snd_soc_dai_driver wcd9335_slim_dais[] = {
2068 [0] = {
2069 .name = "wcd9335_rx1",
2070 .id = AIF1_PB,
2071 .playback = {
2072 .stream_name = "AIF1 Playback",
2073 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK |
2074 SNDRV_PCM_RATE_384000,
2075 .formats = WCD9335_FORMATS_S16_S24_LE,
2076 .rate_max = 384000,
2077 .rate_min = 8000,
2078 .channels_min = 1,
2079 .channels_max = 2,
2080 },
2081 .ops = &wcd9335_dai_ops,
2082 },
2083 [1] = {
2084 .name = "wcd9335_tx1",
2085 .id = AIF1_CAP,
2086 .capture = {
2087 .stream_name = "AIF1 Capture",
2088 .rates = WCD9335_RATES_MASK,
2089 .formats = SNDRV_PCM_FMTBIT_S16_LE,
2090 .rate_min = 8000,
2091 .rate_max = 192000,
2092 .channels_min = 1,
2093 .channels_max = 4,
2094 },
2095 .ops = &wcd9335_dai_ops,
2096 },
2097 [2] = {
2098 .name = "wcd9335_rx2",
2099 .id = AIF2_PB,
2100 .playback = {
2101 .stream_name = "AIF2 Playback",
2102 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK |
2103 SNDRV_PCM_RATE_384000,
2104 .formats = WCD9335_FORMATS_S16_S24_LE,
2105 .rate_min = 8000,
2106 .rate_max = 384000,
2107 .channels_min = 1,
2108 .channels_max = 2,
2109 },
2110 .ops = &wcd9335_dai_ops,
2111 },
2112 [3] = {
2113 .name = "wcd9335_tx2",
2114 .id = AIF2_CAP,
2115 .capture = {
2116 .stream_name = "AIF2 Capture",
2117 .rates = WCD9335_RATES_MASK,
2118 .formats = SNDRV_PCM_FMTBIT_S16_LE,
2119 .rate_min = 8000,
2120 .rate_max = 192000,
2121 .channels_min = 1,
2122 .channels_max = 4,
2123 },
2124 .ops = &wcd9335_dai_ops,
2125 },
2126 [4] = {
2127 .name = "wcd9335_rx3",
2128 .id = AIF3_PB,
2129 .playback = {
2130 .stream_name = "AIF3 Playback",
2131 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK |
2132 SNDRV_PCM_RATE_384000,
2133 .formats = WCD9335_FORMATS_S16_S24_LE,
2134 .rate_min = 8000,
2135 .rate_max = 384000,
2136 .channels_min = 1,
2137 .channels_max = 2,
2138 },
2139 .ops = &wcd9335_dai_ops,
2140 },
2141 [5] = {
2142 .name = "wcd9335_tx3",
2143 .id = AIF3_CAP,
2144 .capture = {
2145 .stream_name = "AIF3 Capture",
2146 .rates = WCD9335_RATES_MASK,
2147 .formats = SNDRV_PCM_FMTBIT_S16_LE,
2148 .rate_min = 8000,
2149 .rate_max = 192000,
2150 .channels_min = 1,
2151 .channels_max = 4,
2152 },
2153 .ops = &wcd9335_dai_ops,
2154 },
2155 [6] = {
2156 .name = "wcd9335_rx4",
2157 .id = AIF4_PB,
2158 .playback = {
2159 .stream_name = "AIF4 Playback",
2160 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK |
2161 SNDRV_PCM_RATE_384000,
2162 .formats = WCD9335_FORMATS_S16_S24_LE,
2163 .rate_min = 8000,
2164 .rate_max = 384000,
2165 .channels_min = 1,
2166 .channels_max = 2,
2167 },
2168 .ops = &wcd9335_dai_ops,
2169 },
2170 };
2171
wcd9335_get_compander(struct snd_kcontrol * kc,struct snd_ctl_elem_value * ucontrol)2172 static int wcd9335_get_compander(struct snd_kcontrol *kc,
2173 struct snd_ctl_elem_value *ucontrol)
2174 {
2175
2176 struct snd_soc_component *component = snd_soc_kcontrol_component(kc);
2177 int comp = ((struct soc_mixer_control *)kc->private_value)->shift;
2178 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
2179
2180 ucontrol->value.integer.value[0] = wcd->comp_enabled[comp];
2181 return 0;
2182 }
2183
wcd9335_set_compander(struct snd_kcontrol * kc,struct snd_ctl_elem_value * ucontrol)2184 static int wcd9335_set_compander(struct snd_kcontrol *kc,
2185 struct snd_ctl_elem_value *ucontrol)
2186 {
2187 struct snd_soc_component *component = snd_soc_kcontrol_component(kc);
2188 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
2189 int comp = ((struct soc_mixer_control *) kc->private_value)->shift;
2190 int value = ucontrol->value.integer.value[0];
2191 int sel;
2192
2193 wcd->comp_enabled[comp] = value;
2194 sel = value ? WCD9335_HPH_GAIN_SRC_SEL_COMPANDER :
2195 WCD9335_HPH_GAIN_SRC_SEL_REGISTER;
2196
2197 /* Any specific register configuration for compander */
2198 switch (comp) {
2199 case COMPANDER_1:
2200 /* Set Gain Source Select based on compander enable/disable */
2201 snd_soc_component_update_bits(component, WCD9335_HPH_L_EN,
2202 WCD9335_HPH_GAIN_SRC_SEL_MASK, sel);
2203 break;
2204 case COMPANDER_2:
2205 snd_soc_component_update_bits(component, WCD9335_HPH_R_EN,
2206 WCD9335_HPH_GAIN_SRC_SEL_MASK, sel);
2207 break;
2208 case COMPANDER_5:
2209 snd_soc_component_update_bits(component, WCD9335_SE_LO_LO3_GAIN,
2210 WCD9335_HPH_GAIN_SRC_SEL_MASK, sel);
2211 break;
2212 case COMPANDER_6:
2213 snd_soc_component_update_bits(component, WCD9335_SE_LO_LO4_GAIN,
2214 WCD9335_HPH_GAIN_SRC_SEL_MASK, sel);
2215 break;
2216 default:
2217 break;
2218 }
2219
2220 return 0;
2221 }
2222
wcd9335_rx_hph_mode_get(struct snd_kcontrol * kc,struct snd_ctl_elem_value * ucontrol)2223 static int wcd9335_rx_hph_mode_get(struct snd_kcontrol *kc,
2224 struct snd_ctl_elem_value *ucontrol)
2225 {
2226 struct snd_soc_component *component = snd_soc_kcontrol_component(kc);
2227 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
2228
2229 ucontrol->value.enumerated.item[0] = wcd->hph_mode;
2230
2231 return 0;
2232 }
2233
wcd9335_rx_hph_mode_put(struct snd_kcontrol * kc,struct snd_ctl_elem_value * ucontrol)2234 static int wcd9335_rx_hph_mode_put(struct snd_kcontrol *kc,
2235 struct snd_ctl_elem_value *ucontrol)
2236 {
2237 struct snd_soc_component *component = snd_soc_kcontrol_component(kc);
2238 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
2239 u32 mode_val;
2240
2241 mode_val = ucontrol->value.enumerated.item[0];
2242
2243 if (mode_val == 0) {
2244 dev_err(wcd->dev, "Invalid HPH Mode, default to ClSH HiFi\n");
2245 mode_val = CLS_H_HIFI;
2246 }
2247 wcd->hph_mode = mode_val;
2248
2249 return 0;
2250 }
2251
2252 static const struct snd_kcontrol_new wcd9335_snd_controls[] = {
2253 /* -84dB min - 40dB max */
2254 SOC_SINGLE_S8_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL,
2255 -84, 40, digital_gain),
2256 SOC_SINGLE_S8_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL,
2257 -84, 40, digital_gain),
2258 SOC_SINGLE_S8_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL,
2259 -84, 40, digital_gain),
2260 SOC_SINGLE_S8_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL,
2261 -84, 40, digital_gain),
2262 SOC_SINGLE_S8_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL,
2263 -84, 40, digital_gain),
2264 SOC_SINGLE_S8_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL,
2265 -84, 40, digital_gain),
2266 SOC_SINGLE_S8_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL,
2267 -84, 40, digital_gain),
2268 SOC_SINGLE_S8_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL,
2269 -84, 40, digital_gain),
2270 SOC_SINGLE_S8_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL,
2271 -84, 40, digital_gain),
2272 SOC_SINGLE_S8_TLV("RX0 Mix Digital Volume", WCD9335_CDC_RX0_RX_VOL_MIX_CTL,
2273 -84, 40, digital_gain),
2274 SOC_SINGLE_S8_TLV("RX1 Mix Digital Volume", WCD9335_CDC_RX1_RX_VOL_MIX_CTL,
2275 -84, 40, digital_gain),
2276 SOC_SINGLE_S8_TLV("RX2 Mix Digital Volume", WCD9335_CDC_RX2_RX_VOL_MIX_CTL,
2277 -84, 40, digital_gain),
2278 SOC_SINGLE_S8_TLV("RX3 Mix Digital Volume", WCD9335_CDC_RX3_RX_VOL_MIX_CTL,
2279 -84, 40, digital_gain),
2280 SOC_SINGLE_S8_TLV("RX4 Mix Digital Volume", WCD9335_CDC_RX4_RX_VOL_MIX_CTL,
2281 -84, 40, digital_gain),
2282 SOC_SINGLE_S8_TLV("RX5 Mix Digital Volume", WCD9335_CDC_RX5_RX_VOL_MIX_CTL,
2283 -84, 40, digital_gain),
2284 SOC_SINGLE_S8_TLV("RX6 Mix Digital Volume", WCD9335_CDC_RX6_RX_VOL_MIX_CTL,
2285 -84, 40, digital_gain),
2286 SOC_SINGLE_S8_TLV("RX7 Mix Digital Volume", WCD9335_CDC_RX7_RX_VOL_MIX_CTL,
2287 -84, 40, digital_gain),
2288 SOC_SINGLE_S8_TLV("RX8 Mix Digital Volume", WCD9335_CDC_RX8_RX_VOL_MIX_CTL,
2289 -84, 40, digital_gain),
2290 SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum),
2291 SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum),
2292 SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum),
2293 SOC_ENUM("RX INT1_2 HPF cut off", cf_int1_2_enum),
2294 SOC_ENUM("RX INT2_1 HPF cut off", cf_int2_1_enum),
2295 SOC_ENUM("RX INT2_2 HPF cut off", cf_int2_2_enum),
2296 SOC_ENUM("RX INT3_1 HPF cut off", cf_int3_1_enum),
2297 SOC_ENUM("RX INT3_2 HPF cut off", cf_int3_2_enum),
2298 SOC_ENUM("RX INT4_1 HPF cut off", cf_int4_1_enum),
2299 SOC_ENUM("RX INT4_2 HPF cut off", cf_int4_2_enum),
2300 SOC_ENUM("RX INT5_1 HPF cut off", cf_int5_1_enum),
2301 SOC_ENUM("RX INT5_2 HPF cut off", cf_int5_2_enum),
2302 SOC_ENUM("RX INT6_1 HPF cut off", cf_int6_1_enum),
2303 SOC_ENUM("RX INT6_2 HPF cut off", cf_int6_2_enum),
2304 SOC_ENUM("RX INT7_1 HPF cut off", cf_int7_1_enum),
2305 SOC_ENUM("RX INT7_2 HPF cut off", cf_int7_2_enum),
2306 SOC_ENUM("RX INT8_1 HPF cut off", cf_int8_1_enum),
2307 SOC_ENUM("RX INT8_2 HPF cut off", cf_int8_2_enum),
2308 SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0,
2309 wcd9335_get_compander, wcd9335_set_compander),
2310 SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0,
2311 wcd9335_get_compander, wcd9335_set_compander),
2312 SOC_SINGLE_EXT("COMP3 Switch", SND_SOC_NOPM, COMPANDER_3, 1, 0,
2313 wcd9335_get_compander, wcd9335_set_compander),
2314 SOC_SINGLE_EXT("COMP4 Switch", SND_SOC_NOPM, COMPANDER_4, 1, 0,
2315 wcd9335_get_compander, wcd9335_set_compander),
2316 SOC_SINGLE_EXT("COMP5 Switch", SND_SOC_NOPM, COMPANDER_5, 1, 0,
2317 wcd9335_get_compander, wcd9335_set_compander),
2318 SOC_SINGLE_EXT("COMP6 Switch", SND_SOC_NOPM, COMPANDER_6, 1, 0,
2319 wcd9335_get_compander, wcd9335_set_compander),
2320 SOC_SINGLE_EXT("COMP7 Switch", SND_SOC_NOPM, COMPANDER_7, 1, 0,
2321 wcd9335_get_compander, wcd9335_set_compander),
2322 SOC_SINGLE_EXT("COMP8 Switch", SND_SOC_NOPM, COMPANDER_8, 1, 0,
2323 wcd9335_get_compander, wcd9335_set_compander),
2324 SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum,
2325 wcd9335_rx_hph_mode_get, wcd9335_rx_hph_mode_put),
2326
2327 /* Gain Controls */
2328 SOC_SINGLE_TLV("EAR PA Volume", WCD9335_ANA_EAR, 4, 4, 1,
2329 ear_pa_gain),
2330 SOC_SINGLE_TLV("HPHL Volume", WCD9335_HPH_L_EN, 0, 20, 1,
2331 line_gain),
2332 SOC_SINGLE_TLV("HPHR Volume", WCD9335_HPH_R_EN, 0, 20, 1,
2333 line_gain),
2334 SOC_SINGLE_TLV("LINEOUT1 Volume", WCD9335_DIFF_LO_LO1_COMPANDER,
2335 3, 16, 1, line_gain),
2336 SOC_SINGLE_TLV("LINEOUT2 Volume", WCD9335_DIFF_LO_LO2_COMPANDER,
2337 3, 16, 1, line_gain),
2338 SOC_SINGLE_TLV("LINEOUT3 Volume", WCD9335_SE_LO_LO3_GAIN, 0, 20, 1,
2339 line_gain),
2340 SOC_SINGLE_TLV("LINEOUT4 Volume", WCD9335_SE_LO_LO4_GAIN, 0, 20, 1,
2341 line_gain),
2342
2343 SOC_SINGLE_TLV("ADC1 Volume", WCD9335_ANA_AMIC1, 0, 20, 0,
2344 analog_gain),
2345 SOC_SINGLE_TLV("ADC2 Volume", WCD9335_ANA_AMIC2, 0, 20, 0,
2346 analog_gain),
2347 SOC_SINGLE_TLV("ADC3 Volume", WCD9335_ANA_AMIC3, 0, 20, 0,
2348 analog_gain),
2349 SOC_SINGLE_TLV("ADC4 Volume", WCD9335_ANA_AMIC4, 0, 20, 0,
2350 analog_gain),
2351 SOC_SINGLE_TLV("ADC5 Volume", WCD9335_ANA_AMIC5, 0, 20, 0,
2352 analog_gain),
2353 SOC_SINGLE_TLV("ADC6 Volume", WCD9335_ANA_AMIC6, 0, 20, 0,
2354 analog_gain),
2355
2356 SOC_ENUM("TX0 HPF cut off", cf_dec0_enum),
2357 SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
2358 SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
2359 SOC_ENUM("TX3 HPF cut off", cf_dec3_enum),
2360 SOC_ENUM("TX4 HPF cut off", cf_dec4_enum),
2361 SOC_ENUM("TX5 HPF cut off", cf_dec5_enum),
2362 SOC_ENUM("TX6 HPF cut off", cf_dec6_enum),
2363 SOC_ENUM("TX7 HPF cut off", cf_dec7_enum),
2364 SOC_ENUM("TX8 HPF cut off", cf_dec8_enum),
2365 };
2366
2367 static const struct snd_soc_dapm_route wcd9335_audio_map[] = {
2368 {"SLIM RX0 MUX", "AIF1_PB", "AIF1 PB"},
2369 {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"},
2370 {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"},
2371 {"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"},
2372 {"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"},
2373 {"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"},
2374 {"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"},
2375 {"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"},
2376
2377 {"SLIM RX0 MUX", "AIF2_PB", "AIF2 PB"},
2378 {"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"},
2379 {"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"},
2380 {"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"},
2381 {"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"},
2382 {"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"},
2383 {"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"},
2384 {"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"},
2385
2386 {"SLIM RX0 MUX", "AIF3_PB", "AIF3 PB"},
2387 {"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"},
2388 {"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"},
2389 {"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"},
2390 {"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"},
2391 {"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"},
2392 {"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"},
2393 {"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"},
2394
2395 {"SLIM RX0 MUX", "AIF4_PB", "AIF4 PB"},
2396 {"SLIM RX1 MUX", "AIF4_PB", "AIF4 PB"},
2397 {"SLIM RX2 MUX", "AIF4_PB", "AIF4 PB"},
2398 {"SLIM RX3 MUX", "AIF4_PB", "AIF4 PB"},
2399 {"SLIM RX4 MUX", "AIF4_PB", "AIF4 PB"},
2400 {"SLIM RX5 MUX", "AIF4_PB", "AIF4 PB"},
2401 {"SLIM RX6 MUX", "AIF4_PB", "AIF4 PB"},
2402 {"SLIM RX7 MUX", "AIF4_PB", "AIF4 PB"},
2403
2404 {"SLIM RX0", NULL, "SLIM RX0 MUX"},
2405 {"SLIM RX1", NULL, "SLIM RX1 MUX"},
2406 {"SLIM RX2", NULL, "SLIM RX2 MUX"},
2407 {"SLIM RX3", NULL, "SLIM RX3 MUX"},
2408 {"SLIM RX4", NULL, "SLIM RX4 MUX"},
2409 {"SLIM RX5", NULL, "SLIM RX5 MUX"},
2410 {"SLIM RX6", NULL, "SLIM RX6 MUX"},
2411 {"SLIM RX7", NULL, "SLIM RX7 MUX"},
2412
2413 WCD9335_INTERPOLATOR_PATH(0),
2414 WCD9335_INTERPOLATOR_PATH(1),
2415 WCD9335_INTERPOLATOR_PATH(2),
2416 WCD9335_INTERPOLATOR_PATH(3),
2417 WCD9335_INTERPOLATOR_PATH(4),
2418 WCD9335_INTERPOLATOR_PATH(5),
2419 WCD9335_INTERPOLATOR_PATH(6),
2420 WCD9335_INTERPOLATOR_PATH(7),
2421 WCD9335_INTERPOLATOR_PATH(8),
2422
2423 /* EAR PA */
2424 {"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 INTERP"},
2425 {"RX INT0 DAC", NULL, "RX INT0 DEM MUX"},
2426 {"RX INT0 DAC", NULL, "RX_BIAS"},
2427 {"EAR PA", NULL, "RX INT0 DAC"},
2428 {"EAR", NULL, "EAR PA"},
2429
2430 /* HPHL */
2431 {"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 INTERP"},
2432 {"RX INT1 DAC", NULL, "RX INT1 DEM MUX"},
2433 {"RX INT1 DAC", NULL, "RX_BIAS"},
2434 {"HPHL PA", NULL, "RX INT1 DAC"},
2435 {"HPHL", NULL, "HPHL PA"},
2436
2437 /* HPHR */
2438 {"RX INT2 DEM MUX", "CLSH_DSM_OUT", "RX INT2 INTERP"},
2439 {"RX INT2 DAC", NULL, "RX INT2 DEM MUX"},
2440 {"RX INT2 DAC", NULL, "RX_BIAS"},
2441 {"HPHR PA", NULL, "RX INT2 DAC"},
2442 {"HPHR", NULL, "HPHR PA"},
2443
2444 /* LINEOUT1 */
2445 {"RX INT3 DAC", NULL, "RX INT3 INTERP"},
2446 {"RX INT3 DAC", NULL, "RX_BIAS"},
2447 {"LINEOUT1 PA", NULL, "RX INT3 DAC"},
2448 {"LINEOUT1", NULL, "LINEOUT1 PA"},
2449
2450 /* LINEOUT2 */
2451 {"RX INT4 DAC", NULL, "RX INT4 INTERP"},
2452 {"RX INT4 DAC", NULL, "RX_BIAS"},
2453 {"LINEOUT2 PA", NULL, "RX INT4 DAC"},
2454 {"LINEOUT2", NULL, "LINEOUT2 PA"},
2455
2456 /* LINEOUT3 */
2457 {"RX INT5 DAC", NULL, "RX INT5 INTERP"},
2458 {"RX INT5 DAC", NULL, "RX_BIAS"},
2459 {"LINEOUT3 PA", NULL, "RX INT5 DAC"},
2460 {"LINEOUT3", NULL, "LINEOUT3 PA"},
2461
2462 /* LINEOUT4 */
2463 {"RX INT6 DAC", NULL, "RX INT6 INTERP"},
2464 {"RX INT6 DAC", NULL, "RX_BIAS"},
2465 {"LINEOUT4 PA", NULL, "RX INT6 DAC"},
2466 {"LINEOUT4", NULL, "LINEOUT4 PA"},
2467
2468 /* SLIMBUS Connections */
2469 {"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
2470 {"AIF2 CAP", NULL, "AIF2_CAP Mixer"},
2471 {"AIF3 CAP", NULL, "AIF3_CAP Mixer"},
2472
2473 /* ADC Mux */
2474 WCD9335_ADC_MUX_PATH(0),
2475 WCD9335_ADC_MUX_PATH(1),
2476 WCD9335_ADC_MUX_PATH(2),
2477 WCD9335_ADC_MUX_PATH(3),
2478 WCD9335_ADC_MUX_PATH(4),
2479 WCD9335_ADC_MUX_PATH(5),
2480 WCD9335_ADC_MUX_PATH(6),
2481 WCD9335_ADC_MUX_PATH(7),
2482 WCD9335_ADC_MUX_PATH(8),
2483
2484 /* ADC Connections */
2485 {"ADC1", NULL, "AMIC1"},
2486 {"ADC2", NULL, "AMIC2"},
2487 {"ADC3", NULL, "AMIC3"},
2488 {"ADC4", NULL, "AMIC4"},
2489 {"ADC5", NULL, "AMIC5"},
2490 {"ADC6", NULL, "AMIC6"},
2491 };
2492
wcd9335_micbias_control(struct snd_soc_component * component,int micb_num,int req,bool is_dapm)2493 static int wcd9335_micbias_control(struct snd_soc_component *component,
2494 int micb_num, int req, bool is_dapm)
2495 {
2496 struct wcd9335_codec *wcd = snd_soc_component_get_drvdata(component);
2497 int micb_index = micb_num - 1;
2498 u16 micb_reg;
2499
2500 if ((micb_index < 0) || (micb_index > WCD9335_MAX_MICBIAS - 1)) {
2501 dev_err(wcd->dev, "Invalid micbias index, micb_ind:%d\n",
2502 micb_index);
2503 return -EINVAL;
2504 }
2505
2506 switch (micb_num) {
2507 case MIC_BIAS_1:
2508 micb_reg = WCD9335_ANA_MICB1;
2509 break;
2510 case MIC_BIAS_2:
2511 micb_reg = WCD9335_ANA_MICB2;
2512 break;
2513 case MIC_BIAS_3:
2514 micb_reg = WCD9335_ANA_MICB3;
2515 break;
2516 case MIC_BIAS_4:
2517 micb_reg = WCD9335_ANA_MICB4;
2518 break;
2519 default:
2520 dev_err(component->dev, "%s: Invalid micbias number: %d\n",
2521 __func__, micb_num);
2522 return -EINVAL;
2523 }
2524
2525 switch (req) {
2526 case MICB_PULLUP_ENABLE:
2527 wcd->pullup_ref[micb_index]++;
2528 if ((wcd->pullup_ref[micb_index] == 1) &&
2529 (wcd->micb_ref[micb_index] == 0))
2530 snd_soc_component_update_bits(component, micb_reg,
2531 0xC0, 0x80);
2532 break;
2533 case MICB_PULLUP_DISABLE:
2534 wcd->pullup_ref[micb_index]--;
2535 if ((wcd->pullup_ref[micb_index] == 0) &&
2536 (wcd->micb_ref[micb_index] == 0))
2537 snd_soc_component_update_bits(component, micb_reg,
2538 0xC0, 0x00);
2539 break;
2540 case MICB_ENABLE:
2541 wcd->micb_ref[micb_index]++;
2542 if (wcd->micb_ref[micb_index] == 1)
2543 snd_soc_component_update_bits(component, micb_reg,
2544 0xC0, 0x40);
2545 break;
2546 case MICB_DISABLE:
2547 wcd->micb_ref[micb_index]--;
2548 if ((wcd->micb_ref[micb_index] == 0) &&
2549 (wcd->pullup_ref[micb_index] > 0))
2550 snd_soc_component_update_bits(component, micb_reg,
2551 0xC0, 0x80);
2552 else if ((wcd->micb_ref[micb_index] == 0) &&
2553 (wcd->pullup_ref[micb_index] == 0)) {
2554 snd_soc_component_update_bits(component, micb_reg,
2555 0xC0, 0x00);
2556 }
2557 break;
2558 }
2559
2560 return 0;
2561 }
2562
__wcd9335_codec_enable_micbias(struct snd_soc_dapm_widget * w,int event)2563 static int __wcd9335_codec_enable_micbias(struct snd_soc_dapm_widget *w,
2564 int event)
2565 {
2566 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
2567 int micb_num;
2568
2569 if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1")))
2570 micb_num = MIC_BIAS_1;
2571 else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2")))
2572 micb_num = MIC_BIAS_2;
2573 else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3")))
2574 micb_num = MIC_BIAS_3;
2575 else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4")))
2576 micb_num = MIC_BIAS_4;
2577 else
2578 return -EINVAL;
2579
2580 switch (event) {
2581 case SND_SOC_DAPM_PRE_PMU:
2582 /*
2583 * MIC BIAS can also be requested by MBHC,
2584 * so use ref count to handle micbias pullup
2585 * and enable requests
2586 */
2587 wcd9335_micbias_control(comp, micb_num, MICB_ENABLE, true);
2588 break;
2589 case SND_SOC_DAPM_POST_PMU:
2590 /* wait for cnp time */
2591 usleep_range(1000, 1100);
2592 break;
2593 case SND_SOC_DAPM_POST_PMD:
2594 wcd9335_micbias_control(comp, micb_num, MICB_DISABLE, true);
2595 break;
2596 }
2597
2598 return 0;
2599 }
2600
wcd9335_codec_enable_micbias(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kc,int event)2601 static int wcd9335_codec_enable_micbias(struct snd_soc_dapm_widget *w,
2602 struct snd_kcontrol *kc, int event)
2603 {
2604 return __wcd9335_codec_enable_micbias(w, event);
2605 }
2606
wcd9335_codec_set_tx_hold(struct snd_soc_component * comp,u16 amic_reg,bool set)2607 static void wcd9335_codec_set_tx_hold(struct snd_soc_component *comp,
2608 u16 amic_reg, bool set)
2609 {
2610 u8 mask = 0x20;
2611 u8 val;
2612
2613 if (amic_reg == WCD9335_ANA_AMIC1 || amic_reg == WCD9335_ANA_AMIC3 ||
2614 amic_reg == WCD9335_ANA_AMIC5)
2615 mask = 0x40;
2616
2617 val = set ? mask : 0x00;
2618
2619 switch (amic_reg) {
2620 case WCD9335_ANA_AMIC1:
2621 case WCD9335_ANA_AMIC2:
2622 snd_soc_component_update_bits(comp, WCD9335_ANA_AMIC2, mask,
2623 val);
2624 break;
2625 case WCD9335_ANA_AMIC3:
2626 case WCD9335_ANA_AMIC4:
2627 snd_soc_component_update_bits(comp, WCD9335_ANA_AMIC4, mask,
2628 val);
2629 break;
2630 case WCD9335_ANA_AMIC5:
2631 case WCD9335_ANA_AMIC6:
2632 snd_soc_component_update_bits(comp, WCD9335_ANA_AMIC6, mask,
2633 val);
2634 break;
2635 default:
2636 dev_err(comp->dev, "%s: invalid amic: %d\n",
2637 __func__, amic_reg);
2638 break;
2639 }
2640 }
2641
wcd9335_codec_enable_adc(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kc,int event)2642 static int wcd9335_codec_enable_adc(struct snd_soc_dapm_widget *w,
2643 struct snd_kcontrol *kc, int event)
2644 {
2645 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
2646
2647 switch (event) {
2648 case SND_SOC_DAPM_PRE_PMU:
2649 wcd9335_codec_set_tx_hold(comp, w->reg, true);
2650 break;
2651 default:
2652 break;
2653 }
2654
2655 return 0;
2656 }
2657
wcd9335_codec_find_amic_input(struct snd_soc_component * comp,int adc_mux_n)2658 static int wcd9335_codec_find_amic_input(struct snd_soc_component *comp,
2659 int adc_mux_n)
2660 {
2661 int mux_sel, reg, mreg;
2662
2663 if (adc_mux_n < 0 || adc_mux_n > WCD9335_MAX_VALID_ADC_MUX ||
2664 adc_mux_n == WCD9335_INVALID_ADC_MUX)
2665 return 0;
2666
2667 /* Check whether adc mux input is AMIC or DMIC */
2668 if (adc_mux_n < 4) {
2669 reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + 2 * adc_mux_n;
2670 mreg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + 2 * adc_mux_n;
2671 mux_sel = snd_soc_component_read(comp, reg) & 0x3;
2672 } else {
2673 reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + adc_mux_n - 4;
2674 mreg = reg;
2675 mux_sel = snd_soc_component_read(comp, reg) >> 6;
2676 }
2677
2678 if (mux_sel != WCD9335_CDC_TX_INP_MUX_SEL_AMIC)
2679 return 0;
2680
2681 return snd_soc_component_read(comp, mreg) & 0x07;
2682 }
2683
wcd9335_codec_get_amic_pwlvl_reg(struct snd_soc_component * comp,int amic)2684 static u16 wcd9335_codec_get_amic_pwlvl_reg(struct snd_soc_component *comp,
2685 int amic)
2686 {
2687 u16 pwr_level_reg = 0;
2688
2689 switch (amic) {
2690 case 1:
2691 case 2:
2692 pwr_level_reg = WCD9335_ANA_AMIC1;
2693 break;
2694
2695 case 3:
2696 case 4:
2697 pwr_level_reg = WCD9335_ANA_AMIC3;
2698 break;
2699
2700 case 5:
2701 case 6:
2702 pwr_level_reg = WCD9335_ANA_AMIC5;
2703 break;
2704 default:
2705 dev_err(comp->dev, "invalid amic: %d\n", amic);
2706 break;
2707 }
2708
2709 return pwr_level_reg;
2710 }
2711
wcd9335_codec_enable_dec(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kc,int event)2712 static int wcd9335_codec_enable_dec(struct snd_soc_dapm_widget *w,
2713 struct snd_kcontrol *kc, int event)
2714 {
2715 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
2716 unsigned int decimator;
2717 char *dec_adc_mux_name = NULL;
2718 char *widget_name;
2719 int ret = 0, amic_n;
2720 u16 tx_vol_ctl_reg, pwr_level_reg = 0, dec_cfg_reg, hpf_gate_reg;
2721 u16 tx_gain_ctl_reg;
2722 char *dec;
2723 u8 hpf_coff_freq;
2724
2725 char *wname __free(kfree) = kmemdup_nul(w->name, 15, GFP_KERNEL);
2726 if (!wname)
2727 return -ENOMEM;
2728
2729 widget_name = wname;
2730 dec_adc_mux_name = strsep(&widget_name, " ");
2731 if (!dec_adc_mux_name) {
2732 dev_err(comp->dev, "%s: Invalid decimator = %s\n",
2733 __func__, w->name);
2734 return -EINVAL;
2735 }
2736 dec_adc_mux_name = widget_name;
2737
2738 dec = strpbrk(dec_adc_mux_name, "012345678");
2739 if (!dec) {
2740 dev_err(comp->dev, "%s: decimator index not found\n",
2741 __func__);
2742 return -EINVAL;
2743 }
2744
2745 ret = kstrtouint(dec, 10, &decimator);
2746 if (ret < 0) {
2747 dev_err(comp->dev, "%s: Invalid decimator = %s\n",
2748 __func__, wname);
2749 return -EINVAL;
2750 }
2751
2752 tx_vol_ctl_reg = WCD9335_CDC_TX0_TX_PATH_CTL + 16 * decimator;
2753 hpf_gate_reg = WCD9335_CDC_TX0_TX_PATH_SEC2 + 16 * decimator;
2754 dec_cfg_reg = WCD9335_CDC_TX0_TX_PATH_CFG0 + 16 * decimator;
2755 tx_gain_ctl_reg = WCD9335_CDC_TX0_TX_VOL_CTL + 16 * decimator;
2756
2757 switch (event) {
2758 case SND_SOC_DAPM_PRE_PMU:
2759 amic_n = wcd9335_codec_find_amic_input(comp, decimator);
2760 if (amic_n)
2761 pwr_level_reg = wcd9335_codec_get_amic_pwlvl_reg(comp,
2762 amic_n);
2763
2764 if (pwr_level_reg) {
2765 switch ((snd_soc_component_read(comp, pwr_level_reg) &
2766 WCD9335_AMIC_PWR_LVL_MASK) >>
2767 WCD9335_AMIC_PWR_LVL_SHIFT) {
2768 case WCD9335_AMIC_PWR_LEVEL_LP:
2769 snd_soc_component_update_bits(comp, dec_cfg_reg,
2770 WCD9335_DEC_PWR_LVL_MASK,
2771 WCD9335_DEC_PWR_LVL_LP);
2772 break;
2773
2774 case WCD9335_AMIC_PWR_LEVEL_HP:
2775 snd_soc_component_update_bits(comp, dec_cfg_reg,
2776 WCD9335_DEC_PWR_LVL_MASK,
2777 WCD9335_DEC_PWR_LVL_HP);
2778 break;
2779 case WCD9335_AMIC_PWR_LEVEL_DEFAULT:
2780 default:
2781 snd_soc_component_update_bits(comp, dec_cfg_reg,
2782 WCD9335_DEC_PWR_LVL_MASK,
2783 WCD9335_DEC_PWR_LVL_DF);
2784 break;
2785 }
2786 }
2787 hpf_coff_freq = (snd_soc_component_read(comp, dec_cfg_reg) &
2788 TX_HPF_CUT_OFF_FREQ_MASK) >> 5;
2789
2790 if (hpf_coff_freq != CF_MIN_3DB_150HZ)
2791 snd_soc_component_update_bits(comp, dec_cfg_reg,
2792 TX_HPF_CUT_OFF_FREQ_MASK,
2793 CF_MIN_3DB_150HZ << 5);
2794 /* Enable TX PGA Mute */
2795 snd_soc_component_update_bits(comp, tx_vol_ctl_reg,
2796 0x10, 0x10);
2797 /* Enable APC */
2798 snd_soc_component_update_bits(comp, dec_cfg_reg, 0x08, 0x08);
2799 break;
2800 case SND_SOC_DAPM_POST_PMU:
2801 snd_soc_component_update_bits(comp, hpf_gate_reg, 0x01, 0x00);
2802
2803 if (decimator == 0) {
2804 snd_soc_component_write(comp,
2805 WCD9335_MBHC_ZDET_RAMP_CTL, 0x83);
2806 snd_soc_component_write(comp,
2807 WCD9335_MBHC_ZDET_RAMP_CTL, 0xA3);
2808 snd_soc_component_write(comp,
2809 WCD9335_MBHC_ZDET_RAMP_CTL, 0x83);
2810 snd_soc_component_write(comp,
2811 WCD9335_MBHC_ZDET_RAMP_CTL, 0x03);
2812 }
2813
2814 snd_soc_component_update_bits(comp, hpf_gate_reg,
2815 0x01, 0x01);
2816 snd_soc_component_update_bits(comp, tx_vol_ctl_reg,
2817 0x10, 0x00);
2818 snd_soc_component_write(comp, tx_gain_ctl_reg,
2819 snd_soc_component_read(comp, tx_gain_ctl_reg));
2820 break;
2821 case SND_SOC_DAPM_PRE_PMD:
2822 hpf_coff_freq = (snd_soc_component_read(comp, dec_cfg_reg) &
2823 TX_HPF_CUT_OFF_FREQ_MASK) >> 5;
2824 snd_soc_component_update_bits(comp, tx_vol_ctl_reg, 0x10, 0x10);
2825 snd_soc_component_update_bits(comp, dec_cfg_reg, 0x08, 0x00);
2826 if (hpf_coff_freq != CF_MIN_3DB_150HZ) {
2827 snd_soc_component_update_bits(comp, dec_cfg_reg,
2828 TX_HPF_CUT_OFF_FREQ_MASK,
2829 hpf_coff_freq << 5);
2830 }
2831 break;
2832 case SND_SOC_DAPM_POST_PMD:
2833 snd_soc_component_update_bits(comp, tx_vol_ctl_reg, 0x10, 0x00);
2834 break;
2835 }
2836
2837 return ret;
2838 }
2839
wcd9335_get_dmic_clk_val(struct snd_soc_component * component,u32 mclk_rate)2840 static u8 wcd9335_get_dmic_clk_val(struct snd_soc_component *component,
2841 u32 mclk_rate)
2842 {
2843 u8 dmic_ctl_val;
2844
2845 if (mclk_rate == WCD9335_MCLK_CLK_9P6MHZ)
2846 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2;
2847 else
2848 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3;
2849
2850 return dmic_ctl_val;
2851 }
2852
wcd9335_codec_enable_dmic(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kc,int event)2853 static int wcd9335_codec_enable_dmic(struct snd_soc_dapm_widget *w,
2854 struct snd_kcontrol *kc, int event)
2855 {
2856 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
2857 struct wcd9335_codec *wcd = snd_soc_component_get_drvdata(comp);
2858 u8 dmic_clk_en = 0x01;
2859 u16 dmic_clk_reg;
2860 s32 *dmic_clk_cnt;
2861 u8 dmic_rate_val, dmic_rate_shift = 1;
2862 unsigned int dmic;
2863 int ret;
2864 char *wname;
2865
2866 wname = strpbrk(w->name, "012345");
2867 if (!wname) {
2868 dev_err(comp->dev, "%s: widget not found\n", __func__);
2869 return -EINVAL;
2870 }
2871
2872 ret = kstrtouint(wname, 10, &dmic);
2873 if (ret < 0) {
2874 dev_err(comp->dev, "%s: Invalid DMIC line on the codec\n",
2875 __func__);
2876 return -EINVAL;
2877 }
2878
2879 switch (dmic) {
2880 case 0:
2881 case 1:
2882 dmic_clk_cnt = &(wcd->dmic_0_1_clk_cnt);
2883 dmic_clk_reg = WCD9335_CPE_SS_DMIC0_CTL;
2884 break;
2885 case 2:
2886 case 3:
2887 dmic_clk_cnt = &(wcd->dmic_2_3_clk_cnt);
2888 dmic_clk_reg = WCD9335_CPE_SS_DMIC1_CTL;
2889 break;
2890 case 4:
2891 case 5:
2892 dmic_clk_cnt = &(wcd->dmic_4_5_clk_cnt);
2893 dmic_clk_reg = WCD9335_CPE_SS_DMIC2_CTL;
2894 break;
2895 default:
2896 dev_err(comp->dev, "%s: Invalid DMIC Selection\n",
2897 __func__);
2898 return -EINVAL;
2899 }
2900
2901 switch (event) {
2902 case SND_SOC_DAPM_PRE_PMU:
2903 dmic_rate_val = wcd9335_get_dmic_clk_val(comp, wcd->mclk_rate);
2904 (*dmic_clk_cnt)++;
2905 if (*dmic_clk_cnt == 1) {
2906 snd_soc_component_update_bits(comp, dmic_clk_reg,
2907 0x07 << dmic_rate_shift,
2908 dmic_rate_val << dmic_rate_shift);
2909 snd_soc_component_update_bits(comp, dmic_clk_reg,
2910 dmic_clk_en, dmic_clk_en);
2911 }
2912
2913 break;
2914 case SND_SOC_DAPM_POST_PMD:
2915 dmic_rate_val = wcd9335_get_dmic_clk_val(comp, wcd->mclk_rate);
2916 (*dmic_clk_cnt)--;
2917 if (*dmic_clk_cnt == 0) {
2918 snd_soc_component_update_bits(comp, dmic_clk_reg,
2919 dmic_clk_en, 0);
2920 snd_soc_component_update_bits(comp, dmic_clk_reg,
2921 0x07 << dmic_rate_shift,
2922 dmic_rate_val << dmic_rate_shift);
2923 }
2924 break;
2925 }
2926
2927 return 0;
2928 }
2929
wcd9335_codec_enable_int_port(struct wcd_slim_codec_dai_data * dai,struct snd_soc_component * component)2930 static void wcd9335_codec_enable_int_port(struct wcd_slim_codec_dai_data *dai,
2931 struct snd_soc_component *component)
2932 {
2933 int port_num = 0;
2934 unsigned short reg = 0;
2935 unsigned int val = 0;
2936 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
2937 struct wcd9335_slim_ch *ch;
2938
2939 list_for_each_entry(ch, &dai->slim_ch_list, list) {
2940 if (ch->port >= WCD9335_RX_START) {
2941 port_num = ch->port - WCD9335_RX_START;
2942 reg = WCD9335_SLIM_PGD_PORT_INT_EN0 + (port_num / 8);
2943 } else {
2944 port_num = ch->port;
2945 reg = WCD9335_SLIM_PGD_PORT_INT_TX_EN0 + (port_num / 8);
2946 }
2947
2948 regmap_read(wcd->if_regmap, reg, &val);
2949 if (!(val & BIT(port_num % 8)))
2950 regmap_write(wcd->if_regmap, reg,
2951 val | BIT(port_num % 8));
2952 }
2953 }
2954
wcd9335_codec_enable_slim(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kc,int event)2955 static int wcd9335_codec_enable_slim(struct snd_soc_dapm_widget *w,
2956 struct snd_kcontrol *kc,
2957 int event)
2958 {
2959 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
2960 struct wcd9335_codec *wcd = snd_soc_component_get_drvdata(comp);
2961 struct wcd_slim_codec_dai_data *dai = &wcd->dai[w->shift];
2962
2963 switch (event) {
2964 case SND_SOC_DAPM_POST_PMU:
2965 wcd9335_codec_enable_int_port(dai, comp);
2966 break;
2967 case SND_SOC_DAPM_POST_PMD:
2968 kfree(dai->sconfig.chs);
2969
2970 break;
2971 }
2972
2973 return 0;
2974 }
2975
wcd9335_codec_enable_mix_path(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kc,int event)2976 static int wcd9335_codec_enable_mix_path(struct snd_soc_dapm_widget *w,
2977 struct snd_kcontrol *kc, int event)
2978 {
2979 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
2980 u16 gain_reg;
2981 int val = 0;
2982
2983 switch (w->reg) {
2984 case WCD9335_CDC_RX0_RX_PATH_MIX_CTL:
2985 gain_reg = WCD9335_CDC_RX0_RX_VOL_MIX_CTL;
2986 break;
2987 case WCD9335_CDC_RX1_RX_PATH_MIX_CTL:
2988 gain_reg = WCD9335_CDC_RX1_RX_VOL_MIX_CTL;
2989 break;
2990 case WCD9335_CDC_RX2_RX_PATH_MIX_CTL:
2991 gain_reg = WCD9335_CDC_RX2_RX_VOL_MIX_CTL;
2992 break;
2993 case WCD9335_CDC_RX3_RX_PATH_MIX_CTL:
2994 gain_reg = WCD9335_CDC_RX3_RX_VOL_MIX_CTL;
2995 break;
2996 case WCD9335_CDC_RX4_RX_PATH_MIX_CTL:
2997 gain_reg = WCD9335_CDC_RX4_RX_VOL_MIX_CTL;
2998 break;
2999 case WCD9335_CDC_RX5_RX_PATH_MIX_CTL:
3000 gain_reg = WCD9335_CDC_RX5_RX_VOL_MIX_CTL;
3001 break;
3002 case WCD9335_CDC_RX6_RX_PATH_MIX_CTL:
3003 gain_reg = WCD9335_CDC_RX6_RX_VOL_MIX_CTL;
3004 break;
3005 case WCD9335_CDC_RX7_RX_PATH_MIX_CTL:
3006 gain_reg = WCD9335_CDC_RX7_RX_VOL_MIX_CTL;
3007 break;
3008 case WCD9335_CDC_RX8_RX_PATH_MIX_CTL:
3009 gain_reg = WCD9335_CDC_RX8_RX_VOL_MIX_CTL;
3010 break;
3011 default:
3012 dev_err(comp->dev, "%s: No gain register avail for %s\n",
3013 __func__, w->name);
3014 return 0;
3015 }
3016
3017 switch (event) {
3018 case SND_SOC_DAPM_POST_PMU:
3019 val = snd_soc_component_read(comp, gain_reg);
3020 snd_soc_component_write(comp, gain_reg, val);
3021 break;
3022 case SND_SOC_DAPM_POST_PMD:
3023 break;
3024 }
3025
3026 return 0;
3027 }
3028
wcd9335_interp_get_primary_reg(u16 reg,u16 * ind)3029 static u16 wcd9335_interp_get_primary_reg(u16 reg, u16 *ind)
3030 {
3031 u16 prim_int_reg = WCD9335_CDC_RX0_RX_PATH_CTL;
3032
3033 switch (reg) {
3034 case WCD9335_CDC_RX0_RX_PATH_CTL:
3035 case WCD9335_CDC_RX0_RX_PATH_MIX_CTL:
3036 prim_int_reg = WCD9335_CDC_RX0_RX_PATH_CTL;
3037 *ind = 0;
3038 break;
3039 case WCD9335_CDC_RX1_RX_PATH_CTL:
3040 case WCD9335_CDC_RX1_RX_PATH_MIX_CTL:
3041 prim_int_reg = WCD9335_CDC_RX1_RX_PATH_CTL;
3042 *ind = 1;
3043 break;
3044 case WCD9335_CDC_RX2_RX_PATH_CTL:
3045 case WCD9335_CDC_RX2_RX_PATH_MIX_CTL:
3046 prim_int_reg = WCD9335_CDC_RX2_RX_PATH_CTL;
3047 *ind = 2;
3048 break;
3049 case WCD9335_CDC_RX3_RX_PATH_CTL:
3050 case WCD9335_CDC_RX3_RX_PATH_MIX_CTL:
3051 prim_int_reg = WCD9335_CDC_RX3_RX_PATH_CTL;
3052 *ind = 3;
3053 break;
3054 case WCD9335_CDC_RX4_RX_PATH_CTL:
3055 case WCD9335_CDC_RX4_RX_PATH_MIX_CTL:
3056 prim_int_reg = WCD9335_CDC_RX4_RX_PATH_CTL;
3057 *ind = 4;
3058 break;
3059 case WCD9335_CDC_RX5_RX_PATH_CTL:
3060 case WCD9335_CDC_RX5_RX_PATH_MIX_CTL:
3061 prim_int_reg = WCD9335_CDC_RX5_RX_PATH_CTL;
3062 *ind = 5;
3063 break;
3064 case WCD9335_CDC_RX6_RX_PATH_CTL:
3065 case WCD9335_CDC_RX6_RX_PATH_MIX_CTL:
3066 prim_int_reg = WCD9335_CDC_RX6_RX_PATH_CTL;
3067 *ind = 6;
3068 break;
3069 case WCD9335_CDC_RX7_RX_PATH_CTL:
3070 case WCD9335_CDC_RX7_RX_PATH_MIX_CTL:
3071 prim_int_reg = WCD9335_CDC_RX7_RX_PATH_CTL;
3072 *ind = 7;
3073 break;
3074 case WCD9335_CDC_RX8_RX_PATH_CTL:
3075 case WCD9335_CDC_RX8_RX_PATH_MIX_CTL:
3076 prim_int_reg = WCD9335_CDC_RX8_RX_PATH_CTL;
3077 *ind = 8;
3078 break;
3079 }
3080
3081 return prim_int_reg;
3082 }
3083
wcd9335_codec_hd2_control(struct snd_soc_component * component,u16 prim_int_reg,int event)3084 static void wcd9335_codec_hd2_control(struct snd_soc_component *component,
3085 u16 prim_int_reg, int event)
3086 {
3087 u16 hd2_scale_reg;
3088 u16 hd2_enable_reg = 0;
3089
3090 if (prim_int_reg == WCD9335_CDC_RX1_RX_PATH_CTL) {
3091 hd2_scale_reg = WCD9335_CDC_RX1_RX_PATH_SEC3;
3092 hd2_enable_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
3093 }
3094 if (prim_int_reg == WCD9335_CDC_RX2_RX_PATH_CTL) {
3095 hd2_scale_reg = WCD9335_CDC_RX2_RX_PATH_SEC3;
3096 hd2_enable_reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
3097 }
3098
3099 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
3100 snd_soc_component_update_bits(component, hd2_scale_reg,
3101 WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_MASK,
3102 WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_0P2500);
3103 snd_soc_component_update_bits(component, hd2_scale_reg,
3104 WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_MASK,
3105 WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_2);
3106 snd_soc_component_update_bits(component, hd2_enable_reg,
3107 WCD9335_CDC_RX_PATH_CFG_HD2_EN_MASK,
3108 WCD9335_CDC_RX_PATH_CFG_HD2_ENABLE);
3109 }
3110
3111 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
3112 snd_soc_component_update_bits(component, hd2_enable_reg,
3113 WCD9335_CDC_RX_PATH_CFG_HD2_EN_MASK,
3114 WCD9335_CDC_RX_PATH_CFG_HD2_DISABLE);
3115 snd_soc_component_update_bits(component, hd2_scale_reg,
3116 WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_MASK,
3117 WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_1);
3118 snd_soc_component_update_bits(component, hd2_scale_reg,
3119 WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_MASK,
3120 WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_0P0000);
3121 }
3122 }
3123
wcd9335_codec_enable_prim_interpolator(struct snd_soc_component * comp,u16 reg,int event)3124 static int wcd9335_codec_enable_prim_interpolator(
3125 struct snd_soc_component *comp,
3126 u16 reg, int event)
3127 {
3128 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
3129 u16 ind = 0;
3130 int prim_int_reg = wcd9335_interp_get_primary_reg(reg, &ind);
3131
3132 switch (event) {
3133 case SND_SOC_DAPM_PRE_PMU:
3134 wcd->prim_int_users[ind]++;
3135 if (wcd->prim_int_users[ind] == 1) {
3136 snd_soc_component_update_bits(comp, prim_int_reg,
3137 WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
3138 WCD9335_CDC_RX_PGA_MUTE_ENABLE);
3139 wcd9335_codec_hd2_control(comp, prim_int_reg, event);
3140 snd_soc_component_update_bits(comp, prim_int_reg,
3141 WCD9335_CDC_RX_CLK_EN_MASK,
3142 WCD9335_CDC_RX_CLK_ENABLE);
3143 }
3144
3145 if ((reg != prim_int_reg) &&
3146 ((snd_soc_component_read(comp, prim_int_reg)) &
3147 WCD9335_CDC_RX_PGA_MUTE_EN_MASK))
3148 snd_soc_component_update_bits(comp, reg,
3149 WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
3150 WCD9335_CDC_RX_PGA_MUTE_ENABLE);
3151 break;
3152 case SND_SOC_DAPM_POST_PMD:
3153 wcd->prim_int_users[ind]--;
3154 if (wcd->prim_int_users[ind] == 0) {
3155 snd_soc_component_update_bits(comp, prim_int_reg,
3156 WCD9335_CDC_RX_CLK_EN_MASK,
3157 WCD9335_CDC_RX_CLK_DISABLE);
3158 snd_soc_component_update_bits(comp, prim_int_reg,
3159 WCD9335_CDC_RX_RESET_MASK,
3160 WCD9335_CDC_RX_RESET_ENABLE);
3161 snd_soc_component_update_bits(comp, prim_int_reg,
3162 WCD9335_CDC_RX_RESET_MASK,
3163 WCD9335_CDC_RX_RESET_DISABLE);
3164 wcd9335_codec_hd2_control(comp, prim_int_reg, event);
3165 }
3166 break;
3167 }
3168
3169 return 0;
3170 }
3171
wcd9335_config_compander(struct snd_soc_component * component,int interp_n,int event)3172 static int wcd9335_config_compander(struct snd_soc_component *component,
3173 int interp_n, int event)
3174 {
3175 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
3176 int comp;
3177 u16 comp_ctl0_reg, rx_path_cfg0_reg;
3178
3179 /* EAR does not have compander */
3180 if (!interp_n)
3181 return 0;
3182
3183 comp = interp_n - 1;
3184 if (!wcd->comp_enabled[comp])
3185 return 0;
3186
3187 comp_ctl0_reg = WCD9335_CDC_COMPANDER1_CTL(comp);
3188 rx_path_cfg0_reg = WCD9335_CDC_RX1_RX_PATH_CFG(comp);
3189
3190 if (SND_SOC_DAPM_EVENT_ON(event)) {
3191 /* Enable Compander Clock */
3192 snd_soc_component_update_bits(component, comp_ctl0_reg,
3193 WCD9335_CDC_COMPANDER_CLK_EN_MASK,
3194 WCD9335_CDC_COMPANDER_CLK_ENABLE);
3195 /* Reset comander */
3196 snd_soc_component_update_bits(component, comp_ctl0_reg,
3197 WCD9335_CDC_COMPANDER_SOFT_RST_MASK,
3198 WCD9335_CDC_COMPANDER_SOFT_RST_ENABLE);
3199 snd_soc_component_update_bits(component, comp_ctl0_reg,
3200 WCD9335_CDC_COMPANDER_SOFT_RST_MASK,
3201 WCD9335_CDC_COMPANDER_SOFT_RST_DISABLE);
3202 /* Enables DRE in this path */
3203 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
3204 WCD9335_CDC_RX_PATH_CFG_CMP_EN_MASK,
3205 WCD9335_CDC_RX_PATH_CFG_CMP_ENABLE);
3206 }
3207
3208 if (SND_SOC_DAPM_EVENT_OFF(event)) {
3209 snd_soc_component_update_bits(component, comp_ctl0_reg,
3210 WCD9335_CDC_COMPANDER_HALT_MASK,
3211 WCD9335_CDC_COMPANDER_HALT);
3212 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
3213 WCD9335_CDC_RX_PATH_CFG_CMP_EN_MASK,
3214 WCD9335_CDC_RX_PATH_CFG_CMP_DISABLE);
3215
3216 snd_soc_component_update_bits(component, comp_ctl0_reg,
3217 WCD9335_CDC_COMPANDER_SOFT_RST_MASK,
3218 WCD9335_CDC_COMPANDER_SOFT_RST_ENABLE);
3219 snd_soc_component_update_bits(component, comp_ctl0_reg,
3220 WCD9335_CDC_COMPANDER_SOFT_RST_MASK,
3221 WCD9335_CDC_COMPANDER_SOFT_RST_DISABLE);
3222 snd_soc_component_update_bits(component, comp_ctl0_reg,
3223 WCD9335_CDC_COMPANDER_CLK_EN_MASK,
3224 WCD9335_CDC_COMPANDER_CLK_DISABLE);
3225 snd_soc_component_update_bits(component, comp_ctl0_reg,
3226 WCD9335_CDC_COMPANDER_HALT_MASK,
3227 WCD9335_CDC_COMPANDER_NOHALT);
3228 }
3229
3230 return 0;
3231 }
3232
wcd9335_codec_enable_interpolator(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kc,int event)3233 static int wcd9335_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
3234 struct snd_kcontrol *kc, int event)
3235 {
3236 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
3237 u16 gain_reg;
3238 u16 reg;
3239 int val;
3240
3241 if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT0 INTERP"))) {
3242 reg = WCD9335_CDC_RX0_RX_PATH_CTL;
3243 gain_reg = WCD9335_CDC_RX0_RX_VOL_CTL;
3244 } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT1 INTERP"))) {
3245 reg = WCD9335_CDC_RX1_RX_PATH_CTL;
3246 gain_reg = WCD9335_CDC_RX1_RX_VOL_CTL;
3247 } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT2 INTERP"))) {
3248 reg = WCD9335_CDC_RX2_RX_PATH_CTL;
3249 gain_reg = WCD9335_CDC_RX2_RX_VOL_CTL;
3250 } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT3 INTERP"))) {
3251 reg = WCD9335_CDC_RX3_RX_PATH_CTL;
3252 gain_reg = WCD9335_CDC_RX3_RX_VOL_CTL;
3253 } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT4 INTERP"))) {
3254 reg = WCD9335_CDC_RX4_RX_PATH_CTL;
3255 gain_reg = WCD9335_CDC_RX4_RX_VOL_CTL;
3256 } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT5 INTERP"))) {
3257 reg = WCD9335_CDC_RX5_RX_PATH_CTL;
3258 gain_reg = WCD9335_CDC_RX5_RX_VOL_CTL;
3259 } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT6 INTERP"))) {
3260 reg = WCD9335_CDC_RX6_RX_PATH_CTL;
3261 gain_reg = WCD9335_CDC_RX6_RX_VOL_CTL;
3262 } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT7 INTERP"))) {
3263 reg = WCD9335_CDC_RX7_RX_PATH_CTL;
3264 gain_reg = WCD9335_CDC_RX7_RX_VOL_CTL;
3265 } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT8 INTERP"))) {
3266 reg = WCD9335_CDC_RX8_RX_PATH_CTL;
3267 gain_reg = WCD9335_CDC_RX8_RX_VOL_CTL;
3268 } else {
3269 dev_err(comp->dev, "%s: Interpolator reg not found\n",
3270 __func__);
3271 return -EINVAL;
3272 }
3273
3274 switch (event) {
3275 case SND_SOC_DAPM_PRE_PMU:
3276 /* Reset if needed */
3277 wcd9335_codec_enable_prim_interpolator(comp, reg, event);
3278 break;
3279 case SND_SOC_DAPM_POST_PMU:
3280 wcd9335_config_compander(comp, w->shift, event);
3281 val = snd_soc_component_read(comp, gain_reg);
3282 snd_soc_component_write(comp, gain_reg, val);
3283 break;
3284 case SND_SOC_DAPM_POST_PMD:
3285 wcd9335_config_compander(comp, w->shift, event);
3286 wcd9335_codec_enable_prim_interpolator(comp, reg, event);
3287 break;
3288 }
3289
3290 return 0;
3291 }
3292
wcd9335_codec_hph_mode_gain_opt(struct snd_soc_component * component,u8 gain)3293 static void wcd9335_codec_hph_mode_gain_opt(struct snd_soc_component *component,
3294 u8 gain)
3295 {
3296 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
3297 u8 hph_l_en, hph_r_en;
3298 u8 l_val, r_val;
3299 u8 hph_pa_status;
3300 bool is_hphl_pa, is_hphr_pa;
3301
3302 hph_pa_status = snd_soc_component_read(component, WCD9335_ANA_HPH);
3303 is_hphl_pa = hph_pa_status >> 7;
3304 is_hphr_pa = (hph_pa_status & 0x40) >> 6;
3305
3306 hph_l_en = snd_soc_component_read(component, WCD9335_HPH_L_EN);
3307 hph_r_en = snd_soc_component_read(component, WCD9335_HPH_R_EN);
3308
3309 l_val = (hph_l_en & 0xC0) | 0x20 | gain;
3310 r_val = (hph_r_en & 0xC0) | 0x20 | gain;
3311
3312 /*
3313 * Set HPH_L & HPH_R gain source selection to REGISTER
3314 * for better click and pop only if corresponding PAs are
3315 * not enabled. Also cache the values of the HPHL/R
3316 * PA gains to be applied after PAs are enabled
3317 */
3318 if ((l_val != hph_l_en) && !is_hphl_pa) {
3319 snd_soc_component_write(component, WCD9335_HPH_L_EN, l_val);
3320 wcd->hph_l_gain = hph_l_en & 0x1F;
3321 }
3322
3323 if ((r_val != hph_r_en) && !is_hphr_pa) {
3324 snd_soc_component_write(component, WCD9335_HPH_R_EN, r_val);
3325 wcd->hph_r_gain = hph_r_en & 0x1F;
3326 }
3327 }
3328
wcd9335_codec_hph_lohifi_config(struct snd_soc_component * comp,int event)3329 static void wcd9335_codec_hph_lohifi_config(struct snd_soc_component *comp,
3330 int event)
3331 {
3332 if (SND_SOC_DAPM_EVENT_ON(event)) {
3333 snd_soc_component_update_bits(comp, WCD9335_RX_BIAS_HPH_PA,
3334 WCD9335_RX_BIAS_HPH_PA_AMP_5_UA_MASK,
3335 0x06);
3336 snd_soc_component_update_bits(comp,
3337 WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2,
3338 0xF0, 0x40);
3339 snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL,
3340 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK,
3341 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_1000);
3342 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
3343 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK,
3344 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_ENABLE);
3345 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL1,
3346 WCD9335_HPH_PA_GM3_IB_SCALE_MASK,
3347 0x0C);
3348 wcd9335_codec_hph_mode_gain_opt(comp, 0x11);
3349 }
3350
3351 if (SND_SOC_DAPM_EVENT_OFF(event)) {
3352 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
3353 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK,
3354 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_DISABLE);
3355 snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL,
3356 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK,
3357 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_500);
3358 snd_soc_component_write(comp, WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2,
3359 0x8A);
3360 snd_soc_component_update_bits(comp, WCD9335_RX_BIAS_HPH_PA,
3361 WCD9335_RX_BIAS_HPH_PA_AMP_5_UA_MASK,
3362 0x0A);
3363 }
3364 }
3365
wcd9335_codec_hph_lp_config(struct snd_soc_component * comp,int event)3366 static void wcd9335_codec_hph_lp_config(struct snd_soc_component *comp,
3367 int event)
3368 {
3369 if (SND_SOC_DAPM_EVENT_ON(event)) {
3370 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL1,
3371 WCD9335_HPH_PA_GM3_IB_SCALE_MASK,
3372 0x0C);
3373 wcd9335_codec_hph_mode_gain_opt(comp, 0x10);
3374 snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL,
3375 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK,
3376 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_1000);
3377 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
3378 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK,
3379 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_ENABLE);
3380 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
3381 WCD9335_HPH_PA_CTL2_FORCE_PSRREH_MASK,
3382 WCD9335_HPH_PA_CTL2_FORCE_PSRREH_ENABLE);
3383 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
3384 WCD9335_HPH_PA_CTL2_HPH_PSRR_ENH_MASK,
3385 WCD9335_HPH_PA_CTL2_HPH_PSRR_ENABLE);
3386 snd_soc_component_update_bits(comp, WCD9335_HPH_RDAC_LDO_CTL,
3387 WCD9335_HPH_RDAC_N1P65_LD_OUTCTL_MASK,
3388 WCD9335_HPH_RDAC_N1P65_LD_OUTCTL_V_N1P60);
3389 snd_soc_component_update_bits(comp, WCD9335_HPH_RDAC_LDO_CTL,
3390 WCD9335_HPH_RDAC_1P65_LD_OUTCTL_MASK,
3391 WCD9335_HPH_RDAC_1P65_LD_OUTCTL_V_N1P60);
3392 snd_soc_component_update_bits(comp,
3393 WCD9335_RX_BIAS_HPH_RDAC_LDO, 0x0F, 0x01);
3394 snd_soc_component_update_bits(comp,
3395 WCD9335_RX_BIAS_HPH_RDAC_LDO, 0xF0, 0x10);
3396 }
3397
3398 if (SND_SOC_DAPM_EVENT_OFF(event)) {
3399 snd_soc_component_write(comp, WCD9335_RX_BIAS_HPH_RDAC_LDO,
3400 0x88);
3401 snd_soc_component_write(comp, WCD9335_HPH_RDAC_LDO_CTL,
3402 0x33);
3403 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
3404 WCD9335_HPH_PA_CTL2_HPH_PSRR_ENH_MASK,
3405 WCD9335_HPH_PA_CTL2_HPH_PSRR_DISABLE);
3406 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
3407 WCD9335_HPH_PA_CTL2_FORCE_PSRREH_MASK,
3408 WCD9335_HPH_PA_CTL2_FORCE_PSRREH_DISABLE);
3409 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
3410 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK,
3411 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_DISABLE);
3412 snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL,
3413 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK,
3414 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_500);
3415 snd_soc_component_update_bits(comp, WCD9335_HPH_R_EN,
3416 WCD9335_HPH_CONST_SEL_L_MASK,
3417 WCD9335_HPH_CONST_SEL_L_HQ_PATH);
3418 snd_soc_component_update_bits(comp, WCD9335_HPH_L_EN,
3419 WCD9335_HPH_CONST_SEL_L_MASK,
3420 WCD9335_HPH_CONST_SEL_L_HQ_PATH);
3421 }
3422 }
3423
wcd9335_codec_hph_hifi_config(struct snd_soc_component * comp,int event)3424 static void wcd9335_codec_hph_hifi_config(struct snd_soc_component *comp,
3425 int event)
3426 {
3427 if (SND_SOC_DAPM_EVENT_ON(event)) {
3428 snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL,
3429 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK,
3430 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_1000);
3431 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
3432 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK,
3433 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_ENABLE);
3434 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL1,
3435 WCD9335_HPH_PA_GM3_IB_SCALE_MASK,
3436 0x0C);
3437 wcd9335_codec_hph_mode_gain_opt(comp, 0x11);
3438 }
3439
3440 if (SND_SOC_DAPM_EVENT_OFF(event)) {
3441 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
3442 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK,
3443 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_DISABLE);
3444 snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL,
3445 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK,
3446 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_500);
3447 }
3448 }
3449
wcd9335_codec_hph_mode_config(struct snd_soc_component * component,int event,int mode)3450 static void wcd9335_codec_hph_mode_config(struct snd_soc_component *component,
3451 int event, int mode)
3452 {
3453 switch (mode) {
3454 case CLS_H_LP:
3455 wcd9335_codec_hph_lp_config(component, event);
3456 break;
3457 case CLS_H_LOHIFI:
3458 wcd9335_codec_hph_lohifi_config(component, event);
3459 break;
3460 case CLS_H_HIFI:
3461 wcd9335_codec_hph_hifi_config(component, event);
3462 break;
3463 }
3464 }
3465
wcd9335_codec_hphl_dac_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kc,int event)3466 static int wcd9335_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
3467 struct snd_kcontrol *kc,
3468 int event)
3469 {
3470 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
3471 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
3472 int hph_mode = wcd->hph_mode;
3473 u8 dem_inp;
3474
3475 switch (event) {
3476 case SND_SOC_DAPM_PRE_PMU:
3477 /* Read DEM INP Select */
3478 dem_inp = snd_soc_component_read(comp,
3479 WCD9335_CDC_RX1_RX_PATH_SEC0) & 0x03;
3480 if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) ||
3481 (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
3482 dev_err(comp->dev, "Incorrect DEM Input\n");
3483 return -EINVAL;
3484 }
3485 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC,
3486 WCD_CLSH_STATE_HPHL,
3487 ((hph_mode == CLS_H_LOHIFI) ?
3488 CLS_H_HIFI : hph_mode));
3489
3490 wcd9335_codec_hph_mode_config(comp, event, hph_mode);
3491
3492 break;
3493 case SND_SOC_DAPM_POST_PMU:
3494 usleep_range(1000, 1100);
3495 break;
3496 case SND_SOC_DAPM_PRE_PMD:
3497 break;
3498 case SND_SOC_DAPM_POST_PMD:
3499 /* 1000us required as per HW requirement */
3500 usleep_range(1000, 1100);
3501
3502 if (!(wcd_clsh_ctrl_get_state(wcd->clsh_ctrl) &
3503 WCD_CLSH_STATE_HPHR))
3504 wcd9335_codec_hph_mode_config(comp, event, hph_mode);
3505
3506 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA,
3507 WCD_CLSH_STATE_HPHL,
3508 ((hph_mode == CLS_H_LOHIFI) ?
3509 CLS_H_HIFI : hph_mode));
3510 break;
3511 }
3512
3513 return 0;
3514 }
3515
wcd9335_codec_lineout_dac_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kc,int event)3516 static int wcd9335_codec_lineout_dac_event(struct snd_soc_dapm_widget *w,
3517 struct snd_kcontrol *kc, int event)
3518 {
3519 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
3520 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
3521
3522 switch (event) {
3523 case SND_SOC_DAPM_PRE_PMU:
3524 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC,
3525 WCD_CLSH_STATE_LO, CLS_AB);
3526 break;
3527 case SND_SOC_DAPM_POST_PMD:
3528 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA,
3529 WCD_CLSH_STATE_LO, CLS_AB);
3530 break;
3531 }
3532
3533 return 0;
3534 }
3535
wcd9335_codec_ear_dac_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kc,int event)3536 static int wcd9335_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
3537 struct snd_kcontrol *kc, int event)
3538 {
3539 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
3540 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
3541
3542 switch (event) {
3543 case SND_SOC_DAPM_PRE_PMU:
3544 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC,
3545 WCD_CLSH_STATE_EAR, CLS_H_NORMAL);
3546
3547 break;
3548 case SND_SOC_DAPM_POST_PMD:
3549 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA,
3550 WCD_CLSH_STATE_EAR, CLS_H_NORMAL);
3551 break;
3552 }
3553
3554 return 0;
3555 }
3556
wcd9335_codec_hph_post_pa_config(struct wcd9335_codec * wcd,int mode,int event)3557 static void wcd9335_codec_hph_post_pa_config(struct wcd9335_codec *wcd,
3558 int mode, int event)
3559 {
3560 u8 scale_val = 0;
3561
3562 switch (event) {
3563 case SND_SOC_DAPM_POST_PMU:
3564 switch (mode) {
3565 case CLS_H_HIFI:
3566 scale_val = 0x3;
3567 break;
3568 case CLS_H_LOHIFI:
3569 scale_val = 0x1;
3570 break;
3571 }
3572 break;
3573 case SND_SOC_DAPM_PRE_PMD:
3574 scale_val = 0x6;
3575 break;
3576 }
3577
3578 if (scale_val)
3579 snd_soc_component_update_bits(wcd->component,
3580 WCD9335_HPH_PA_CTL1,
3581 WCD9335_HPH_PA_GM3_IB_SCALE_MASK,
3582 scale_val << 1);
3583 if (SND_SOC_DAPM_EVENT_ON(event)) {
3584 if (wcd->comp_enabled[COMPANDER_1] ||
3585 wcd->comp_enabled[COMPANDER_2]) {
3586 /* GAIN Source Selection */
3587 snd_soc_component_update_bits(wcd->component,
3588 WCD9335_HPH_L_EN,
3589 WCD9335_HPH_GAIN_SRC_SEL_MASK,
3590 WCD9335_HPH_GAIN_SRC_SEL_COMPANDER);
3591 snd_soc_component_update_bits(wcd->component,
3592 WCD9335_HPH_R_EN,
3593 WCD9335_HPH_GAIN_SRC_SEL_MASK,
3594 WCD9335_HPH_GAIN_SRC_SEL_COMPANDER);
3595 snd_soc_component_update_bits(wcd->component,
3596 WCD9335_HPH_AUTO_CHOP,
3597 WCD9335_HPH_AUTO_CHOP_MASK,
3598 WCD9335_HPH_AUTO_CHOP_FORCE_ENABLE);
3599 }
3600 snd_soc_component_update_bits(wcd->component,
3601 WCD9335_HPH_L_EN,
3602 WCD9335_HPH_PA_GAIN_MASK,
3603 wcd->hph_l_gain);
3604 snd_soc_component_update_bits(wcd->component,
3605 WCD9335_HPH_R_EN,
3606 WCD9335_HPH_PA_GAIN_MASK,
3607 wcd->hph_r_gain);
3608 }
3609
3610 if (SND_SOC_DAPM_EVENT_OFF(event))
3611 snd_soc_component_update_bits(wcd->component,
3612 WCD9335_HPH_AUTO_CHOP,
3613 WCD9335_HPH_AUTO_CHOP_MASK,
3614 WCD9335_HPH_AUTO_CHOP_ENABLE_BY_CMPDR_GAIN);
3615 }
3616
wcd9335_codec_hphr_dac_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kc,int event)3617 static int wcd9335_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
3618 struct snd_kcontrol *kc,
3619 int event)
3620 {
3621 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
3622 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
3623 int hph_mode = wcd->hph_mode;
3624 u8 dem_inp;
3625
3626 switch (event) {
3627 case SND_SOC_DAPM_PRE_PMU:
3628
3629 /* Read DEM INP Select */
3630 dem_inp = snd_soc_component_read(comp,
3631 WCD9335_CDC_RX2_RX_PATH_SEC0) &
3632 WCD9335_CDC_RX_PATH_DEM_INP_SEL_MASK;
3633 if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) ||
3634 (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
3635 dev_err(comp->dev, "DEM Input not set correctly, hph_mode: %d\n",
3636 hph_mode);
3637 return -EINVAL;
3638 }
3639
3640 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl,
3641 WCD_CLSH_EVENT_PRE_DAC,
3642 WCD_CLSH_STATE_HPHR,
3643 ((hph_mode == CLS_H_LOHIFI) ?
3644 CLS_H_HIFI : hph_mode));
3645
3646 wcd9335_codec_hph_mode_config(comp, event, hph_mode);
3647
3648 break;
3649 case SND_SOC_DAPM_POST_PMD:
3650 /* 1000us required as per HW requirement */
3651 usleep_range(1000, 1100);
3652
3653 if (!(wcd_clsh_ctrl_get_state(wcd->clsh_ctrl) &
3654 WCD_CLSH_STATE_HPHL))
3655 wcd9335_codec_hph_mode_config(comp, event, hph_mode);
3656
3657 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA,
3658 WCD_CLSH_STATE_HPHR, ((hph_mode == CLS_H_LOHIFI) ?
3659 CLS_H_HIFI : hph_mode));
3660 break;
3661 }
3662
3663 return 0;
3664 }
3665
wcd9335_codec_enable_hphl_pa(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kc,int event)3666 static int wcd9335_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
3667 struct snd_kcontrol *kc,
3668 int event)
3669 {
3670 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
3671 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
3672 int hph_mode = wcd->hph_mode;
3673
3674 switch (event) {
3675 case SND_SOC_DAPM_PRE_PMU:
3676 break;
3677 case SND_SOC_DAPM_POST_PMU:
3678 /*
3679 * 7ms sleep is required after PA is enabled as per
3680 * HW requirement
3681 */
3682 usleep_range(7000, 7100);
3683
3684 wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event);
3685 snd_soc_component_update_bits(comp,
3686 WCD9335_CDC_RX1_RX_PATH_CTL,
3687 WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
3688 WCD9335_CDC_RX_PGA_MUTE_DISABLE);
3689
3690 /* Remove mix path mute if it is enabled */
3691 if ((snd_soc_component_read(comp,
3692 WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) &
3693 WCD9335_CDC_RX_PGA_MUTE_EN_MASK)
3694 snd_soc_component_update_bits(comp,
3695 WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
3696 WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
3697 WCD9335_CDC_RX_PGA_MUTE_DISABLE);
3698
3699 break;
3700 case SND_SOC_DAPM_PRE_PMD:
3701 wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event);
3702 break;
3703 case SND_SOC_DAPM_POST_PMD:
3704 /* 5ms sleep is required after PA is disabled as per
3705 * HW requirement
3706 */
3707 usleep_range(5000, 5500);
3708 break;
3709 }
3710
3711 return 0;
3712 }
3713
wcd9335_codec_enable_lineout_pa(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kc,int event)3714 static int wcd9335_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w,
3715 struct snd_kcontrol *kc,
3716 int event)
3717 {
3718 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
3719 int vol_reg = 0, mix_vol_reg = 0;
3720
3721 if (w->reg == WCD9335_ANA_LO_1_2) {
3722 if (w->shift == 7) {
3723 vol_reg = WCD9335_CDC_RX3_RX_PATH_CTL;
3724 mix_vol_reg = WCD9335_CDC_RX3_RX_PATH_MIX_CTL;
3725 } else if (w->shift == 6) {
3726 vol_reg = WCD9335_CDC_RX4_RX_PATH_CTL;
3727 mix_vol_reg = WCD9335_CDC_RX4_RX_PATH_MIX_CTL;
3728 }
3729 } else if (w->reg == WCD9335_ANA_LO_3_4) {
3730 if (w->shift == 7) {
3731 vol_reg = WCD9335_CDC_RX5_RX_PATH_CTL;
3732 mix_vol_reg = WCD9335_CDC_RX5_RX_PATH_MIX_CTL;
3733 } else if (w->shift == 6) {
3734 vol_reg = WCD9335_CDC_RX6_RX_PATH_CTL;
3735 mix_vol_reg = WCD9335_CDC_RX6_RX_PATH_MIX_CTL;
3736 }
3737 } else {
3738 dev_err(comp->dev, "Error enabling lineout PA\n");
3739 return -EINVAL;
3740 }
3741
3742 switch (event) {
3743 case SND_SOC_DAPM_POST_PMU:
3744 /* 5ms sleep is required after PA is enabled as per
3745 * HW requirement
3746 */
3747 usleep_range(5000, 5500);
3748 snd_soc_component_update_bits(comp, vol_reg,
3749 WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
3750 WCD9335_CDC_RX_PGA_MUTE_DISABLE);
3751
3752 /* Remove mix path mute if it is enabled */
3753 if ((snd_soc_component_read(comp, mix_vol_reg)) &
3754 WCD9335_CDC_RX_PGA_MUTE_EN_MASK)
3755 snd_soc_component_update_bits(comp, mix_vol_reg,
3756 WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
3757 WCD9335_CDC_RX_PGA_MUTE_DISABLE);
3758 break;
3759 case SND_SOC_DAPM_POST_PMD:
3760 /* 5ms sleep is required after PA is disabled as per
3761 * HW requirement
3762 */
3763 usleep_range(5000, 5500);
3764 break;
3765 }
3766
3767 return 0;
3768 }
3769
wcd9335_codec_init_flyback(struct snd_soc_component * component)3770 static void wcd9335_codec_init_flyback(struct snd_soc_component *component)
3771 {
3772 snd_soc_component_update_bits(component, WCD9335_HPH_L_EN,
3773 WCD9335_HPH_CONST_SEL_L_MASK,
3774 WCD9335_HPH_CONST_SEL_L_BYPASS);
3775 snd_soc_component_update_bits(component, WCD9335_HPH_R_EN,
3776 WCD9335_HPH_CONST_SEL_L_MASK,
3777 WCD9335_HPH_CONST_SEL_L_BYPASS);
3778 snd_soc_component_update_bits(component, WCD9335_RX_BIAS_FLYB_BUFF,
3779 WCD9335_RX_BIAS_FLYB_VPOS_5_UA_MASK,
3780 WCD9335_RX_BIAS_FLYB_I_0P0_UA);
3781 snd_soc_component_update_bits(component, WCD9335_RX_BIAS_FLYB_BUFF,
3782 WCD9335_RX_BIAS_FLYB_VNEG_5_UA_MASK,
3783 WCD9335_RX_BIAS_FLYB_I_0P0_UA);
3784 }
3785
wcd9335_codec_enable_rx_bias(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kc,int event)3786 static int wcd9335_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
3787 struct snd_kcontrol *kc, int event)
3788 {
3789 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
3790 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
3791
3792 switch (event) {
3793 case SND_SOC_DAPM_PRE_PMU:
3794 wcd->rx_bias_count++;
3795 if (wcd->rx_bias_count == 1) {
3796 wcd9335_codec_init_flyback(comp);
3797 snd_soc_component_update_bits(comp,
3798 WCD9335_ANA_RX_SUPPLIES,
3799 WCD9335_ANA_RX_BIAS_ENABLE_MASK,
3800 WCD9335_ANA_RX_BIAS_ENABLE);
3801 }
3802 break;
3803 case SND_SOC_DAPM_POST_PMD:
3804 wcd->rx_bias_count--;
3805 if (!wcd->rx_bias_count)
3806 snd_soc_component_update_bits(comp,
3807 WCD9335_ANA_RX_SUPPLIES,
3808 WCD9335_ANA_RX_BIAS_ENABLE_MASK,
3809 WCD9335_ANA_RX_BIAS_DISABLE);
3810 break;
3811 }
3812
3813 return 0;
3814 }
3815
wcd9335_codec_enable_hphr_pa(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kc,int event)3816 static int wcd9335_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
3817 struct snd_kcontrol *kc, int event)
3818 {
3819 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
3820 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
3821 int hph_mode = wcd->hph_mode;
3822
3823 switch (event) {
3824 case SND_SOC_DAPM_PRE_PMU:
3825 break;
3826 case SND_SOC_DAPM_POST_PMU:
3827 /*
3828 * 7ms sleep is required after PA is enabled as per
3829 * HW requirement
3830 */
3831 usleep_range(7000, 7100);
3832 wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event);
3833 snd_soc_component_update_bits(comp,
3834 WCD9335_CDC_RX2_RX_PATH_CTL,
3835 WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
3836 WCD9335_CDC_RX_PGA_MUTE_DISABLE);
3837 /* Remove mix path mute if it is enabled */
3838 if ((snd_soc_component_read(comp,
3839 WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) &
3840 WCD9335_CDC_RX_PGA_MUTE_EN_MASK)
3841 snd_soc_component_update_bits(comp,
3842 WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
3843 WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
3844 WCD9335_CDC_RX_PGA_MUTE_DISABLE);
3845
3846 break;
3847
3848 case SND_SOC_DAPM_PRE_PMD:
3849 wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event);
3850 break;
3851 case SND_SOC_DAPM_POST_PMD:
3852 /* 5ms sleep is required after PA is disabled as per
3853 * HW requirement
3854 */
3855 usleep_range(5000, 5500);
3856 break;
3857 }
3858
3859 return 0;
3860 }
3861
wcd9335_codec_enable_ear_pa(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kc,int event)3862 static int wcd9335_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
3863 struct snd_kcontrol *kc, int event)
3864 {
3865 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
3866
3867 switch (event) {
3868 case SND_SOC_DAPM_POST_PMU:
3869 /* 5ms sleep is required after PA is enabled as per
3870 * HW requirement
3871 */
3872 usleep_range(5000, 5500);
3873 snd_soc_component_update_bits(comp,
3874 WCD9335_CDC_RX0_RX_PATH_CTL,
3875 WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
3876 WCD9335_CDC_RX_PGA_MUTE_DISABLE);
3877 /* Remove mix path mute if it is enabled */
3878 if ((snd_soc_component_read(comp,
3879 WCD9335_CDC_RX0_RX_PATH_MIX_CTL)) &
3880 WCD9335_CDC_RX_PGA_MUTE_EN_MASK)
3881 snd_soc_component_update_bits(comp,
3882 WCD9335_CDC_RX0_RX_PATH_MIX_CTL,
3883 WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
3884 WCD9335_CDC_RX_PGA_MUTE_DISABLE);
3885 break;
3886 case SND_SOC_DAPM_POST_PMD:
3887 /* 5ms sleep is required after PA is disabled as per
3888 * HW requirement
3889 */
3890 usleep_range(5000, 5500);
3891
3892 break;
3893 }
3894
3895 return 0;
3896 }
3897
wcd9335_slimbus_irq(int irq,void * data)3898 static irqreturn_t wcd9335_slimbus_irq(int irq, void *data)
3899 {
3900 struct wcd9335_codec *wcd = data;
3901 unsigned long status = 0;
3902 int i, j, port_id;
3903 unsigned int val, int_val = 0;
3904 irqreturn_t ret = IRQ_NONE;
3905 bool tx;
3906 unsigned short reg = 0;
3907
3908 for (i = WCD9335_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0;
3909 i <= WCD9335_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) {
3910 regmap_read(wcd->if_regmap, i, &val);
3911 status |= ((u32)val << (8 * j));
3912 }
3913
3914 for_each_set_bit(j, &status, 32) {
3915 tx = (j >= 16);
3916 port_id = (tx ? j - 16 : j);
3917 regmap_read(wcd->if_regmap,
3918 WCD9335_SLIM_PGD_PORT_INT_RX_SOURCE0 + j, &val);
3919 if (val) {
3920 if (!tx)
3921 reg = WCD9335_SLIM_PGD_PORT_INT_EN0 +
3922 (port_id / 8);
3923 else
3924 reg = WCD9335_SLIM_PGD_PORT_INT_TX_EN0 +
3925 (port_id / 8);
3926 regmap_read(
3927 wcd->if_regmap, reg, &int_val);
3928 /*
3929 * Ignore interrupts for ports for which the
3930 * interrupts are not specifically enabled.
3931 */
3932 if (!(int_val & (1 << (port_id % 8))))
3933 continue;
3934 }
3935
3936 if (val & WCD9335_SLIM_IRQ_OVERFLOW)
3937 dev_err_ratelimited(wcd->dev,
3938 "%s: overflow error on %s port %d, value %x\n",
3939 __func__, (tx ? "TX" : "RX"), port_id, val);
3940
3941 if (val & WCD9335_SLIM_IRQ_UNDERFLOW)
3942 dev_err_ratelimited(wcd->dev,
3943 "%s: underflow error on %s port %d, value %x\n",
3944 __func__, (tx ? "TX" : "RX"), port_id, val);
3945
3946 if ((val & WCD9335_SLIM_IRQ_OVERFLOW) ||
3947 (val & WCD9335_SLIM_IRQ_UNDERFLOW)) {
3948 if (!tx)
3949 reg = WCD9335_SLIM_PGD_PORT_INT_EN0 +
3950 (port_id / 8);
3951 else
3952 reg = WCD9335_SLIM_PGD_PORT_INT_TX_EN0 +
3953 (port_id / 8);
3954 regmap_read(
3955 wcd->if_regmap, reg, &int_val);
3956 if (int_val & (1 << (port_id % 8))) {
3957 int_val = int_val ^ (1 << (port_id % 8));
3958 regmap_write(wcd->if_regmap,
3959 reg, int_val);
3960 }
3961 }
3962
3963 regmap_write(wcd->if_regmap,
3964 WCD9335_SLIM_PGD_PORT_INT_CLR_RX_0 + (j / 8),
3965 BIT(j % 8));
3966 ret = IRQ_HANDLED;
3967 }
3968
3969 return ret;
3970 }
3971
3972 static const struct wcd9335_irq wcd9335_irqs[] = {
3973 {
3974 .irq = WCD9335_IRQ_SLIMBUS,
3975 .handler = wcd9335_slimbus_irq,
3976 .name = "SLIM Slave",
3977 },
3978 };
3979
wcd9335_setup_irqs(struct wcd9335_codec * wcd)3980 static int wcd9335_setup_irqs(struct wcd9335_codec *wcd)
3981 {
3982 int irq, ret, i;
3983
3984 for (i = 0; i < ARRAY_SIZE(wcd9335_irqs); i++) {
3985 irq = regmap_irq_get_virq(wcd->irq_data, wcd9335_irqs[i].irq);
3986 if (irq < 0) {
3987 dev_err(wcd->dev, "Failed to get %s\n",
3988 wcd9335_irqs[i].name);
3989 return irq;
3990 }
3991
3992 ret = devm_request_threaded_irq(wcd->dev, irq, NULL,
3993 wcd9335_irqs[i].handler,
3994 IRQF_TRIGGER_RISING |
3995 IRQF_ONESHOT,
3996 wcd9335_irqs[i].name, wcd);
3997 if (ret) {
3998 dev_err(wcd->dev, "Failed to request %s\n",
3999 wcd9335_irqs[i].name);
4000 return ret;
4001 }
4002 }
4003
4004 /* enable interrupts on all slave ports */
4005 for (i = 0; i < WCD9335_SLIM_NUM_PORT_REG; i++)
4006 regmap_write(wcd->if_regmap, WCD9335_SLIM_PGD_PORT_INT_EN0 + i,
4007 0xFF);
4008
4009 return ret;
4010 }
4011
wcd9335_teardown_irqs(struct wcd9335_codec * wcd)4012 static void wcd9335_teardown_irqs(struct wcd9335_codec *wcd)
4013 {
4014 int i;
4015
4016 /* disable interrupts on all slave ports */
4017 for (i = 0; i < WCD9335_SLIM_NUM_PORT_REG; i++)
4018 regmap_write(wcd->if_regmap, WCD9335_SLIM_PGD_PORT_INT_EN0 + i,
4019 0x00);
4020 }
4021
wcd9335_cdc_sido_ccl_enable(struct wcd9335_codec * wcd,bool ccl_flag)4022 static void wcd9335_cdc_sido_ccl_enable(struct wcd9335_codec *wcd,
4023 bool ccl_flag)
4024 {
4025 struct snd_soc_component *comp = wcd->component;
4026
4027 if (ccl_flag) {
4028 if (++wcd->sido_ccl_cnt == 1)
4029 snd_soc_component_write(comp, WCD9335_SIDO_SIDO_CCL_10,
4030 WCD9335_SIDO_SIDO_CCL_DEF_VALUE);
4031 } else {
4032 if (wcd->sido_ccl_cnt == 0) {
4033 dev_err(wcd->dev, "sido_ccl already disabled\n");
4034 return;
4035 }
4036 if (--wcd->sido_ccl_cnt == 0)
4037 snd_soc_component_write(comp, WCD9335_SIDO_SIDO_CCL_10,
4038 WCD9335_SIDO_SIDO_CCL_10_ICHARG_PWR_SEL_C320FF);
4039 }
4040 }
4041
wcd9335_enable_master_bias(struct wcd9335_codec * wcd)4042 static int wcd9335_enable_master_bias(struct wcd9335_codec *wcd)
4043 {
4044 wcd->master_bias_users++;
4045 if (wcd->master_bias_users == 1) {
4046 regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS,
4047 WCD9335_ANA_BIAS_EN_MASK,
4048 WCD9335_ANA_BIAS_ENABLE);
4049 regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS,
4050 WCD9335_ANA_BIAS_PRECHRG_EN_MASK,
4051 WCD9335_ANA_BIAS_PRECHRG_ENABLE);
4052 /*
4053 * 1ms delay is required after pre-charge is enabled
4054 * as per HW requirement
4055 */
4056 usleep_range(1000, 1100);
4057 regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS,
4058 WCD9335_ANA_BIAS_PRECHRG_EN_MASK,
4059 WCD9335_ANA_BIAS_PRECHRG_DISABLE);
4060 regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS,
4061 WCD9335_ANA_BIAS_PRECHRG_CTL_MODE,
4062 WCD9335_ANA_BIAS_PRECHRG_CTL_MODE_MANUAL);
4063 }
4064
4065 return 0;
4066 }
4067
wcd9335_enable_mclk(struct wcd9335_codec * wcd)4068 static int wcd9335_enable_mclk(struct wcd9335_codec *wcd)
4069 {
4070 /* Enable mclk requires master bias to be enabled first */
4071 if (wcd->master_bias_users <= 0)
4072 return -EINVAL;
4073
4074 if (((wcd->clk_mclk_users == 0) && (wcd->clk_type == WCD_CLK_MCLK)) ||
4075 ((wcd->clk_mclk_users > 0) && (wcd->clk_type != WCD_CLK_MCLK))) {
4076 dev_err(wcd->dev, "Error enabling MCLK, clk_type: %d\n",
4077 wcd->clk_type);
4078 return -EINVAL;
4079 }
4080
4081 if (++wcd->clk_mclk_users == 1) {
4082 regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP,
4083 WCD9335_ANA_CLK_EXT_CLKBUF_EN_MASK,
4084 WCD9335_ANA_CLK_EXT_CLKBUF_ENABLE);
4085 regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP,
4086 WCD9335_ANA_CLK_MCLK_SRC_MASK,
4087 WCD9335_ANA_CLK_MCLK_SRC_EXTERNAL);
4088 regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP,
4089 WCD9335_ANA_CLK_MCLK_EN_MASK,
4090 WCD9335_ANA_CLK_MCLK_ENABLE);
4091 regmap_update_bits(wcd->regmap,
4092 WCD9335_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
4093 WCD9335_CDC_CLK_RST_CTRL_FS_CNT_EN_MASK,
4094 WCD9335_CDC_CLK_RST_CTRL_FS_CNT_ENABLE);
4095 regmap_update_bits(wcd->regmap,
4096 WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL,
4097 WCD9335_CDC_CLK_RST_CTRL_MCLK_EN_MASK,
4098 WCD9335_CDC_CLK_RST_CTRL_MCLK_ENABLE);
4099 /*
4100 * 10us sleep is required after clock is enabled
4101 * as per HW requirement
4102 */
4103 usleep_range(10, 15);
4104 }
4105
4106 wcd->clk_type = WCD_CLK_MCLK;
4107
4108 return 0;
4109 }
4110
wcd9335_disable_mclk(struct wcd9335_codec * wcd)4111 static int wcd9335_disable_mclk(struct wcd9335_codec *wcd)
4112 {
4113 if (wcd->clk_mclk_users <= 0)
4114 return -EINVAL;
4115
4116 if (--wcd->clk_mclk_users == 0) {
4117 if (wcd->clk_rco_users > 0) {
4118 /* MCLK to RCO switch */
4119 regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP,
4120 WCD9335_ANA_CLK_MCLK_SRC_MASK,
4121 WCD9335_ANA_CLK_MCLK_SRC_RCO);
4122 wcd->clk_type = WCD_CLK_RCO;
4123 } else {
4124 regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP,
4125 WCD9335_ANA_CLK_MCLK_EN_MASK,
4126 WCD9335_ANA_CLK_MCLK_DISABLE);
4127 wcd->clk_type = WCD_CLK_OFF;
4128 }
4129
4130 regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP,
4131 WCD9335_ANA_CLK_EXT_CLKBUF_EN_MASK,
4132 WCD9335_ANA_CLK_EXT_CLKBUF_DISABLE);
4133 }
4134
4135 return 0;
4136 }
4137
wcd9335_disable_master_bias(struct wcd9335_codec * wcd)4138 static int wcd9335_disable_master_bias(struct wcd9335_codec *wcd)
4139 {
4140 if (wcd->master_bias_users <= 0)
4141 return -EINVAL;
4142
4143 wcd->master_bias_users--;
4144 if (wcd->master_bias_users == 0) {
4145 regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS,
4146 WCD9335_ANA_BIAS_EN_MASK,
4147 WCD9335_ANA_BIAS_DISABLE);
4148 regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS,
4149 WCD9335_ANA_BIAS_PRECHRG_CTL_MODE,
4150 WCD9335_ANA_BIAS_PRECHRG_CTL_MODE_MANUAL);
4151 }
4152 return 0;
4153 }
4154
wcd9335_cdc_req_mclk_enable(struct wcd9335_codec * wcd,bool enable)4155 static int wcd9335_cdc_req_mclk_enable(struct wcd9335_codec *wcd,
4156 bool enable)
4157 {
4158 int ret = 0;
4159
4160 if (enable) {
4161 wcd9335_cdc_sido_ccl_enable(wcd, true);
4162 ret = clk_prepare_enable(wcd->mclk);
4163 if (ret) {
4164 dev_err(wcd->dev, "%s: ext clk enable failed\n",
4165 __func__);
4166 goto err;
4167 }
4168 /* get BG */
4169 wcd9335_enable_master_bias(wcd);
4170 /* get MCLK */
4171 wcd9335_enable_mclk(wcd);
4172
4173 } else {
4174 /* put MCLK */
4175 wcd9335_disable_mclk(wcd);
4176 /* put BG */
4177 wcd9335_disable_master_bias(wcd);
4178 clk_disable_unprepare(wcd->mclk);
4179 wcd9335_cdc_sido_ccl_enable(wcd, false);
4180 }
4181 err:
4182 return ret;
4183 }
4184
wcd9335_codec_apply_sido_voltage(struct wcd9335_codec * wcd,enum wcd9335_sido_voltage req_mv)4185 static void wcd9335_codec_apply_sido_voltage(struct wcd9335_codec *wcd,
4186 enum wcd9335_sido_voltage req_mv)
4187 {
4188 struct snd_soc_component *comp = wcd->component;
4189 int vout_d_val;
4190
4191 if (req_mv == wcd->sido_voltage)
4192 return;
4193
4194 /* compute the vout_d step value */
4195 vout_d_val = WCD9335_CALCULATE_VOUT_D(req_mv) &
4196 WCD9335_ANA_BUCK_VOUT_MASK;
4197 snd_soc_component_write(comp, WCD9335_ANA_BUCK_VOUT_D, vout_d_val);
4198 snd_soc_component_update_bits(comp, WCD9335_ANA_BUCK_CTL,
4199 WCD9335_ANA_BUCK_CTL_RAMP_START_MASK,
4200 WCD9335_ANA_BUCK_CTL_RAMP_START_ENABLE);
4201
4202 /* 1 msec sleep required after SIDO Vout_D voltage change */
4203 usleep_range(1000, 1100);
4204 wcd->sido_voltage = req_mv;
4205 snd_soc_component_update_bits(comp, WCD9335_ANA_BUCK_CTL,
4206 WCD9335_ANA_BUCK_CTL_RAMP_START_MASK,
4207 WCD9335_ANA_BUCK_CTL_RAMP_START_DISABLE);
4208 }
4209
wcd9335_codec_update_sido_voltage(struct wcd9335_codec * wcd,enum wcd9335_sido_voltage req_mv)4210 static int wcd9335_codec_update_sido_voltage(struct wcd9335_codec *wcd,
4211 enum wcd9335_sido_voltage req_mv)
4212 {
4213 int ret = 0;
4214
4215 /* enable mclk before setting SIDO voltage */
4216 ret = wcd9335_cdc_req_mclk_enable(wcd, true);
4217 if (ret) {
4218 dev_err(wcd->dev, "Ext clk enable failed\n");
4219 goto err;
4220 }
4221
4222 wcd9335_codec_apply_sido_voltage(wcd, req_mv);
4223 wcd9335_cdc_req_mclk_enable(wcd, false);
4224
4225 err:
4226 return ret;
4227 }
4228
_wcd9335_codec_enable_mclk(struct snd_soc_component * component,int enable)4229 static int _wcd9335_codec_enable_mclk(struct snd_soc_component *component,
4230 int enable)
4231 {
4232 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
4233 int ret;
4234
4235 if (enable) {
4236 ret = wcd9335_cdc_req_mclk_enable(wcd, true);
4237 if (ret)
4238 return ret;
4239
4240 wcd9335_codec_apply_sido_voltage(wcd,
4241 SIDO_VOLTAGE_NOMINAL_MV);
4242 } else {
4243 wcd9335_codec_update_sido_voltage(wcd,
4244 wcd->sido_voltage);
4245 wcd9335_cdc_req_mclk_enable(wcd, false);
4246 }
4247
4248 return 0;
4249 }
4250
wcd9335_codec_enable_mclk(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kc,int event)4251 static int wcd9335_codec_enable_mclk(struct snd_soc_dapm_widget *w,
4252 struct snd_kcontrol *kc, int event)
4253 {
4254 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
4255
4256 switch (event) {
4257 case SND_SOC_DAPM_PRE_PMU:
4258 return _wcd9335_codec_enable_mclk(comp, true);
4259 case SND_SOC_DAPM_POST_PMD:
4260 return _wcd9335_codec_enable_mclk(comp, false);
4261 }
4262
4263 return 0;
4264 }
4265
4266 static const struct snd_soc_dapm_widget wcd9335_dapm_widgets[] = {
4267 /* TODO SPK1 & SPK2 OUT*/
4268 SND_SOC_DAPM_OUTPUT("EAR"),
4269 SND_SOC_DAPM_OUTPUT("HPHL"),
4270 SND_SOC_DAPM_OUTPUT("HPHR"),
4271 SND_SOC_DAPM_OUTPUT("LINEOUT1"),
4272 SND_SOC_DAPM_OUTPUT("LINEOUT2"),
4273 SND_SOC_DAPM_OUTPUT("LINEOUT3"),
4274 SND_SOC_DAPM_OUTPUT("LINEOUT4"),
4275 SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
4276 AIF1_PB, 0, wcd9335_codec_enable_slim,
4277 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4278 SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM,
4279 AIF2_PB, 0, wcd9335_codec_enable_slim,
4280 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4281 SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM,
4282 AIF3_PB, 0, wcd9335_codec_enable_slim,
4283 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4284 SND_SOC_DAPM_AIF_IN_E("AIF4 PB", "AIF4 Playback", 0, SND_SOC_NOPM,
4285 AIF4_PB, 0, wcd9335_codec_enable_slim,
4286 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4287 SND_SOC_DAPM_MUX("SLIM RX0 MUX", SND_SOC_NOPM, WCD9335_RX0, 0,
4288 &slim_rx_mux[WCD9335_RX0]),
4289 SND_SOC_DAPM_MUX("SLIM RX1 MUX", SND_SOC_NOPM, WCD9335_RX1, 0,
4290 &slim_rx_mux[WCD9335_RX1]),
4291 SND_SOC_DAPM_MUX("SLIM RX2 MUX", SND_SOC_NOPM, WCD9335_RX2, 0,
4292 &slim_rx_mux[WCD9335_RX2]),
4293 SND_SOC_DAPM_MUX("SLIM RX3 MUX", SND_SOC_NOPM, WCD9335_RX3, 0,
4294 &slim_rx_mux[WCD9335_RX3]),
4295 SND_SOC_DAPM_MUX("SLIM RX4 MUX", SND_SOC_NOPM, WCD9335_RX4, 0,
4296 &slim_rx_mux[WCD9335_RX4]),
4297 SND_SOC_DAPM_MUX("SLIM RX5 MUX", SND_SOC_NOPM, WCD9335_RX5, 0,
4298 &slim_rx_mux[WCD9335_RX5]),
4299 SND_SOC_DAPM_MUX("SLIM RX6 MUX", SND_SOC_NOPM, WCD9335_RX6, 0,
4300 &slim_rx_mux[WCD9335_RX6]),
4301 SND_SOC_DAPM_MUX("SLIM RX7 MUX", SND_SOC_NOPM, WCD9335_RX7, 0,
4302 &slim_rx_mux[WCD9335_RX7]),
4303 SND_SOC_DAPM_MIXER("SLIM RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
4304 SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
4305 SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
4306 SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
4307 SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
4308 SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
4309 SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0),
4310 SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0),
4311 SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", WCD9335_CDC_RX0_RX_PATH_MIX_CTL,
4312 5, 0, &rx_int0_2_mux, wcd9335_codec_enable_mix_path,
4313 SND_SOC_DAPM_POST_PMU),
4314 SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
4315 5, 0, &rx_int1_2_mux, wcd9335_codec_enable_mix_path,
4316 SND_SOC_DAPM_POST_PMU),
4317 SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
4318 5, 0, &rx_int2_2_mux, wcd9335_codec_enable_mix_path,
4319 SND_SOC_DAPM_POST_PMU),
4320 SND_SOC_DAPM_MUX_E("RX INT3_2 MUX", WCD9335_CDC_RX3_RX_PATH_MIX_CTL,
4321 5, 0, &rx_int3_2_mux, wcd9335_codec_enable_mix_path,
4322 SND_SOC_DAPM_POST_PMU),
4323 SND_SOC_DAPM_MUX_E("RX INT4_2 MUX", WCD9335_CDC_RX4_RX_PATH_MIX_CTL,
4324 5, 0, &rx_int4_2_mux, wcd9335_codec_enable_mix_path,
4325 SND_SOC_DAPM_POST_PMU),
4326 SND_SOC_DAPM_MUX_E("RX INT5_2 MUX", WCD9335_CDC_RX5_RX_PATH_MIX_CTL,
4327 5, 0, &rx_int5_2_mux, wcd9335_codec_enable_mix_path,
4328 SND_SOC_DAPM_POST_PMU),
4329 SND_SOC_DAPM_MUX_E("RX INT6_2 MUX", WCD9335_CDC_RX6_RX_PATH_MIX_CTL,
4330 5, 0, &rx_int6_2_mux, wcd9335_codec_enable_mix_path,
4331 SND_SOC_DAPM_POST_PMU),
4332 SND_SOC_DAPM_MUX_E("RX INT7_2 MUX", WCD9335_CDC_RX7_RX_PATH_MIX_CTL,
4333 5, 0, &rx_int7_2_mux, wcd9335_codec_enable_mix_path,
4334 SND_SOC_DAPM_POST_PMU),
4335 SND_SOC_DAPM_MUX_E("RX INT8_2 MUX", WCD9335_CDC_RX8_RX_PATH_MIX_CTL,
4336 5, 0, &rx_int8_2_mux, wcd9335_codec_enable_mix_path,
4337 SND_SOC_DAPM_POST_PMU),
4338 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
4339 &rx_int0_1_mix_inp0_mux),
4340 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4341 &rx_int0_1_mix_inp1_mux),
4342 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4343 &rx_int0_1_mix_inp2_mux),
4344 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
4345 &rx_int1_1_mix_inp0_mux),
4346 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4347 &rx_int1_1_mix_inp1_mux),
4348 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4349 &rx_int1_1_mix_inp2_mux),
4350 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
4351 &rx_int2_1_mix_inp0_mux),
4352 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4353 &rx_int2_1_mix_inp1_mux),
4354 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4355 &rx_int2_1_mix_inp2_mux),
4356 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
4357 &rx_int3_1_mix_inp0_mux),
4358 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4359 &rx_int3_1_mix_inp1_mux),
4360 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4361 &rx_int3_1_mix_inp2_mux),
4362 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
4363 &rx_int4_1_mix_inp0_mux),
4364 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4365 &rx_int4_1_mix_inp1_mux),
4366 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4367 &rx_int4_1_mix_inp2_mux),
4368 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
4369 &rx_int5_1_mix_inp0_mux),
4370 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4371 &rx_int5_1_mix_inp1_mux),
4372 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4373 &rx_int5_1_mix_inp2_mux),
4374 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
4375 &rx_int6_1_mix_inp0_mux),
4376 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4377 &rx_int6_1_mix_inp1_mux),
4378 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4379 &rx_int6_1_mix_inp2_mux),
4380 SND_SOC_DAPM_MUX("RX INT7_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
4381 &rx_int7_1_mix_inp0_mux),
4382 SND_SOC_DAPM_MUX("RX INT7_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4383 &rx_int7_1_mix_inp1_mux),
4384 SND_SOC_DAPM_MUX("RX INT7_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4385 &rx_int7_1_mix_inp2_mux),
4386 SND_SOC_DAPM_MUX("RX INT8_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
4387 &rx_int8_1_mix_inp0_mux),
4388 SND_SOC_DAPM_MUX("RX INT8_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
4389 &rx_int8_1_mix_inp1_mux),
4390 SND_SOC_DAPM_MUX("RX INT8_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
4391 &rx_int8_1_mix_inp2_mux),
4392
4393 SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
4394 SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
4395 SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
4396 SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
4397 SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
4398 SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
4399 SND_SOC_DAPM_MIXER("RX INT3_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
4400 SND_SOC_DAPM_MIXER("RX INT3 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
4401 SND_SOC_DAPM_MIXER("RX INT4_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
4402 SND_SOC_DAPM_MIXER("RX INT4 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
4403 SND_SOC_DAPM_MIXER("RX INT5_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
4404 SND_SOC_DAPM_MIXER("RX INT5 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
4405 SND_SOC_DAPM_MIXER("RX INT6_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
4406 SND_SOC_DAPM_MIXER("RX INT6 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
4407 SND_SOC_DAPM_MIXER("RX INT7_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
4408 SND_SOC_DAPM_MIXER("RX INT7 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
4409 SND_SOC_DAPM_MIXER("RX INT8_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
4410 SND_SOC_DAPM_MIXER("RX INT8 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
4411
4412 SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
4413 SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
4414 SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
4415 SND_SOC_DAPM_MIXER("RX INT3 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
4416 SND_SOC_DAPM_MIXER("RX INT4 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
4417 SND_SOC_DAPM_MIXER("RX INT5 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
4418 SND_SOC_DAPM_MIXER("RX INT6 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
4419 SND_SOC_DAPM_MIXER("RX INT7 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
4420 SND_SOC_DAPM_MIXER("RX INT8 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
4421
4422 SND_SOC_DAPM_MUX("RX INT0 DEM MUX", SND_SOC_NOPM, 0, 0,
4423 &rx_int0_dem_inp_mux),
4424 SND_SOC_DAPM_MUX("RX INT1 DEM MUX", SND_SOC_NOPM, 0, 0,
4425 &rx_int1_dem_inp_mux),
4426 SND_SOC_DAPM_MUX("RX INT2 DEM MUX", SND_SOC_NOPM, 0, 0,
4427 &rx_int2_dem_inp_mux),
4428
4429 SND_SOC_DAPM_MUX_E("RX INT0 INTERP", SND_SOC_NOPM,
4430 INTERP_EAR, 0, &rx_int0_interp_mux,
4431 wcd9335_codec_enable_interpolator,
4432 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4433 SND_SOC_DAPM_POST_PMD),
4434 SND_SOC_DAPM_MUX_E("RX INT1 INTERP", SND_SOC_NOPM,
4435 INTERP_HPHL, 0, &rx_int1_interp_mux,
4436 wcd9335_codec_enable_interpolator,
4437 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4438 SND_SOC_DAPM_POST_PMD),
4439 SND_SOC_DAPM_MUX_E("RX INT2 INTERP", SND_SOC_NOPM,
4440 INTERP_HPHR, 0, &rx_int2_interp_mux,
4441 wcd9335_codec_enable_interpolator,
4442 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4443 SND_SOC_DAPM_POST_PMD),
4444 SND_SOC_DAPM_MUX_E("RX INT3 INTERP", SND_SOC_NOPM,
4445 INTERP_LO1, 0, &rx_int3_interp_mux,
4446 wcd9335_codec_enable_interpolator,
4447 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4448 SND_SOC_DAPM_POST_PMD),
4449 SND_SOC_DAPM_MUX_E("RX INT4 INTERP", SND_SOC_NOPM,
4450 INTERP_LO2, 0, &rx_int4_interp_mux,
4451 wcd9335_codec_enable_interpolator,
4452 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4453 SND_SOC_DAPM_POST_PMD),
4454 SND_SOC_DAPM_MUX_E("RX INT5 INTERP", SND_SOC_NOPM,
4455 INTERP_LO3, 0, &rx_int5_interp_mux,
4456 wcd9335_codec_enable_interpolator,
4457 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4458 SND_SOC_DAPM_POST_PMD),
4459 SND_SOC_DAPM_MUX_E("RX INT6 INTERP", SND_SOC_NOPM,
4460 INTERP_LO4, 0, &rx_int6_interp_mux,
4461 wcd9335_codec_enable_interpolator,
4462 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4463 SND_SOC_DAPM_POST_PMD),
4464 SND_SOC_DAPM_MUX_E("RX INT7 INTERP", SND_SOC_NOPM,
4465 INTERP_SPKR1, 0, &rx_int7_interp_mux,
4466 wcd9335_codec_enable_interpolator,
4467 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4468 SND_SOC_DAPM_POST_PMD),
4469 SND_SOC_DAPM_MUX_E("RX INT8 INTERP", SND_SOC_NOPM,
4470 INTERP_SPKR2, 0, &rx_int8_interp_mux,
4471 wcd9335_codec_enable_interpolator,
4472 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4473 SND_SOC_DAPM_POST_PMD),
4474
4475 SND_SOC_DAPM_DAC_E("RX INT0 DAC", NULL, SND_SOC_NOPM,
4476 0, 0, wcd9335_codec_ear_dac_event,
4477 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4478 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4479 SND_SOC_DAPM_DAC_E("RX INT1 DAC", NULL, WCD9335_ANA_HPH,
4480 5, 0, wcd9335_codec_hphl_dac_event,
4481 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4482 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4483 SND_SOC_DAPM_DAC_E("RX INT2 DAC", NULL, WCD9335_ANA_HPH,
4484 4, 0, wcd9335_codec_hphr_dac_event,
4485 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4486 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4487 SND_SOC_DAPM_DAC_E("RX INT3 DAC", NULL, SND_SOC_NOPM,
4488 0, 0, wcd9335_codec_lineout_dac_event,
4489 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
4490 SND_SOC_DAPM_DAC_E("RX INT4 DAC", NULL, SND_SOC_NOPM,
4491 0, 0, wcd9335_codec_lineout_dac_event,
4492 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
4493 SND_SOC_DAPM_DAC_E("RX INT5 DAC", NULL, SND_SOC_NOPM,
4494 0, 0, wcd9335_codec_lineout_dac_event,
4495 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
4496 SND_SOC_DAPM_DAC_E("RX INT6 DAC", NULL, SND_SOC_NOPM,
4497 0, 0, wcd9335_codec_lineout_dac_event,
4498 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
4499 SND_SOC_DAPM_PGA_E("HPHL PA", WCD9335_ANA_HPH, 7, 0, NULL, 0,
4500 wcd9335_codec_enable_hphl_pa,
4501 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4502 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4503 SND_SOC_DAPM_PGA_E("HPHR PA", WCD9335_ANA_HPH, 6, 0, NULL, 0,
4504 wcd9335_codec_enable_hphr_pa,
4505 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4506 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4507 SND_SOC_DAPM_PGA_E("EAR PA", WCD9335_ANA_EAR, 7, 0, NULL, 0,
4508 wcd9335_codec_enable_ear_pa,
4509 SND_SOC_DAPM_POST_PMU |
4510 SND_SOC_DAPM_POST_PMD),
4511 SND_SOC_DAPM_PGA_E("LINEOUT1 PA", WCD9335_ANA_LO_1_2, 7, 0, NULL, 0,
4512 wcd9335_codec_enable_lineout_pa,
4513 SND_SOC_DAPM_POST_PMU |
4514 SND_SOC_DAPM_POST_PMD),
4515 SND_SOC_DAPM_PGA_E("LINEOUT2 PA", WCD9335_ANA_LO_1_2, 6, 0, NULL, 0,
4516 wcd9335_codec_enable_lineout_pa,
4517 SND_SOC_DAPM_POST_PMU |
4518 SND_SOC_DAPM_POST_PMD),
4519 SND_SOC_DAPM_PGA_E("LINEOUT3 PA", WCD9335_ANA_LO_3_4, 7, 0, NULL, 0,
4520 wcd9335_codec_enable_lineout_pa,
4521 SND_SOC_DAPM_POST_PMU |
4522 SND_SOC_DAPM_POST_PMD),
4523 SND_SOC_DAPM_PGA_E("LINEOUT4 PA", WCD9335_ANA_LO_3_4, 6, 0, NULL, 0,
4524 wcd9335_codec_enable_lineout_pa,
4525 SND_SOC_DAPM_POST_PMU |
4526 SND_SOC_DAPM_POST_PMD),
4527 SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
4528 wcd9335_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
4529 SND_SOC_DAPM_POST_PMD),
4530 SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0,
4531 wcd9335_codec_enable_mclk, SND_SOC_DAPM_PRE_PMU |
4532 SND_SOC_DAPM_POST_PMD),
4533
4534 /* TX */
4535 SND_SOC_DAPM_INPUT("AMIC1"),
4536 SND_SOC_DAPM_INPUT("AMIC2"),
4537 SND_SOC_DAPM_INPUT("AMIC3"),
4538 SND_SOC_DAPM_INPUT("AMIC4"),
4539 SND_SOC_DAPM_INPUT("AMIC5"),
4540 SND_SOC_DAPM_INPUT("AMIC6"),
4541
4542 SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
4543 AIF1_CAP, 0, wcd9335_codec_enable_slim,
4544 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4545
4546 SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM,
4547 AIF2_CAP, 0, wcd9335_codec_enable_slim,
4548 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4549
4550 SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM,
4551 AIF3_CAP, 0, wcd9335_codec_enable_slim,
4552 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
4553
4554 SND_SOC_DAPM_SUPPLY("MIC BIAS1", SND_SOC_NOPM, 0, 0,
4555 wcd9335_codec_enable_micbias,
4556 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4557 SND_SOC_DAPM_POST_PMD),
4558 SND_SOC_DAPM_SUPPLY("MIC BIAS2", SND_SOC_NOPM, 0, 0,
4559 wcd9335_codec_enable_micbias,
4560 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4561 SND_SOC_DAPM_POST_PMD),
4562 SND_SOC_DAPM_SUPPLY("MIC BIAS3", SND_SOC_NOPM, 0, 0,
4563 wcd9335_codec_enable_micbias,
4564 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4565 SND_SOC_DAPM_POST_PMD),
4566 SND_SOC_DAPM_SUPPLY("MIC BIAS4", SND_SOC_NOPM, 0, 0,
4567 wcd9335_codec_enable_micbias,
4568 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4569 SND_SOC_DAPM_POST_PMD),
4570
4571 SND_SOC_DAPM_ADC_E("ADC1", NULL, WCD9335_ANA_AMIC1, 7, 0,
4572 wcd9335_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
4573 SND_SOC_DAPM_ADC_E("ADC2", NULL, WCD9335_ANA_AMIC2, 7, 0,
4574 wcd9335_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
4575 SND_SOC_DAPM_ADC_E("ADC3", NULL, WCD9335_ANA_AMIC3, 7, 0,
4576 wcd9335_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
4577 SND_SOC_DAPM_ADC_E("ADC4", NULL, WCD9335_ANA_AMIC4, 7, 0,
4578 wcd9335_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
4579 SND_SOC_DAPM_ADC_E("ADC5", NULL, WCD9335_ANA_AMIC5, 7, 0,
4580 wcd9335_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
4581 SND_SOC_DAPM_ADC_E("ADC6", NULL, WCD9335_ANA_AMIC6, 7, 0,
4582 wcd9335_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
4583
4584 /* Digital Mic Inputs */
4585 SND_SOC_DAPM_ADC_E("DMIC0", NULL, SND_SOC_NOPM, 0, 0,
4586 wcd9335_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
4587 SND_SOC_DAPM_POST_PMD),
4588
4589 SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
4590 wcd9335_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
4591 SND_SOC_DAPM_POST_PMD),
4592
4593 SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
4594 wcd9335_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
4595 SND_SOC_DAPM_POST_PMD),
4596
4597 SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0,
4598 wcd9335_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
4599 SND_SOC_DAPM_POST_PMD),
4600
4601 SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0,
4602 wcd9335_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
4603 SND_SOC_DAPM_POST_PMD),
4604
4605 SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0,
4606 wcd9335_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
4607 SND_SOC_DAPM_POST_PMD),
4608
4609 SND_SOC_DAPM_MUX("DMIC MUX0", SND_SOC_NOPM, 0, 0,
4610 &tx_dmic_mux0),
4611 SND_SOC_DAPM_MUX("DMIC MUX1", SND_SOC_NOPM, 0, 0,
4612 &tx_dmic_mux1),
4613 SND_SOC_DAPM_MUX("DMIC MUX2", SND_SOC_NOPM, 0, 0,
4614 &tx_dmic_mux2),
4615 SND_SOC_DAPM_MUX("DMIC MUX3", SND_SOC_NOPM, 0, 0,
4616 &tx_dmic_mux3),
4617 SND_SOC_DAPM_MUX("DMIC MUX4", SND_SOC_NOPM, 0, 0,
4618 &tx_dmic_mux4),
4619 SND_SOC_DAPM_MUX("DMIC MUX5", SND_SOC_NOPM, 0, 0,
4620 &tx_dmic_mux5),
4621 SND_SOC_DAPM_MUX("DMIC MUX6", SND_SOC_NOPM, 0, 0,
4622 &tx_dmic_mux6),
4623 SND_SOC_DAPM_MUX("DMIC MUX7", SND_SOC_NOPM, 0, 0,
4624 &tx_dmic_mux7),
4625 SND_SOC_DAPM_MUX("DMIC MUX8", SND_SOC_NOPM, 0, 0,
4626 &tx_dmic_mux8),
4627
4628 SND_SOC_DAPM_MUX("AMIC MUX0", SND_SOC_NOPM, 0, 0,
4629 &tx_amic_mux0),
4630 SND_SOC_DAPM_MUX("AMIC MUX1", SND_SOC_NOPM, 0, 0,
4631 &tx_amic_mux1),
4632 SND_SOC_DAPM_MUX("AMIC MUX2", SND_SOC_NOPM, 0, 0,
4633 &tx_amic_mux2),
4634 SND_SOC_DAPM_MUX("AMIC MUX3", SND_SOC_NOPM, 0, 0,
4635 &tx_amic_mux3),
4636 SND_SOC_DAPM_MUX("AMIC MUX4", SND_SOC_NOPM, 0, 0,
4637 &tx_amic_mux4),
4638 SND_SOC_DAPM_MUX("AMIC MUX5", SND_SOC_NOPM, 0, 0,
4639 &tx_amic_mux5),
4640 SND_SOC_DAPM_MUX("AMIC MUX6", SND_SOC_NOPM, 0, 0,
4641 &tx_amic_mux6),
4642 SND_SOC_DAPM_MUX("AMIC MUX7", SND_SOC_NOPM, 0, 0,
4643 &tx_amic_mux7),
4644 SND_SOC_DAPM_MUX("AMIC MUX8", SND_SOC_NOPM, 0, 0,
4645 &tx_amic_mux8),
4646
4647 SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
4648 aif1_cap_mixer, ARRAY_SIZE(aif1_cap_mixer)),
4649
4650 SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0,
4651 aif2_cap_mixer, ARRAY_SIZE(aif2_cap_mixer)),
4652
4653 SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0,
4654 aif3_cap_mixer, ARRAY_SIZE(aif3_cap_mixer)),
4655
4656 SND_SOC_DAPM_MUX("SLIM TX0 MUX", SND_SOC_NOPM, WCD9335_TX0, 0,
4657 &sb_tx0_mux),
4658 SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, WCD9335_TX1, 0,
4659 &sb_tx1_mux),
4660 SND_SOC_DAPM_MUX("SLIM TX2 MUX", SND_SOC_NOPM, WCD9335_TX2, 0,
4661 &sb_tx2_mux),
4662 SND_SOC_DAPM_MUX("SLIM TX3 MUX", SND_SOC_NOPM, WCD9335_TX3, 0,
4663 &sb_tx3_mux),
4664 SND_SOC_DAPM_MUX("SLIM TX4 MUX", SND_SOC_NOPM, WCD9335_TX4, 0,
4665 &sb_tx4_mux),
4666 SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, WCD9335_TX5, 0,
4667 &sb_tx5_mux),
4668 SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, WCD9335_TX6, 0,
4669 &sb_tx6_mux),
4670 SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, WCD9335_TX7, 0,
4671 &sb_tx7_mux),
4672 SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, WCD9335_TX8, 0,
4673 &sb_tx8_mux),
4674
4675 SND_SOC_DAPM_MUX_E("ADC MUX0", WCD9335_CDC_TX0_TX_PATH_CTL, 5, 0,
4676 &tx_adc_mux0, wcd9335_codec_enable_dec,
4677 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4678 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4679
4680 SND_SOC_DAPM_MUX_E("ADC MUX1", WCD9335_CDC_TX1_TX_PATH_CTL, 5, 0,
4681 &tx_adc_mux1, wcd9335_codec_enable_dec,
4682 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4683 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4684
4685 SND_SOC_DAPM_MUX_E("ADC MUX2", WCD9335_CDC_TX2_TX_PATH_CTL, 5, 0,
4686 &tx_adc_mux2, wcd9335_codec_enable_dec,
4687 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4688 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4689
4690 SND_SOC_DAPM_MUX_E("ADC MUX3", WCD9335_CDC_TX3_TX_PATH_CTL, 5, 0,
4691 &tx_adc_mux3, wcd9335_codec_enable_dec,
4692 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4693 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4694
4695 SND_SOC_DAPM_MUX_E("ADC MUX4", WCD9335_CDC_TX4_TX_PATH_CTL, 5, 0,
4696 &tx_adc_mux4, wcd9335_codec_enable_dec,
4697 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4698 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4699
4700 SND_SOC_DAPM_MUX_E("ADC MUX5", WCD9335_CDC_TX5_TX_PATH_CTL, 5, 0,
4701 &tx_adc_mux5, wcd9335_codec_enable_dec,
4702 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4703 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4704
4705 SND_SOC_DAPM_MUX_E("ADC MUX6", WCD9335_CDC_TX6_TX_PATH_CTL, 5, 0,
4706 &tx_adc_mux6, wcd9335_codec_enable_dec,
4707 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4708 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4709
4710 SND_SOC_DAPM_MUX_E("ADC MUX7", WCD9335_CDC_TX7_TX_PATH_CTL, 5, 0,
4711 &tx_adc_mux7, wcd9335_codec_enable_dec,
4712 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4713 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4714
4715 SND_SOC_DAPM_MUX_E("ADC MUX8", WCD9335_CDC_TX8_TX_PATH_CTL, 5, 0,
4716 &tx_adc_mux8, wcd9335_codec_enable_dec,
4717 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4718 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
4719 };
4720
wcd9335_enable_sido_buck(struct snd_soc_component * component)4721 static void wcd9335_enable_sido_buck(struct snd_soc_component *component)
4722 {
4723 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
4724
4725 snd_soc_component_update_bits(component, WCD9335_ANA_RCO,
4726 WCD9335_ANA_RCO_BG_EN_MASK,
4727 WCD9335_ANA_RCO_BG_ENABLE);
4728 snd_soc_component_update_bits(component, WCD9335_ANA_BUCK_CTL,
4729 WCD9335_ANA_BUCK_CTL_VOUT_D_IREF_MASK,
4730 WCD9335_ANA_BUCK_CTL_VOUT_D_IREF_EXT);
4731 /* 100us sleep needed after IREF settings */
4732 usleep_range(100, 110);
4733 snd_soc_component_update_bits(component, WCD9335_ANA_BUCK_CTL,
4734 WCD9335_ANA_BUCK_CTL_VOUT_D_VREF_MASK,
4735 WCD9335_ANA_BUCK_CTL_VOUT_D_VREF_EXT);
4736 /* 100us sleep needed after VREF settings */
4737 usleep_range(100, 110);
4738 wcd->sido_input_src = SIDO_SOURCE_RCO_BG;
4739 }
4740
wcd9335_enable_efuse_sensing(struct snd_soc_component * comp)4741 static int wcd9335_enable_efuse_sensing(struct snd_soc_component *comp)
4742 {
4743 _wcd9335_codec_enable_mclk(comp, true);
4744 snd_soc_component_update_bits(comp,
4745 WCD9335_CHIP_TIER_CTRL_EFUSE_CTL,
4746 WCD9335_CHIP_TIER_CTRL_EFUSE_EN_MASK,
4747 WCD9335_CHIP_TIER_CTRL_EFUSE_ENABLE);
4748 /*
4749 * 5ms sleep required after enabling efuse control
4750 * before checking the status.
4751 */
4752 usleep_range(5000, 5500);
4753
4754 if (!(snd_soc_component_read(comp,
4755 WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS) &
4756 WCD9335_CHIP_TIER_CTRL_EFUSE_EN_MASK))
4757 WARN(1, "%s: Efuse sense is not complete\n", __func__);
4758
4759 wcd9335_enable_sido_buck(comp);
4760 _wcd9335_codec_enable_mclk(comp, false);
4761
4762 return 0;
4763 }
4764
wcd9335_codec_init(struct snd_soc_component * component)4765 static void wcd9335_codec_init(struct snd_soc_component *component)
4766 {
4767 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
4768 int i;
4769
4770 /* ungate MCLK and set clk rate */
4771 regmap_update_bits(wcd->regmap, WCD9335_CODEC_RPM_CLK_GATE,
4772 WCD9335_CODEC_RPM_CLK_GATE_MCLK_GATE_MASK, 0);
4773
4774 regmap_update_bits(wcd->regmap, WCD9335_CODEC_RPM_CLK_MCLK_CFG,
4775 WCD9335_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK,
4776 WCD9335_CODEC_RPM_CLK_MCLK_CFG_9P6MHZ);
4777
4778 for (i = 0; i < ARRAY_SIZE(wcd9335_codec_reg_init); i++)
4779 snd_soc_component_update_bits(component,
4780 wcd9335_codec_reg_init[i].reg,
4781 wcd9335_codec_reg_init[i].mask,
4782 wcd9335_codec_reg_init[i].val);
4783
4784 wcd9335_enable_efuse_sensing(component);
4785 }
4786
wcd9335_codec_probe(struct snd_soc_component * component)4787 static int wcd9335_codec_probe(struct snd_soc_component *component)
4788 {
4789 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
4790 int ret;
4791 int i;
4792
4793 snd_soc_component_init_regmap(component, wcd->regmap);
4794 /* Class-H Init*/
4795 wcd->clsh_ctrl = wcd_clsh_ctrl_alloc(component, WCD9335);
4796 if (IS_ERR(wcd->clsh_ctrl))
4797 return PTR_ERR(wcd->clsh_ctrl);
4798
4799 /* Default HPH Mode to Class-H HiFi */
4800 wcd->hph_mode = CLS_H_HIFI;
4801 wcd->component = component;
4802
4803 wcd9335_codec_init(component);
4804
4805 for (i = 0; i < NUM_CODEC_DAIS; i++)
4806 INIT_LIST_HEAD(&wcd->dai[i].slim_ch_list);
4807
4808 ret = wcd9335_setup_irqs(wcd);
4809 if (ret)
4810 goto free_clsh_ctrl;
4811
4812 return 0;
4813
4814 free_clsh_ctrl:
4815 wcd_clsh_ctrl_free(wcd->clsh_ctrl);
4816 return ret;
4817 }
4818
wcd9335_codec_remove(struct snd_soc_component * comp)4819 static void wcd9335_codec_remove(struct snd_soc_component *comp)
4820 {
4821 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
4822
4823 wcd_clsh_ctrl_free(wcd->clsh_ctrl);
4824 wcd9335_teardown_irqs(wcd);
4825 }
4826
wcd9335_codec_set_sysclk(struct snd_soc_component * comp,int clk_id,int source,unsigned int freq,int dir)4827 static int wcd9335_codec_set_sysclk(struct snd_soc_component *comp,
4828 int clk_id, int source,
4829 unsigned int freq, int dir)
4830 {
4831 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
4832
4833 wcd->mclk_rate = freq;
4834
4835 if (wcd->mclk_rate == WCD9335_MCLK_CLK_12P288MHZ)
4836 snd_soc_component_update_bits(comp,
4837 WCD9335_CODEC_RPM_CLK_MCLK_CFG,
4838 WCD9335_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK,
4839 WCD9335_CODEC_RPM_CLK_MCLK_CFG_12P288MHZ);
4840 else if (wcd->mclk_rate == WCD9335_MCLK_CLK_9P6MHZ)
4841 snd_soc_component_update_bits(comp,
4842 WCD9335_CODEC_RPM_CLK_MCLK_CFG,
4843 WCD9335_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK,
4844 WCD9335_CODEC_RPM_CLK_MCLK_CFG_9P6MHZ);
4845
4846 return clk_set_rate(wcd->mclk, freq);
4847 }
4848
4849 static const struct snd_soc_component_driver wcd9335_component_drv = {
4850 .probe = wcd9335_codec_probe,
4851 .remove = wcd9335_codec_remove,
4852 .set_sysclk = wcd9335_codec_set_sysclk,
4853 .controls = wcd9335_snd_controls,
4854 .num_controls = ARRAY_SIZE(wcd9335_snd_controls),
4855 .dapm_widgets = wcd9335_dapm_widgets,
4856 .num_dapm_widgets = ARRAY_SIZE(wcd9335_dapm_widgets),
4857 .dapm_routes = wcd9335_audio_map,
4858 .num_dapm_routes = ARRAY_SIZE(wcd9335_audio_map),
4859 .endianness = 1,
4860 };
4861
wcd9335_probe(struct wcd9335_codec * wcd)4862 static int wcd9335_probe(struct wcd9335_codec *wcd)
4863 {
4864 struct device *dev = wcd->dev;
4865
4866 memcpy(wcd->rx_chs, wcd9335_rx_chs, sizeof(wcd9335_rx_chs));
4867 memcpy(wcd->tx_chs, wcd9335_tx_chs, sizeof(wcd9335_tx_chs));
4868
4869 wcd->sido_input_src = SIDO_SOURCE_INTERNAL;
4870 wcd->sido_voltage = SIDO_VOLTAGE_NOMINAL_MV;
4871
4872 return devm_snd_soc_register_component(dev, &wcd9335_component_drv,
4873 wcd9335_slim_dais,
4874 ARRAY_SIZE(wcd9335_slim_dais));
4875 }
4876
4877 static const struct regmap_range_cfg wcd9335_ranges[] = {
4878 {
4879 .name = "WCD9335",
4880 .range_min = 0x0,
4881 .range_max = WCD9335_MAX_REGISTER,
4882 .selector_reg = WCD9335_SEL_REGISTER,
4883 .selector_mask = 0xff,
4884 .selector_shift = 0,
4885 .window_start = 0x800,
4886 .window_len = 0x100,
4887 },
4888 };
4889
wcd9335_is_volatile_register(struct device * dev,unsigned int reg)4890 static bool wcd9335_is_volatile_register(struct device *dev, unsigned int reg)
4891 {
4892 switch (reg) {
4893 case WCD9335_INTR_PIN1_STATUS0...WCD9335_INTR_PIN2_CLEAR3:
4894 case WCD9335_ANA_MBHC_RESULT_3:
4895 case WCD9335_ANA_MBHC_RESULT_2:
4896 case WCD9335_ANA_MBHC_RESULT_1:
4897 case WCD9335_ANA_MBHC_MECH:
4898 case WCD9335_ANA_MBHC_ELECT:
4899 case WCD9335_ANA_MBHC_ZDET:
4900 case WCD9335_ANA_MICB2:
4901 case WCD9335_ANA_RCO:
4902 case WCD9335_ANA_BIAS:
4903 return true;
4904 default:
4905 return false;
4906 }
4907 }
4908
4909 static const struct regmap_config wcd9335_regmap_config = {
4910 .reg_bits = 16,
4911 .val_bits = 8,
4912 .cache_type = REGCACHE_MAPLE,
4913 .max_register = WCD9335_MAX_REGISTER,
4914 .can_multi_write = true,
4915 .ranges = wcd9335_ranges,
4916 .num_ranges = ARRAY_SIZE(wcd9335_ranges),
4917 .volatile_reg = wcd9335_is_volatile_register,
4918 };
4919
4920 static const struct regmap_range_cfg wcd9335_ifc_ranges[] = {
4921 {
4922 .name = "WCD9335-IFC-DEV",
4923 .range_min = 0x0,
4924 .range_max = WCD9335_MAX_REGISTER,
4925 .selector_reg = WCD9335_SEL_REGISTER,
4926 .selector_mask = 0xfff,
4927 .selector_shift = 0,
4928 .window_start = 0x800,
4929 .window_len = 0x400,
4930 },
4931 };
4932
4933 static const struct regmap_config wcd9335_ifc_regmap_config = {
4934 .reg_bits = 16,
4935 .val_bits = 8,
4936 .can_multi_write = true,
4937 .max_register = WCD9335_MAX_REGISTER,
4938 .ranges = wcd9335_ifc_ranges,
4939 .num_ranges = ARRAY_SIZE(wcd9335_ifc_ranges),
4940 };
4941
4942 static const struct regmap_irq wcd9335_codec_irqs[] = {
4943 /* INTR_REG 0 */
4944 [WCD9335_IRQ_SLIMBUS] = {
4945 .reg_offset = 0,
4946 .mask = BIT(0),
4947 .type = {
4948 .type_reg_offset = 0,
4949 .types_supported = IRQ_TYPE_EDGE_BOTH,
4950 .type_reg_mask = BIT(0),
4951 },
4952 },
4953 };
4954
4955 static const unsigned int wcd9335_config_regs[] = {
4956 WCD9335_INTR_LEVEL0,
4957 };
4958
4959 static const struct regmap_irq_chip wcd9335_regmap_irq1_chip = {
4960 .name = "wcd9335_pin1_irq",
4961 .status_base = WCD9335_INTR_PIN1_STATUS0,
4962 .mask_base = WCD9335_INTR_PIN1_MASK0,
4963 .ack_base = WCD9335_INTR_PIN1_CLEAR0,
4964 .num_regs = 4,
4965 .irqs = wcd9335_codec_irqs,
4966 .num_irqs = ARRAY_SIZE(wcd9335_codec_irqs),
4967 .config_base = wcd9335_config_regs,
4968 .num_config_bases = ARRAY_SIZE(wcd9335_config_regs),
4969 .num_config_regs = 4,
4970 .set_type_config = regmap_irq_set_type_config_simple,
4971 };
4972
wcd9335_parse_dt(struct wcd9335_codec * wcd)4973 static int wcd9335_parse_dt(struct wcd9335_codec *wcd)
4974 {
4975 struct device *dev = wcd->dev;
4976 struct device_node *np = dev->of_node;
4977 int ret;
4978
4979 wcd->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0);
4980 if (wcd->reset_gpio < 0)
4981 return dev_err_probe(dev, wcd->reset_gpio, "Reset GPIO missing from DT\n");
4982
4983 wcd->mclk = devm_clk_get(dev, "mclk");
4984 if (IS_ERR(wcd->mclk))
4985 return dev_err_probe(dev, PTR_ERR(wcd->mclk), "mclk not found\n");
4986
4987 wcd->native_clk = devm_clk_get(dev, "slimbus");
4988 if (IS_ERR(wcd->native_clk))
4989 return dev_err_probe(dev, PTR_ERR(wcd->native_clk), "slimbus clock not found\n");
4990
4991 wcd->supplies[0].supply = "vdd-buck";
4992 wcd->supplies[1].supply = "vdd-buck-sido";
4993 wcd->supplies[2].supply = "vdd-tx";
4994 wcd->supplies[3].supply = "vdd-rx";
4995 wcd->supplies[4].supply = "vdd-io";
4996
4997 ret = regulator_bulk_get(dev, WCD9335_MAX_SUPPLY, wcd->supplies);
4998 if (ret)
4999 return dev_err_probe(dev, ret, "Failed to get supplies\n");
5000
5001 return 0;
5002 }
5003
wcd9335_power_on_reset(struct wcd9335_codec * wcd)5004 static int wcd9335_power_on_reset(struct wcd9335_codec *wcd)
5005 {
5006 struct device *dev = wcd->dev;
5007 int ret;
5008
5009 ret = regulator_bulk_enable(WCD9335_MAX_SUPPLY, wcd->supplies);
5010 if (ret) {
5011 dev_err(dev, "Failed to get supplies: err = %d\n", ret);
5012 return ret;
5013 }
5014
5015 /*
5016 * For WCD9335, it takes about 600us for the Vout_A and
5017 * Vout_D to be ready after BUCK_SIDO is powered up.
5018 * SYS_RST_N shouldn't be pulled high during this time
5019 * Toggle the reset line to make sure the reset pulse is
5020 * correctly applied
5021 */
5022 usleep_range(600, 650);
5023
5024 gpio_direction_output(wcd->reset_gpio, 0);
5025 msleep(20);
5026 gpio_set_value(wcd->reset_gpio, 1);
5027 msleep(20);
5028
5029 return 0;
5030 }
5031
wcd9335_bring_up(struct wcd9335_codec * wcd)5032 static int wcd9335_bring_up(struct wcd9335_codec *wcd)
5033 {
5034 struct regmap *rm = wcd->regmap;
5035 int val, byte0;
5036
5037 regmap_read(rm, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0, &val);
5038 regmap_read(rm, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0, &byte0);
5039
5040 if ((val < 0) || (byte0 < 0)) {
5041 dev_err(wcd->dev, "WCD9335 CODEC version detection fail!\n");
5042 return -EINVAL;
5043 }
5044
5045 if (byte0 == 0x1) {
5046 dev_info(wcd->dev, "WCD9335 CODEC version is v2.0\n");
5047 regmap_write(rm, WCD9335_CODEC_RPM_RST_CTL, 0x01);
5048 regmap_write(rm, WCD9335_SIDO_SIDO_TEST_2, 0x00);
5049 regmap_write(rm, WCD9335_SIDO_SIDO_CCL_8, 0x6F);
5050 regmap_write(rm, WCD9335_BIAS_VBG_FINE_ADJ, 0x65);
5051 regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5);
5052 regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7);
5053 regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3);
5054 regmap_write(rm, WCD9335_CODEC_RPM_RST_CTL, 0x3);
5055 } else {
5056 dev_err(wcd->dev, "WCD9335 CODEC version not supported\n");
5057 return -EINVAL;
5058 }
5059
5060 return 0;
5061 }
5062
wcd9335_irq_init(struct wcd9335_codec * wcd)5063 static int wcd9335_irq_init(struct wcd9335_codec *wcd)
5064 {
5065 int ret;
5066
5067 /*
5068 * INTR1 consists of all possible interrupt sources Ear OCP,
5069 * HPH OCP, MBHC, MAD, VBAT, and SVA
5070 * INTR2 is a subset of first interrupt sources MAD, VBAT, and SVA
5071 */
5072 wcd->intr1 = of_irq_get_byname(wcd->dev->of_node, "intr1");
5073 if (wcd->intr1 < 0)
5074 return dev_err_probe(wcd->dev, wcd->intr1,
5075 "Unable to configure IRQ\n");
5076
5077 ret = devm_regmap_add_irq_chip(wcd->dev, wcd->regmap, wcd->intr1,
5078 IRQF_TRIGGER_HIGH, 0,
5079 &wcd9335_regmap_irq1_chip, &wcd->irq_data);
5080 if (ret)
5081 return dev_err_probe(wcd->dev, ret, "Failed to register IRQ chip\n");
5082
5083 return 0;
5084 }
5085
wcd9335_slim_probe(struct slim_device * slim)5086 static int wcd9335_slim_probe(struct slim_device *slim)
5087 {
5088 struct device *dev = &slim->dev;
5089 struct wcd9335_codec *wcd;
5090 int ret;
5091
5092 wcd = devm_kzalloc(dev, sizeof(*wcd), GFP_KERNEL);
5093 if (!wcd)
5094 return -ENOMEM;
5095
5096 wcd->dev = dev;
5097 ret = wcd9335_parse_dt(wcd);
5098 if (ret)
5099 return ret;
5100
5101 ret = wcd9335_power_on_reset(wcd);
5102 if (ret)
5103 return ret;
5104
5105 dev_set_drvdata(dev, wcd);
5106
5107 return 0;
5108 }
5109
wcd9335_slim_status(struct slim_device * sdev,enum slim_device_status status)5110 static int wcd9335_slim_status(struct slim_device *sdev,
5111 enum slim_device_status status)
5112 {
5113 struct device *dev = &sdev->dev;
5114 struct device_node *ifc_dev_np;
5115 struct wcd9335_codec *wcd;
5116 int ret;
5117
5118 wcd = dev_get_drvdata(dev);
5119
5120 ifc_dev_np = of_parse_phandle(dev->of_node, "slim-ifc-dev", 0);
5121 if (!ifc_dev_np) {
5122 dev_err(dev, "No Interface device found\n");
5123 return -EINVAL;
5124 }
5125
5126 wcd->slim = sdev;
5127 wcd->slim_ifc_dev = of_slim_get_device(sdev->ctrl, ifc_dev_np);
5128 of_node_put(ifc_dev_np);
5129 if (!wcd->slim_ifc_dev) {
5130 dev_err(dev, "Unable to get SLIM Interface device\n");
5131 return -EINVAL;
5132 }
5133
5134 slim_get_logical_addr(wcd->slim_ifc_dev);
5135
5136 wcd->regmap = regmap_init_slimbus(sdev, &wcd9335_regmap_config);
5137 if (IS_ERR(wcd->regmap))
5138 return dev_err_probe(dev, PTR_ERR(wcd->regmap),
5139 "Failed to allocate slim register map\n");
5140
5141 wcd->if_regmap = regmap_init_slimbus(wcd->slim_ifc_dev,
5142 &wcd9335_ifc_regmap_config);
5143 if (IS_ERR(wcd->if_regmap))
5144 return dev_err_probe(dev, PTR_ERR(wcd->if_regmap),
5145 "Failed to allocate ifc register map\n");
5146
5147 ret = wcd9335_bring_up(wcd);
5148 if (ret) {
5149 dev_err(dev, "Failed to bringup WCD9335\n");
5150 return ret;
5151 }
5152
5153 ret = wcd9335_irq_init(wcd);
5154 if (ret)
5155 return ret;
5156
5157 wcd9335_probe(wcd);
5158
5159 return 0;
5160 }
5161
5162 static const struct slim_device_id wcd9335_slim_id[] = {
5163 {SLIM_MANF_ID_QCOM, SLIM_PROD_CODE_WCD9335, 0x1, 0x0},
5164 {}
5165 };
5166 MODULE_DEVICE_TABLE(slim, wcd9335_slim_id);
5167
5168 static struct slim_driver wcd9335_slim_driver = {
5169 .driver = {
5170 .name = "wcd9335-slim",
5171 },
5172 .probe = wcd9335_slim_probe,
5173 .device_status = wcd9335_slim_status,
5174 .id_table = wcd9335_slim_id,
5175 };
5176
5177 module_slim_driver(wcd9335_slim_driver);
5178 MODULE_DESCRIPTION("WCD9335 slim driver");
5179 MODULE_LICENSE("GPL v2");
5180 MODULE_ALIAS("slim:217:1a0:*");
5181