xref: /linux/sound/soc/codecs/wcd9335.c (revision 354461486f66e4311d9412c53205d773aac85b78)
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/device.h>
9 #include <linux/wait.h>
10 #include <linux/bitops.h>
11 #include <linux/regulator/consumer.h>
12 #include <linux/clk.h>
13 #include <linux/delay.h>
14 #include <linux/kernel.h>
15 #include <linux/slimbus.h>
16 #include <sound/soc.h>
17 #include <sound/pcm_params.h>
18 #include <sound/soc-dapm.h>
19 #include <linux/of_gpio.h>
20 #include <linux/of.h>
21 #include <linux/of_irq.h>
22 #include <sound/tlv.h>
23 #include <sound/info.h>
24 #include "wcd9335.h"
25 #include "wcd-clsh-v2.h"
26 
27 #define WCD9335_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
28 			    SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
29 			    SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
30 /* Fractional Rates */
31 #define WCD9335_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100)
32 #define WCD9335_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \
33 				  SNDRV_PCM_FMTBIT_S24_LE)
34 
35 /* slave port water mark level
36  *   (0: 6bytes, 1: 9bytes, 2: 12 bytes, 3: 15 bytes)
37  */
38 #define SLAVE_PORT_WATER_MARK_6BYTES  0
39 #define SLAVE_PORT_WATER_MARK_9BYTES  1
40 #define SLAVE_PORT_WATER_MARK_12BYTES 2
41 #define SLAVE_PORT_WATER_MARK_15BYTES 3
42 #define SLAVE_PORT_WATER_MARK_SHIFT 1
43 #define SLAVE_PORT_ENABLE           1
44 #define SLAVE_PORT_DISABLE          0
45 #define WCD9335_SLIM_WATER_MARK_VAL \
46 	((SLAVE_PORT_WATER_MARK_12BYTES << SLAVE_PORT_WATER_MARK_SHIFT) | \
47 	 (SLAVE_PORT_ENABLE))
48 
49 #define WCD9335_SLIM_NUM_PORT_REG 3
50 #define WCD9335_SLIM_PGD_PORT_INT_TX_EN0 (WCD9335_SLIM_PGD_PORT_INT_EN0 + 2)
51 
52 #define WCD9335_MCLK_CLK_12P288MHZ	12288000
53 #define WCD9335_MCLK_CLK_9P6MHZ		9600000
54 
55 #define WCD9335_SLIM_CLOSE_TIMEOUT 1000
56 #define WCD9335_SLIM_IRQ_OVERFLOW (1 << 0)
57 #define WCD9335_SLIM_IRQ_UNDERFLOW (1 << 1)
58 #define WCD9335_SLIM_IRQ_PORT_CLOSED (1 << 2)
59 
60 #define WCD9335_NUM_INTERPOLATORS 9
61 #define WCD9335_RX_START	16
62 #define WCD9335_SLIM_CH_START 128
63 
64 #define WCD9335_SLIM_RX_CH(p) \
65 	{.port = p + WCD9335_RX_START, .shift = p,}
66 
67 /* vout step value */
68 #define WCD9335_CALCULATE_VOUT_D(req_mv) (((req_mv - 650) * 10) / 25)
69 
70 enum {
71 	WCD9335_RX0 = 0,
72 	WCD9335_RX1,
73 	WCD9335_RX2,
74 	WCD9335_RX3,
75 	WCD9335_RX4,
76 	WCD9335_RX5,
77 	WCD9335_RX6,
78 	WCD9335_RX7,
79 	WCD9335_RX8,
80 	WCD9335_RX9,
81 	WCD9335_RX10,
82 	WCD9335_RX11,
83 	WCD9335_RX12,
84 	WCD9335_RX_MAX,
85 };
86 
87 enum {
88 	SIDO_SOURCE_INTERNAL = 0,
89 	SIDO_SOURCE_RCO_BG,
90 };
91 
92 enum wcd9335_sido_voltage {
93 	SIDO_VOLTAGE_SVS_MV = 950,
94 	SIDO_VOLTAGE_NOMINAL_MV = 1100,
95 };
96 
97 enum {
98 	AIF1_PB = 0,
99 	AIF1_CAP,
100 	AIF2_PB,
101 	AIF2_CAP,
102 	AIF3_PB,
103 	AIF3_CAP,
104 	AIF4_PB,
105 	NUM_CODEC_DAIS,
106 };
107 
108 enum {
109 	COMPANDER_1, /* HPH_L */
110 	COMPANDER_2, /* HPH_R */
111 	COMPANDER_3, /* LO1_DIFF */
112 	COMPANDER_4, /* LO2_DIFF */
113 	COMPANDER_5, /* LO3_SE */
114 	COMPANDER_6, /* LO4_SE */
115 	COMPANDER_7, /* SWR SPK CH1 */
116 	COMPANDER_8, /* SWR SPK CH2 */
117 	COMPANDER_MAX,
118 };
119 
120 enum {
121 	INTn_2_INP_SEL_ZERO = 0,
122 	INTn_2_INP_SEL_RX0,
123 	INTn_2_INP_SEL_RX1,
124 	INTn_2_INP_SEL_RX2,
125 	INTn_2_INP_SEL_RX3,
126 	INTn_2_INP_SEL_RX4,
127 	INTn_2_INP_SEL_RX5,
128 	INTn_2_INP_SEL_RX6,
129 	INTn_2_INP_SEL_RX7,
130 	INTn_2_INP_SEL_PROXIMITY,
131 };
132 
133 enum {
134 	INTn_1_MIX_INP_SEL_ZERO = 0,
135 	INTn_1_MIX_INP_SEL_DEC0,
136 	INTn_1_MIX_INP_SEL_DEC1,
137 	INTn_1_MIX_INP_SEL_IIR0,
138 	INTn_1_MIX_INP_SEL_IIR1,
139 	INTn_1_MIX_INP_SEL_RX0,
140 	INTn_1_MIX_INP_SEL_RX1,
141 	INTn_1_MIX_INP_SEL_RX2,
142 	INTn_1_MIX_INP_SEL_RX3,
143 	INTn_1_MIX_INP_SEL_RX4,
144 	INTn_1_MIX_INP_SEL_RX5,
145 	INTn_1_MIX_INP_SEL_RX6,
146 	INTn_1_MIX_INP_SEL_RX7,
147 
148 };
149 
150 enum {
151 	INTERP_EAR = 0,
152 	INTERP_HPHL,
153 	INTERP_HPHR,
154 	INTERP_LO1,
155 	INTERP_LO2,
156 	INTERP_LO3,
157 	INTERP_LO4,
158 	INTERP_SPKR1,
159 	INTERP_SPKR2,
160 };
161 
162 enum wcd_clock_type {
163 	WCD_CLK_OFF,
164 	WCD_CLK_RCO,
165 	WCD_CLK_MCLK,
166 };
167 
168 struct wcd9335_slim_ch {
169 	u32 ch_num;
170 	u16 port;
171 	u16 shift;
172 	struct list_head list;
173 };
174 
175 struct wcd_slim_codec_dai_data {
176 	struct list_head slim_ch_list;
177 	struct slim_stream_config sconfig;
178 	struct slim_stream_runtime *sruntime;
179 };
180 
181 struct wcd9335_codec {
182 	struct device *dev;
183 	struct clk *mclk;
184 	struct clk *native_clk;
185 	u32 mclk_rate;
186 	u8 version;
187 
188 	struct slim_device *slim;
189 	struct slim_device *slim_ifc_dev;
190 	struct regmap *regmap;
191 	struct regmap *if_regmap;
192 	struct regmap_irq_chip_data *irq_data;
193 
194 	struct wcd9335_slim_ch rx_chs[WCD9335_RX_MAX];
195 	u32 num_rx_port;
196 
197 	int sido_input_src;
198 	enum wcd9335_sido_voltage sido_voltage;
199 
200 	struct wcd_slim_codec_dai_data dai[NUM_CODEC_DAIS];
201 	struct snd_soc_component *component;
202 
203 	int master_bias_users;
204 	int clk_mclk_users;
205 	int clk_rco_users;
206 	int sido_ccl_cnt;
207 	enum wcd_clock_type clk_type;
208 
209 	struct wcd_clsh_ctrl *clsh_ctrl;
210 	u32 hph_mode;
211 	int prim_int_users[WCD9335_NUM_INTERPOLATORS];
212 
213 	int comp_enabled[COMPANDER_MAX];
214 
215 	int intr1;
216 	int reset_gpio;
217 	struct regulator_bulk_data supplies[WCD9335_MAX_SUPPLY];
218 
219 	unsigned int rx_port_value;
220 	int hph_l_gain;
221 	int hph_r_gain;
222 	u32 rx_bias_count;
223 
224 };
225 
226 struct wcd9335_irq {
227 	int irq;
228 	irqreturn_t (*handler)(int irq, void *data);
229 	char *name;
230 };
231 
232 static const struct wcd9335_slim_ch wcd9335_rx_chs[WCD9335_RX_MAX] = {
233 	WCD9335_SLIM_RX_CH(0),	 /* 16 */
234 	WCD9335_SLIM_RX_CH(1),	 /* 17 */
235 	WCD9335_SLIM_RX_CH(2),
236 	WCD9335_SLIM_RX_CH(3),
237 	WCD9335_SLIM_RX_CH(4),
238 	WCD9335_SLIM_RX_CH(5),
239 	WCD9335_SLIM_RX_CH(6),
240 	WCD9335_SLIM_RX_CH(7),
241 	WCD9335_SLIM_RX_CH(8),
242 	WCD9335_SLIM_RX_CH(9),
243 	WCD9335_SLIM_RX_CH(10),
244 	WCD9335_SLIM_RX_CH(11),
245 	WCD9335_SLIM_RX_CH(12),
246 };
247 
248 struct interp_sample_rate {
249 	int rate;
250 	int rate_val;
251 };
252 
253 static struct interp_sample_rate int_mix_rate_val[] = {
254 	{48000, 0x4},	/* 48K */
255 	{96000, 0x5},	/* 96K */
256 	{192000, 0x6},	/* 192K */
257 };
258 
259 static struct interp_sample_rate int_prim_rate_val[] = {
260 	{8000, 0x0},	/* 8K */
261 	{16000, 0x1},	/* 16K */
262 	{24000, -EINVAL},/* 24K */
263 	{32000, 0x3},	/* 32K */
264 	{48000, 0x4},	/* 48K */
265 	{96000, 0x5},	/* 96K */
266 	{192000, 0x6},	/* 192K */
267 	{384000, 0x7},	/* 384K */
268 	{44100, 0x8}, /* 44.1K */
269 };
270 
271 struct wcd9335_reg_mask_val {
272 	u16 reg;
273 	u8 mask;
274 	u8 val;
275 };
276 
277 static const struct wcd9335_reg_mask_val wcd9335_codec_reg_init[] = {
278 	/* Rbuckfly/R_EAR(32) */
279 	{WCD9335_CDC_CLSH_K2_MSB, 0x0F, 0x00},
280 	{WCD9335_CDC_CLSH_K2_LSB, 0xFF, 0x60},
281 	{WCD9335_CPE_SS_DMIC_CFG, 0x80, 0x00},
282 	{WCD9335_CDC_BOOST0_BOOST_CTL, 0x70, 0x50},
283 	{WCD9335_CDC_BOOST1_BOOST_CTL, 0x70, 0x50},
284 	{WCD9335_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08},
285 	{WCD9335_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08},
286 	{WCD9335_ANA_LO_1_2, 0x3C, 0X3C},
287 	{WCD9335_DIFF_LO_COM_SWCAP_REFBUF_FREQ, 0x70, 0x00},
288 	{WCD9335_DIFF_LO_COM_PA_FREQ, 0x70, 0x40},
289 	{WCD9335_SOC_MAD_AUDIO_CTL_2, 0x03, 0x03},
290 	{WCD9335_CDC_TOP_TOP_CFG1, 0x02, 0x02},
291 	{WCD9335_CDC_TOP_TOP_CFG1, 0x01, 0x01},
292 	{WCD9335_EAR_CMBUFF, 0x08, 0x00},
293 	{WCD9335_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
294 	{WCD9335_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
295 	{WCD9335_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
296 	{WCD9335_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
297 	{WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x80},
298 	{WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x80},
299 	{WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x01},
300 	{WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x01},
301 	{WCD9335_CDC_RX0_RX_PATH_CFG0, 0x01, 0x01},
302 	{WCD9335_CDC_RX1_RX_PATH_CFG0, 0x01, 0x01},
303 	{WCD9335_CDC_RX2_RX_PATH_CFG0, 0x01, 0x01},
304 	{WCD9335_CDC_RX3_RX_PATH_CFG0, 0x01, 0x01},
305 	{WCD9335_CDC_RX4_RX_PATH_CFG0, 0x01, 0x01},
306 	{WCD9335_CDC_RX5_RX_PATH_CFG0, 0x01, 0x01},
307 	{WCD9335_CDC_RX6_RX_PATH_CFG0, 0x01, 0x01},
308 	{WCD9335_CDC_RX7_RX_PATH_CFG0, 0x01, 0x01},
309 	{WCD9335_CDC_RX8_RX_PATH_CFG0, 0x01, 0x01},
310 	{WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
311 	{WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
312 	{WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 0x01, 0x01},
313 	{WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 0x01, 0x01},
314 	{WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 0x01, 0x01},
315 	{WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 0x01, 0x01},
316 	{WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 0x01, 0x01},
317 	{WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 0x01, 0x01},
318 	{WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 0x01, 0x01},
319 	{WCD9335_VBADC_IBIAS_FE, 0x0C, 0x08},
320 	{WCD9335_RCO_CTRL_2, 0x0F, 0x08},
321 	{WCD9335_RX_BIAS_FLYB_MID_RST, 0xF0, 0x10},
322 	{WCD9335_FLYBACK_CTRL_1, 0x20, 0x20},
323 	{WCD9335_HPH_OCP_CTL, 0xFF, 0x5A},
324 	{WCD9335_HPH_L_TEST, 0x01, 0x01},
325 	{WCD9335_HPH_R_TEST, 0x01, 0x01},
326 	{WCD9335_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12},
327 	{WCD9335_CDC_BOOST0_BOOST_CFG2, 0x1C, 0x08},
328 	{WCD9335_CDC_COMPANDER7_CTL7, 0x1E, 0x18},
329 	{WCD9335_CDC_BOOST1_BOOST_CFG1, 0x3F, 0x12},
330 	{WCD9335_CDC_BOOST1_BOOST_CFG2, 0x1C, 0x08},
331 	{WCD9335_CDC_COMPANDER8_CTL7, 0x1E, 0x18},
332 	{WCD9335_CDC_TX0_TX_PATH_SEC7, 0xFF, 0x45},
333 	{WCD9335_CDC_RX0_RX_PATH_SEC0, 0xFC, 0xF4},
334 	{WCD9335_HPH_REFBUFF_LP_CTL, 0x08, 0x08},
335 	{WCD9335_HPH_REFBUFF_LP_CTL, 0x06, 0x02},
336 };
337 
338 /* Cutoff frequency for high pass filter */
339 static const char * const cf_text[] = {
340 	"CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ"
341 };
342 
343 static const char * const rx_cf_text[] = {
344 	"CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ",
345 	"CF_NEG_3DB_0P48HZ"
346 };
347 
348 static const char * const rx_int0_7_mix_mux_text[] = {
349 	"ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5",
350 	"RX6", "RX7", "PROXIMITY"
351 };
352 
353 static const char * const rx_int_mix_mux_text[] = {
354 	"ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5",
355 	"RX6", "RX7"
356 };
357 
358 static const char * const rx_prim_mix_text[] = {
359 	"ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2",
360 	"RX3", "RX4", "RX5", "RX6", "RX7"
361 };
362 
363 static const char * const rx_int_dem_inp_mux_text[] = {
364 	"NORMAL_DSM_OUT", "CLSH_DSM_OUT",
365 };
366 
367 static const char * const rx_int0_interp_mux_text[] = {
368 	"ZERO", "RX INT0 MIX2",
369 };
370 
371 static const char * const rx_int1_interp_mux_text[] = {
372 	"ZERO", "RX INT1 MIX2",
373 };
374 
375 static const char * const rx_int2_interp_mux_text[] = {
376 	"ZERO", "RX INT2 MIX2",
377 };
378 
379 static const char * const rx_int3_interp_mux_text[] = {
380 	"ZERO", "RX INT3 MIX2",
381 };
382 
383 static const char * const rx_int4_interp_mux_text[] = {
384 	"ZERO", "RX INT4 MIX2",
385 };
386 
387 static const char * const rx_int5_interp_mux_text[] = {
388 	"ZERO", "RX INT5 MIX2",
389 };
390 
391 static const char * const rx_int6_interp_mux_text[] = {
392 	"ZERO", "RX INT6 MIX2",
393 };
394 
395 static const char * const rx_int7_interp_mux_text[] = {
396 	"ZERO", "RX INT7 MIX2",
397 };
398 
399 static const char * const rx_int8_interp_mux_text[] = {
400 	"ZERO", "RX INT8 SEC MIX"
401 };
402 
403 static const char * const rx_hph_mode_mux_text[] = {
404 	"Class H Invalid", "Class-H Hi-Fi", "Class-H Low Power", "Class-AB",
405 	"Class-H Hi-Fi Low Power"
406 };
407 
408 static const char *const slim_rx_mux_text[] = {
409 	"ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB",
410 };
411 
412 static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
413 static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
414 static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
415 static const DECLARE_TLV_DB_SCALE(ear_pa_gain, 0, 150, 0);
416 
417 static const struct soc_enum cf_dec0_enum =
418 	SOC_ENUM_SINGLE(WCD9335_CDC_TX0_TX_PATH_CFG0, 5, 3, cf_text);
419 
420 static const struct soc_enum cf_dec1_enum =
421 	SOC_ENUM_SINGLE(WCD9335_CDC_TX1_TX_PATH_CFG0, 5, 3, cf_text);
422 
423 static const struct soc_enum cf_dec2_enum =
424 	SOC_ENUM_SINGLE(WCD9335_CDC_TX2_TX_PATH_CFG0, 5, 3, cf_text);
425 
426 static const struct soc_enum cf_dec3_enum =
427 	SOC_ENUM_SINGLE(WCD9335_CDC_TX3_TX_PATH_CFG0, 5, 3, cf_text);
428 
429 static const struct soc_enum cf_dec4_enum =
430 	SOC_ENUM_SINGLE(WCD9335_CDC_TX4_TX_PATH_CFG0, 5, 3, cf_text);
431 
432 static const struct soc_enum cf_dec5_enum =
433 	SOC_ENUM_SINGLE(WCD9335_CDC_TX5_TX_PATH_CFG0, 5, 3, cf_text);
434 
435 static const struct soc_enum cf_dec6_enum =
436 	SOC_ENUM_SINGLE(WCD9335_CDC_TX6_TX_PATH_CFG0, 5, 3, cf_text);
437 
438 static const struct soc_enum cf_dec7_enum =
439 	SOC_ENUM_SINGLE(WCD9335_CDC_TX7_TX_PATH_CFG0, 5, 3, cf_text);
440 
441 static const struct soc_enum cf_dec8_enum =
442 	SOC_ENUM_SINGLE(WCD9335_CDC_TX8_TX_PATH_CFG0, 5, 3, cf_text);
443 
444 static const struct soc_enum cf_int0_1_enum =
445 	SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CFG2, 0, 4, rx_cf_text);
446 
447 static SOC_ENUM_SINGLE_DECL(cf_int0_2_enum, WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 2,
448 		     rx_cf_text);
449 
450 static const struct soc_enum cf_int1_1_enum =
451 	SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CFG2, 0, 4, rx_cf_text);
452 
453 static SOC_ENUM_SINGLE_DECL(cf_int1_2_enum, WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 2,
454 		     rx_cf_text);
455 
456 static const struct soc_enum cf_int2_1_enum =
457 	SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CFG2, 0, 4, rx_cf_text);
458 
459 static SOC_ENUM_SINGLE_DECL(cf_int2_2_enum, WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 2,
460 		     rx_cf_text);
461 
462 static const struct soc_enum cf_int3_1_enum =
463 	SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CFG2, 0, 4, rx_cf_text);
464 
465 static SOC_ENUM_SINGLE_DECL(cf_int3_2_enum, WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 2,
466 		     rx_cf_text);
467 
468 static const struct soc_enum cf_int4_1_enum =
469 	SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CFG2, 0, 4, rx_cf_text);
470 
471 static SOC_ENUM_SINGLE_DECL(cf_int4_2_enum, WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 2,
472 		     rx_cf_text);
473 
474 static const struct soc_enum cf_int5_1_enum =
475 	SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CFG2, 0, 4, rx_cf_text);
476 
477 static SOC_ENUM_SINGLE_DECL(cf_int5_2_enum, WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 2,
478 		     rx_cf_text);
479 
480 static const struct soc_enum cf_int6_1_enum =
481 	SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CFG2, 0, 4, rx_cf_text);
482 
483 static SOC_ENUM_SINGLE_DECL(cf_int6_2_enum, WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 2,
484 		     rx_cf_text);
485 
486 static const struct soc_enum cf_int7_1_enum =
487 	SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CFG2, 0, 4, rx_cf_text);
488 
489 static SOC_ENUM_SINGLE_DECL(cf_int7_2_enum, WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 2,
490 		     rx_cf_text);
491 
492 static const struct soc_enum cf_int8_1_enum =
493 	SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CFG2, 0, 4, rx_cf_text);
494 
495 static SOC_ENUM_SINGLE_DECL(cf_int8_2_enum, WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 2,
496 		     rx_cf_text);
497 
498 static const struct soc_enum rx_hph_mode_mux_enum =
499 	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text),
500 			    rx_hph_mode_mux_text);
501 
502 static const struct soc_enum slim_rx_mux_enum =
503 	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text);
504 
505 static const struct soc_enum rx_int0_2_mux_chain_enum =
506 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, 10,
507 			rx_int0_7_mix_mux_text);
508 
509 static const struct soc_enum rx_int1_2_mux_chain_enum =
510 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, 9,
511 			rx_int_mix_mux_text);
512 
513 static const struct soc_enum rx_int2_2_mux_chain_enum =
514 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 0, 9,
515 			rx_int_mix_mux_text);
516 
517 static const struct soc_enum rx_int3_2_mux_chain_enum =
518 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 0, 9,
519 			rx_int_mix_mux_text);
520 
521 static const struct soc_enum rx_int4_2_mux_chain_enum =
522 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 0, 9,
523 			rx_int_mix_mux_text);
524 
525 static const struct soc_enum rx_int5_2_mux_chain_enum =
526 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 0, 9,
527 			rx_int_mix_mux_text);
528 
529 static const struct soc_enum rx_int6_2_mux_chain_enum =
530 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 0, 9,
531 			rx_int_mix_mux_text);
532 
533 static const struct soc_enum rx_int7_2_mux_chain_enum =
534 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 0, 10,
535 			rx_int0_7_mix_mux_text);
536 
537 static const struct soc_enum rx_int8_2_mux_chain_enum =
538 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 0, 9,
539 			rx_int_mix_mux_text);
540 
541 static const struct soc_enum rx_int0_1_mix_inp0_chain_enum =
542 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 0, 13,
543 			rx_prim_mix_text);
544 
545 static const struct soc_enum rx_int0_1_mix_inp1_chain_enum =
546 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 4, 13,
547 			rx_prim_mix_text);
548 
549 static const struct soc_enum rx_int0_1_mix_inp2_chain_enum =
550 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 4, 13,
551 			rx_prim_mix_text);
552 
553 static const struct soc_enum rx_int1_1_mix_inp0_chain_enum =
554 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 0, 13,
555 			rx_prim_mix_text);
556 
557 static const struct soc_enum rx_int1_1_mix_inp1_chain_enum =
558 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 4, 13,
559 			rx_prim_mix_text);
560 
561 static const struct soc_enum rx_int1_1_mix_inp2_chain_enum =
562 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 4, 13,
563 			rx_prim_mix_text);
564 
565 static const struct soc_enum rx_int2_1_mix_inp0_chain_enum =
566 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 0, 13,
567 			rx_prim_mix_text);
568 
569 static const struct soc_enum rx_int2_1_mix_inp1_chain_enum =
570 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 4, 13,
571 			rx_prim_mix_text);
572 
573 static const struct soc_enum rx_int2_1_mix_inp2_chain_enum =
574 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 4, 13,
575 			rx_prim_mix_text);
576 
577 static const struct soc_enum rx_int3_1_mix_inp0_chain_enum =
578 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 0, 13,
579 			rx_prim_mix_text);
580 
581 static const struct soc_enum rx_int3_1_mix_inp1_chain_enum =
582 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 4, 13,
583 			rx_prim_mix_text);
584 
585 static const struct soc_enum rx_int3_1_mix_inp2_chain_enum =
586 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 4, 13,
587 			rx_prim_mix_text);
588 
589 static const struct soc_enum rx_int4_1_mix_inp0_chain_enum =
590 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 0, 13,
591 			rx_prim_mix_text);
592 
593 static const struct soc_enum rx_int4_1_mix_inp1_chain_enum =
594 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 4, 13,
595 			rx_prim_mix_text);
596 
597 static const struct soc_enum rx_int4_1_mix_inp2_chain_enum =
598 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 4, 13,
599 			rx_prim_mix_text);
600 
601 static const struct soc_enum rx_int5_1_mix_inp0_chain_enum =
602 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 0, 13,
603 			rx_prim_mix_text);
604 
605 static const struct soc_enum rx_int5_1_mix_inp1_chain_enum =
606 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 4, 13,
607 			rx_prim_mix_text);
608 
609 static const struct soc_enum rx_int5_1_mix_inp2_chain_enum =
610 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 4, 13,
611 			rx_prim_mix_text);
612 
613 static const struct soc_enum rx_int6_1_mix_inp0_chain_enum =
614 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 0, 13,
615 			rx_prim_mix_text);
616 
617 static const struct soc_enum rx_int6_1_mix_inp1_chain_enum =
618 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 4, 13,
619 			rx_prim_mix_text);
620 
621 static const struct soc_enum rx_int6_1_mix_inp2_chain_enum =
622 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 4, 13,
623 			rx_prim_mix_text);
624 
625 static const struct soc_enum rx_int7_1_mix_inp0_chain_enum =
626 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 0, 13,
627 			rx_prim_mix_text);
628 
629 static const struct soc_enum rx_int7_1_mix_inp1_chain_enum =
630 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 4, 13,
631 			rx_prim_mix_text);
632 
633 static const struct soc_enum rx_int7_1_mix_inp2_chain_enum =
634 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 4, 13,
635 			rx_prim_mix_text);
636 
637 static const struct soc_enum rx_int8_1_mix_inp0_chain_enum =
638 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 0, 13,
639 			rx_prim_mix_text);
640 
641 static const struct soc_enum rx_int8_1_mix_inp1_chain_enum =
642 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 4, 13,
643 			rx_prim_mix_text);
644 
645 static const struct soc_enum rx_int8_1_mix_inp2_chain_enum =
646 	SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 4, 13,
647 			rx_prim_mix_text);
648 
649 static const struct soc_enum rx_int0_dem_inp_mux_enum =
650 	SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_SEC0, 0,
651 			ARRAY_SIZE(rx_int_dem_inp_mux_text),
652 			rx_int_dem_inp_mux_text);
653 
654 static const struct soc_enum rx_int1_dem_inp_mux_enum =
655 	SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_SEC0, 0,
656 			ARRAY_SIZE(rx_int_dem_inp_mux_text),
657 			rx_int_dem_inp_mux_text);
658 
659 static const struct soc_enum rx_int2_dem_inp_mux_enum =
660 	SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_SEC0, 0,
661 			ARRAY_SIZE(rx_int_dem_inp_mux_text),
662 			rx_int_dem_inp_mux_text);
663 
664 static const struct soc_enum rx_int0_interp_mux_enum =
665 	SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CTL, 5, 2,
666 			rx_int0_interp_mux_text);
667 
668 static const struct soc_enum rx_int1_interp_mux_enum =
669 	SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CTL, 5, 2,
670 			rx_int1_interp_mux_text);
671 
672 static const struct soc_enum rx_int2_interp_mux_enum =
673 	SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CTL, 5, 2,
674 			rx_int2_interp_mux_text);
675 
676 static const struct soc_enum rx_int3_interp_mux_enum =
677 	SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CTL, 5, 2,
678 			rx_int3_interp_mux_text);
679 
680 static const struct soc_enum rx_int4_interp_mux_enum =
681 	SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CTL, 5, 2,
682 			rx_int4_interp_mux_text);
683 
684 static const struct soc_enum rx_int5_interp_mux_enum =
685 	SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CTL, 5, 2,
686 			rx_int5_interp_mux_text);
687 
688 static const struct soc_enum rx_int6_interp_mux_enum =
689 	SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CTL, 5, 2,
690 			rx_int6_interp_mux_text);
691 
692 static const struct soc_enum rx_int7_interp_mux_enum =
693 	SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CTL, 5, 2,
694 			rx_int7_interp_mux_text);
695 
696 static const struct soc_enum rx_int8_interp_mux_enum =
697 	SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CTL, 5, 2,
698 			rx_int8_interp_mux_text);
699 
700 static const struct snd_kcontrol_new rx_int0_2_mux =
701 	SOC_DAPM_ENUM("RX INT0_2 MUX Mux", rx_int0_2_mux_chain_enum);
702 
703 static const struct snd_kcontrol_new rx_int1_2_mux =
704 	SOC_DAPM_ENUM("RX INT1_2 MUX Mux", rx_int1_2_mux_chain_enum);
705 
706 static const struct snd_kcontrol_new rx_int2_2_mux =
707 	SOC_DAPM_ENUM("RX INT2_2 MUX Mux", rx_int2_2_mux_chain_enum);
708 
709 static const struct snd_kcontrol_new rx_int3_2_mux =
710 	SOC_DAPM_ENUM("RX INT3_2 MUX Mux", rx_int3_2_mux_chain_enum);
711 
712 static const struct snd_kcontrol_new rx_int4_2_mux =
713 	SOC_DAPM_ENUM("RX INT4_2 MUX Mux", rx_int4_2_mux_chain_enum);
714 
715 static const struct snd_kcontrol_new rx_int5_2_mux =
716 	SOC_DAPM_ENUM("RX INT5_2 MUX Mux", rx_int5_2_mux_chain_enum);
717 
718 static const struct snd_kcontrol_new rx_int6_2_mux =
719 	SOC_DAPM_ENUM("RX INT6_2 MUX Mux", rx_int6_2_mux_chain_enum);
720 
721 static const struct snd_kcontrol_new rx_int7_2_mux =
722 	SOC_DAPM_ENUM("RX INT7_2 MUX Mux", rx_int7_2_mux_chain_enum);
723 
724 static const struct snd_kcontrol_new rx_int8_2_mux =
725 	SOC_DAPM_ENUM("RX INT8_2 MUX Mux", rx_int8_2_mux_chain_enum);
726 
727 static const struct snd_kcontrol_new rx_int0_1_mix_inp0_mux =
728 	SOC_DAPM_ENUM("RX INT0_1 MIX1 INP0 Mux", rx_int0_1_mix_inp0_chain_enum);
729 
730 static const struct snd_kcontrol_new rx_int0_1_mix_inp1_mux =
731 	SOC_DAPM_ENUM("RX INT0_1 MIX1 INP1 Mux", rx_int0_1_mix_inp1_chain_enum);
732 
733 static const struct snd_kcontrol_new rx_int0_1_mix_inp2_mux =
734 	SOC_DAPM_ENUM("RX INT0_1 MIX1 INP2 Mux", rx_int0_1_mix_inp2_chain_enum);
735 
736 static const struct snd_kcontrol_new rx_int1_1_mix_inp0_mux =
737 	SOC_DAPM_ENUM("RX INT1_1 MIX1 INP0 Mux", rx_int1_1_mix_inp0_chain_enum);
738 
739 static const struct snd_kcontrol_new rx_int1_1_mix_inp1_mux =
740 	SOC_DAPM_ENUM("RX INT1_1 MIX1 INP1 Mux", rx_int1_1_mix_inp1_chain_enum);
741 
742 static const struct snd_kcontrol_new rx_int1_1_mix_inp2_mux =
743 	SOC_DAPM_ENUM("RX INT1_1 MIX1 INP2 Mux", rx_int1_1_mix_inp2_chain_enum);
744 
745 static const struct snd_kcontrol_new rx_int2_1_mix_inp0_mux =
746 	SOC_DAPM_ENUM("RX INT2_1 MIX1 INP0 Mux", rx_int2_1_mix_inp0_chain_enum);
747 
748 static const struct snd_kcontrol_new rx_int2_1_mix_inp1_mux =
749 	SOC_DAPM_ENUM("RX INT2_1 MIX1 INP1 Mux", rx_int2_1_mix_inp1_chain_enum);
750 
751 static const struct snd_kcontrol_new rx_int2_1_mix_inp2_mux =
752 	SOC_DAPM_ENUM("RX INT2_1 MIX1 INP2 Mux", rx_int2_1_mix_inp2_chain_enum);
753 
754 static const struct snd_kcontrol_new rx_int3_1_mix_inp0_mux =
755 	SOC_DAPM_ENUM("RX INT3_1 MIX1 INP0 Mux", rx_int3_1_mix_inp0_chain_enum);
756 
757 static const struct snd_kcontrol_new rx_int3_1_mix_inp1_mux =
758 	SOC_DAPM_ENUM("RX INT3_1 MIX1 INP1 Mux", rx_int3_1_mix_inp1_chain_enum);
759 
760 static const struct snd_kcontrol_new rx_int3_1_mix_inp2_mux =
761 	SOC_DAPM_ENUM("RX INT3_1 MIX1 INP2 Mux", rx_int3_1_mix_inp2_chain_enum);
762 
763 static const struct snd_kcontrol_new rx_int4_1_mix_inp0_mux =
764 	SOC_DAPM_ENUM("RX INT4_1 MIX1 INP0 Mux", rx_int4_1_mix_inp0_chain_enum);
765 
766 static const struct snd_kcontrol_new rx_int4_1_mix_inp1_mux =
767 	SOC_DAPM_ENUM("RX INT4_1 MIX1 INP1 Mux", rx_int4_1_mix_inp1_chain_enum);
768 
769 static const struct snd_kcontrol_new rx_int4_1_mix_inp2_mux =
770 	SOC_DAPM_ENUM("RX INT4_1 MIX1 INP2 Mux", rx_int4_1_mix_inp2_chain_enum);
771 
772 static const struct snd_kcontrol_new rx_int5_1_mix_inp0_mux =
773 	SOC_DAPM_ENUM("RX INT5_1 MIX1 INP0 Mux", rx_int5_1_mix_inp0_chain_enum);
774 
775 static const struct snd_kcontrol_new rx_int5_1_mix_inp1_mux =
776 	SOC_DAPM_ENUM("RX INT5_1 MIX1 INP1 Mux", rx_int5_1_mix_inp1_chain_enum);
777 
778 static const struct snd_kcontrol_new rx_int5_1_mix_inp2_mux =
779 	SOC_DAPM_ENUM("RX INT5_1 MIX1 INP2 Mux", rx_int5_1_mix_inp2_chain_enum);
780 
781 static const struct snd_kcontrol_new rx_int6_1_mix_inp0_mux =
782 	SOC_DAPM_ENUM("RX INT6_1 MIX1 INP0 Mux", rx_int6_1_mix_inp0_chain_enum);
783 
784 static const struct snd_kcontrol_new rx_int6_1_mix_inp1_mux =
785 	SOC_DAPM_ENUM("RX INT6_1 MIX1 INP1 Mux", rx_int6_1_mix_inp1_chain_enum);
786 
787 static const struct snd_kcontrol_new rx_int6_1_mix_inp2_mux =
788 	SOC_DAPM_ENUM("RX INT6_1 MIX1 INP2 Mux", rx_int6_1_mix_inp2_chain_enum);
789 
790 static const struct snd_kcontrol_new rx_int7_1_mix_inp0_mux =
791 	SOC_DAPM_ENUM("RX INT7_1 MIX1 INP0 Mux", rx_int7_1_mix_inp0_chain_enum);
792 
793 static const struct snd_kcontrol_new rx_int7_1_mix_inp1_mux =
794 	SOC_DAPM_ENUM("RX INT7_1 MIX1 INP1 Mux", rx_int7_1_mix_inp1_chain_enum);
795 
796 static const struct snd_kcontrol_new rx_int7_1_mix_inp2_mux =
797 	SOC_DAPM_ENUM("RX INT7_1 MIX1 INP2 Mux", rx_int7_1_mix_inp2_chain_enum);
798 
799 static const struct snd_kcontrol_new rx_int8_1_mix_inp0_mux =
800 	SOC_DAPM_ENUM("RX INT8_1 MIX1 INP0 Mux", rx_int8_1_mix_inp0_chain_enum);
801 
802 static const struct snd_kcontrol_new rx_int8_1_mix_inp1_mux =
803 	SOC_DAPM_ENUM("RX INT8_1 MIX1 INP1 Mux", rx_int8_1_mix_inp1_chain_enum);
804 
805 static const struct snd_kcontrol_new rx_int8_1_mix_inp2_mux =
806 	SOC_DAPM_ENUM("RX INT8_1 MIX1 INP2 Mux", rx_int8_1_mix_inp2_chain_enum);
807 
808 static const struct snd_kcontrol_new rx_int0_interp_mux =
809 	SOC_DAPM_ENUM("RX INT0 INTERP Mux", rx_int0_interp_mux_enum);
810 
811 static const struct snd_kcontrol_new rx_int1_interp_mux =
812 	SOC_DAPM_ENUM("RX INT1 INTERP Mux", rx_int1_interp_mux_enum);
813 
814 static const struct snd_kcontrol_new rx_int2_interp_mux =
815 	SOC_DAPM_ENUM("RX INT2 INTERP Mux", rx_int2_interp_mux_enum);
816 
817 static const struct snd_kcontrol_new rx_int3_interp_mux =
818 	SOC_DAPM_ENUM("RX INT3 INTERP Mux", rx_int3_interp_mux_enum);
819 
820 static const struct snd_kcontrol_new rx_int4_interp_mux =
821 	SOC_DAPM_ENUM("RX INT4 INTERP Mux", rx_int4_interp_mux_enum);
822 
823 static const struct snd_kcontrol_new rx_int5_interp_mux =
824 	SOC_DAPM_ENUM("RX INT5 INTERP Mux", rx_int5_interp_mux_enum);
825 
826 static const struct snd_kcontrol_new rx_int6_interp_mux =
827 	SOC_DAPM_ENUM("RX INT6 INTERP Mux", rx_int6_interp_mux_enum);
828 
829 static const struct snd_kcontrol_new rx_int7_interp_mux =
830 	SOC_DAPM_ENUM("RX INT7 INTERP Mux", rx_int7_interp_mux_enum);
831 
832 static const struct snd_kcontrol_new rx_int8_interp_mux =
833 	SOC_DAPM_ENUM("RX INT8 INTERP Mux", rx_int8_interp_mux_enum);
834 
835 static int slim_rx_mux_get(struct snd_kcontrol *kc,
836 			   struct snd_ctl_elem_value *ucontrol)
837 {
838 	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kc);
839 	struct wcd9335_codec *wcd = dev_get_drvdata(dapm->dev);
840 
841 	ucontrol->value.enumerated.item[0] = wcd->rx_port_value;
842 
843 	return 0;
844 }
845 
846 static int slim_rx_mux_put(struct snd_kcontrol *kc,
847 			   struct snd_ctl_elem_value *ucontrol)
848 {
849 	struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kc);
850 	struct wcd9335_codec *wcd = dev_get_drvdata(w->dapm->dev);
851 	struct soc_enum *e = (struct soc_enum *)kc->private_value;
852 	struct snd_soc_dapm_update *update = NULL;
853 	u32 port_id = w->shift;
854 
855 	wcd->rx_port_value = ucontrol->value.enumerated.item[0];
856 
857 	switch (wcd->rx_port_value) {
858 	case 0:
859 		list_del_init(&wcd->rx_chs[port_id].list);
860 		break;
861 	case 1:
862 		list_add_tail(&wcd->rx_chs[port_id].list,
863 			      &wcd->dai[AIF1_PB].slim_ch_list);
864 		break;
865 	case 2:
866 		list_add_tail(&wcd->rx_chs[port_id].list,
867 			      &wcd->dai[AIF2_PB].slim_ch_list);
868 		break;
869 	case 3:
870 		list_add_tail(&wcd->rx_chs[port_id].list,
871 			      &wcd->dai[AIF3_PB].slim_ch_list);
872 		break;
873 	case 4:
874 		list_add_tail(&wcd->rx_chs[port_id].list,
875 			      &wcd->dai[AIF4_PB].slim_ch_list);
876 		break;
877 	default:
878 		dev_err(wcd->dev, "Unknown AIF %d\n", wcd->rx_port_value);
879 		goto err;
880 	}
881 
882 	snd_soc_dapm_mux_update_power(w->dapm, kc, wcd->rx_port_value,
883 				      e, update);
884 
885 	return 0;
886 err:
887 	return -EINVAL;
888 }
889 
890 static const struct snd_kcontrol_new slim_rx_mux[WCD9335_RX_MAX] = {
891 	SOC_DAPM_ENUM_EXT("SLIM RX0 Mux", slim_rx_mux_enum,
892 			  slim_rx_mux_get, slim_rx_mux_put),
893 	SOC_DAPM_ENUM_EXT("SLIM RX1 Mux", slim_rx_mux_enum,
894 			  slim_rx_mux_get, slim_rx_mux_put),
895 	SOC_DAPM_ENUM_EXT("SLIM RX2 Mux", slim_rx_mux_enum,
896 			  slim_rx_mux_get, slim_rx_mux_put),
897 	SOC_DAPM_ENUM_EXT("SLIM RX3 Mux", slim_rx_mux_enum,
898 			  slim_rx_mux_get, slim_rx_mux_put),
899 	SOC_DAPM_ENUM_EXT("SLIM RX4 Mux", slim_rx_mux_enum,
900 			  slim_rx_mux_get, slim_rx_mux_put),
901 	SOC_DAPM_ENUM_EXT("SLIM RX5 Mux", slim_rx_mux_enum,
902 			  slim_rx_mux_get, slim_rx_mux_put),
903 	SOC_DAPM_ENUM_EXT("SLIM RX6 Mux", slim_rx_mux_enum,
904 			  slim_rx_mux_get, slim_rx_mux_put),
905 	SOC_DAPM_ENUM_EXT("SLIM RX7 Mux", slim_rx_mux_enum,
906 			  slim_rx_mux_get, slim_rx_mux_put),
907 };
908 
909 static int wcd9335_int_dem_inp_mux_put(struct snd_kcontrol *kc,
910 				 struct snd_ctl_elem_value *ucontrol)
911 {
912 	struct soc_enum *e = (struct soc_enum *)kc->private_value;
913 	struct snd_soc_component *component;
914 	int reg, val;
915 
916 	component = snd_soc_dapm_kcontrol_component(kc);
917 	val = ucontrol->value.enumerated.item[0];
918 
919 	if (e->reg == WCD9335_CDC_RX0_RX_PATH_SEC0)
920 		reg = WCD9335_CDC_RX0_RX_PATH_CFG0;
921 	else if (e->reg == WCD9335_CDC_RX1_RX_PATH_SEC0)
922 		reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
923 	else if (e->reg == WCD9335_CDC_RX2_RX_PATH_SEC0)
924 		reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
925 	else
926 		return -EINVAL;
927 
928 	/* Set Look Ahead Delay */
929 	snd_soc_component_update_bits(component, reg,
930 				WCD9335_CDC_RX_PATH_CFG0_DLY_ZN_EN_MASK,
931 				val ? WCD9335_CDC_RX_PATH_CFG0_DLY_ZN_EN : 0);
932 	/* Set DEM INP Select */
933 	return snd_soc_dapm_put_enum_double(kc, ucontrol);
934 }
935 
936 static const struct snd_kcontrol_new rx_int0_dem_inp_mux =
937 	SOC_DAPM_ENUM_EXT("RX INT0 DEM MUX Mux", rx_int0_dem_inp_mux_enum,
938 			  snd_soc_dapm_get_enum_double,
939 			  wcd9335_int_dem_inp_mux_put);
940 
941 static const struct snd_kcontrol_new rx_int1_dem_inp_mux =
942 	SOC_DAPM_ENUM_EXT("RX INT1 DEM MUX Mux", rx_int1_dem_inp_mux_enum,
943 			  snd_soc_dapm_get_enum_double,
944 			  wcd9335_int_dem_inp_mux_put);
945 
946 static const struct snd_kcontrol_new rx_int2_dem_inp_mux =
947 	SOC_DAPM_ENUM_EXT("RX INT2 DEM MUX Mux", rx_int2_dem_inp_mux_enum,
948 			  snd_soc_dapm_get_enum_double,
949 			  wcd9335_int_dem_inp_mux_put);
950 
951 static int wcd9335_set_mix_interpolator_rate(struct snd_soc_dai *dai,
952 					     int rate_val,
953 					     u32 rate)
954 {
955 	struct snd_soc_component *component = dai->component;
956 	struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
957 	struct wcd9335_slim_ch *ch;
958 	int val, j;
959 
960 	list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) {
961 		for (j = 0; j < WCD9335_NUM_INTERPOLATORS; j++) {
962 			val = snd_soc_component_read32(component,
963 					WCD9335_CDC_RX_INP_MUX_RX_INT_CFG1(j)) &
964 					WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK;
965 
966 			if (val == (ch->shift + INTn_2_INP_SEL_RX0))
967 				snd_soc_component_update_bits(component,
968 						WCD9335_CDC_RX_PATH_MIX_CTL(j),
969 						WCD9335_CDC_MIX_PCM_RATE_MASK,
970 						rate_val);
971 		}
972 	}
973 
974 	return 0;
975 }
976 
977 static int wcd9335_set_prim_interpolator_rate(struct snd_soc_dai *dai,
978 					      u8 rate_val,
979 					      u32 rate)
980 {
981 	struct snd_soc_component *comp = dai->component;
982 	struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
983 	struct wcd9335_slim_ch *ch;
984 	u8 cfg0, cfg1, inp0_sel, inp1_sel, inp2_sel;
985 	int inp, j;
986 
987 	list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) {
988 		inp = ch->shift + INTn_1_MIX_INP_SEL_RX0;
989 		/*
990 		 * Loop through all interpolator MUX inputs and find out
991 		 * to which interpolator input, the slim rx port
992 		 * is connected
993 		 */
994 		for (j = 0; j < WCD9335_NUM_INTERPOLATORS; j++) {
995 			cfg0 = snd_soc_component_read32(comp,
996 					WCD9335_CDC_RX_INP_MUX_RX_INT_CFG0(j));
997 			cfg1 = snd_soc_component_read32(comp,
998 					WCD9335_CDC_RX_INP_MUX_RX_INT_CFG1(j));
999 
1000 			inp0_sel = cfg0 &
1001 				 WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK;
1002 			inp1_sel = (cfg0 >> 4) &
1003 				 WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK;
1004 			inp2_sel = (cfg1 >> 4) &
1005 				 WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK;
1006 
1007 			if ((inp0_sel == inp) ||  (inp1_sel == inp) ||
1008 			    (inp2_sel == inp)) {
1009 				/* rate is in Hz */
1010 				if ((j == 0) && (rate == 44100))
1011 					dev_info(wcd->dev,
1012 						"Cannot set 44.1KHz on INT0\n");
1013 				else
1014 					snd_soc_component_update_bits(comp,
1015 						WCD9335_CDC_RX_PATH_CTL(j),
1016 						WCD9335_CDC_MIX_PCM_RATE_MASK,
1017 						rate_val);
1018 			}
1019 		}
1020 	}
1021 
1022 	return 0;
1023 }
1024 
1025 static int wcd9335_set_interpolator_rate(struct snd_soc_dai *dai, u32 rate)
1026 {
1027 	int i;
1028 
1029 	/* set mixing path rate */
1030 	for (i = 0; i < ARRAY_SIZE(int_mix_rate_val); i++) {
1031 		if (rate == int_mix_rate_val[i].rate) {
1032 			wcd9335_set_mix_interpolator_rate(dai,
1033 					int_mix_rate_val[i].rate_val, rate);
1034 			break;
1035 		}
1036 	}
1037 
1038 	/* set primary path sample rate */
1039 	for (i = 0; i < ARRAY_SIZE(int_prim_rate_val); i++) {
1040 		if (rate == int_prim_rate_val[i].rate) {
1041 			wcd9335_set_prim_interpolator_rate(dai,
1042 					int_prim_rate_val[i].rate_val, rate);
1043 			break;
1044 		}
1045 	}
1046 
1047 	return 0;
1048 }
1049 
1050 static int wcd9335_slim_set_hw_params(struct wcd9335_codec *wcd,
1051 				 struct wcd_slim_codec_dai_data *dai_data,
1052 				 int direction)
1053 {
1054 	struct list_head *slim_ch_list = &dai_data->slim_ch_list;
1055 	struct slim_stream_config *cfg = &dai_data->sconfig;
1056 	struct wcd9335_slim_ch *ch;
1057 	u16 payload = 0;
1058 	int ret, i;
1059 
1060 	cfg->ch_count = 0;
1061 	cfg->direction = direction;
1062 	cfg->port_mask = 0;
1063 
1064 	/* Configure slave interface device */
1065 	list_for_each_entry(ch, slim_ch_list, list) {
1066 		cfg->ch_count++;
1067 		payload |= 1 << ch->shift;
1068 		cfg->port_mask |= BIT(ch->port);
1069 	}
1070 
1071 	cfg->chs = kcalloc(cfg->ch_count, sizeof(unsigned int), GFP_KERNEL);
1072 	if (!cfg->chs)
1073 		return -ENOMEM;
1074 
1075 	i = 0;
1076 	list_for_each_entry(ch, slim_ch_list, list) {
1077 		cfg->chs[i++] = ch->ch_num;
1078 		if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
1079 			/* write to interface device */
1080 			ret = regmap_write(wcd->if_regmap,
1081 				WCD9335_SLIM_PGD_RX_PORT_MULTI_CHNL_0(ch->port),
1082 				payload);
1083 
1084 			if (ret < 0)
1085 				goto err;
1086 
1087 			/* configure the slave port for water mark and enable*/
1088 			ret = regmap_write(wcd->if_regmap,
1089 					WCD9335_SLIM_PGD_RX_PORT_CFG(ch->port),
1090 					WCD9335_SLIM_WATER_MARK_VAL);
1091 			if (ret < 0)
1092 				goto err;
1093 		}
1094 	}
1095 
1096 	dai_data->sruntime = slim_stream_allocate(wcd->slim, "WCD9335-SLIM");
1097 
1098 	return 0;
1099 
1100 err:
1101 	dev_err(wcd->dev, "Error Setting slim hw params\n");
1102 	kfree(cfg->chs);
1103 	cfg->chs = NULL;
1104 
1105 	return ret;
1106 }
1107 
1108 static int wcd9335_hw_params(struct snd_pcm_substream *substream,
1109 			   struct snd_pcm_hw_params *params,
1110 			   struct snd_soc_dai *dai)
1111 {
1112 	struct wcd9335_codec *wcd;
1113 	int ret;
1114 
1115 	wcd = snd_soc_component_get_drvdata(dai->component);
1116 
1117 	switch (substream->stream) {
1118 	case SNDRV_PCM_STREAM_PLAYBACK:
1119 		ret = wcd9335_set_interpolator_rate(dai, params_rate(params));
1120 		if (ret) {
1121 			dev_err(wcd->dev, "cannot set sample rate: %u\n",
1122 				params_rate(params));
1123 			return ret;
1124 		}
1125 		switch (params_width(params)) {
1126 		case 16 ... 24:
1127 			wcd->dai[dai->id].sconfig.bps = params_width(params);
1128 			break;
1129 		default:
1130 			dev_err(wcd->dev, "%s: Invalid format 0x%x\n",
1131 				__func__, params_width(params));
1132 			return -EINVAL;
1133 		}
1134 		break;
1135 	default:
1136 		dev_err(wcd->dev, "Invalid stream type %d\n",
1137 			substream->stream);
1138 		return -EINVAL;
1139 	};
1140 
1141 	wcd->dai[dai->id].sconfig.rate = params_rate(params);
1142 	wcd9335_slim_set_hw_params(wcd, &wcd->dai[dai->id], substream->stream);
1143 
1144 	return 0;
1145 }
1146 
1147 static int wcd9335_trigger(struct snd_pcm_substream *substream, int cmd,
1148 			   struct snd_soc_dai *dai)
1149 {
1150 	struct wcd_slim_codec_dai_data *dai_data;
1151 	struct wcd9335_codec *wcd;
1152 	struct slim_stream_config *cfg;
1153 
1154 	wcd = snd_soc_component_get_drvdata(dai->component);
1155 
1156 	dai_data = &wcd->dai[dai->id];
1157 
1158 	switch (cmd) {
1159 	case SNDRV_PCM_TRIGGER_START:
1160 	case SNDRV_PCM_TRIGGER_RESUME:
1161 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1162 		cfg = &dai_data->sconfig;
1163 		slim_stream_prepare(dai_data->sruntime, cfg);
1164 		slim_stream_enable(dai_data->sruntime);
1165 		break;
1166 	case SNDRV_PCM_TRIGGER_STOP:
1167 	case SNDRV_PCM_TRIGGER_SUSPEND:
1168 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1169 		slim_stream_unprepare(dai_data->sruntime);
1170 		slim_stream_disable(dai_data->sruntime);
1171 		break;
1172 	default:
1173 		break;
1174 	}
1175 
1176 	return 0;
1177 }
1178 
1179 static int wcd9335_set_channel_map(struct snd_soc_dai *dai,
1180 				   unsigned int tx_num, unsigned int *tx_slot,
1181 				   unsigned int rx_num, unsigned int *rx_slot)
1182 {
1183 	struct wcd9335_codec *wcd;
1184 	int i;
1185 
1186 	wcd = snd_soc_component_get_drvdata(dai->component);
1187 
1188 	if (!tx_slot || !rx_slot) {
1189 		dev_err(wcd->dev, "Invalid tx_slot=%p, rx_slot=%p\n",
1190 			tx_slot, rx_slot);
1191 		return -EINVAL;
1192 	}
1193 
1194 	if (wcd->rx_chs) {
1195 		wcd->num_rx_port = rx_num;
1196 		for (i = 0; i < rx_num; i++) {
1197 			wcd->rx_chs[i].ch_num = rx_slot[i];
1198 			INIT_LIST_HEAD(&wcd->rx_chs[i].list);
1199 		}
1200 	}
1201 
1202 	return 0;
1203 }
1204 
1205 static int wcd9335_get_channel_map(struct snd_soc_dai *dai,
1206 				   unsigned int *tx_num, unsigned int *tx_slot,
1207 				   unsigned int *rx_num, unsigned int *rx_slot)
1208 {
1209 	struct wcd9335_slim_ch *ch;
1210 	struct wcd9335_codec *wcd;
1211 	int i = 0;
1212 
1213 	wcd = snd_soc_component_get_drvdata(dai->component);
1214 
1215 	switch (dai->id) {
1216 	case AIF1_PB:
1217 	case AIF2_PB:
1218 	case AIF3_PB:
1219 	case AIF4_PB:
1220 		if (!rx_slot || !rx_num) {
1221 			dev_err(wcd->dev, "Invalid rx_slot %p or rx_num %p\n",
1222 				rx_slot, rx_num);
1223 			return -EINVAL;
1224 		}
1225 
1226 		list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list)
1227 			rx_slot[i++] = ch->ch_num;
1228 
1229 		*rx_num = i;
1230 		break;
1231 	default:
1232 		dev_err(wcd->dev, "Invalid DAI ID %x\n", dai->id);
1233 		break;
1234 	}
1235 
1236 	return 0;
1237 }
1238 
1239 static struct snd_soc_dai_ops wcd9335_dai_ops = {
1240 	.hw_params = wcd9335_hw_params,
1241 	.trigger = wcd9335_trigger,
1242 	.set_channel_map = wcd9335_set_channel_map,
1243 	.get_channel_map = wcd9335_get_channel_map,
1244 };
1245 
1246 static struct snd_soc_dai_driver wcd9335_slim_dais[] = {
1247 	[0] = {
1248 		.name = "wcd9335_rx1",
1249 		.id = AIF1_PB,
1250 		.playback = {
1251 			.stream_name = "AIF1 Playback",
1252 			.rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
1253 			.formats = WCD9335_FORMATS_S16_S24_LE,
1254 			.rate_max = 192000,
1255 			.rate_min = 8000,
1256 			.channels_min = 1,
1257 			.channels_max = 2,
1258 		},
1259 		.ops = &wcd9335_dai_ops,
1260 	},
1261 	[1] = {
1262 		.name = "wcd9335_tx1",
1263 		.id = AIF1_CAP,
1264 		.capture = {
1265 			.stream_name = "AIF1 Capture",
1266 			.rates = WCD9335_RATES_MASK,
1267 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
1268 			.rate_min = 8000,
1269 			.rate_max = 192000,
1270 			.channels_min = 1,
1271 			.channels_max = 4,
1272 		},
1273 		.ops = &wcd9335_dai_ops,
1274 	},
1275 	[2] = {
1276 		.name = "wcd9335_rx2",
1277 		.id = AIF2_PB,
1278 		.playback = {
1279 			.stream_name = "AIF2 Playback",
1280 			.rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
1281 			.formats = WCD9335_FORMATS_S16_S24_LE,
1282 			.rate_min = 8000,
1283 			.rate_max = 192000,
1284 			.channels_min = 1,
1285 			.channels_max = 2,
1286 		},
1287 		.ops = &wcd9335_dai_ops,
1288 	},
1289 	[3] = {
1290 		.name = "wcd9335_tx2",
1291 		.id = AIF2_CAP,
1292 		.capture = {
1293 			.stream_name = "AIF2 Capture",
1294 			.rates = WCD9335_RATES_MASK,
1295 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
1296 			.rate_min = 8000,
1297 			.rate_max = 192000,
1298 			.channels_min = 1,
1299 			.channels_max = 4,
1300 		},
1301 		.ops = &wcd9335_dai_ops,
1302 	},
1303 	[4] = {
1304 		.name = "wcd9335_rx3",
1305 		.id = AIF3_PB,
1306 		.playback = {
1307 			.stream_name = "AIF3 Playback",
1308 			.rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
1309 			.formats = WCD9335_FORMATS_S16_S24_LE,
1310 			.rate_min = 8000,
1311 			.rate_max = 192000,
1312 			.channels_min = 1,
1313 			.channels_max = 2,
1314 		},
1315 		.ops = &wcd9335_dai_ops,
1316 	},
1317 	[5] = {
1318 		.name = "wcd9335_tx3",
1319 		.id = AIF3_CAP,
1320 		.capture = {
1321 			.stream_name = "AIF3 Capture",
1322 			.rates = WCD9335_RATES_MASK,
1323 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
1324 			.rate_min = 8000,
1325 			.rate_max = 192000,
1326 			.channels_min = 1,
1327 			.channels_max = 4,
1328 		},
1329 		.ops = &wcd9335_dai_ops,
1330 	},
1331 	[6] = {
1332 		.name = "wcd9335_rx4",
1333 		.id = AIF4_PB,
1334 		.playback = {
1335 			.stream_name = "AIF4 Playback",
1336 			.rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
1337 			.formats = WCD9335_FORMATS_S16_S24_LE,
1338 			.rate_min = 8000,
1339 			.rate_max = 192000,
1340 			.channels_min = 1,
1341 			.channels_max = 2,
1342 		},
1343 		.ops = &wcd9335_dai_ops,
1344 	},
1345 };
1346 
1347 static int wcd9335_get_compander(struct snd_kcontrol *kc,
1348 			       struct snd_ctl_elem_value *ucontrol)
1349 {
1350 
1351 	struct snd_soc_component *component = snd_soc_kcontrol_component(kc);
1352 	int comp = ((struct soc_mixer_control *)kc->private_value)->shift;
1353 	struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
1354 
1355 	ucontrol->value.integer.value[0] = wcd->comp_enabled[comp];
1356 	return 0;
1357 }
1358 
1359 static int wcd9335_set_compander(struct snd_kcontrol *kc,
1360 				 struct snd_ctl_elem_value *ucontrol)
1361 {
1362 	struct snd_soc_component *component = snd_soc_kcontrol_component(kc);
1363 	struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
1364 	int comp = ((struct soc_mixer_control *) kc->private_value)->shift;
1365 	int value = ucontrol->value.integer.value[0];
1366 	int sel;
1367 
1368 	wcd->comp_enabled[comp] = value;
1369 	sel = value ? WCD9335_HPH_GAIN_SRC_SEL_COMPANDER :
1370 		WCD9335_HPH_GAIN_SRC_SEL_REGISTER;
1371 
1372 	/* Any specific register configuration for compander */
1373 	switch (comp) {
1374 	case COMPANDER_1:
1375 		/* Set Gain Source Select based on compander enable/disable */
1376 		snd_soc_component_update_bits(component, WCD9335_HPH_L_EN,
1377 				      WCD9335_HPH_GAIN_SRC_SEL_MASK, sel);
1378 		break;
1379 	case COMPANDER_2:
1380 		snd_soc_component_update_bits(component, WCD9335_HPH_R_EN,
1381 				      WCD9335_HPH_GAIN_SRC_SEL_MASK, sel);
1382 		break;
1383 	case COMPANDER_5:
1384 		snd_soc_component_update_bits(component, WCD9335_SE_LO_LO3_GAIN,
1385 				      WCD9335_HPH_GAIN_SRC_SEL_MASK, sel);
1386 		break;
1387 	case COMPANDER_6:
1388 		snd_soc_component_update_bits(component, WCD9335_SE_LO_LO4_GAIN,
1389 				      WCD9335_HPH_GAIN_SRC_SEL_MASK, sel);
1390 		break;
1391 	default:
1392 		break;
1393 	};
1394 
1395 	return 0;
1396 }
1397 
1398 static int wcd9335_rx_hph_mode_get(struct snd_kcontrol *kc,
1399 				 struct snd_ctl_elem_value *ucontrol)
1400 {
1401 	struct snd_soc_component *component = snd_soc_kcontrol_component(kc);
1402 	struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
1403 
1404 	ucontrol->value.enumerated.item[0] = wcd->hph_mode;
1405 
1406 	return 0;
1407 }
1408 
1409 static int wcd9335_rx_hph_mode_put(struct snd_kcontrol *kc,
1410 				 struct snd_ctl_elem_value *ucontrol)
1411 {
1412 	struct snd_soc_component *component = snd_soc_kcontrol_component(kc);
1413 	struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
1414 	u32 mode_val;
1415 
1416 	mode_val = ucontrol->value.enumerated.item[0];
1417 
1418 	if (mode_val == 0) {
1419 		dev_err(wcd->dev, "Invalid HPH Mode, default to ClSH HiFi\n");
1420 		mode_val = CLS_H_HIFI;
1421 	}
1422 	wcd->hph_mode = mode_val;
1423 
1424 	return 0;
1425 }
1426 
1427 static const struct snd_kcontrol_new wcd9335_snd_controls[] = {
1428 	/* -84dB min - 40dB max */
1429 	SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL,
1430 		0, -84, 40, digital_gain),
1431 	SOC_SINGLE_SX_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL,
1432 		0, -84, 40, digital_gain),
1433 	SOC_SINGLE_SX_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL,
1434 		0, -84, 40, digital_gain),
1435 	SOC_SINGLE_SX_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL,
1436 		0, -84, 40, digital_gain),
1437 	SOC_SINGLE_SX_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL,
1438 		0, -84, 40, digital_gain),
1439 	SOC_SINGLE_SX_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL,
1440 		0, -84, 40, digital_gain),
1441 	SOC_SINGLE_SX_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL,
1442 		0, -84, 40, digital_gain),
1443 	SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL,
1444 		0, -84, 40, digital_gain),
1445 	SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL,
1446 		0, -84, 40, digital_gain),
1447 	SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume",
1448 			  WCD9335_CDC_RX0_RX_VOL_MIX_CTL,
1449 			  0, -84, 40, digital_gain),
1450 	SOC_SINGLE_SX_TLV("RX1 Mix Digital Volume",
1451 			  WCD9335_CDC_RX1_RX_VOL_MIX_CTL,
1452 			  0, -84, 40, digital_gain),
1453 	SOC_SINGLE_SX_TLV("RX2 Mix Digital Volume",
1454 			  WCD9335_CDC_RX2_RX_VOL_MIX_CTL,
1455 			  0, -84, 40, digital_gain),
1456 	SOC_SINGLE_SX_TLV("RX3 Mix Digital Volume",
1457 			  WCD9335_CDC_RX3_RX_VOL_MIX_CTL,
1458 			  0, -84, 40, digital_gain),
1459 	SOC_SINGLE_SX_TLV("RX4 Mix Digital Volume",
1460 			  WCD9335_CDC_RX4_RX_VOL_MIX_CTL,
1461 			  0, -84, 40, digital_gain),
1462 	SOC_SINGLE_SX_TLV("RX5 Mix Digital Volume",
1463 			  WCD9335_CDC_RX5_RX_VOL_MIX_CTL,
1464 			  0, -84, 40, digital_gain),
1465 	SOC_SINGLE_SX_TLV("RX6 Mix Digital Volume",
1466 			  WCD9335_CDC_RX6_RX_VOL_MIX_CTL,
1467 			  0, -84, 40, digital_gain),
1468 	SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume",
1469 			  WCD9335_CDC_RX7_RX_VOL_MIX_CTL,
1470 			  0, -84, 40, digital_gain),
1471 	SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume",
1472 			  WCD9335_CDC_RX8_RX_VOL_MIX_CTL,
1473 			  0, -84, 40, digital_gain),
1474 	SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum),
1475 	SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum),
1476 	SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum),
1477 	SOC_ENUM("RX INT1_2 HPF cut off", cf_int1_2_enum),
1478 	SOC_ENUM("RX INT2_1 HPF cut off", cf_int2_1_enum),
1479 	SOC_ENUM("RX INT2_2 HPF cut off", cf_int2_2_enum),
1480 	SOC_ENUM("RX INT3_1 HPF cut off", cf_int3_1_enum),
1481 	SOC_ENUM("RX INT3_2 HPF cut off", cf_int3_2_enum),
1482 	SOC_ENUM("RX INT4_1 HPF cut off", cf_int4_1_enum),
1483 	SOC_ENUM("RX INT4_2 HPF cut off", cf_int4_2_enum),
1484 	SOC_ENUM("RX INT5_1 HPF cut off", cf_int5_1_enum),
1485 	SOC_ENUM("RX INT5_2 HPF cut off", cf_int5_2_enum),
1486 	SOC_ENUM("RX INT6_1 HPF cut off", cf_int6_1_enum),
1487 	SOC_ENUM("RX INT6_2 HPF cut off", cf_int6_2_enum),
1488 	SOC_ENUM("RX INT7_1 HPF cut off", cf_int7_1_enum),
1489 	SOC_ENUM("RX INT7_2 HPF cut off", cf_int7_2_enum),
1490 	SOC_ENUM("RX INT8_1 HPF cut off", cf_int8_1_enum),
1491 	SOC_ENUM("RX INT8_2 HPF cut off", cf_int8_2_enum),
1492 	SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0,
1493 		       wcd9335_get_compander, wcd9335_set_compander),
1494 	SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0,
1495 		       wcd9335_get_compander, wcd9335_set_compander),
1496 	SOC_SINGLE_EXT("COMP3 Switch", SND_SOC_NOPM, COMPANDER_3, 1, 0,
1497 		       wcd9335_get_compander, wcd9335_set_compander),
1498 	SOC_SINGLE_EXT("COMP4 Switch", SND_SOC_NOPM, COMPANDER_4, 1, 0,
1499 		       wcd9335_get_compander, wcd9335_set_compander),
1500 	SOC_SINGLE_EXT("COMP5 Switch", SND_SOC_NOPM, COMPANDER_5, 1, 0,
1501 		       wcd9335_get_compander, wcd9335_set_compander),
1502 	SOC_SINGLE_EXT("COMP6 Switch", SND_SOC_NOPM, COMPANDER_6, 1, 0,
1503 		       wcd9335_get_compander, wcd9335_set_compander),
1504 	SOC_SINGLE_EXT("COMP7 Switch", SND_SOC_NOPM, COMPANDER_7, 1, 0,
1505 		       wcd9335_get_compander, wcd9335_set_compander),
1506 	SOC_SINGLE_EXT("COMP8 Switch", SND_SOC_NOPM, COMPANDER_8, 1, 0,
1507 		       wcd9335_get_compander, wcd9335_set_compander),
1508 	SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum,
1509 		       wcd9335_rx_hph_mode_get, wcd9335_rx_hph_mode_put),
1510 
1511 	/* Gain Controls */
1512 	SOC_SINGLE_TLV("EAR PA Volume", WCD9335_ANA_EAR, 4, 4, 1,
1513 		ear_pa_gain),
1514 	SOC_SINGLE_TLV("HPHL Volume", WCD9335_HPH_L_EN, 0, 20, 1,
1515 		line_gain),
1516 	SOC_SINGLE_TLV("HPHR Volume", WCD9335_HPH_R_EN, 0, 20, 1,
1517 		line_gain),
1518 	SOC_SINGLE_TLV("LINEOUT1 Volume", WCD9335_DIFF_LO_LO1_COMPANDER,
1519 			3, 16, 1, line_gain),
1520 	SOC_SINGLE_TLV("LINEOUT2 Volume", WCD9335_DIFF_LO_LO2_COMPANDER,
1521 			3, 16, 1, line_gain),
1522 	SOC_SINGLE_TLV("LINEOUT3 Volume", WCD9335_SE_LO_LO3_GAIN, 0, 20, 1,
1523 			line_gain),
1524 	SOC_SINGLE_TLV("LINEOUT4 Volume", WCD9335_SE_LO_LO4_GAIN, 0, 20, 1,
1525 			line_gain),
1526 
1527 	SOC_SINGLE_TLV("ADC1 Volume", WCD9335_ANA_AMIC1, 0, 20, 0,
1528 			analog_gain),
1529 	SOC_SINGLE_TLV("ADC2 Volume", WCD9335_ANA_AMIC2, 0, 20, 0,
1530 			analog_gain),
1531 	SOC_SINGLE_TLV("ADC3 Volume", WCD9335_ANA_AMIC3, 0, 20, 0,
1532 			analog_gain),
1533 	SOC_SINGLE_TLV("ADC4 Volume", WCD9335_ANA_AMIC4, 0, 20, 0,
1534 			analog_gain),
1535 	SOC_SINGLE_TLV("ADC5 Volume", WCD9335_ANA_AMIC5, 0, 20, 0,
1536 			analog_gain),
1537 	SOC_SINGLE_TLV("ADC6 Volume", WCD9335_ANA_AMIC6, 0, 20, 0,
1538 			analog_gain),
1539 
1540 	SOC_ENUM("TX0 HPF cut off", cf_dec0_enum),
1541 	SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
1542 	SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
1543 	SOC_ENUM("TX3 HPF cut off", cf_dec3_enum),
1544 	SOC_ENUM("TX4 HPF cut off", cf_dec4_enum),
1545 	SOC_ENUM("TX5 HPF cut off", cf_dec5_enum),
1546 	SOC_ENUM("TX6 HPF cut off", cf_dec6_enum),
1547 	SOC_ENUM("TX7 HPF cut off", cf_dec7_enum),
1548 	SOC_ENUM("TX8 HPF cut off", cf_dec8_enum),
1549 };
1550 
1551 static void wcd9335_codec_enable_int_port(struct wcd_slim_codec_dai_data *dai,
1552 					struct snd_soc_component *component)
1553 {
1554 	int port_num = 0;
1555 	unsigned short reg = 0;
1556 	unsigned int val = 0;
1557 	struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
1558 	struct wcd9335_slim_ch *ch;
1559 
1560 	list_for_each_entry(ch, &dai->slim_ch_list, list) {
1561 		if (ch->port >= WCD9335_RX_START) {
1562 			port_num = ch->port - WCD9335_RX_START;
1563 			reg = WCD9335_SLIM_PGD_PORT_INT_EN0 + (port_num / 8);
1564 		} else {
1565 			port_num = ch->port;
1566 			reg = WCD9335_SLIM_PGD_PORT_INT_TX_EN0 + (port_num / 8);
1567 		}
1568 
1569 		regmap_read(wcd->if_regmap, reg, &val);
1570 		if (!(val & BIT(port_num % 8)))
1571 			regmap_write(wcd->if_regmap, reg,
1572 					val | BIT(port_num % 8));
1573 	}
1574 }
1575 
1576 static int wcd9335_codec_enable_slim(struct snd_soc_dapm_widget *w,
1577 				       struct snd_kcontrol *kc,
1578 				       int event)
1579 {
1580 	struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
1581 	struct wcd9335_codec *wcd = snd_soc_component_get_drvdata(comp);
1582 	struct wcd_slim_codec_dai_data *dai = &wcd->dai[w->shift];
1583 	int ret = 0;
1584 
1585 	switch (event) {
1586 	case SND_SOC_DAPM_POST_PMU:
1587 		wcd9335_codec_enable_int_port(dai, comp);
1588 		break;
1589 	case SND_SOC_DAPM_POST_PMD:
1590 		kfree(dai->sconfig.chs);
1591 
1592 		break;
1593 	}
1594 
1595 	return ret;
1596 }
1597 
1598 static int wcd9335_codec_enable_mix_path(struct snd_soc_dapm_widget *w,
1599 		struct snd_kcontrol *kc, int event)
1600 {
1601 	struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
1602 	u16 gain_reg;
1603 	int offset_val = 0;
1604 	int val = 0;
1605 
1606 	switch (w->reg) {
1607 	case WCD9335_CDC_RX0_RX_PATH_MIX_CTL:
1608 		gain_reg = WCD9335_CDC_RX0_RX_VOL_MIX_CTL;
1609 		break;
1610 	case WCD9335_CDC_RX1_RX_PATH_MIX_CTL:
1611 		gain_reg = WCD9335_CDC_RX1_RX_VOL_MIX_CTL;
1612 		break;
1613 	case WCD9335_CDC_RX2_RX_PATH_MIX_CTL:
1614 		gain_reg = WCD9335_CDC_RX2_RX_VOL_MIX_CTL;
1615 		break;
1616 	case WCD9335_CDC_RX3_RX_PATH_MIX_CTL:
1617 		gain_reg = WCD9335_CDC_RX3_RX_VOL_MIX_CTL;
1618 		break;
1619 	case WCD9335_CDC_RX4_RX_PATH_MIX_CTL:
1620 		gain_reg = WCD9335_CDC_RX4_RX_VOL_MIX_CTL;
1621 		break;
1622 	case WCD9335_CDC_RX5_RX_PATH_MIX_CTL:
1623 		gain_reg = WCD9335_CDC_RX5_RX_VOL_MIX_CTL;
1624 		break;
1625 	case WCD9335_CDC_RX6_RX_PATH_MIX_CTL:
1626 		gain_reg = WCD9335_CDC_RX6_RX_VOL_MIX_CTL;
1627 		break;
1628 	case WCD9335_CDC_RX7_RX_PATH_MIX_CTL:
1629 		gain_reg = WCD9335_CDC_RX7_RX_VOL_MIX_CTL;
1630 		break;
1631 	case WCD9335_CDC_RX8_RX_PATH_MIX_CTL:
1632 		gain_reg = WCD9335_CDC_RX8_RX_VOL_MIX_CTL;
1633 		break;
1634 	default:
1635 		dev_err(comp->dev, "%s: No gain register avail for %s\n",
1636 			__func__, w->name);
1637 		return 0;
1638 	};
1639 
1640 	switch (event) {
1641 	case SND_SOC_DAPM_POST_PMU:
1642 		val = snd_soc_component_read32(comp, gain_reg);
1643 		val += offset_val;
1644 		snd_soc_component_write(comp, gain_reg, val);
1645 		break;
1646 	case SND_SOC_DAPM_POST_PMD:
1647 		break;
1648 	};
1649 
1650 	return 0;
1651 }
1652 
1653 static u16 wcd9335_interp_get_primary_reg(u16 reg, u16 *ind)
1654 {
1655 	u16 prim_int_reg = WCD9335_CDC_RX0_RX_PATH_CTL;
1656 
1657 	switch (reg) {
1658 	case WCD9335_CDC_RX0_RX_PATH_CTL:
1659 	case WCD9335_CDC_RX0_RX_PATH_MIX_CTL:
1660 		prim_int_reg = WCD9335_CDC_RX0_RX_PATH_CTL;
1661 		*ind = 0;
1662 		break;
1663 	case WCD9335_CDC_RX1_RX_PATH_CTL:
1664 	case WCD9335_CDC_RX1_RX_PATH_MIX_CTL:
1665 		prim_int_reg = WCD9335_CDC_RX1_RX_PATH_CTL;
1666 		*ind = 1;
1667 		break;
1668 	case WCD9335_CDC_RX2_RX_PATH_CTL:
1669 	case WCD9335_CDC_RX2_RX_PATH_MIX_CTL:
1670 		prim_int_reg = WCD9335_CDC_RX2_RX_PATH_CTL;
1671 		*ind = 2;
1672 		break;
1673 	case WCD9335_CDC_RX3_RX_PATH_CTL:
1674 	case WCD9335_CDC_RX3_RX_PATH_MIX_CTL:
1675 		prim_int_reg = WCD9335_CDC_RX3_RX_PATH_CTL;
1676 		*ind = 3;
1677 		break;
1678 	case WCD9335_CDC_RX4_RX_PATH_CTL:
1679 	case WCD9335_CDC_RX4_RX_PATH_MIX_CTL:
1680 		prim_int_reg = WCD9335_CDC_RX4_RX_PATH_CTL;
1681 		*ind = 4;
1682 		break;
1683 	case WCD9335_CDC_RX5_RX_PATH_CTL:
1684 	case WCD9335_CDC_RX5_RX_PATH_MIX_CTL:
1685 		prim_int_reg = WCD9335_CDC_RX5_RX_PATH_CTL;
1686 		*ind = 5;
1687 		break;
1688 	case WCD9335_CDC_RX6_RX_PATH_CTL:
1689 	case WCD9335_CDC_RX6_RX_PATH_MIX_CTL:
1690 		prim_int_reg = WCD9335_CDC_RX6_RX_PATH_CTL;
1691 		*ind = 6;
1692 		break;
1693 	case WCD9335_CDC_RX7_RX_PATH_CTL:
1694 	case WCD9335_CDC_RX7_RX_PATH_MIX_CTL:
1695 		prim_int_reg = WCD9335_CDC_RX7_RX_PATH_CTL;
1696 		*ind = 7;
1697 		break;
1698 	case WCD9335_CDC_RX8_RX_PATH_CTL:
1699 	case WCD9335_CDC_RX8_RX_PATH_MIX_CTL:
1700 		prim_int_reg = WCD9335_CDC_RX8_RX_PATH_CTL;
1701 		*ind = 8;
1702 		break;
1703 	};
1704 
1705 	return prim_int_reg;
1706 }
1707 
1708 static void wcd9335_codec_hd2_control(struct snd_soc_component *component,
1709 				    u16 prim_int_reg, int event)
1710 {
1711 	u16 hd2_scale_reg;
1712 	u16 hd2_enable_reg = 0;
1713 
1714 	if (prim_int_reg == WCD9335_CDC_RX1_RX_PATH_CTL) {
1715 		hd2_scale_reg = WCD9335_CDC_RX1_RX_PATH_SEC3;
1716 		hd2_enable_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
1717 	}
1718 	if (prim_int_reg == WCD9335_CDC_RX2_RX_PATH_CTL) {
1719 		hd2_scale_reg = WCD9335_CDC_RX2_RX_PATH_SEC3;
1720 		hd2_enable_reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
1721 	}
1722 
1723 	if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
1724 		snd_soc_component_update_bits(component, hd2_scale_reg,
1725 				WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_MASK,
1726 				WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_0P2500);
1727 		snd_soc_component_update_bits(component, hd2_scale_reg,
1728 				WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_MASK,
1729 				WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_2);
1730 		snd_soc_component_update_bits(component, hd2_enable_reg,
1731 				WCD9335_CDC_RX_PATH_CFG_HD2_EN_MASK,
1732 				WCD9335_CDC_RX_PATH_CFG_HD2_ENABLE);
1733 	}
1734 
1735 	if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
1736 		snd_soc_component_update_bits(component, hd2_enable_reg,
1737 					WCD9335_CDC_RX_PATH_CFG_HD2_EN_MASK,
1738 					WCD9335_CDC_RX_PATH_CFG_HD2_DISABLE);
1739 		snd_soc_component_update_bits(component, hd2_scale_reg,
1740 					WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_MASK,
1741 					WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_1);
1742 		snd_soc_component_update_bits(component, hd2_scale_reg,
1743 				WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_MASK,
1744 				WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_0P0000);
1745 	}
1746 }
1747 
1748 static int wcd9335_codec_enable_prim_interpolator(
1749 						struct snd_soc_component *comp,
1750 						u16 reg, int event)
1751 {
1752 	struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
1753 	u16 ind = 0;
1754 	int prim_int_reg = wcd9335_interp_get_primary_reg(reg, &ind);
1755 
1756 	switch (event) {
1757 	case SND_SOC_DAPM_PRE_PMU:
1758 		wcd->prim_int_users[ind]++;
1759 		if (wcd->prim_int_users[ind] == 1) {
1760 			snd_soc_component_update_bits(comp, prim_int_reg,
1761 					WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
1762 					WCD9335_CDC_RX_PGA_MUTE_ENABLE);
1763 			wcd9335_codec_hd2_control(comp, prim_int_reg, event);
1764 			snd_soc_component_update_bits(comp, prim_int_reg,
1765 					WCD9335_CDC_RX_CLK_EN_MASK,
1766 					WCD9335_CDC_RX_CLK_ENABLE);
1767 		}
1768 
1769 		if ((reg != prim_int_reg) &&
1770 			((snd_soc_component_read32(comp, prim_int_reg)) &
1771 			 WCD9335_CDC_RX_PGA_MUTE_EN_MASK))
1772 			snd_soc_component_update_bits(comp, reg,
1773 						WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
1774 						WCD9335_CDC_RX_PGA_MUTE_ENABLE);
1775 		break;
1776 	case SND_SOC_DAPM_POST_PMD:
1777 		wcd->prim_int_users[ind]--;
1778 		if (wcd->prim_int_users[ind] == 0) {
1779 			snd_soc_component_update_bits(comp, prim_int_reg,
1780 					WCD9335_CDC_RX_CLK_EN_MASK,
1781 					WCD9335_CDC_RX_CLK_DISABLE);
1782 			snd_soc_component_update_bits(comp, prim_int_reg,
1783 					WCD9335_CDC_RX_RESET_MASK,
1784 					WCD9335_CDC_RX_RESET_ENABLE);
1785 			snd_soc_component_update_bits(comp, prim_int_reg,
1786 					WCD9335_CDC_RX_RESET_MASK,
1787 					WCD9335_CDC_RX_RESET_DISABLE);
1788 			wcd9335_codec_hd2_control(comp, prim_int_reg, event);
1789 		}
1790 		break;
1791 	};
1792 
1793 	return 0;
1794 }
1795 
1796 static int wcd9335_config_compander(struct snd_soc_component *component,
1797 				    int interp_n, int event)
1798 {
1799 	struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
1800 	int comp;
1801 	u16 comp_ctl0_reg, rx_path_cfg0_reg;
1802 
1803 	/* EAR does not have compander */
1804 	if (!interp_n)
1805 		return 0;
1806 
1807 	comp = interp_n - 1;
1808 	if (!wcd->comp_enabled[comp])
1809 		return 0;
1810 
1811 	comp_ctl0_reg = WCD9335_CDC_COMPANDER1_CTL(comp);
1812 	rx_path_cfg0_reg = WCD9335_CDC_RX1_RX_PATH_CFG(comp);
1813 
1814 	if (SND_SOC_DAPM_EVENT_ON(event)) {
1815 		/* Enable Compander Clock */
1816 		snd_soc_component_update_bits(component, comp_ctl0_reg,
1817 					WCD9335_CDC_COMPANDER_CLK_EN_MASK,
1818 					WCD9335_CDC_COMPANDER_CLK_ENABLE);
1819 		/* Reset comander */
1820 		snd_soc_component_update_bits(component, comp_ctl0_reg,
1821 					WCD9335_CDC_COMPANDER_SOFT_RST_MASK,
1822 					WCD9335_CDC_COMPANDER_SOFT_RST_ENABLE);
1823 		snd_soc_component_update_bits(component, comp_ctl0_reg,
1824 				WCD9335_CDC_COMPANDER_SOFT_RST_MASK,
1825 				WCD9335_CDC_COMPANDER_SOFT_RST_DISABLE);
1826 		/* Enables DRE in this path */
1827 		snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1828 					WCD9335_CDC_RX_PATH_CFG_CMP_EN_MASK,
1829 					WCD9335_CDC_RX_PATH_CFG_CMP_ENABLE);
1830 	}
1831 
1832 	if (SND_SOC_DAPM_EVENT_OFF(event)) {
1833 		snd_soc_component_update_bits(component, comp_ctl0_reg,
1834 					WCD9335_CDC_COMPANDER_HALT_MASK,
1835 					WCD9335_CDC_COMPANDER_HALT);
1836 		snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1837 					WCD9335_CDC_RX_PATH_CFG_CMP_EN_MASK,
1838 					WCD9335_CDC_RX_PATH_CFG_CMP_DISABLE);
1839 
1840 		snd_soc_component_update_bits(component, comp_ctl0_reg,
1841 					WCD9335_CDC_COMPANDER_SOFT_RST_MASK,
1842 					WCD9335_CDC_COMPANDER_SOFT_RST_ENABLE);
1843 		snd_soc_component_update_bits(component, comp_ctl0_reg,
1844 				WCD9335_CDC_COMPANDER_SOFT_RST_MASK,
1845 				WCD9335_CDC_COMPANDER_SOFT_RST_DISABLE);
1846 		snd_soc_component_update_bits(component, comp_ctl0_reg,
1847 					WCD9335_CDC_COMPANDER_CLK_EN_MASK,
1848 					WCD9335_CDC_COMPANDER_CLK_DISABLE);
1849 		snd_soc_component_update_bits(component, comp_ctl0_reg,
1850 					WCD9335_CDC_COMPANDER_HALT_MASK,
1851 					WCD9335_CDC_COMPANDER_NOHALT);
1852 	}
1853 
1854 	return 0;
1855 }
1856 
1857 static int wcd9335_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
1858 		struct snd_kcontrol *kc, int event)
1859 {
1860 	struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
1861 	u16 gain_reg;
1862 	u16 reg;
1863 	int val;
1864 	int offset_val = 0;
1865 
1866 	if (!(strcmp(w->name, "RX INT0 INTERP"))) {
1867 		reg = WCD9335_CDC_RX0_RX_PATH_CTL;
1868 		gain_reg = WCD9335_CDC_RX0_RX_VOL_CTL;
1869 	} else if (!(strcmp(w->name, "RX INT1 INTERP"))) {
1870 		reg = WCD9335_CDC_RX1_RX_PATH_CTL;
1871 		gain_reg = WCD9335_CDC_RX1_RX_VOL_CTL;
1872 	} else if (!(strcmp(w->name, "RX INT2 INTERP"))) {
1873 		reg = WCD9335_CDC_RX2_RX_PATH_CTL;
1874 		gain_reg = WCD9335_CDC_RX2_RX_VOL_CTL;
1875 	} else if (!(strcmp(w->name, "RX INT3 INTERP"))) {
1876 		reg = WCD9335_CDC_RX3_RX_PATH_CTL;
1877 		gain_reg = WCD9335_CDC_RX3_RX_VOL_CTL;
1878 	} else if (!(strcmp(w->name, "RX INT4 INTERP"))) {
1879 		reg = WCD9335_CDC_RX4_RX_PATH_CTL;
1880 		gain_reg = WCD9335_CDC_RX4_RX_VOL_CTL;
1881 	} else if (!(strcmp(w->name, "RX INT5 INTERP"))) {
1882 		reg = WCD9335_CDC_RX5_RX_PATH_CTL;
1883 		gain_reg = WCD9335_CDC_RX5_RX_VOL_CTL;
1884 	} else if (!(strcmp(w->name, "RX INT6 INTERP"))) {
1885 		reg = WCD9335_CDC_RX6_RX_PATH_CTL;
1886 		gain_reg = WCD9335_CDC_RX6_RX_VOL_CTL;
1887 	} else if (!(strcmp(w->name, "RX INT7 INTERP"))) {
1888 		reg = WCD9335_CDC_RX7_RX_PATH_CTL;
1889 		gain_reg = WCD9335_CDC_RX7_RX_VOL_CTL;
1890 	} else if (!(strcmp(w->name, "RX INT8 INTERP"))) {
1891 		reg = WCD9335_CDC_RX8_RX_PATH_CTL;
1892 		gain_reg = WCD9335_CDC_RX8_RX_VOL_CTL;
1893 	} else {
1894 		dev_err(comp->dev, "%s: Interpolator reg not found\n",
1895 			__func__);
1896 		return -EINVAL;
1897 	}
1898 
1899 	switch (event) {
1900 	case SND_SOC_DAPM_PRE_PMU:
1901 		/* Reset if needed */
1902 		wcd9335_codec_enable_prim_interpolator(comp, reg, event);
1903 		break;
1904 	case SND_SOC_DAPM_POST_PMU:
1905 		wcd9335_config_compander(comp, w->shift, event);
1906 		val = snd_soc_component_read32(comp, gain_reg);
1907 		val += offset_val;
1908 		snd_soc_component_write(comp, gain_reg, val);
1909 		break;
1910 	case SND_SOC_DAPM_POST_PMD:
1911 		wcd9335_config_compander(comp, w->shift, event);
1912 		wcd9335_codec_enable_prim_interpolator(comp, reg, event);
1913 		break;
1914 	};
1915 
1916 	return 0;
1917 }
1918 
1919 static void wcd9335_codec_hph_mode_gain_opt(struct snd_soc_component *component,
1920 					    u8 gain)
1921 {
1922 	struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
1923 	u8 hph_l_en, hph_r_en;
1924 	u8 l_val, r_val;
1925 	u8 hph_pa_status;
1926 	bool is_hphl_pa, is_hphr_pa;
1927 
1928 	hph_pa_status = snd_soc_component_read32(component, WCD9335_ANA_HPH);
1929 	is_hphl_pa = hph_pa_status >> 7;
1930 	is_hphr_pa = (hph_pa_status & 0x40) >> 6;
1931 
1932 	hph_l_en = snd_soc_component_read32(component, WCD9335_HPH_L_EN);
1933 	hph_r_en = snd_soc_component_read32(component, WCD9335_HPH_R_EN);
1934 
1935 	l_val = (hph_l_en & 0xC0) | 0x20 | gain;
1936 	r_val = (hph_r_en & 0xC0) | 0x20 | gain;
1937 
1938 	/*
1939 	 * Set HPH_L & HPH_R gain source selection to REGISTER
1940 	 * for better click and pop only if corresponding PAs are
1941 	 * not enabled. Also cache the values of the HPHL/R
1942 	 * PA gains to be applied after PAs are enabled
1943 	 */
1944 	if ((l_val != hph_l_en) && !is_hphl_pa) {
1945 		snd_soc_component_write(component, WCD9335_HPH_L_EN, l_val);
1946 		wcd->hph_l_gain = hph_l_en & 0x1F;
1947 	}
1948 
1949 	if ((r_val != hph_r_en) && !is_hphr_pa) {
1950 		snd_soc_component_write(component, WCD9335_HPH_R_EN, r_val);
1951 		wcd->hph_r_gain = hph_r_en & 0x1F;
1952 	}
1953 }
1954 
1955 static void wcd9335_codec_hph_lohifi_config(struct snd_soc_component *comp,
1956 					  int event)
1957 {
1958 	if (SND_SOC_DAPM_EVENT_ON(event)) {
1959 		snd_soc_component_update_bits(comp, WCD9335_RX_BIAS_HPH_PA,
1960 					WCD9335_RX_BIAS_HPH_PA_AMP_5_UA_MASK,
1961 					0x06);
1962 		snd_soc_component_update_bits(comp,
1963 					WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2,
1964 					0xF0, 0x40);
1965 		snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL,
1966 				WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK,
1967 				WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_1000);
1968 		snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
1969 				WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK,
1970 				WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_ENABLE);
1971 		snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL1,
1972 				WCD9335_HPH_PA_GM3_IB_SCALE_MASK,
1973 				0x0C);
1974 		wcd9335_codec_hph_mode_gain_opt(comp, 0x11);
1975 	}
1976 
1977 	if (SND_SOC_DAPM_EVENT_OFF(event)) {
1978 		snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
1979 			WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK,
1980 			WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_DISABLE);
1981 		snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL,
1982 				WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK,
1983 				WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_500);
1984 		snd_soc_component_write(comp, WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2,
1985 					0x8A);
1986 		snd_soc_component_update_bits(comp, WCD9335_RX_BIAS_HPH_PA,
1987 					WCD9335_RX_BIAS_HPH_PA_AMP_5_UA_MASK,
1988 					0x0A);
1989 	}
1990 }
1991 
1992 static void wcd9335_codec_hph_lp_config(struct snd_soc_component *comp,
1993 				      int event)
1994 {
1995 	if (SND_SOC_DAPM_EVENT_ON(event)) {
1996 		snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL1,
1997 				WCD9335_HPH_PA_GM3_IB_SCALE_MASK,
1998 				0x0C);
1999 		wcd9335_codec_hph_mode_gain_opt(comp, 0x10);
2000 		snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL,
2001 				WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK,
2002 				WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_1000);
2003 		snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
2004 			WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK,
2005 			WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_ENABLE);
2006 		snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
2007 				WCD9335_HPH_PA_CTL2_FORCE_PSRREH_MASK,
2008 				WCD9335_HPH_PA_CTL2_FORCE_PSRREH_ENABLE);
2009 		snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
2010 				WCD9335_HPH_PA_CTL2_HPH_PSRR_ENH_MASK,
2011 				WCD9335_HPH_PA_CTL2_HPH_PSRR_ENABLE);
2012 		snd_soc_component_update_bits(comp, WCD9335_HPH_RDAC_LDO_CTL,
2013 				WCD9335_HPH_RDAC_N1P65_LD_OUTCTL_MASK,
2014 				WCD9335_HPH_RDAC_N1P65_LD_OUTCTL_V_N1P60);
2015 		snd_soc_component_update_bits(comp, WCD9335_HPH_RDAC_LDO_CTL,
2016 				WCD9335_HPH_RDAC_1P65_LD_OUTCTL_MASK,
2017 				WCD9335_HPH_RDAC_1P65_LD_OUTCTL_V_N1P60);
2018 		snd_soc_component_update_bits(comp,
2019 				WCD9335_RX_BIAS_HPH_RDAC_LDO, 0x0F, 0x01);
2020 		snd_soc_component_update_bits(comp,
2021 				WCD9335_RX_BIAS_HPH_RDAC_LDO, 0xF0, 0x10);
2022 	}
2023 
2024 	if (SND_SOC_DAPM_EVENT_OFF(event)) {
2025 		snd_soc_component_write(comp, WCD9335_RX_BIAS_HPH_RDAC_LDO,
2026 					0x88);
2027 		snd_soc_component_write(comp, WCD9335_HPH_RDAC_LDO_CTL,
2028 					0x33);
2029 		snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
2030 				WCD9335_HPH_PA_CTL2_HPH_PSRR_ENH_MASK,
2031 				WCD9335_HPH_PA_CTL2_HPH_PSRR_DISABLE);
2032 		snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
2033 				WCD9335_HPH_PA_CTL2_FORCE_PSRREH_MASK,
2034 				WCD9335_HPH_PA_CTL2_FORCE_PSRREH_DISABLE);
2035 		snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
2036 				WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK,
2037 				WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_DISABLE);
2038 		snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL,
2039 				WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK,
2040 				WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_500);
2041 		snd_soc_component_update_bits(comp, WCD9335_HPH_R_EN,
2042 				WCD9335_HPH_CONST_SEL_L_MASK,
2043 				WCD9335_HPH_CONST_SEL_L_HQ_PATH);
2044 		snd_soc_component_update_bits(comp, WCD9335_HPH_L_EN,
2045 				WCD9335_HPH_CONST_SEL_L_MASK,
2046 				WCD9335_HPH_CONST_SEL_L_HQ_PATH);
2047 	}
2048 }
2049 
2050 static void wcd9335_codec_hph_hifi_config(struct snd_soc_component *comp,
2051 					int event)
2052 {
2053 	if (SND_SOC_DAPM_EVENT_ON(event)) {
2054 		snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL,
2055 				WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK,
2056 				WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_1000);
2057 		snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
2058 				WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK,
2059 				WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_ENABLE);
2060 		snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL1,
2061 				WCD9335_HPH_PA_GM3_IB_SCALE_MASK,
2062 				0x0C);
2063 		wcd9335_codec_hph_mode_gain_opt(comp, 0x11);
2064 	}
2065 
2066 	if (SND_SOC_DAPM_EVENT_OFF(event)) {
2067 		snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
2068 			WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK,
2069 			WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_DISABLE);
2070 		snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL,
2071 				WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK,
2072 				WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_500);
2073 	}
2074 }
2075 
2076 static void wcd9335_codec_hph_mode_config(struct snd_soc_component *component,
2077 					  int event, int mode)
2078 {
2079 	switch (mode) {
2080 	case CLS_H_LP:
2081 		wcd9335_codec_hph_lp_config(component, event);
2082 		break;
2083 	case CLS_H_LOHIFI:
2084 		wcd9335_codec_hph_lohifi_config(component, event);
2085 		break;
2086 	case CLS_H_HIFI:
2087 		wcd9335_codec_hph_hifi_config(component, event);
2088 		break;
2089 	}
2090 }
2091 
2092 static int wcd9335_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
2093 					struct snd_kcontrol *kc,
2094 					int event)
2095 {
2096 	struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
2097 	struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
2098 	int hph_mode = wcd->hph_mode;
2099 	u8 dem_inp;
2100 	int ret = 0;
2101 
2102 	switch (event) {
2103 	case SND_SOC_DAPM_PRE_PMU:
2104 		/* Read DEM INP Select */
2105 		dem_inp = snd_soc_component_read32(comp,
2106 				WCD9335_CDC_RX1_RX_PATH_SEC0) & 0x03;
2107 		if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) ||
2108 				(hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
2109 			dev_err(comp->dev, "Incorrect DEM Input\n");
2110 			return -EINVAL;
2111 		}
2112 		wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC,
2113 					WCD_CLSH_STATE_HPHL,
2114 					((hph_mode == CLS_H_LOHIFI) ?
2115 					 CLS_H_HIFI : hph_mode));
2116 
2117 		wcd9335_codec_hph_mode_config(comp, event, hph_mode);
2118 
2119 		break;
2120 	case SND_SOC_DAPM_POST_PMU:
2121 		usleep_range(1000, 1100);
2122 		break;
2123 	case SND_SOC_DAPM_PRE_PMD:
2124 		break;
2125 	case SND_SOC_DAPM_POST_PMD:
2126 		/* 1000us required as per HW requirement */
2127 		usleep_range(1000, 1100);
2128 
2129 		if (!(wcd_clsh_ctrl_get_state(wcd->clsh_ctrl) &
2130 				WCD_CLSH_STATE_HPHR))
2131 			wcd9335_codec_hph_mode_config(comp, event, hph_mode);
2132 
2133 		wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA,
2134 				WCD_CLSH_STATE_HPHL,
2135 				((hph_mode == CLS_H_LOHIFI) ?
2136 				 CLS_H_HIFI : hph_mode));
2137 		break;
2138 	};
2139 
2140 	return ret;
2141 }
2142 
2143 static int wcd9335_codec_lineout_dac_event(struct snd_soc_dapm_widget *w,
2144 					   struct snd_kcontrol *kc, int event)
2145 {
2146 	struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
2147 	struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
2148 
2149 	switch (event) {
2150 	case SND_SOC_DAPM_PRE_PMU:
2151 		wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC,
2152 					WCD_CLSH_STATE_LO, CLS_AB);
2153 		break;
2154 	case SND_SOC_DAPM_POST_PMD:
2155 		wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA,
2156 					WCD_CLSH_STATE_LO, CLS_AB);
2157 		break;
2158 	}
2159 
2160 	return 0;
2161 }
2162 
2163 static int wcd9335_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
2164 				       struct snd_kcontrol *kc, int event)
2165 {
2166 	struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
2167 	struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
2168 	int ret = 0;
2169 
2170 	switch (event) {
2171 	case SND_SOC_DAPM_PRE_PMU:
2172 		wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC,
2173 					WCD_CLSH_STATE_EAR, CLS_H_NORMAL);
2174 
2175 		break;
2176 	case SND_SOC_DAPM_POST_PMD:
2177 		wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA,
2178 					WCD_CLSH_STATE_EAR, CLS_H_NORMAL);
2179 		break;
2180 	};
2181 
2182 	return ret;
2183 }
2184 
2185 static void wcd9335_codec_hph_post_pa_config(struct wcd9335_codec *wcd,
2186 					     int mode, int event)
2187 {
2188 	u8 scale_val = 0;
2189 
2190 	switch (event) {
2191 	case SND_SOC_DAPM_POST_PMU:
2192 		switch (mode) {
2193 		case CLS_H_HIFI:
2194 			scale_val = 0x3;
2195 			break;
2196 		case CLS_H_LOHIFI:
2197 			scale_val = 0x1;
2198 			break;
2199 		}
2200 		break;
2201 	case SND_SOC_DAPM_PRE_PMD:
2202 		scale_val = 0x6;
2203 		break;
2204 	}
2205 
2206 	if (scale_val)
2207 		snd_soc_component_update_bits(wcd->component,
2208 					WCD9335_HPH_PA_CTL1,
2209 					WCD9335_HPH_PA_GM3_IB_SCALE_MASK,
2210 					scale_val << 1);
2211 	if (SND_SOC_DAPM_EVENT_ON(event)) {
2212 		if (wcd->comp_enabled[COMPANDER_1] ||
2213 		    wcd->comp_enabled[COMPANDER_2]) {
2214 			/* GAIN Source Selection */
2215 			snd_soc_component_update_bits(wcd->component,
2216 					WCD9335_HPH_L_EN,
2217 					WCD9335_HPH_GAIN_SRC_SEL_MASK,
2218 					WCD9335_HPH_GAIN_SRC_SEL_COMPANDER);
2219 			snd_soc_component_update_bits(wcd->component,
2220 					WCD9335_HPH_R_EN,
2221 					WCD9335_HPH_GAIN_SRC_SEL_MASK,
2222 					WCD9335_HPH_GAIN_SRC_SEL_COMPANDER);
2223 			snd_soc_component_update_bits(wcd->component,
2224 					WCD9335_HPH_AUTO_CHOP,
2225 					WCD9335_HPH_AUTO_CHOP_MASK,
2226 					WCD9335_HPH_AUTO_CHOP_FORCE_ENABLE);
2227 		}
2228 		snd_soc_component_update_bits(wcd->component,
2229 						WCD9335_HPH_L_EN,
2230 						WCD9335_HPH_PA_GAIN_MASK,
2231 						wcd->hph_l_gain);
2232 		snd_soc_component_update_bits(wcd->component,
2233 						WCD9335_HPH_R_EN,
2234 						WCD9335_HPH_PA_GAIN_MASK,
2235 						wcd->hph_r_gain);
2236 	}
2237 
2238 	if (SND_SOC_DAPM_EVENT_OFF(event))
2239 		snd_soc_component_update_bits(wcd->component,
2240 				WCD9335_HPH_AUTO_CHOP,
2241 				WCD9335_HPH_AUTO_CHOP_MASK,
2242 				WCD9335_HPH_AUTO_CHOP_ENABLE_BY_CMPDR_GAIN);
2243 }
2244 
2245 static int wcd9335_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
2246 				      struct snd_kcontrol *kc,
2247 				      int event)
2248 {
2249 	struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
2250 	struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
2251 	int hph_mode = wcd->hph_mode;
2252 	u8 dem_inp;
2253 	int ret = 0;
2254 
2255 	switch (event) {
2256 	case SND_SOC_DAPM_PRE_PMU:
2257 
2258 		/* Read DEM INP Select */
2259 		dem_inp = snd_soc_component_read32(comp,
2260 				WCD9335_CDC_RX2_RX_PATH_SEC0) &
2261 				WCD9335_CDC_RX_PATH_DEM_INP_SEL_MASK;
2262 		if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) ||
2263 		     (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
2264 			dev_err(comp->dev, "DEM Input not set correctly, hph_mode: %d\n",
2265 				hph_mode);
2266 			return -EINVAL;
2267 		}
2268 
2269 		wcd_clsh_ctrl_set_state(wcd->clsh_ctrl,
2270 			     WCD_CLSH_EVENT_PRE_DAC,
2271 			     WCD_CLSH_STATE_HPHR,
2272 			     ((hph_mode == CLS_H_LOHIFI) ?
2273 			       CLS_H_HIFI : hph_mode));
2274 
2275 		wcd9335_codec_hph_mode_config(comp, event, hph_mode);
2276 
2277 		break;
2278 	case SND_SOC_DAPM_POST_PMD:
2279 		/* 1000us required as per HW requirement */
2280 		usleep_range(1000, 1100);
2281 
2282 		if (!(wcd_clsh_ctrl_get_state(wcd->clsh_ctrl) &
2283 					WCD_CLSH_STATE_HPHL))
2284 			wcd9335_codec_hph_mode_config(comp, event, hph_mode);
2285 
2286 		wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA,
2287 			     WCD_CLSH_STATE_HPHR, ((hph_mode == CLS_H_LOHIFI) ?
2288 						CLS_H_HIFI : hph_mode));
2289 		break;
2290 	};
2291 
2292 	return ret;
2293 }
2294 
2295 static int wcd9335_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
2296 				      struct snd_kcontrol *kc,
2297 				      int event)
2298 {
2299 	struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
2300 	struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
2301 	int hph_mode = wcd->hph_mode;
2302 	int ret = 0;
2303 
2304 	switch (event) {
2305 	case SND_SOC_DAPM_PRE_PMU:
2306 		break;
2307 	case SND_SOC_DAPM_POST_PMU:
2308 		/*
2309 		 * 7ms sleep is required after PA is enabled as per
2310 		 * HW requirement
2311 		 */
2312 		usleep_range(7000, 7100);
2313 
2314 		wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event);
2315 		snd_soc_component_update_bits(comp,
2316 					WCD9335_CDC_RX1_RX_PATH_CTL,
2317 					WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
2318 					WCD9335_CDC_RX_PGA_MUTE_DISABLE);
2319 
2320 		/* Remove mix path mute if it is enabled */
2321 		if ((snd_soc_component_read32(comp,
2322 					WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) &
2323 					WCD9335_CDC_RX_PGA_MUTE_EN_MASK)
2324 			snd_soc_component_update_bits(comp,
2325 					    WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
2326 					    WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
2327 					    WCD9335_CDC_RX_PGA_MUTE_DISABLE);
2328 
2329 		break;
2330 	case SND_SOC_DAPM_PRE_PMD:
2331 		wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event);
2332 		break;
2333 	case SND_SOC_DAPM_POST_PMD:
2334 		/* 5ms sleep is required after PA is disabled as per
2335 		 * HW requirement
2336 		 */
2337 		usleep_range(5000, 5500);
2338 		break;
2339 	};
2340 
2341 	return ret;
2342 }
2343 
2344 static int wcd9335_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w,
2345 					 struct snd_kcontrol *kc,
2346 					 int event)
2347 {
2348 	struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
2349 	int vol_reg = 0, mix_vol_reg = 0;
2350 	int ret = 0;
2351 
2352 	if (w->reg == WCD9335_ANA_LO_1_2) {
2353 		if (w->shift == 7) {
2354 			vol_reg = WCD9335_CDC_RX3_RX_PATH_CTL;
2355 			mix_vol_reg = WCD9335_CDC_RX3_RX_PATH_MIX_CTL;
2356 		} else if (w->shift == 6) {
2357 			vol_reg = WCD9335_CDC_RX4_RX_PATH_CTL;
2358 			mix_vol_reg = WCD9335_CDC_RX4_RX_PATH_MIX_CTL;
2359 		}
2360 	} else if (w->reg == WCD9335_ANA_LO_3_4) {
2361 		if (w->shift == 7) {
2362 			vol_reg = WCD9335_CDC_RX5_RX_PATH_CTL;
2363 			mix_vol_reg = WCD9335_CDC_RX5_RX_PATH_MIX_CTL;
2364 		} else if (w->shift == 6) {
2365 			vol_reg = WCD9335_CDC_RX6_RX_PATH_CTL;
2366 			mix_vol_reg = WCD9335_CDC_RX6_RX_PATH_MIX_CTL;
2367 		}
2368 	} else {
2369 		dev_err(comp->dev, "Error enabling lineout PA\n");
2370 		return -EINVAL;
2371 	}
2372 
2373 	switch (event) {
2374 	case SND_SOC_DAPM_POST_PMU:
2375 		/* 5ms sleep is required after PA is enabled as per
2376 		 * HW requirement
2377 		 */
2378 		usleep_range(5000, 5500);
2379 		snd_soc_component_update_bits(comp, vol_reg,
2380 					WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
2381 					WCD9335_CDC_RX_PGA_MUTE_DISABLE);
2382 
2383 		/* Remove mix path mute if it is enabled */
2384 		if ((snd_soc_component_read32(comp, mix_vol_reg)) &
2385 					WCD9335_CDC_RX_PGA_MUTE_EN_MASK)
2386 			snd_soc_component_update_bits(comp,  mix_vol_reg,
2387 					WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
2388 					WCD9335_CDC_RX_PGA_MUTE_DISABLE);
2389 		break;
2390 	case SND_SOC_DAPM_POST_PMD:
2391 		/* 5ms sleep is required after PA is disabled as per
2392 		 * HW requirement
2393 		 */
2394 		usleep_range(5000, 5500);
2395 		break;
2396 	};
2397 
2398 	return ret;
2399 }
2400 
2401 static void wcd9335_codec_init_flyback(struct snd_soc_component *component)
2402 {
2403 	snd_soc_component_update_bits(component, WCD9335_HPH_L_EN,
2404 					WCD9335_HPH_CONST_SEL_L_MASK,
2405 					WCD9335_HPH_CONST_SEL_L_BYPASS);
2406 	snd_soc_component_update_bits(component, WCD9335_HPH_R_EN,
2407 					WCD9335_HPH_CONST_SEL_L_MASK,
2408 					WCD9335_HPH_CONST_SEL_L_BYPASS);
2409 	snd_soc_component_update_bits(component, WCD9335_RX_BIAS_FLYB_BUFF,
2410 					WCD9335_RX_BIAS_FLYB_VPOS_5_UA_MASK,
2411 					WCD9335_RX_BIAS_FLYB_I_0P0_UA);
2412 	snd_soc_component_update_bits(component, WCD9335_RX_BIAS_FLYB_BUFF,
2413 					WCD9335_RX_BIAS_FLYB_VNEG_5_UA_MASK,
2414 					WCD9335_RX_BIAS_FLYB_I_0P0_UA);
2415 }
2416 
2417 static int wcd9335_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
2418 		struct snd_kcontrol *kc, int event)
2419 {
2420 	struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
2421 	struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
2422 
2423 	switch (event) {
2424 	case SND_SOC_DAPM_PRE_PMU:
2425 		wcd->rx_bias_count++;
2426 		if (wcd->rx_bias_count == 1) {
2427 			wcd9335_codec_init_flyback(comp);
2428 			snd_soc_component_update_bits(comp,
2429 						WCD9335_ANA_RX_SUPPLIES,
2430 						WCD9335_ANA_RX_BIAS_ENABLE_MASK,
2431 						WCD9335_ANA_RX_BIAS_ENABLE);
2432 		}
2433 		break;
2434 	case SND_SOC_DAPM_POST_PMD:
2435 		wcd->rx_bias_count--;
2436 		if (!wcd->rx_bias_count)
2437 			snd_soc_component_update_bits(comp,
2438 					WCD9335_ANA_RX_SUPPLIES,
2439 					WCD9335_ANA_RX_BIAS_ENABLE_MASK,
2440 					WCD9335_ANA_RX_BIAS_DISABLE);
2441 		break;
2442 	};
2443 
2444 	return 0;
2445 }
2446 
2447 static int wcd9335_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
2448 					struct snd_kcontrol *kc, int event)
2449 {
2450 	struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
2451 	struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
2452 	int hph_mode = wcd->hph_mode;
2453 	int ret = 0;
2454 
2455 	switch (event) {
2456 	case SND_SOC_DAPM_PRE_PMU:
2457 		break;
2458 	case SND_SOC_DAPM_POST_PMU:
2459 		/*
2460 		 * 7ms sleep is required after PA is enabled as per
2461 		 * HW requirement
2462 		 */
2463 		usleep_range(7000, 7100);
2464 		wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event);
2465 		snd_soc_component_update_bits(comp,
2466 					WCD9335_CDC_RX2_RX_PATH_CTL,
2467 					WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
2468 					WCD9335_CDC_RX_PGA_MUTE_DISABLE);
2469 		/* Remove mix path mute if it is enabled */
2470 		if ((snd_soc_component_read32(comp,
2471 					WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) &
2472 					WCD9335_CDC_RX_PGA_MUTE_EN_MASK)
2473 			snd_soc_component_update_bits(comp,
2474 					WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
2475 					WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
2476 					WCD9335_CDC_RX_PGA_MUTE_DISABLE);
2477 
2478 		break;
2479 
2480 	case SND_SOC_DAPM_PRE_PMD:
2481 		wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event);
2482 		break;
2483 	case SND_SOC_DAPM_POST_PMD:
2484 		/* 5ms sleep is required after PA is disabled as per
2485 		 * HW requirement
2486 		 */
2487 		usleep_range(5000, 5500);
2488 		break;
2489 	};
2490 
2491 	return ret;
2492 }
2493 
2494 static int wcd9335_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
2495 				       struct snd_kcontrol *kc, int event)
2496 {
2497 	struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
2498 	int ret = 0;
2499 
2500 	switch (event) {
2501 	case SND_SOC_DAPM_POST_PMU:
2502 		/* 5ms sleep is required after PA is enabled as per
2503 		 * HW requirement
2504 		 */
2505 		usleep_range(5000, 5500);
2506 		snd_soc_component_update_bits(comp,
2507 					WCD9335_CDC_RX0_RX_PATH_CTL,
2508 					WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
2509 					WCD9335_CDC_RX_PGA_MUTE_DISABLE);
2510 		/* Remove mix path mute if it is enabled */
2511 		if ((snd_soc_component_read32(comp,
2512 					WCD9335_CDC_RX0_RX_PATH_MIX_CTL)) &
2513 					WCD9335_CDC_RX_PGA_MUTE_EN_MASK)
2514 			snd_soc_component_update_bits(comp,
2515 					WCD9335_CDC_RX0_RX_PATH_MIX_CTL,
2516 					WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
2517 					WCD9335_CDC_RX_PGA_MUTE_DISABLE);
2518 		break;
2519 	case SND_SOC_DAPM_POST_PMD:
2520 		/* 5ms sleep is required after PA is disabled as per
2521 		 * HW requirement
2522 		 */
2523 		usleep_range(5000, 5500);
2524 
2525 		break;
2526 	};
2527 
2528 	return ret;
2529 }
2530 
2531 static irqreturn_t wcd9335_slimbus_irq(int irq, void *data)
2532 {
2533 	struct wcd9335_codec *wcd = data;
2534 	unsigned long status = 0;
2535 	int i, j, port_id;
2536 	unsigned int val, int_val = 0;
2537 	irqreturn_t ret = IRQ_NONE;
2538 	bool tx;
2539 	unsigned short reg = 0;
2540 
2541 	for (i = WCD9335_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0;
2542 	     i <= WCD9335_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) {
2543 		regmap_read(wcd->if_regmap, i, &val);
2544 		status |= ((u32)val << (8 * j));
2545 	}
2546 
2547 	for_each_set_bit(j, &status, 32) {
2548 		tx = (j >= 16 ? true : false);
2549 		port_id = (tx ? j - 16 : j);
2550 		regmap_read(wcd->if_regmap,
2551 				WCD9335_SLIM_PGD_PORT_INT_RX_SOURCE0 + j, &val);
2552 		if (val) {
2553 			if (!tx)
2554 				reg = WCD9335_SLIM_PGD_PORT_INT_EN0 +
2555 					(port_id / 8);
2556 			else
2557 				reg = WCD9335_SLIM_PGD_PORT_INT_TX_EN0 +
2558 					(port_id / 8);
2559 			regmap_read(
2560 				wcd->if_regmap, reg, &int_val);
2561 			/*
2562 			 * Ignore interrupts for ports for which the
2563 			 * interrupts are not specifically enabled.
2564 			 */
2565 			if (!(int_val & (1 << (port_id % 8))))
2566 				continue;
2567 		}
2568 
2569 		if (val & WCD9335_SLIM_IRQ_OVERFLOW)
2570 			dev_err_ratelimited(wcd->dev,
2571 			   "%s: overflow error on %s port %d, value %x\n",
2572 			   __func__, (tx ? "TX" : "RX"), port_id, val);
2573 
2574 		if (val & WCD9335_SLIM_IRQ_UNDERFLOW)
2575 			dev_err_ratelimited(wcd->dev,
2576 			   "%s: underflow error on %s port %d, value %x\n",
2577 			   __func__, (tx ? "TX" : "RX"), port_id, val);
2578 
2579 		if ((val & WCD9335_SLIM_IRQ_OVERFLOW) ||
2580 			(val & WCD9335_SLIM_IRQ_UNDERFLOW)) {
2581 			if (!tx)
2582 				reg = WCD9335_SLIM_PGD_PORT_INT_EN0 +
2583 					(port_id / 8);
2584 			else
2585 				reg = WCD9335_SLIM_PGD_PORT_INT_TX_EN0 +
2586 					(port_id / 8);
2587 			regmap_read(
2588 				wcd->if_regmap, reg, &int_val);
2589 			if (int_val & (1 << (port_id % 8))) {
2590 				int_val = int_val ^ (1 << (port_id % 8));
2591 				regmap_write(wcd->if_regmap,
2592 					reg, int_val);
2593 			}
2594 		}
2595 
2596 		regmap_write(wcd->if_regmap,
2597 				WCD9335_SLIM_PGD_PORT_INT_CLR_RX_0 + (j / 8),
2598 				BIT(j % 8));
2599 		ret = IRQ_HANDLED;
2600 	}
2601 
2602 	return ret;
2603 }
2604 
2605 static struct wcd9335_irq wcd9335_irqs[] = {
2606 	{
2607 		.irq = WCD9335_IRQ_SLIMBUS,
2608 		.handler = wcd9335_slimbus_irq,
2609 		.name = "SLIM Slave",
2610 	},
2611 };
2612 
2613 static int wcd9335_setup_irqs(struct wcd9335_codec *wcd)
2614 {
2615 	int irq, ret, i;
2616 
2617 	for (i = 0; i < ARRAY_SIZE(wcd9335_irqs); i++) {
2618 		irq = regmap_irq_get_virq(wcd->irq_data, wcd9335_irqs[i].irq);
2619 		if (irq < 0) {
2620 			dev_err(wcd->dev, "Failed to get %s\n",
2621 					wcd9335_irqs[i].name);
2622 			return irq;
2623 		}
2624 
2625 		ret = devm_request_threaded_irq(wcd->dev, irq, NULL,
2626 						wcd9335_irqs[i].handler,
2627 						IRQF_TRIGGER_RISING,
2628 						wcd9335_irqs[i].name, wcd);
2629 		if (ret) {
2630 			dev_err(wcd->dev, "Failed to request %s\n",
2631 					wcd9335_irqs[i].name);
2632 			return ret;
2633 		}
2634 	}
2635 
2636 	/* enable interrupts on all slave ports */
2637 	for (i = 0; i < WCD9335_SLIM_NUM_PORT_REG; i++)
2638 		regmap_write(wcd->if_regmap, WCD9335_SLIM_PGD_PORT_INT_EN0 + i,
2639 			     0xFF);
2640 
2641 	return ret;
2642 }
2643 
2644 static void wcd9335_cdc_sido_ccl_enable(struct wcd9335_codec *wcd,
2645 					bool ccl_flag)
2646 {
2647 	struct snd_soc_component *comp = wcd->component;
2648 
2649 	if (ccl_flag) {
2650 		if (++wcd->sido_ccl_cnt == 1)
2651 			snd_soc_component_write(comp, WCD9335_SIDO_SIDO_CCL_10,
2652 					WCD9335_SIDO_SIDO_CCL_DEF_VALUE);
2653 	} else {
2654 		if (wcd->sido_ccl_cnt == 0) {
2655 			dev_err(wcd->dev, "sido_ccl already disabled\n");
2656 			return;
2657 		}
2658 		if (--wcd->sido_ccl_cnt == 0)
2659 			snd_soc_component_write(comp, WCD9335_SIDO_SIDO_CCL_10,
2660 				WCD9335_SIDO_SIDO_CCL_10_ICHARG_PWR_SEL_C320FF);
2661 	}
2662 }
2663 
2664 static int wcd9335_enable_master_bias(struct wcd9335_codec *wcd)
2665 {
2666 	wcd->master_bias_users++;
2667 	if (wcd->master_bias_users == 1) {
2668 		regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS,
2669 					WCD9335_ANA_BIAS_EN_MASK,
2670 					WCD9335_ANA_BIAS_ENABLE);
2671 		regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS,
2672 					WCD9335_ANA_BIAS_PRECHRG_EN_MASK,
2673 					WCD9335_ANA_BIAS_PRECHRG_ENABLE);
2674 		/*
2675 		 * 1ms delay is required after pre-charge is enabled
2676 		 * as per HW requirement
2677 		 */
2678 		usleep_range(1000, 1100);
2679 		regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS,
2680 					WCD9335_ANA_BIAS_PRECHRG_EN_MASK,
2681 					WCD9335_ANA_BIAS_PRECHRG_DISABLE);
2682 		regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS,
2683 				WCD9335_ANA_BIAS_PRECHRG_CTL_MODE,
2684 				WCD9335_ANA_BIAS_PRECHRG_CTL_MODE_MANUAL);
2685 	}
2686 
2687 	return 0;
2688 }
2689 
2690 static int wcd9335_enable_mclk(struct wcd9335_codec *wcd)
2691 {
2692 	/* Enable mclk requires master bias to be enabled first */
2693 	if (wcd->master_bias_users <= 0)
2694 		return -EINVAL;
2695 
2696 	if (((wcd->clk_mclk_users == 0) && (wcd->clk_type == WCD_CLK_MCLK)) ||
2697 	    ((wcd->clk_mclk_users > 0) && (wcd->clk_type != WCD_CLK_MCLK))) {
2698 		dev_err(wcd->dev, "Error enabling MCLK, clk_type: %d\n",
2699 			wcd->clk_type);
2700 		return -EINVAL;
2701 	}
2702 
2703 	if (++wcd->clk_mclk_users == 1) {
2704 		regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP,
2705 					WCD9335_ANA_CLK_EXT_CLKBUF_EN_MASK,
2706 					WCD9335_ANA_CLK_EXT_CLKBUF_ENABLE);
2707 		regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP,
2708 					WCD9335_ANA_CLK_MCLK_SRC_MASK,
2709 					WCD9335_ANA_CLK_MCLK_SRC_EXTERNAL);
2710 		regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP,
2711 					WCD9335_ANA_CLK_MCLK_EN_MASK,
2712 					WCD9335_ANA_CLK_MCLK_ENABLE);
2713 		regmap_update_bits(wcd->regmap,
2714 				   WCD9335_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
2715 				   WCD9335_CDC_CLK_RST_CTRL_FS_CNT_EN_MASK,
2716 				   WCD9335_CDC_CLK_RST_CTRL_FS_CNT_ENABLE);
2717 		regmap_update_bits(wcd->regmap,
2718 				   WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL,
2719 				   WCD9335_CDC_CLK_RST_CTRL_MCLK_EN_MASK,
2720 				   WCD9335_CDC_CLK_RST_CTRL_MCLK_ENABLE);
2721 		/*
2722 		 * 10us sleep is required after clock is enabled
2723 		 * as per HW requirement
2724 		 */
2725 		usleep_range(10, 15);
2726 	}
2727 
2728 	wcd->clk_type = WCD_CLK_MCLK;
2729 
2730 	return 0;
2731 }
2732 
2733 static int wcd9335_disable_mclk(struct wcd9335_codec *wcd)
2734 {
2735 	if (wcd->clk_mclk_users <= 0)
2736 		return -EINVAL;
2737 
2738 	if (--wcd->clk_mclk_users == 0) {
2739 		if (wcd->clk_rco_users > 0) {
2740 			/* MCLK to RCO switch */
2741 			regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP,
2742 					WCD9335_ANA_CLK_MCLK_SRC_MASK,
2743 					WCD9335_ANA_CLK_MCLK_SRC_RCO);
2744 			wcd->clk_type = WCD_CLK_RCO;
2745 		} else {
2746 			regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP,
2747 					WCD9335_ANA_CLK_MCLK_EN_MASK,
2748 					WCD9335_ANA_CLK_MCLK_DISABLE);
2749 			wcd->clk_type = WCD_CLK_OFF;
2750 		}
2751 
2752 		regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP,
2753 					WCD9335_ANA_CLK_EXT_CLKBUF_EN_MASK,
2754 					WCD9335_ANA_CLK_EXT_CLKBUF_DISABLE);
2755 	}
2756 
2757 	return 0;
2758 }
2759 
2760 static int wcd9335_disable_master_bias(struct wcd9335_codec *wcd)
2761 {
2762 	if (wcd->master_bias_users <= 0)
2763 		return -EINVAL;
2764 
2765 	wcd->master_bias_users--;
2766 	if (wcd->master_bias_users == 0) {
2767 		regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS,
2768 				WCD9335_ANA_BIAS_EN_MASK,
2769 				WCD9335_ANA_BIAS_DISABLE);
2770 		regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS,
2771 				WCD9335_ANA_BIAS_PRECHRG_CTL_MODE,
2772 				WCD9335_ANA_BIAS_PRECHRG_CTL_MODE_MANUAL);
2773 	}
2774 	return 0;
2775 }
2776 
2777 static int wcd9335_cdc_req_mclk_enable(struct wcd9335_codec *wcd,
2778 				     bool enable)
2779 {
2780 	int ret = 0;
2781 
2782 	if (enable) {
2783 		wcd9335_cdc_sido_ccl_enable(wcd, true);
2784 		ret = clk_prepare_enable(wcd->mclk);
2785 		if (ret) {
2786 			dev_err(wcd->dev, "%s: ext clk enable failed\n",
2787 				__func__);
2788 			goto err;
2789 		}
2790 		/* get BG */
2791 		wcd9335_enable_master_bias(wcd);
2792 		/* get MCLK */
2793 		wcd9335_enable_mclk(wcd);
2794 
2795 	} else {
2796 		/* put MCLK */
2797 		wcd9335_disable_mclk(wcd);
2798 		/* put BG */
2799 		wcd9335_disable_master_bias(wcd);
2800 		clk_disable_unprepare(wcd->mclk);
2801 		wcd9335_cdc_sido_ccl_enable(wcd, false);
2802 	}
2803 err:
2804 	return ret;
2805 }
2806 
2807 static void wcd9335_codec_apply_sido_voltage(struct wcd9335_codec *wcd,
2808 					     enum wcd9335_sido_voltage req_mv)
2809 {
2810 	struct snd_soc_component *comp = wcd->component;
2811 	int vout_d_val;
2812 
2813 	if (req_mv == wcd->sido_voltage)
2814 		return;
2815 
2816 	/* compute the vout_d step value */
2817 	vout_d_val = WCD9335_CALCULATE_VOUT_D(req_mv) &
2818 			WCD9335_ANA_BUCK_VOUT_MASK;
2819 	snd_soc_component_write(comp, WCD9335_ANA_BUCK_VOUT_D, vout_d_val);
2820 	snd_soc_component_update_bits(comp, WCD9335_ANA_BUCK_CTL,
2821 				WCD9335_ANA_BUCK_CTL_RAMP_START_MASK,
2822 				WCD9335_ANA_BUCK_CTL_RAMP_START_ENABLE);
2823 
2824 	/* 1 msec sleep required after SIDO Vout_D voltage change */
2825 	usleep_range(1000, 1100);
2826 	wcd->sido_voltage = req_mv;
2827 	snd_soc_component_update_bits(comp, WCD9335_ANA_BUCK_CTL,
2828 				WCD9335_ANA_BUCK_CTL_RAMP_START_MASK,
2829 				WCD9335_ANA_BUCK_CTL_RAMP_START_DISABLE);
2830 }
2831 
2832 static int wcd9335_codec_update_sido_voltage(struct wcd9335_codec *wcd,
2833 					     enum wcd9335_sido_voltage req_mv)
2834 {
2835 	int ret = 0;
2836 
2837 	/* enable mclk before setting SIDO voltage */
2838 	ret = wcd9335_cdc_req_mclk_enable(wcd, true);
2839 	if (ret) {
2840 		dev_err(wcd->dev, "Ext clk enable failed\n");
2841 		goto err;
2842 	}
2843 
2844 	wcd9335_codec_apply_sido_voltage(wcd, req_mv);
2845 	wcd9335_cdc_req_mclk_enable(wcd, false);
2846 
2847 err:
2848 	return ret;
2849 }
2850 
2851 static int _wcd9335_codec_enable_mclk(struct snd_soc_component *component,
2852 				      int enable)
2853 {
2854 	struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
2855 	int ret;
2856 
2857 	if (enable) {
2858 		ret = wcd9335_cdc_req_mclk_enable(wcd, true);
2859 		if (ret)
2860 			return ret;
2861 
2862 		wcd9335_codec_apply_sido_voltage(wcd,
2863 				SIDO_VOLTAGE_NOMINAL_MV);
2864 	} else {
2865 		wcd9335_codec_update_sido_voltage(wcd,
2866 					wcd->sido_voltage);
2867 		wcd9335_cdc_req_mclk_enable(wcd, false);
2868 	}
2869 
2870 	return 0;
2871 }
2872 
2873 static int wcd9335_codec_enable_mclk(struct snd_soc_dapm_widget *w,
2874 				     struct snd_kcontrol *kc, int event)
2875 {
2876 	struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
2877 
2878 	switch (event) {
2879 	case SND_SOC_DAPM_PRE_PMU:
2880 		return _wcd9335_codec_enable_mclk(comp, true);
2881 	case SND_SOC_DAPM_POST_PMD:
2882 		return _wcd9335_codec_enable_mclk(comp, false);
2883 	}
2884 
2885 	return 0;
2886 }
2887 
2888 static const struct snd_soc_dapm_widget wcd9335_dapm_widgets[] = {
2889 	/* TODO SPK1 & SPK2 OUT*/
2890 	SND_SOC_DAPM_OUTPUT("EAR"),
2891 	SND_SOC_DAPM_OUTPUT("HPHL"),
2892 	SND_SOC_DAPM_OUTPUT("HPHR"),
2893 	SND_SOC_DAPM_OUTPUT("LINEOUT1"),
2894 	SND_SOC_DAPM_OUTPUT("LINEOUT2"),
2895 	SND_SOC_DAPM_OUTPUT("LINEOUT3"),
2896 	SND_SOC_DAPM_OUTPUT("LINEOUT4"),
2897 	SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
2898 				AIF1_PB, 0, wcd9335_codec_enable_slim,
2899 				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2900 	SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM,
2901 				AIF2_PB, 0, wcd9335_codec_enable_slim,
2902 				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2903 	SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM,
2904 				AIF3_PB, 0, wcd9335_codec_enable_slim,
2905 				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2906 	SND_SOC_DAPM_AIF_IN_E("AIF4 PB", "AIF4 Playback", 0, SND_SOC_NOPM,
2907 				AIF4_PB, 0, wcd9335_codec_enable_slim,
2908 				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2909 	SND_SOC_DAPM_MUX("SLIM RX0 MUX", SND_SOC_NOPM, WCD9335_RX0, 0,
2910 				&slim_rx_mux[WCD9335_RX0]),
2911 	SND_SOC_DAPM_MUX("SLIM RX1 MUX", SND_SOC_NOPM, WCD9335_RX1, 0,
2912 				&slim_rx_mux[WCD9335_RX1]),
2913 	SND_SOC_DAPM_MUX("SLIM RX2 MUX", SND_SOC_NOPM, WCD9335_RX2, 0,
2914 				&slim_rx_mux[WCD9335_RX2]),
2915 	SND_SOC_DAPM_MUX("SLIM RX3 MUX", SND_SOC_NOPM, WCD9335_RX3, 0,
2916 				&slim_rx_mux[WCD9335_RX3]),
2917 	SND_SOC_DAPM_MUX("SLIM RX4 MUX", SND_SOC_NOPM, WCD9335_RX4, 0,
2918 				&slim_rx_mux[WCD9335_RX4]),
2919 	SND_SOC_DAPM_MUX("SLIM RX5 MUX", SND_SOC_NOPM, WCD9335_RX5, 0,
2920 				&slim_rx_mux[WCD9335_RX5]),
2921 	SND_SOC_DAPM_MUX("SLIM RX6 MUX", SND_SOC_NOPM, WCD9335_RX6, 0,
2922 				&slim_rx_mux[WCD9335_RX6]),
2923 	SND_SOC_DAPM_MUX("SLIM RX7 MUX", SND_SOC_NOPM, WCD9335_RX7, 0,
2924 				&slim_rx_mux[WCD9335_RX7]),
2925 	SND_SOC_DAPM_MIXER("SLIM RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2926 	SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2927 	SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
2928 	SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
2929 	SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
2930 	SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
2931 	SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0),
2932 	SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0),
2933 	SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", WCD9335_CDC_RX0_RX_PATH_MIX_CTL,
2934 			5, 0, &rx_int0_2_mux, wcd9335_codec_enable_mix_path,
2935 			SND_SOC_DAPM_POST_PMU),
2936 	SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
2937 			5, 0, &rx_int1_2_mux, wcd9335_codec_enable_mix_path,
2938 			SND_SOC_DAPM_POST_PMU),
2939 	SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
2940 			5, 0, &rx_int2_2_mux, wcd9335_codec_enable_mix_path,
2941 			SND_SOC_DAPM_POST_PMU),
2942 	SND_SOC_DAPM_MUX_E("RX INT3_2 MUX", WCD9335_CDC_RX3_RX_PATH_MIX_CTL,
2943 			5, 0, &rx_int3_2_mux, wcd9335_codec_enable_mix_path,
2944 			SND_SOC_DAPM_POST_PMU),
2945 	SND_SOC_DAPM_MUX_E("RX INT4_2 MUX", WCD9335_CDC_RX4_RX_PATH_MIX_CTL,
2946 			5, 0, &rx_int4_2_mux, wcd9335_codec_enable_mix_path,
2947 			SND_SOC_DAPM_POST_PMU),
2948 	SND_SOC_DAPM_MUX_E("RX INT5_2 MUX", WCD9335_CDC_RX5_RX_PATH_MIX_CTL,
2949 			5, 0, &rx_int5_2_mux, wcd9335_codec_enable_mix_path,
2950 			SND_SOC_DAPM_POST_PMU),
2951 	SND_SOC_DAPM_MUX_E("RX INT6_2 MUX", WCD9335_CDC_RX6_RX_PATH_MIX_CTL,
2952 			5, 0, &rx_int6_2_mux, wcd9335_codec_enable_mix_path,
2953 			SND_SOC_DAPM_POST_PMU),
2954 	SND_SOC_DAPM_MUX_E("RX INT7_2 MUX", WCD9335_CDC_RX7_RX_PATH_MIX_CTL,
2955 			5, 0, &rx_int7_2_mux, wcd9335_codec_enable_mix_path,
2956 			SND_SOC_DAPM_POST_PMU),
2957 	SND_SOC_DAPM_MUX_E("RX INT8_2 MUX", WCD9335_CDC_RX8_RX_PATH_MIX_CTL,
2958 			5, 0, &rx_int8_2_mux, wcd9335_codec_enable_mix_path,
2959 			SND_SOC_DAPM_POST_PMU),
2960 	SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
2961 		&rx_int0_1_mix_inp0_mux),
2962 	SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
2963 		&rx_int0_1_mix_inp1_mux),
2964 	SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
2965 		&rx_int0_1_mix_inp2_mux),
2966 	SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
2967 		&rx_int1_1_mix_inp0_mux),
2968 	SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
2969 		&rx_int1_1_mix_inp1_mux),
2970 	SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
2971 		&rx_int1_1_mix_inp2_mux),
2972 	SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
2973 		&rx_int2_1_mix_inp0_mux),
2974 	SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
2975 		&rx_int2_1_mix_inp1_mux),
2976 	SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
2977 		&rx_int2_1_mix_inp2_mux),
2978 	SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
2979 		&rx_int3_1_mix_inp0_mux),
2980 	SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
2981 		&rx_int3_1_mix_inp1_mux),
2982 	SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
2983 		&rx_int3_1_mix_inp2_mux),
2984 	SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
2985 		&rx_int4_1_mix_inp0_mux),
2986 	SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
2987 		&rx_int4_1_mix_inp1_mux),
2988 	SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
2989 		&rx_int4_1_mix_inp2_mux),
2990 	SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
2991 		&rx_int5_1_mix_inp0_mux),
2992 	SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
2993 		&rx_int5_1_mix_inp1_mux),
2994 	SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
2995 		&rx_int5_1_mix_inp2_mux),
2996 	SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
2997 		&rx_int6_1_mix_inp0_mux),
2998 	SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
2999 		&rx_int6_1_mix_inp1_mux),
3000 	SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
3001 		&rx_int6_1_mix_inp2_mux),
3002 	SND_SOC_DAPM_MUX("RX INT7_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
3003 		&rx_int7_1_mix_inp0_mux),
3004 	SND_SOC_DAPM_MUX("RX INT7_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
3005 		&rx_int7_1_mix_inp1_mux),
3006 	SND_SOC_DAPM_MUX("RX INT7_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
3007 		&rx_int7_1_mix_inp2_mux),
3008 	SND_SOC_DAPM_MUX("RX INT8_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
3009 		&rx_int8_1_mix_inp0_mux),
3010 	SND_SOC_DAPM_MUX("RX INT8_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
3011 		&rx_int8_1_mix_inp1_mux),
3012 	SND_SOC_DAPM_MUX("RX INT8_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
3013 		&rx_int8_1_mix_inp2_mux),
3014 
3015 	SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
3016 	SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
3017 	SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
3018 	SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
3019 	SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
3020 	SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
3021 	SND_SOC_DAPM_MIXER("RX INT3_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
3022 	SND_SOC_DAPM_MIXER("RX INT3 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
3023 	SND_SOC_DAPM_MIXER("RX INT4_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
3024 	SND_SOC_DAPM_MIXER("RX INT4 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
3025 	SND_SOC_DAPM_MIXER("RX INT5_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
3026 	SND_SOC_DAPM_MIXER("RX INT5 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
3027 	SND_SOC_DAPM_MIXER("RX INT6_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
3028 	SND_SOC_DAPM_MIXER("RX INT6 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
3029 	SND_SOC_DAPM_MIXER("RX INT7_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
3030 	SND_SOC_DAPM_MIXER("RX INT7 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
3031 	SND_SOC_DAPM_MIXER("RX INT8_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
3032 	SND_SOC_DAPM_MIXER("RX INT8 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
3033 
3034 	SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
3035 	SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
3036 	SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
3037 	SND_SOC_DAPM_MIXER("RX INT3 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
3038 	SND_SOC_DAPM_MIXER("RX INT4 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
3039 	SND_SOC_DAPM_MIXER("RX INT5 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
3040 	SND_SOC_DAPM_MIXER("RX INT6 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
3041 	SND_SOC_DAPM_MIXER("RX INT7 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
3042 	SND_SOC_DAPM_MIXER("RX INT8 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
3043 
3044 	SND_SOC_DAPM_MUX("RX INT0 DEM MUX", SND_SOC_NOPM, 0, 0,
3045 		&rx_int0_dem_inp_mux),
3046 	SND_SOC_DAPM_MUX("RX INT1 DEM MUX", SND_SOC_NOPM, 0, 0,
3047 		&rx_int1_dem_inp_mux),
3048 	SND_SOC_DAPM_MUX("RX INT2 DEM MUX", SND_SOC_NOPM, 0, 0,
3049 		&rx_int2_dem_inp_mux),
3050 
3051 	SND_SOC_DAPM_MUX_E("RX INT0 INTERP", SND_SOC_NOPM,
3052 		INTERP_EAR, 0, &rx_int0_interp_mux,
3053 		wcd9335_codec_enable_interpolator,
3054 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3055 		SND_SOC_DAPM_POST_PMD),
3056 	SND_SOC_DAPM_MUX_E("RX INT1 INTERP", SND_SOC_NOPM,
3057 		INTERP_HPHL, 0, &rx_int1_interp_mux,
3058 		wcd9335_codec_enable_interpolator,
3059 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3060 		SND_SOC_DAPM_POST_PMD),
3061 	SND_SOC_DAPM_MUX_E("RX INT2 INTERP", SND_SOC_NOPM,
3062 		INTERP_HPHR, 0, &rx_int2_interp_mux,
3063 		wcd9335_codec_enable_interpolator,
3064 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3065 		SND_SOC_DAPM_POST_PMD),
3066 	SND_SOC_DAPM_MUX_E("RX INT3 INTERP", SND_SOC_NOPM,
3067 		INTERP_LO1, 0, &rx_int3_interp_mux,
3068 		wcd9335_codec_enable_interpolator,
3069 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3070 		SND_SOC_DAPM_POST_PMD),
3071 	SND_SOC_DAPM_MUX_E("RX INT4 INTERP", SND_SOC_NOPM,
3072 		INTERP_LO2, 0, &rx_int4_interp_mux,
3073 		wcd9335_codec_enable_interpolator,
3074 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3075 		SND_SOC_DAPM_POST_PMD),
3076 	SND_SOC_DAPM_MUX_E("RX INT5 INTERP", SND_SOC_NOPM,
3077 		INTERP_LO3, 0, &rx_int5_interp_mux,
3078 		wcd9335_codec_enable_interpolator,
3079 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3080 		SND_SOC_DAPM_POST_PMD),
3081 	SND_SOC_DAPM_MUX_E("RX INT6 INTERP", SND_SOC_NOPM,
3082 		INTERP_LO4, 0, &rx_int6_interp_mux,
3083 		wcd9335_codec_enable_interpolator,
3084 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3085 		SND_SOC_DAPM_POST_PMD),
3086 	SND_SOC_DAPM_MUX_E("RX INT7 INTERP", SND_SOC_NOPM,
3087 		INTERP_SPKR1, 0, &rx_int7_interp_mux,
3088 		wcd9335_codec_enable_interpolator,
3089 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3090 		SND_SOC_DAPM_POST_PMD),
3091 	SND_SOC_DAPM_MUX_E("RX INT8 INTERP", SND_SOC_NOPM,
3092 		INTERP_SPKR2, 0, &rx_int8_interp_mux,
3093 		wcd9335_codec_enable_interpolator,
3094 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3095 		SND_SOC_DAPM_POST_PMD),
3096 
3097 	SND_SOC_DAPM_DAC_E("RX INT0 DAC", NULL, SND_SOC_NOPM,
3098 		0, 0, wcd9335_codec_ear_dac_event,
3099 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3100 		SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3101 	SND_SOC_DAPM_DAC_E("RX INT1 DAC", NULL, WCD9335_ANA_HPH,
3102 		5, 0, wcd9335_codec_hphl_dac_event,
3103 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3104 		SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3105 	SND_SOC_DAPM_DAC_E("RX INT2 DAC", NULL, WCD9335_ANA_HPH,
3106 		4, 0, wcd9335_codec_hphr_dac_event,
3107 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3108 		SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3109 	SND_SOC_DAPM_DAC_E("RX INT3 DAC", NULL, SND_SOC_NOPM,
3110 		0, 0, wcd9335_codec_lineout_dac_event,
3111 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
3112 	SND_SOC_DAPM_DAC_E("RX INT4 DAC", NULL, SND_SOC_NOPM,
3113 		0, 0, wcd9335_codec_lineout_dac_event,
3114 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
3115 	SND_SOC_DAPM_DAC_E("RX INT5 DAC", NULL, SND_SOC_NOPM,
3116 		0, 0, wcd9335_codec_lineout_dac_event,
3117 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
3118 	SND_SOC_DAPM_DAC_E("RX INT6 DAC", NULL, SND_SOC_NOPM,
3119 		0, 0, wcd9335_codec_lineout_dac_event,
3120 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
3121 	SND_SOC_DAPM_PGA_E("HPHL PA", WCD9335_ANA_HPH, 7, 0, NULL, 0,
3122 			   wcd9335_codec_enable_hphl_pa,
3123 			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3124 			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3125 	SND_SOC_DAPM_PGA_E("HPHR PA", WCD9335_ANA_HPH, 6, 0, NULL, 0,
3126 			   wcd9335_codec_enable_hphr_pa,
3127 			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3128 			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
3129 	SND_SOC_DAPM_PGA_E("EAR PA", WCD9335_ANA_EAR, 7, 0, NULL, 0,
3130 			   wcd9335_codec_enable_ear_pa,
3131 			   SND_SOC_DAPM_POST_PMU |
3132 			   SND_SOC_DAPM_POST_PMD),
3133 	SND_SOC_DAPM_PGA_E("LINEOUT1 PA", WCD9335_ANA_LO_1_2, 7, 0, NULL, 0,
3134 			   wcd9335_codec_enable_lineout_pa,
3135 			   SND_SOC_DAPM_POST_PMU |
3136 			   SND_SOC_DAPM_POST_PMD),
3137 	SND_SOC_DAPM_PGA_E("LINEOUT2 PA", WCD9335_ANA_LO_1_2, 6, 0, NULL, 0,
3138 			   wcd9335_codec_enable_lineout_pa,
3139 			   SND_SOC_DAPM_POST_PMU |
3140 			   SND_SOC_DAPM_POST_PMD),
3141 	SND_SOC_DAPM_PGA_E("LINEOUT3 PA", WCD9335_ANA_LO_3_4, 7, 0, NULL, 0,
3142 			   wcd9335_codec_enable_lineout_pa,
3143 			   SND_SOC_DAPM_POST_PMU |
3144 			   SND_SOC_DAPM_POST_PMD),
3145 	SND_SOC_DAPM_PGA_E("LINEOUT4 PA", WCD9335_ANA_LO_3_4, 6, 0, NULL, 0,
3146 			   wcd9335_codec_enable_lineout_pa,
3147 			   SND_SOC_DAPM_POST_PMU |
3148 			   SND_SOC_DAPM_POST_PMD),
3149 	SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
3150 		wcd9335_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
3151 		SND_SOC_DAPM_POST_PMD),
3152 	SND_SOC_DAPM_SUPPLY("MCLK",  SND_SOC_NOPM, 0, 0,
3153 		wcd9335_codec_enable_mclk, SND_SOC_DAPM_PRE_PMU |
3154 		SND_SOC_DAPM_POST_PMD),
3155 
3156 };
3157 
3158 static void wcd9335_enable_sido_buck(struct snd_soc_component *component)
3159 {
3160 	struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
3161 
3162 	snd_soc_component_update_bits(component, WCD9335_ANA_RCO,
3163 					WCD9335_ANA_RCO_BG_EN_MASK,
3164 					WCD9335_ANA_RCO_BG_ENABLE);
3165 	snd_soc_component_update_bits(component, WCD9335_ANA_BUCK_CTL,
3166 					WCD9335_ANA_BUCK_CTL_VOUT_D_IREF_MASK,
3167 					WCD9335_ANA_BUCK_CTL_VOUT_D_IREF_EXT);
3168 	/* 100us sleep needed after IREF settings */
3169 	usleep_range(100, 110);
3170 	snd_soc_component_update_bits(component, WCD9335_ANA_BUCK_CTL,
3171 					WCD9335_ANA_BUCK_CTL_VOUT_D_VREF_MASK,
3172 					WCD9335_ANA_BUCK_CTL_VOUT_D_VREF_EXT);
3173 	/* 100us sleep needed after VREF settings */
3174 	usleep_range(100, 110);
3175 	wcd->sido_input_src = SIDO_SOURCE_RCO_BG;
3176 }
3177 
3178 static int wcd9335_enable_efuse_sensing(struct snd_soc_component *comp)
3179 {
3180 	_wcd9335_codec_enable_mclk(comp, true);
3181 	snd_soc_component_update_bits(comp,
3182 				WCD9335_CHIP_TIER_CTRL_EFUSE_CTL,
3183 				WCD9335_CHIP_TIER_CTRL_EFUSE_EN_MASK,
3184 				WCD9335_CHIP_TIER_CTRL_EFUSE_ENABLE);
3185 	/*
3186 	 * 5ms sleep required after enabling efuse control
3187 	 * before checking the status.
3188 	 */
3189 	usleep_range(5000, 5500);
3190 
3191 	if (!(snd_soc_component_read32(comp,
3192 					WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS) &
3193 					WCD9335_CHIP_TIER_CTRL_EFUSE_EN_MASK))
3194 		WARN(1, "%s: Efuse sense is not complete\n", __func__);
3195 
3196 	wcd9335_enable_sido_buck(comp);
3197 	_wcd9335_codec_enable_mclk(comp, false);
3198 
3199 	return 0;
3200 }
3201 
3202 static void wcd9335_codec_init(struct snd_soc_component *component)
3203 {
3204 	struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
3205 	int i;
3206 
3207 	/* ungate MCLK and set clk rate */
3208 	regmap_update_bits(wcd->regmap, WCD9335_CODEC_RPM_CLK_GATE,
3209 				WCD9335_CODEC_RPM_CLK_GATE_MCLK_GATE_MASK, 0);
3210 
3211 	regmap_update_bits(wcd->regmap, WCD9335_CODEC_RPM_CLK_MCLK_CFG,
3212 				WCD9335_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK,
3213 				WCD9335_CODEC_RPM_CLK_MCLK_CFG_9P6MHZ);
3214 
3215 	for (i = 0; i < ARRAY_SIZE(wcd9335_codec_reg_init); i++)
3216 		snd_soc_component_update_bits(component,
3217 					wcd9335_codec_reg_init[i].reg,
3218 					wcd9335_codec_reg_init[i].mask,
3219 					wcd9335_codec_reg_init[i].val);
3220 
3221 	wcd9335_enable_efuse_sensing(component);
3222 }
3223 
3224 static int wcd9335_codec_probe(struct snd_soc_component *component)
3225 {
3226 	struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
3227 	int i;
3228 
3229 	snd_soc_component_init_regmap(component, wcd->regmap);
3230 	/* Class-H Init*/
3231 	wcd->clsh_ctrl = wcd_clsh_ctrl_alloc(component, wcd->version);
3232 	if (IS_ERR(wcd->clsh_ctrl))
3233 		return PTR_ERR(wcd->clsh_ctrl);
3234 
3235 	/* Default HPH Mode to Class-H HiFi */
3236 	wcd->hph_mode = CLS_H_HIFI;
3237 	wcd->component = component;
3238 
3239 	wcd9335_codec_init(component);
3240 
3241 	for (i = 0; i < NUM_CODEC_DAIS; i++)
3242 		INIT_LIST_HEAD(&wcd->dai[i].slim_ch_list);
3243 
3244 	return wcd9335_setup_irqs(wcd);
3245 }
3246 
3247 static void wcd9335_codec_remove(struct snd_soc_component *comp)
3248 {
3249 	struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
3250 
3251 	wcd_clsh_ctrl_free(wcd->clsh_ctrl);
3252 	free_irq(regmap_irq_get_virq(wcd->irq_data, WCD9335_IRQ_SLIMBUS), wcd);
3253 }
3254 
3255 static int wcd9335_codec_set_sysclk(struct snd_soc_component *comp,
3256 				    int clk_id, int source,
3257 				    unsigned int freq, int dir)
3258 {
3259 	struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
3260 
3261 	wcd->mclk_rate = freq;
3262 
3263 	if (wcd->mclk_rate == WCD9335_MCLK_CLK_12P288MHZ)
3264 		snd_soc_component_update_bits(comp,
3265 				WCD9335_CODEC_RPM_CLK_MCLK_CFG,
3266 				WCD9335_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK,
3267 				WCD9335_CODEC_RPM_CLK_MCLK_CFG_12P288MHZ);
3268 	else if (wcd->mclk_rate == WCD9335_MCLK_CLK_9P6MHZ)
3269 		snd_soc_component_update_bits(comp,
3270 				WCD9335_CODEC_RPM_CLK_MCLK_CFG,
3271 				WCD9335_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK,
3272 				WCD9335_CODEC_RPM_CLK_MCLK_CFG_9P6MHZ);
3273 
3274 	return clk_set_rate(wcd->mclk, freq);
3275 }
3276 
3277 static const struct snd_soc_component_driver wcd9335_component_drv = {
3278 	.probe = wcd9335_codec_probe,
3279 	.remove = wcd9335_codec_remove,
3280 	.set_sysclk = wcd9335_codec_set_sysclk,
3281 	.controls = wcd9335_snd_controls,
3282 	.num_controls = ARRAY_SIZE(wcd9335_snd_controls),
3283 	.dapm_widgets = wcd9335_dapm_widgets,
3284 	.num_dapm_widgets = ARRAY_SIZE(wcd9335_dapm_widgets),
3285 };
3286 
3287 static int wcd9335_probe(struct wcd9335_codec *wcd)
3288 {
3289 	struct device *dev = wcd->dev;
3290 
3291 	memcpy(wcd->rx_chs, wcd9335_rx_chs, sizeof(wcd9335_rx_chs));
3292 
3293 	wcd->sido_input_src = SIDO_SOURCE_INTERNAL;
3294 	wcd->sido_voltage = SIDO_VOLTAGE_NOMINAL_MV;
3295 
3296 	return devm_snd_soc_register_component(dev, &wcd9335_component_drv,
3297 					       wcd9335_slim_dais,
3298 					       ARRAY_SIZE(wcd9335_slim_dais));
3299 }
3300 
3301 static const struct regmap_range_cfg wcd9335_ranges[] = {
3302 	{
3303 		.name = "WCD9335",
3304 		.range_min =  0x0,
3305 		.range_max =  WCD9335_MAX_REGISTER,
3306 		.selector_reg = WCD9335_REG(0x0, 0),
3307 		.selector_mask = 0xff,
3308 		.selector_shift = 0,
3309 		.window_start = 0x0,
3310 		.window_len = 0x1000,
3311 	},
3312 };
3313 
3314 static bool wcd9335_is_volatile_register(struct device *dev, unsigned int reg)
3315 {
3316 	switch (reg) {
3317 	case WCD9335_INTR_PIN1_STATUS0...WCD9335_INTR_PIN2_CLEAR3:
3318 	case WCD9335_ANA_MBHC_RESULT_3:
3319 	case WCD9335_ANA_MBHC_RESULT_2:
3320 	case WCD9335_ANA_MBHC_RESULT_1:
3321 	case WCD9335_ANA_MBHC_MECH:
3322 	case WCD9335_ANA_MBHC_ELECT:
3323 	case WCD9335_ANA_MBHC_ZDET:
3324 	case WCD9335_ANA_MICB2:
3325 	case WCD9335_ANA_RCO:
3326 	case WCD9335_ANA_BIAS:
3327 		return true;
3328 	default:
3329 		return false;
3330 	}
3331 }
3332 
3333 static struct regmap_config wcd9335_regmap_config = {
3334 	.reg_bits = 16,
3335 	.val_bits = 8,
3336 	.cache_type = REGCACHE_RBTREE,
3337 	.max_register = WCD9335_MAX_REGISTER,
3338 	.can_multi_write = true,
3339 	.ranges = wcd9335_ranges,
3340 	.num_ranges = ARRAY_SIZE(wcd9335_ranges),
3341 	.volatile_reg = wcd9335_is_volatile_register,
3342 };
3343 
3344 static const struct regmap_range_cfg wcd9335_ifc_ranges[] = {
3345 	{
3346 		.name = "WCD9335-IFC-DEV",
3347 		.range_min =  0x0,
3348 		.range_max = WCD9335_REG(0, 0x7ff),
3349 		.selector_reg = WCD9335_REG(0, 0x0),
3350 		.selector_mask = 0xff,
3351 		.selector_shift = 0,
3352 		.window_start = 0x0,
3353 		.window_len = 0x1000,
3354 	},
3355 };
3356 
3357 static struct regmap_config wcd9335_ifc_regmap_config = {
3358 	.reg_bits = 16,
3359 	.val_bits = 8,
3360 	.can_multi_write = true,
3361 	.max_register = WCD9335_REG(0, 0x7FF),
3362 	.ranges = wcd9335_ifc_ranges,
3363 	.num_ranges = ARRAY_SIZE(wcd9335_ifc_ranges),
3364 };
3365 
3366 static const struct regmap_irq wcd9335_codec_irqs[] = {
3367 	/* INTR_REG 0 */
3368 	[WCD9335_IRQ_SLIMBUS] = {
3369 		.reg_offset = 0,
3370 		.mask = BIT(0),
3371 		.type = {
3372 			.type_reg_offset = 0,
3373 			.types_supported = IRQ_TYPE_EDGE_BOTH,
3374 			.type_reg_mask	= BIT(0),
3375 		},
3376 	},
3377 };
3378 
3379 static const struct regmap_irq_chip wcd9335_regmap_irq1_chip = {
3380 	.name = "wcd9335_pin1_irq",
3381 	.status_base = WCD9335_INTR_PIN1_STATUS0,
3382 	.mask_base = WCD9335_INTR_PIN1_MASK0,
3383 	.ack_base = WCD9335_INTR_PIN1_CLEAR0,
3384 	.type_base = WCD9335_INTR_LEVEL0,
3385 	.num_type_reg = 4,
3386 	.num_regs = 4,
3387 	.irqs = wcd9335_codec_irqs,
3388 	.num_irqs = ARRAY_SIZE(wcd9335_codec_irqs),
3389 };
3390 
3391 static int wcd9335_parse_dt(struct wcd9335_codec *wcd)
3392 {
3393 	struct device *dev = wcd->dev;
3394 	struct device_node *np = dev->of_node;
3395 	int ret;
3396 
3397 	wcd->reset_gpio = of_get_named_gpio(np,	"reset-gpios", 0);
3398 	if (wcd->reset_gpio < 0) {
3399 		dev_err(dev, "Reset GPIO missing from DT\n");
3400 		return wcd->reset_gpio;
3401 	}
3402 
3403 	wcd->mclk = devm_clk_get(dev, "mclk");
3404 	if (IS_ERR(wcd->mclk)) {
3405 		dev_err(dev, "mclk not found\n");
3406 		return PTR_ERR(wcd->mclk);
3407 	}
3408 
3409 	wcd->native_clk = devm_clk_get(dev, "slimbus");
3410 	if (IS_ERR(wcd->native_clk)) {
3411 		dev_err(dev, "slimbus clock not found\n");
3412 		return PTR_ERR(wcd->native_clk);
3413 	}
3414 
3415 	wcd->supplies[0].supply = "vdd-buck";
3416 	wcd->supplies[1].supply = "vdd-buck-sido";
3417 	wcd->supplies[2].supply = "vdd-tx";
3418 	wcd->supplies[3].supply = "vdd-rx";
3419 	wcd->supplies[4].supply = "vdd-io";
3420 
3421 	ret = regulator_bulk_get(dev, WCD9335_MAX_SUPPLY, wcd->supplies);
3422 	if (ret) {
3423 		dev_err(dev, "Failed to get supplies: err = %d\n", ret);
3424 		return ret;
3425 	}
3426 
3427 	return 0;
3428 }
3429 
3430 static int wcd9335_power_on_reset(struct wcd9335_codec *wcd)
3431 {
3432 	struct device *dev = wcd->dev;
3433 	int ret;
3434 
3435 	ret = regulator_bulk_enable(WCD9335_MAX_SUPPLY, wcd->supplies);
3436 	if (ret) {
3437 		dev_err(dev, "Failed to get supplies: err = %d\n", ret);
3438 		return ret;
3439 	}
3440 
3441 	/*
3442 	 * For WCD9335, it takes about 600us for the Vout_A and
3443 	 * Vout_D to be ready after BUCK_SIDO is powered up.
3444 	 * SYS_RST_N shouldn't be pulled high during this time
3445 	 * Toggle the reset line to make sure the reset pulse is
3446 	 * correctly applied
3447 	 */
3448 	usleep_range(600, 650);
3449 
3450 	gpio_direction_output(wcd->reset_gpio, 0);
3451 	msleep(20);
3452 	gpio_set_value(wcd->reset_gpio, 1);
3453 	msleep(20);
3454 
3455 	return 0;
3456 }
3457 
3458 static int wcd9335_bring_up(struct wcd9335_codec *wcd)
3459 {
3460 	struct regmap *rm = wcd->regmap;
3461 	int val, byte0;
3462 
3463 	regmap_read(rm, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0, &val);
3464 	regmap_read(rm, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0, &byte0);
3465 
3466 	if ((val < 0) || (byte0 < 0)) {
3467 		dev_err(wcd->dev, "WCD9335 CODEC version detection fail!\n");
3468 		return -EINVAL;
3469 	}
3470 
3471 	if (byte0 == 0x1) {
3472 		dev_info(wcd->dev, "WCD9335 CODEC version is v2.0\n");
3473 		wcd->version = WCD9335_VERSION_2_0;
3474 		regmap_write(rm, WCD9335_CODEC_RPM_RST_CTL, 0x01);
3475 		regmap_write(rm, WCD9335_SIDO_SIDO_TEST_2, 0x00);
3476 		regmap_write(rm, WCD9335_SIDO_SIDO_CCL_8, 0x6F);
3477 		regmap_write(rm, WCD9335_BIAS_VBG_FINE_ADJ, 0x65);
3478 		regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5);
3479 		regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7);
3480 		regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3);
3481 		regmap_write(rm, WCD9335_CODEC_RPM_RST_CTL, 0x3);
3482 	} else {
3483 		dev_err(wcd->dev, "WCD9335 CODEC version not supported\n");
3484 		return -EINVAL;
3485 	}
3486 
3487 	return 0;
3488 }
3489 
3490 static int wcd9335_irq_init(struct wcd9335_codec *wcd)
3491 {
3492 	int ret;
3493 
3494 	/*
3495 	 * INTR1 consists of all possible interrupt sources Ear OCP,
3496 	 * HPH OCP, MBHC, MAD, VBAT, and SVA
3497 	 * INTR2 is a subset of first interrupt sources MAD, VBAT, and SVA
3498 	 */
3499 	wcd->intr1 = of_irq_get_byname(wcd->dev->of_node, "intr1");
3500 	if (wcd->intr1 < 0) {
3501 		if (wcd->intr1 != -EPROBE_DEFER)
3502 			dev_err(wcd->dev, "Unable to configure IRQ\n");
3503 
3504 		return wcd->intr1;
3505 	}
3506 
3507 	ret = devm_regmap_add_irq_chip(wcd->dev, wcd->regmap, wcd->intr1,
3508 				 IRQF_TRIGGER_HIGH, 0,
3509 				 &wcd9335_regmap_irq1_chip, &wcd->irq_data);
3510 	if (ret)
3511 		dev_err(wcd->dev, "Failed to register IRQ chip: %d\n", ret);
3512 
3513 	return ret;
3514 }
3515 
3516 static int wcd9335_slim_probe(struct slim_device *slim)
3517 {
3518 	struct device *dev = &slim->dev;
3519 	struct wcd9335_codec *wcd;
3520 	int ret;
3521 
3522 	wcd = devm_kzalloc(dev, sizeof(*wcd), GFP_KERNEL);
3523 	if (!wcd)
3524 		return	-ENOMEM;
3525 
3526 	wcd->dev = dev;
3527 	ret = wcd9335_parse_dt(wcd);
3528 	if (ret) {
3529 		dev_err(dev, "Error parsing DT: %d\n", ret);
3530 		return ret;
3531 	}
3532 
3533 	ret = wcd9335_power_on_reset(wcd);
3534 	if (ret)
3535 		return ret;
3536 
3537 	dev_set_drvdata(dev, wcd);
3538 
3539 	return 0;
3540 }
3541 
3542 static int wcd9335_slim_status(struct slim_device *sdev,
3543 			       enum slim_device_status status)
3544 {
3545 	struct device *dev = &sdev->dev;
3546 	struct device_node *ifc_dev_np;
3547 	struct wcd9335_codec *wcd;
3548 	int ret;
3549 
3550 	wcd = dev_get_drvdata(dev);
3551 
3552 	ifc_dev_np = of_parse_phandle(dev->of_node, "slim-ifc-dev", 0);
3553 	if (!ifc_dev_np) {
3554 		dev_err(dev, "No Interface device found\n");
3555 		return -EINVAL;
3556 	}
3557 
3558 	wcd->slim = sdev;
3559 	wcd->slim_ifc_dev = of_slim_get_device(sdev->ctrl, ifc_dev_np);
3560 	if (!wcd->slim_ifc_dev) {
3561 		dev_err(dev, "Unable to get SLIM Interface device\n");
3562 		return -EINVAL;
3563 	}
3564 
3565 	slim_get_logical_addr(wcd->slim_ifc_dev);
3566 
3567 	wcd->regmap = regmap_init_slimbus(sdev, &wcd9335_regmap_config);
3568 	if (IS_ERR(wcd->regmap)) {
3569 		dev_err(dev, "Failed to allocate slim register map\n");
3570 		return PTR_ERR(wcd->regmap);
3571 	}
3572 
3573 	wcd->if_regmap = regmap_init_slimbus(wcd->slim_ifc_dev,
3574 						  &wcd9335_ifc_regmap_config);
3575 	if (IS_ERR(wcd->if_regmap)) {
3576 		dev_err(dev, "Failed to allocate ifc register map\n");
3577 		return PTR_ERR(wcd->if_regmap);
3578 	}
3579 
3580 	ret = wcd9335_bring_up(wcd);
3581 	if (ret) {
3582 		dev_err(dev, "Failed to bringup WCD9335\n");
3583 		return ret;
3584 	}
3585 
3586 	ret = wcd9335_irq_init(wcd);
3587 	if (ret)
3588 		return ret;
3589 
3590 	wcd9335_probe(wcd);
3591 
3592 	return ret;
3593 }
3594 
3595 static const struct slim_device_id wcd9335_slim_id[] = {
3596 	{SLIM_MANF_ID_QCOM, SLIM_PROD_CODE_WCD9335, 0x1, 0x0},
3597 	{}
3598 };
3599 MODULE_DEVICE_TABLE(slim, wcd9335_slim_id);
3600 
3601 static struct slim_driver wcd9335_slim_driver = {
3602 	.driver = {
3603 		.name = "wcd9335-slim",
3604 	},
3605 	.probe = wcd9335_slim_probe,
3606 	.device_status = wcd9335_slim_status,
3607 	.id_table = wcd9335_slim_id,
3608 };
3609 
3610 module_slim_driver(wcd9335_slim_driver);
3611 MODULE_DESCRIPTION("WCD9335 slim driver");
3612 MODULE_LICENSE("GPL v2");
3613 MODULE_ALIAS("slim:217:1a0:*");
3614