xref: /openbmc/linux/sound/soc/codecs/cs35l41.c (revision c4a11bf4)
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // cs35l41.c -- CS35l41 ALSA SoC audio driver
4 //
5 // Copyright 2017-2021 Cirrus Logic, Inc.
6 //
7 // Author: David Rhodes <david.rhodes@cirrus.com>
8 
9 #include <linux/delay.h>
10 #include <linux/err.h>
11 #include <linux/init.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/moduleparam.h>
15 #include <linux/of_device.h>
16 #include <linux/property.h>
17 #include <linux/slab.h>
18 #include <sound/initval.h>
19 #include <sound/pcm.h>
20 #include <sound/pcm_params.h>
21 #include <sound/soc.h>
22 #include <sound/soc-dapm.h>
23 #include <sound/tlv.h>
24 
25 #include "cs35l41.h"
26 
27 static const char * const cs35l41_supplies[CS35L41_NUM_SUPPLIES] = {
28 	"VA",
29 	"VP",
30 };
31 
32 struct cs35l41_pll_sysclk_config {
33 	int freq;
34 	int clk_cfg;
35 };
36 
37 static const struct cs35l41_pll_sysclk_config cs35l41_pll_sysclk[] = {
38 	{ 32768,	0x00 },
39 	{ 8000,		0x01 },
40 	{ 11025,	0x02 },
41 	{ 12000,	0x03 },
42 	{ 16000,	0x04 },
43 	{ 22050,	0x05 },
44 	{ 24000,	0x06 },
45 	{ 32000,	0x07 },
46 	{ 44100,	0x08 },
47 	{ 48000,	0x09 },
48 	{ 88200,	0x0A },
49 	{ 96000,	0x0B },
50 	{ 128000,	0x0C },
51 	{ 176400,	0x0D },
52 	{ 192000,	0x0E },
53 	{ 256000,	0x0F },
54 	{ 352800,	0x10 },
55 	{ 384000,	0x11 },
56 	{ 512000,	0x12 },
57 	{ 705600,	0x13 },
58 	{ 750000,	0x14 },
59 	{ 768000,	0x15 },
60 	{ 1000000,	0x16 },
61 	{ 1024000,	0x17 },
62 	{ 1200000,	0x18 },
63 	{ 1411200,	0x19 },
64 	{ 1500000,	0x1A },
65 	{ 1536000,	0x1B },
66 	{ 2000000,	0x1C },
67 	{ 2048000,	0x1D },
68 	{ 2400000,	0x1E },
69 	{ 2822400,	0x1F },
70 	{ 3000000,	0x20 },
71 	{ 3072000,	0x21 },
72 	{ 3200000,	0x22 },
73 	{ 4000000,	0x23 },
74 	{ 4096000,	0x24 },
75 	{ 4800000,	0x25 },
76 	{ 5644800,	0x26 },
77 	{ 6000000,	0x27 },
78 	{ 6144000,	0x28 },
79 	{ 6250000,	0x29 },
80 	{ 6400000,	0x2A },
81 	{ 6500000,	0x2B },
82 	{ 6750000,	0x2C },
83 	{ 7526400,	0x2D },
84 	{ 8000000,	0x2E },
85 	{ 8192000,	0x2F },
86 	{ 9600000,	0x30 },
87 	{ 11289600,	0x31 },
88 	{ 12000000,	0x32 },
89 	{ 12288000,	0x33 },
90 	{ 12500000,	0x34 },
91 	{ 12800000,	0x35 },
92 	{ 13000000,	0x36 },
93 	{ 13500000,	0x37 },
94 	{ 19200000,	0x38 },
95 	{ 22579200,	0x39 },
96 	{ 24000000,	0x3A },
97 	{ 24576000,	0x3B },
98 	{ 25000000,	0x3C },
99 	{ 25600000,	0x3D },
100 	{ 26000000,	0x3E },
101 	{ 27000000,	0x3F },
102 };
103 
104 struct cs35l41_fs_mon_config {
105 	int freq;
106 	unsigned int fs1;
107 	unsigned int fs2;
108 };
109 
110 static const struct cs35l41_fs_mon_config cs35l41_fs_mon[] = {
111 	{ 32768,	2254,	3754 },
112 	{ 8000,		9220,	15364 },
113 	{ 11025,	6148,	10244 },
114 	{ 12000,	6148,	10244 },
115 	{ 16000,	4612,	7684 },
116 	{ 22050,	3076,	5124 },
117 	{ 24000,	3076,	5124 },
118 	{ 32000,	2308,	3844 },
119 	{ 44100,	1540,	2564 },
120 	{ 48000,	1540,	2564 },
121 	{ 88200,	772,	1284 },
122 	{ 96000,	772,	1284 },
123 	{ 128000,	580,	964 },
124 	{ 176400,	388,	644 },
125 	{ 192000,	388,	644 },
126 	{ 256000,	292,	484 },
127 	{ 352800,	196,	324 },
128 	{ 384000,	196,	324 },
129 	{ 512000,	148,	244 },
130 	{ 705600,	100,	164 },
131 	{ 750000,	100,	164 },
132 	{ 768000,	100,	164 },
133 	{ 1000000,	76,	124 },
134 	{ 1024000,	76,	124 },
135 	{ 1200000,	64,	104 },
136 	{ 1411200,	52,	84 },
137 	{ 1500000,	52,	84 },
138 	{ 1536000,	52,	84 },
139 	{ 2000000,	40,	64 },
140 	{ 2048000,	40,	64 },
141 	{ 2400000,	34,	54 },
142 	{ 2822400,	28,	44 },
143 	{ 3000000,	28,	44 },
144 	{ 3072000,	28,	44 },
145 	{ 3200000,	27,	42 },
146 	{ 4000000,	22,	34 },
147 	{ 4096000,	22,	34 },
148 	{ 4800000,	19,	29 },
149 	{ 5644800,	16,	24 },
150 	{ 6000000,	16,	24 },
151 	{ 6144000,	16,	24 },
152 };
153 
154 static const unsigned char cs35l41_bst_k1_table[4][5] = {
155 	{ 0x24, 0x32, 0x32, 0x4F, 0x57 },
156 	{ 0x24, 0x32, 0x32, 0x4F, 0x57 },
157 	{ 0x40, 0x32, 0x32, 0x4F, 0x57 },
158 	{ 0x40, 0x32, 0x32, 0x4F, 0x57 }
159 };
160 
161 static const unsigned char cs35l41_bst_k2_table[4][5] = {
162 	{ 0x24, 0x49, 0x66, 0xA3, 0xEA },
163 	{ 0x24, 0x49, 0x66, 0xA3, 0xEA },
164 	{ 0x48, 0x49, 0x66, 0xA3, 0xEA },
165 	{ 0x48, 0x49, 0x66, 0xA3, 0xEA }
166 };
167 
168 static const unsigned char cs35l41_bst_slope_table[4] = {
169 	0x75, 0x6B, 0x3B, 0x28
170 };
171 
172 static int cs35l41_get_fs_mon_config_index(int freq)
173 {
174 	int i;
175 
176 	for (i = 0; i < ARRAY_SIZE(cs35l41_fs_mon); i++) {
177 		if (cs35l41_fs_mon[i].freq == freq)
178 			return i;
179 	}
180 
181 	return -EINVAL;
182 }
183 
184 static const DECLARE_TLV_DB_RANGE(dig_vol_tlv,
185 		0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
186 		1, 913, TLV_DB_MINMAX_ITEM(-10200, 1200));
187 static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1);
188 
189 static const struct snd_kcontrol_new dre_ctrl =
190 	SOC_DAPM_SINGLE("Switch", CS35L41_PWR_CTRL3, 20, 1, 0);
191 
192 static const char * const cs35l41_pcm_sftramp_text[] =  {
193 	"Off", ".5ms", "1ms", "2ms", "4ms", "8ms", "15ms", "30ms"
194 };
195 
196 static SOC_ENUM_SINGLE_DECL(pcm_sft_ramp,
197 			    CS35L41_AMP_DIG_VOL_CTRL, 0,
198 			    cs35l41_pcm_sftramp_text);
199 
200 static const char * const cs35l41_pcm_source_texts[] = {"ASP", "DSP"};
201 static const unsigned int cs35l41_pcm_source_values[] = {0x08, 0x32};
202 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_pcm_source_enum,
203 				  CS35L41_DAC_PCM1_SRC,
204 				  0, CS35L41_ASP_SOURCE_MASK,
205 				  cs35l41_pcm_source_texts,
206 				  cs35l41_pcm_source_values);
207 
208 static const struct snd_kcontrol_new pcm_source_mux =
209 	SOC_DAPM_ENUM("PCM Source", cs35l41_pcm_source_enum);
210 
211 static const char * const cs35l41_tx_input_texts[] = {
212 	"Zero", "ASPRX1", "ASPRX2", "VMON", "IMON",
213 	"VPMON", "VBSTMON", "DSPTX1", "DSPTX2"
214 };
215 
216 static const unsigned int cs35l41_tx_input_values[] = {
217 	0x00, CS35L41_INPUT_SRC_ASPRX1, CS35L41_INPUT_SRC_ASPRX2,
218 	CS35L41_INPUT_SRC_VMON, CS35L41_INPUT_SRC_IMON, CS35L41_INPUT_SRC_VPMON,
219 	CS35L41_INPUT_SRC_VBSTMON, CS35L41_INPUT_DSP_TX1, CS35L41_INPUT_DSP_TX2
220 };
221 
222 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx1_enum,
223 				  CS35L41_ASP_TX1_SRC,
224 				  0, CS35L41_ASP_SOURCE_MASK,
225 				  cs35l41_tx_input_texts,
226 				  cs35l41_tx_input_values);
227 
228 static const struct snd_kcontrol_new asp_tx1_mux =
229 	SOC_DAPM_ENUM("ASPTX1 SRC", cs35l41_asptx1_enum);
230 
231 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx2_enum,
232 				  CS35L41_ASP_TX2_SRC,
233 				  0, CS35L41_ASP_SOURCE_MASK,
234 				  cs35l41_tx_input_texts,
235 				  cs35l41_tx_input_values);
236 
237 static const struct snd_kcontrol_new asp_tx2_mux =
238 	SOC_DAPM_ENUM("ASPTX2 SRC", cs35l41_asptx2_enum);
239 
240 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx3_enum,
241 				  CS35L41_ASP_TX3_SRC,
242 				  0, CS35L41_ASP_SOURCE_MASK,
243 				  cs35l41_tx_input_texts,
244 				  cs35l41_tx_input_values);
245 
246 static const struct snd_kcontrol_new asp_tx3_mux =
247 	SOC_DAPM_ENUM("ASPTX3 SRC", cs35l41_asptx3_enum);
248 
249 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx4_enum,
250 				  CS35L41_ASP_TX4_SRC,
251 				  0, CS35L41_ASP_SOURCE_MASK,
252 				  cs35l41_tx_input_texts,
253 				  cs35l41_tx_input_values);
254 
255 static const struct snd_kcontrol_new asp_tx4_mux =
256 	SOC_DAPM_ENUM("ASPTX4 SRC", cs35l41_asptx4_enum);
257 
258 static const struct snd_kcontrol_new cs35l41_aud_controls[] = {
259 	SOC_SINGLE_SX_TLV("Digital PCM Volume", CS35L41_AMP_DIG_VOL_CTRL,
260 			  3, 0x4CF, 0x391, dig_vol_tlv),
261 	SOC_SINGLE_TLV("Analog PCM Volume", CS35L41_AMP_GAIN_CTRL, 5, 0x14, 0,
262 		       amp_gain_tlv),
263 	SOC_ENUM("PCM Soft Ramp", pcm_sft_ramp),
264 	SOC_SINGLE("HW Noise Gate Enable", CS35L41_NG_CFG, 8, 63, 0),
265 	SOC_SINGLE("HW Noise Gate Delay", CS35L41_NG_CFG, 4, 7, 0),
266 	SOC_SINGLE("HW Noise Gate Threshold", CS35L41_NG_CFG, 0, 7, 0),
267 	SOC_SINGLE("Aux Noise Gate CH1 Enable",
268 		   CS35L41_MIXER_NGATE_CH1_CFG, 16, 1, 0),
269 	SOC_SINGLE("Aux Noise Gate CH1 Entry Delay",
270 		   CS35L41_MIXER_NGATE_CH1_CFG, 8, 15, 0),
271 	SOC_SINGLE("Aux Noise Gate CH1 Threshold",
272 		   CS35L41_MIXER_NGATE_CH1_CFG, 0, 7, 0),
273 	SOC_SINGLE("Aux Noise Gate CH2 Entry Delay",
274 		   CS35L41_MIXER_NGATE_CH2_CFG, 8, 15, 0),
275 	SOC_SINGLE("Aux Noise Gate CH2 Enable",
276 		   CS35L41_MIXER_NGATE_CH2_CFG, 16, 1, 0),
277 	SOC_SINGLE("Aux Noise Gate CH2 Threshold",
278 		   CS35L41_MIXER_NGATE_CH2_CFG, 0, 7, 0),
279 	SOC_SINGLE("SCLK Force", CS35L41_SP_FORMAT, CS35L41_SCLK_FRC_SHIFT, 1, 0),
280 	SOC_SINGLE("LRCLK Force", CS35L41_SP_FORMAT, CS35L41_LRCLK_FRC_SHIFT, 1, 0),
281 	SOC_SINGLE("Invert Class D", CS35L41_AMP_DIG_VOL_CTRL,
282 		   CS35L41_AMP_INV_PCM_SHIFT, 1, 0),
283 	SOC_SINGLE("Amp Gain ZC", CS35L41_AMP_GAIN_CTRL,
284 		   CS35L41_AMP_GAIN_ZC_SHIFT, 1, 0),
285 };
286 
287 static const struct cs35l41_otp_map_element_t *cs35l41_find_otp_map(u32 otp_id)
288 {
289 	int i;
290 
291 	for (i = 0; i < ARRAY_SIZE(cs35l41_otp_map_map); i++) {
292 		if (cs35l41_otp_map_map[i].id == otp_id)
293 			return &cs35l41_otp_map_map[i];
294 	}
295 
296 	return NULL;
297 }
298 
299 static int cs35l41_otp_unpack(void *data)
300 {
301 	const struct cs35l41_otp_map_element_t *otp_map_match;
302 	const struct cs35l41_otp_packed_element_t *otp_map;
303 	struct cs35l41_private *cs35l41 = data;
304 	int bit_offset, word_offset, ret, i;
305 	unsigned int orig_spi_freq;
306 	unsigned int bit_sum = 8;
307 	u32 otp_val, otp_id_reg;
308 	u32 *otp_mem;
309 
310 	otp_mem = kmalloc_array(CS35L41_OTP_SIZE_WORDS, sizeof(*otp_mem), GFP_KERNEL);
311 	if (!otp_mem)
312 		return -ENOMEM;
313 
314 	ret = regmap_read(cs35l41->regmap, CS35L41_OTPID, &otp_id_reg);
315 	if (ret < 0) {
316 		dev_err(cs35l41->dev, "Read OTP ID failed: %d\n", ret);
317 		goto err_otp_unpack;
318 	}
319 
320 	otp_map_match = cs35l41_find_otp_map(otp_id_reg);
321 
322 	if (!otp_map_match) {
323 		dev_err(cs35l41->dev, "OTP Map matching ID %d not found\n",
324 			otp_id_reg);
325 		ret = -EINVAL;
326 		goto err_otp_unpack;
327 	}
328 
329 	if (cs35l41->otp_setup)
330 		cs35l41->otp_setup(cs35l41, true, &orig_spi_freq);
331 
332 	ret = regmap_bulk_read(cs35l41->regmap, CS35L41_OTP_MEM0, otp_mem,
333 			       CS35L41_OTP_SIZE_WORDS);
334 	if (ret < 0) {
335 		dev_err(cs35l41->dev, "Read OTP Mem failed: %d\n", ret);
336 		goto err_otp_unpack;
337 	}
338 
339 	if (cs35l41->otp_setup)
340 		cs35l41->otp_setup(cs35l41, false, &orig_spi_freq);
341 
342 	otp_map = otp_map_match->map;
343 
344 	bit_offset = otp_map_match->bit_offset;
345 	word_offset = otp_map_match->word_offset;
346 
347 	ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000055);
348 	if (ret < 0) {
349 		dev_err(cs35l41->dev, "Write Unlock key failed 1/2: %d\n", ret);
350 		goto err_otp_unpack;
351 	}
352 	ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000AA);
353 	if (ret < 0) {
354 		dev_err(cs35l41->dev, "Write Unlock key failed 2/2: %d\n", ret);
355 		goto err_otp_unpack;
356 	}
357 
358 	for (i = 0; i < otp_map_match->num_elements; i++) {
359 		dev_dbg(cs35l41->dev,
360 			"bitoffset= %d, word_offset=%d, bit_sum mod 32=%d\n",
361 			bit_offset, word_offset, bit_sum % 32);
362 		if (bit_offset + otp_map[i].size - 1 >= 32) {
363 			otp_val = (otp_mem[word_offset] &
364 					GENMASK(31, bit_offset)) >>
365 					bit_offset;
366 			otp_val |= (otp_mem[++word_offset] &
367 					GENMASK(bit_offset +
368 						otp_map[i].size - 33, 0)) <<
369 					(32 - bit_offset);
370 			bit_offset += otp_map[i].size - 32;
371 		} else {
372 			otp_val = (otp_mem[word_offset] &
373 				GENMASK(bit_offset + otp_map[i].size - 1,
374 					bit_offset)) >>	bit_offset;
375 			bit_offset += otp_map[i].size;
376 		}
377 		bit_sum += otp_map[i].size;
378 
379 		if (bit_offset == 32) {
380 			bit_offset = 0;
381 			word_offset++;
382 		}
383 
384 		if (otp_map[i].reg != 0) {
385 			ret = regmap_update_bits(cs35l41->regmap,
386 						 otp_map[i].reg,
387 						 GENMASK(otp_map[i].shift +
388 							 otp_map[i].size - 1,
389 						 otp_map[i].shift),
390 						 otp_val << otp_map[i].shift);
391 			if (ret < 0) {
392 				dev_err(cs35l41->dev, "Write OTP val failed: %d\n",
393 					ret);
394 				goto err_otp_unpack;
395 			}
396 		}
397 	}
398 
399 	ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000CC);
400 	if (ret < 0) {
401 		dev_err(cs35l41->dev, "Write Lock key failed 1/2: %d\n", ret);
402 		goto err_otp_unpack;
403 	}
404 	ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000033);
405 	if (ret < 0) {
406 		dev_err(cs35l41->dev, "Write Lock key failed 2/2: %d\n", ret);
407 		goto err_otp_unpack;
408 	}
409 	ret = 0;
410 
411 err_otp_unpack:
412 	kfree(otp_mem);
413 	return ret;
414 }
415 
416 static irqreturn_t cs35l41_irq(int irq, void *data)
417 {
418 	struct cs35l41_private *cs35l41 = data;
419 	unsigned int status[4] = { 0, 0, 0, 0 };
420 	unsigned int masks[4] = { 0, 0, 0, 0 };
421 	int ret = IRQ_NONE;
422 	unsigned int i;
423 
424 	for (i = 0; i < ARRAY_SIZE(status); i++) {
425 		regmap_read(cs35l41->regmap,
426 			    CS35L41_IRQ1_STATUS1 + (i * CS35L41_REGSTRIDE),
427 			    &status[i]);
428 		regmap_read(cs35l41->regmap,
429 			    CS35L41_IRQ1_MASK1 + (i * CS35L41_REGSTRIDE),
430 			    &masks[i]);
431 	}
432 
433 	/* Check to see if unmasked bits are active */
434 	if (!(status[0] & ~masks[0]) && !(status[1] & ~masks[1]) &&
435 	    !(status[2] & ~masks[2]) && !(status[3] & ~masks[3]))
436 		return IRQ_NONE;
437 
438 	if (status[3] & CS35L41_OTP_BOOT_DONE) {
439 		regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK4,
440 				   CS35L41_OTP_BOOT_DONE, CS35L41_OTP_BOOT_DONE);
441 	}
442 
443 	/*
444 	 * The following interrupts require a
445 	 * protection release cycle to get the
446 	 * speaker out of Safe-Mode.
447 	 */
448 	if (status[0] & CS35L41_AMP_SHORT_ERR) {
449 		dev_crit_ratelimited(cs35l41->dev, "Amp short error\n");
450 		regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
451 			     CS35L41_AMP_SHORT_ERR);
452 		regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
453 		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
454 				   CS35L41_AMP_SHORT_ERR_RLS,
455 				   CS35L41_AMP_SHORT_ERR_RLS);
456 		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
457 				   CS35L41_AMP_SHORT_ERR_RLS, 0);
458 		ret = IRQ_HANDLED;
459 	}
460 
461 	if (status[0] & CS35L41_TEMP_WARN) {
462 		dev_crit_ratelimited(cs35l41->dev, "Over temperature warning\n");
463 		regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
464 			     CS35L41_TEMP_WARN);
465 		regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
466 		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
467 				   CS35L41_TEMP_WARN_ERR_RLS,
468 				   CS35L41_TEMP_WARN_ERR_RLS);
469 		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
470 				   CS35L41_TEMP_WARN_ERR_RLS, 0);
471 		ret = IRQ_HANDLED;
472 	}
473 
474 	if (status[0] & CS35L41_TEMP_ERR) {
475 		dev_crit_ratelimited(cs35l41->dev, "Over temperature error\n");
476 		regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
477 			     CS35L41_TEMP_ERR);
478 		regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
479 		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
480 				   CS35L41_TEMP_ERR_RLS,
481 				   CS35L41_TEMP_ERR_RLS);
482 		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
483 				   CS35L41_TEMP_ERR_RLS, 0);
484 		ret = IRQ_HANDLED;
485 	}
486 
487 	if (status[0] & CS35L41_BST_OVP_ERR) {
488 		dev_crit_ratelimited(cs35l41->dev, "VBST Over Voltage error\n");
489 		regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
490 				   CS35L41_BST_EN_MASK, 0);
491 		regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
492 			     CS35L41_BST_OVP_ERR);
493 		regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
494 		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
495 				   CS35L41_BST_OVP_ERR_RLS,
496 				   CS35L41_BST_OVP_ERR_RLS);
497 		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
498 				   CS35L41_BST_OVP_ERR_RLS, 0);
499 		regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
500 				   CS35L41_BST_EN_MASK,
501 				   CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
502 		ret = IRQ_HANDLED;
503 	}
504 
505 	if (status[0] & CS35L41_BST_DCM_UVP_ERR) {
506 		dev_crit_ratelimited(cs35l41->dev, "DCM VBST Under Voltage Error\n");
507 		regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
508 				   CS35L41_BST_EN_MASK, 0);
509 		regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
510 			     CS35L41_BST_DCM_UVP_ERR);
511 		regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
512 		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
513 				   CS35L41_BST_UVP_ERR_RLS,
514 				   CS35L41_BST_UVP_ERR_RLS);
515 		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
516 				   CS35L41_BST_UVP_ERR_RLS, 0);
517 		regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
518 				   CS35L41_BST_EN_MASK,
519 				   CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
520 		ret = IRQ_HANDLED;
521 	}
522 
523 	if (status[0] & CS35L41_BST_SHORT_ERR) {
524 		dev_crit_ratelimited(cs35l41->dev, "LBST error: powering off!\n");
525 		regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
526 				   CS35L41_BST_EN_MASK, 0);
527 		regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
528 			     CS35L41_BST_SHORT_ERR);
529 		regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
530 		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
531 				   CS35L41_BST_SHORT_ERR_RLS,
532 				   CS35L41_BST_SHORT_ERR_RLS);
533 		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
534 				   CS35L41_BST_SHORT_ERR_RLS, 0);
535 		regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
536 				   CS35L41_BST_EN_MASK,
537 				   CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
538 		ret = IRQ_HANDLED;
539 	}
540 
541 	return ret;
542 }
543 
544 static const struct reg_sequence cs35l41_pup_patch[] = {
545 	{ 0x00000040, 0x00000055 },
546 	{ 0x00000040, 0x000000AA },
547 	{ 0x00002084, 0x002F1AA0 },
548 	{ 0x00000040, 0x000000CC },
549 	{ 0x00000040, 0x00000033 },
550 };
551 
552 static const struct reg_sequence cs35l41_pdn_patch[] = {
553 	{ 0x00000040, 0x00000055 },
554 	{ 0x00000040, 0x000000AA },
555 	{ 0x00002084, 0x002F1AA3 },
556 	{ 0x00000040, 0x000000CC },
557 	{ 0x00000040, 0x00000033 },
558 };
559 
560 static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w,
561 				  struct snd_kcontrol *kcontrol, int event)
562 {
563 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
564 	struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
565 	unsigned int val;
566 	int ret = 0;
567 
568 	switch (event) {
569 	case SND_SOC_DAPM_POST_PMU:
570 		regmap_multi_reg_write_bypassed(cs35l41->regmap,
571 						cs35l41_pup_patch,
572 						ARRAY_SIZE(cs35l41_pup_patch));
573 
574 		regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1,
575 				   CS35L41_GLOBAL_EN_MASK,
576 				   1 << CS35L41_GLOBAL_EN_SHIFT);
577 
578 		usleep_range(1000, 1100);
579 		break;
580 	case SND_SOC_DAPM_POST_PMD:
581 		regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1,
582 				   CS35L41_GLOBAL_EN_MASK, 0);
583 
584 		ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
585 					       val, val &  CS35L41_PDN_DONE_MASK,
586 					       1000, 100000);
587 		if (ret)
588 			dev_warn(cs35l41->dev, "PDN failed: %d\n", ret);
589 
590 		regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
591 			     CS35L41_PDN_DONE_MASK);
592 
593 		regmap_multi_reg_write_bypassed(cs35l41->regmap,
594 						cs35l41_pdn_patch,
595 						ARRAY_SIZE(cs35l41_pdn_patch));
596 		break;
597 	default:
598 		dev_err(cs35l41->dev, "Invalid event = 0x%x\n", event);
599 		ret = -EINVAL;
600 	}
601 
602 	return ret;
603 }
604 
605 static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = {
606 	SND_SOC_DAPM_OUTPUT("SPK"),
607 
608 	SND_SOC_DAPM_AIF_IN("ASPRX1", NULL, 0, CS35L41_SP_ENABLES, 16, 0),
609 	SND_SOC_DAPM_AIF_IN("ASPRX2", NULL, 0, CS35L41_SP_ENABLES, 17, 0),
610 	SND_SOC_DAPM_AIF_OUT("ASPTX1", NULL, 0, CS35L41_SP_ENABLES, 0, 0),
611 	SND_SOC_DAPM_AIF_OUT("ASPTX2", NULL, 0, CS35L41_SP_ENABLES, 1, 0),
612 	SND_SOC_DAPM_AIF_OUT("ASPTX3", NULL, 0, CS35L41_SP_ENABLES, 2, 0),
613 	SND_SOC_DAPM_AIF_OUT("ASPTX4", NULL, 0, CS35L41_SP_ENABLES, 3, 0),
614 
615 	SND_SOC_DAPM_ADC("VMON ADC", NULL, CS35L41_PWR_CTRL2, 12, 0),
616 	SND_SOC_DAPM_ADC("IMON ADC", NULL, CS35L41_PWR_CTRL2, 13, 0),
617 	SND_SOC_DAPM_ADC("VPMON ADC", NULL, CS35L41_PWR_CTRL2, 8, 0),
618 	SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, CS35L41_PWR_CTRL2, 9, 0),
619 	SND_SOC_DAPM_ADC("TEMPMON ADC", NULL, CS35L41_PWR_CTRL2, 10, 0),
620 	SND_SOC_DAPM_ADC("CLASS H", NULL, CS35L41_PWR_CTRL3, 4, 0),
621 
622 	SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L41_PWR_CTRL2, 0, 0, NULL, 0,
623 			       cs35l41_main_amp_event,
624 			       SND_SOC_DAPM_POST_PMD |	SND_SOC_DAPM_POST_PMU),
625 
626 	SND_SOC_DAPM_INPUT("VP"),
627 	SND_SOC_DAPM_INPUT("VBST"),
628 	SND_SOC_DAPM_INPUT("ISENSE"),
629 	SND_SOC_DAPM_INPUT("VSENSE"),
630 	SND_SOC_DAPM_INPUT("TEMP"),
631 
632 	SND_SOC_DAPM_MUX("ASP TX1 Source", SND_SOC_NOPM, 0, 0, &asp_tx1_mux),
633 	SND_SOC_DAPM_MUX("ASP TX2 Source", SND_SOC_NOPM, 0, 0, &asp_tx2_mux),
634 	SND_SOC_DAPM_MUX("ASP TX3 Source", SND_SOC_NOPM, 0, 0, &asp_tx3_mux),
635 	SND_SOC_DAPM_MUX("ASP TX4 Source", SND_SOC_NOPM, 0, 0, &asp_tx4_mux),
636 	SND_SOC_DAPM_MUX("PCM Source", SND_SOC_NOPM, 0, 0, &pcm_source_mux),
637 	SND_SOC_DAPM_SWITCH("DRE", SND_SOC_NOPM, 0, 0, &dre_ctrl),
638 };
639 
640 static const struct snd_soc_dapm_route cs35l41_audio_map[] = {
641 	{"ASP TX1 Source", "VMON", "VMON ADC"},
642 	{"ASP TX1 Source", "IMON", "IMON ADC"},
643 	{"ASP TX1 Source", "VPMON", "VPMON ADC"},
644 	{"ASP TX1 Source", "VBSTMON", "VBSTMON ADC"},
645 	{"ASP TX1 Source", "ASPRX1", "ASPRX1" },
646 	{"ASP TX1 Source", "ASPRX2", "ASPRX2" },
647 	{"ASP TX2 Source", "VMON", "VMON ADC"},
648 	{"ASP TX2 Source", "IMON", "IMON ADC"},
649 	{"ASP TX2 Source", "VPMON", "VPMON ADC"},
650 	{"ASP TX2 Source", "VBSTMON", "VBSTMON ADC"},
651 	{"ASP TX2 Source", "ASPRX1", "ASPRX1" },
652 	{"ASP TX2 Source", "ASPRX2", "ASPRX2" },
653 	{"ASP TX3 Source", "VMON", "VMON ADC"},
654 	{"ASP TX3 Source", "IMON", "IMON ADC"},
655 	{"ASP TX3 Source", "VPMON", "VPMON ADC"},
656 	{"ASP TX3 Source", "VBSTMON", "VBSTMON ADC"},
657 	{"ASP TX3 Source", "ASPRX1", "ASPRX1" },
658 	{"ASP TX3 Source", "ASPRX2", "ASPRX2" },
659 	{"ASP TX4 Source", "VMON", "VMON ADC"},
660 	{"ASP TX4 Source", "IMON", "IMON ADC"},
661 	{"ASP TX4 Source", "VPMON", "VPMON ADC"},
662 	{"ASP TX4 Source", "VBSTMON", "VBSTMON ADC"},
663 	{"ASP TX4 Source", "ASPRX1", "ASPRX1" },
664 	{"ASP TX4 Source", "ASPRX2", "ASPRX2" },
665 	{"ASPTX1", NULL, "ASP TX1 Source"},
666 	{"ASPTX2", NULL, "ASP TX2 Source"},
667 	{"ASPTX3", NULL, "ASP TX3 Source"},
668 	{"ASPTX4", NULL, "ASP TX4 Source"},
669 	{"AMP Capture", NULL, "ASPTX1"},
670 	{"AMP Capture", NULL, "ASPTX2"},
671 	{"AMP Capture", NULL, "ASPTX3"},
672 	{"AMP Capture", NULL, "ASPTX4"},
673 
674 	{"VMON ADC", NULL, "VSENSE"},
675 	{"IMON ADC", NULL, "ISENSE"},
676 	{"VPMON ADC", NULL, "VP"},
677 	{"TEMPMON ADC", NULL, "TEMP"},
678 	{"VBSTMON ADC", NULL, "VBST"},
679 
680 	{"ASPRX1", NULL, "AMP Playback"},
681 	{"ASPRX2", NULL, "AMP Playback"},
682 	{"DRE", "Switch", "CLASS H"},
683 	{"Main AMP", NULL, "CLASS H"},
684 	{"Main AMP", NULL, "DRE"},
685 	{"SPK", NULL, "Main AMP"},
686 
687 	{"PCM Source", "ASP", "ASPRX1"},
688 	{"CLASS H", NULL, "PCM Source"},
689 };
690 
691 static int cs35l41_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_num,
692 				   unsigned int *tx_slot, unsigned int rx_num,
693 				   unsigned int *rx_slot)
694 {
695 	struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
696 	unsigned int val, mask;
697 	int i;
698 
699 	if (tx_num > 4 || rx_num > 2)
700 		return -EINVAL;
701 
702 	val = 0;
703 	mask = 0;
704 	for (i = 0; i < rx_num; i++) {
705 		dev_dbg(cs35l41->dev, "rx slot %d position = %d\n", i, rx_slot[i]);
706 		val |= rx_slot[i] << (i * 8);
707 		mask |= 0x3F << (i * 8);
708 	}
709 	regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_RX_SLOT, mask, val);
710 
711 	val = 0;
712 	mask = 0;
713 	for (i = 0; i < tx_num; i++) {
714 		dev_dbg(cs35l41->dev, "tx slot %d position = %d\n", i, tx_slot[i]);
715 		val |= tx_slot[i] << (i * 8);
716 		mask |= 0x3F << (i * 8);
717 	}
718 	regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_TX_SLOT, mask, val);
719 
720 	return 0;
721 }
722 
723 static int cs35l41_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
724 {
725 	struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
726 	unsigned int daifmt = 0;
727 
728 	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
729 	case SND_SOC_DAIFMT_CBP_CFP:
730 		daifmt |= CS35L41_SCLK_MSTR_MASK | CS35L41_LRCLK_MSTR_MASK;
731 		break;
732 	case SND_SOC_DAIFMT_CBC_CFC:
733 		break;
734 	default:
735 		dev_warn(cs35l41->dev, "Mixed provider/consumer mode unsupported\n");
736 		return -EINVAL;
737 	}
738 
739 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
740 	case SND_SOC_DAIFMT_DSP_A:
741 		break;
742 	case SND_SOC_DAIFMT_I2S:
743 		daifmt |= 2 << CS35L41_ASP_FMT_SHIFT;
744 		break;
745 	default:
746 		dev_warn(cs35l41->dev, "Invalid or unsupported DAI format\n");
747 		return -EINVAL;
748 	}
749 
750 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
751 	case SND_SOC_DAIFMT_NB_IF:
752 		daifmt |= CS35L41_LRCLK_INV_MASK;
753 		break;
754 	case SND_SOC_DAIFMT_IB_NF:
755 		daifmt |= CS35L41_SCLK_INV_MASK;
756 		break;
757 	case SND_SOC_DAIFMT_IB_IF:
758 		daifmt |= CS35L41_LRCLK_INV_MASK | CS35L41_SCLK_INV_MASK;
759 		break;
760 	case SND_SOC_DAIFMT_NB_NF:
761 		break;
762 	default:
763 		dev_warn(cs35l41->dev, "Invalid DAI clock INV\n");
764 		return -EINVAL;
765 	}
766 
767 	return regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
768 				  CS35L41_SCLK_MSTR_MASK | CS35L41_LRCLK_MSTR_MASK |
769 				  CS35L41_ASP_FMT_MASK | CS35L41_LRCLK_INV_MASK |
770 				  CS35L41_SCLK_INV_MASK, daifmt);
771 }
772 
773 struct cs35l41_global_fs_config {
774 	int rate;
775 	int fs_cfg;
776 };
777 
778 static const struct cs35l41_global_fs_config cs35l41_fs_rates[] = {
779 	{ 12000,	0x01 },
780 	{ 24000,	0x02 },
781 	{ 48000,	0x03 },
782 	{ 96000,	0x04 },
783 	{ 192000,	0x05 },
784 	{ 11025,	0x09 },
785 	{ 22050,	0x0A },
786 	{ 44100,	0x0B },
787 	{ 88200,	0x0C },
788 	{ 176400,	0x0D },
789 	{ 8000,		0x11 },
790 	{ 16000,	0x12 },
791 	{ 32000,	0x13 },
792 };
793 
794 static int cs35l41_pcm_hw_params(struct snd_pcm_substream *substream,
795 				 struct snd_pcm_hw_params *params,
796 				 struct snd_soc_dai *dai)
797 {
798 	struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
799 	unsigned int rate = params_rate(params);
800 	u8 asp_wl;
801 	int i;
802 
803 	for (i = 0; i < ARRAY_SIZE(cs35l41_fs_rates); i++) {
804 		if (rate == cs35l41_fs_rates[i].rate)
805 			break;
806 	}
807 
808 	if (i >= ARRAY_SIZE(cs35l41_fs_rates)) {
809 		dev_err(cs35l41->dev, "Unsupported rate: %u\n", rate);
810 		return -EINVAL;
811 	}
812 
813 	asp_wl = params_width(params);
814 
815 	if (i < ARRAY_SIZE(cs35l41_fs_rates))
816 		regmap_update_bits(cs35l41->regmap, CS35L41_GLOBAL_CLK_CTRL,
817 				   CS35L41_GLOBAL_FS_MASK,
818 				   cs35l41_fs_rates[i].fs_cfg << CS35L41_GLOBAL_FS_SHIFT);
819 
820 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
821 		regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
822 				   CS35L41_ASP_WIDTH_RX_MASK,
823 				   asp_wl << CS35L41_ASP_WIDTH_RX_SHIFT);
824 		regmap_update_bits(cs35l41->regmap, CS35L41_SP_RX_WL,
825 				   CS35L41_ASP_RX_WL_MASK,
826 				   asp_wl << CS35L41_ASP_RX_WL_SHIFT);
827 	} else {
828 		regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
829 				   CS35L41_ASP_WIDTH_TX_MASK,
830 				   asp_wl << CS35L41_ASP_WIDTH_TX_SHIFT);
831 		regmap_update_bits(cs35l41->regmap, CS35L41_SP_TX_WL,
832 				   CS35L41_ASP_TX_WL_MASK,
833 				   asp_wl << CS35L41_ASP_TX_WL_SHIFT);
834 	}
835 
836 	return 0;
837 }
838 
839 static int cs35l41_get_clk_config(int freq)
840 {
841 	int i;
842 
843 	for (i = 0; i < ARRAY_SIZE(cs35l41_pll_sysclk); i++) {
844 		if (cs35l41_pll_sysclk[i].freq == freq)
845 			return cs35l41_pll_sysclk[i].clk_cfg;
846 	}
847 
848 	return -EINVAL;
849 }
850 
851 static const unsigned int cs35l41_src_rates[] = {
852 	8000, 12000, 11025, 16000, 22050, 24000, 32000,
853 	44100, 48000, 88200, 96000, 176400, 192000
854 };
855 
856 static const struct snd_pcm_hw_constraint_list cs35l41_constraints = {
857 	.count = ARRAY_SIZE(cs35l41_src_rates),
858 	.list = cs35l41_src_rates,
859 };
860 
861 static int cs35l41_pcm_startup(struct snd_pcm_substream *substream,
862 			       struct snd_soc_dai *dai)
863 {
864 	if (substream->runtime)
865 		return snd_pcm_hw_constraint_list(substream->runtime, 0,
866 						  SNDRV_PCM_HW_PARAM_RATE,
867 						  &cs35l41_constraints);
868 	return 0;
869 }
870 
871 static int cs35l41_component_set_sysclk(struct snd_soc_component *component,
872 					int clk_id, int source,
873 					unsigned int freq, int dir)
874 {
875 	struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
876 	int extclk_cfg, clksrc;
877 
878 	switch (clk_id) {
879 	case CS35L41_CLKID_SCLK:
880 		clksrc = CS35L41_PLLSRC_SCLK;
881 		break;
882 	case CS35L41_CLKID_LRCLK:
883 		clksrc = CS35L41_PLLSRC_LRCLK;
884 		break;
885 	case CS35L41_CLKID_MCLK:
886 		clksrc = CS35L41_PLLSRC_MCLK;
887 		break;
888 	default:
889 		dev_err(cs35l41->dev, "Invalid CLK Config\n");
890 		return -EINVAL;
891 	}
892 
893 	extclk_cfg = cs35l41_get_clk_config(freq);
894 
895 	if (extclk_cfg < 0) {
896 		dev_err(cs35l41->dev, "Invalid CLK Config: %d, freq: %u\n",
897 			extclk_cfg, freq);
898 		return -EINVAL;
899 	}
900 
901 	regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
902 			   CS35L41_PLL_OPENLOOP_MASK,
903 			   1 << CS35L41_PLL_OPENLOOP_SHIFT);
904 	regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
905 			   CS35L41_REFCLK_FREQ_MASK,
906 			   extclk_cfg << CS35L41_REFCLK_FREQ_SHIFT);
907 	regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
908 			   CS35L41_PLL_CLK_EN_MASK,
909 			   0 << CS35L41_PLL_CLK_EN_SHIFT);
910 	regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
911 			   CS35L41_PLL_CLK_SEL_MASK, clksrc);
912 	regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
913 			   CS35L41_PLL_OPENLOOP_MASK,
914 			   0 << CS35L41_PLL_OPENLOOP_SHIFT);
915 	regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
916 			   CS35L41_PLL_CLK_EN_MASK,
917 			   1 << CS35L41_PLL_CLK_EN_SHIFT);
918 
919 	return 0;
920 }
921 
922 static int cs35l41_dai_set_sysclk(struct snd_soc_dai *dai,
923 				  int clk_id, unsigned int freq, int dir)
924 {
925 	struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
926 	unsigned int fs1_val;
927 	unsigned int fs2_val;
928 	unsigned int val;
929 	int fsindex;
930 
931 	fsindex = cs35l41_get_fs_mon_config_index(freq);
932 	if (fsindex < 0) {
933 		dev_err(cs35l41->dev, "Invalid CLK Config freq: %u\n", freq);
934 		return -EINVAL;
935 	}
936 
937 	dev_dbg(cs35l41->dev, "Set DAI sysclk %d\n", freq);
938 
939 	if (freq <= 6144000) {
940 		/* Use the lookup table */
941 		fs1_val = cs35l41_fs_mon[fsindex].fs1;
942 		fs2_val = cs35l41_fs_mon[fsindex].fs2;
943 	} else {
944 		/* Use hard-coded values */
945 		fs1_val = 0x10;
946 		fs2_val = 0x24;
947 	}
948 
949 	val = fs1_val;
950 	val |= (fs2_val << CS35L41_FS2_WINDOW_SHIFT) & CS35L41_FS2_WINDOW_MASK;
951 	regmap_write(cs35l41->regmap, CS35L41_TST_FS_MON0, val);
952 
953 	return 0;
954 }
955 
956 static int cs35l41_boost_config(struct cs35l41_private *cs35l41,
957 				int boost_ind, int boost_cap, int boost_ipk)
958 {
959 	unsigned char bst_lbst_val, bst_cbst_range, bst_ipk_scaled;
960 	struct regmap *regmap = cs35l41->regmap;
961 	struct device *dev = cs35l41->dev;
962 	int ret;
963 
964 	switch (boost_ind) {
965 	case 1000:	/* 1.0 uH */
966 		bst_lbst_val = 0;
967 		break;
968 	case 1200:	/* 1.2 uH */
969 		bst_lbst_val = 1;
970 		break;
971 	case 1500:	/* 1.5 uH */
972 		bst_lbst_val = 2;
973 		break;
974 	case 2200:	/* 2.2 uH */
975 		bst_lbst_val = 3;
976 		break;
977 	default:
978 		dev_err(dev, "Invalid boost inductor value: %d nH\n", boost_ind);
979 		return -EINVAL;
980 	}
981 
982 	switch (boost_cap) {
983 	case 0 ... 19:
984 		bst_cbst_range = 0;
985 		break;
986 	case 20 ... 50:
987 		bst_cbst_range = 1;
988 		break;
989 	case 51 ... 100:
990 		bst_cbst_range = 2;
991 		break;
992 	case 101 ... 200:
993 		bst_cbst_range = 3;
994 		break;
995 	default:	/* 201 uF and greater */
996 		bst_cbst_range = 4;
997 	}
998 
999 	ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_COEFF,
1000 				 CS35L41_BST_K1_MASK | CS35L41_BST_K2_MASK,
1001 				 cs35l41_bst_k1_table[bst_lbst_val][bst_cbst_range]
1002 					<< CS35L41_BST_K1_SHIFT |
1003 				 cs35l41_bst_k2_table[bst_lbst_val][bst_cbst_range]
1004 					<< CS35L41_BST_K2_SHIFT);
1005 	if (ret) {
1006 		dev_err(dev, "Failed to write boost coefficients: %d\n", ret);
1007 		return ret;
1008 	}
1009 
1010 	ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST,
1011 				 CS35L41_BST_SLOPE_MASK | CS35L41_BST_LBST_VAL_MASK,
1012 				 cs35l41_bst_slope_table[bst_lbst_val]
1013 					<< CS35L41_BST_SLOPE_SHIFT |
1014 				 bst_lbst_val << CS35L41_BST_LBST_VAL_SHIFT);
1015 	if (ret) {
1016 		dev_err(dev, "Failed to write boost slope/inductor value: %d\n", ret);
1017 		return ret;
1018 	}
1019 
1020 	if (boost_ipk < 1600 || boost_ipk > 4500) {
1021 		dev_err(dev, "Invalid boost inductor peak current: %d mA\n",
1022 			boost_ipk);
1023 		return -EINVAL;
1024 	}
1025 	bst_ipk_scaled = ((boost_ipk - 1600) / 50) + 0x10;
1026 
1027 	ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_PEAK_CUR,
1028 				 CS35L41_BST_IPK_MASK,
1029 				 bst_ipk_scaled << CS35L41_BST_IPK_SHIFT);
1030 	if (ret) {
1031 		dev_err(dev, "Failed to write boost inductor peak current: %d\n", ret);
1032 		return ret;
1033 	}
1034 
1035 	return 0;
1036 }
1037 
1038 static int cs35l41_set_pdata(struct cs35l41_private *cs35l41)
1039 {
1040 	int ret;
1041 
1042 	/* Set Platform Data */
1043 	/* Required */
1044 	if (cs35l41->pdata.bst_ipk &&
1045 	    cs35l41->pdata.bst_ind && cs35l41->pdata.bst_cap) {
1046 		ret = cs35l41_boost_config(cs35l41, cs35l41->pdata.bst_ind,
1047 					   cs35l41->pdata.bst_cap,
1048 					   cs35l41->pdata.bst_ipk);
1049 		if (ret) {
1050 			dev_err(cs35l41->dev, "Error in Boost DT config: %d\n", ret);
1051 			return ret;
1052 		}
1053 	} else {
1054 		dev_err(cs35l41->dev, "Incomplete Boost component DT config\n");
1055 		return -EINVAL;
1056 	}
1057 
1058 	/* Optional */
1059 	if (cs35l41->pdata.dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK &&
1060 	    cs35l41->pdata.dout_hiz >= 0)
1061 		regmap_update_bits(cs35l41->regmap, CS35L41_SP_HIZ_CTRL,
1062 				   CS35L41_ASP_DOUT_HIZ_MASK,
1063 				   cs35l41->pdata.dout_hiz);
1064 
1065 	return 0;
1066 }
1067 
1068 static int cs35l41_irq_gpio_config(struct cs35l41_private *cs35l41)
1069 {
1070 	struct cs35l41_irq_cfg *irq_gpio_cfg1 = &cs35l41->pdata.irq_config1;
1071 	struct cs35l41_irq_cfg *irq_gpio_cfg2 = &cs35l41->pdata.irq_config2;
1072 	int irq_pol = IRQF_TRIGGER_NONE;
1073 
1074 	regmap_update_bits(cs35l41->regmap, CS35L41_GPIO1_CTRL1,
1075 			   CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK,
1076 			   irq_gpio_cfg1->irq_pol_inv << CS35L41_GPIO_POL_SHIFT |
1077 			   !irq_gpio_cfg1->irq_out_en << CS35L41_GPIO_DIR_SHIFT);
1078 
1079 	regmap_update_bits(cs35l41->regmap, CS35L41_GPIO2_CTRL1,
1080 			   CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK,
1081 			   irq_gpio_cfg1->irq_pol_inv << CS35L41_GPIO_POL_SHIFT |
1082 			   !irq_gpio_cfg1->irq_out_en << CS35L41_GPIO_DIR_SHIFT);
1083 
1084 	regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL,
1085 			   CS35L41_GPIO1_CTRL_MASK | CS35L41_GPIO2_CTRL_MASK,
1086 			   irq_gpio_cfg1->irq_src_sel << CS35L41_GPIO1_CTRL_SHIFT |
1087 			   irq_gpio_cfg2->irq_src_sel << CS35L41_GPIO2_CTRL_SHIFT);
1088 
1089 	if ((irq_gpio_cfg2->irq_src_sel ==
1090 			(CS35L41_GPIO_CTRL_ACTV_LO | CS35L41_VALID_PDATA)) ||
1091 		(irq_gpio_cfg2->irq_src_sel ==
1092 			(CS35L41_GPIO_CTRL_OPEN_INT | CS35L41_VALID_PDATA)))
1093 		irq_pol = IRQF_TRIGGER_LOW;
1094 	else if (irq_gpio_cfg2->irq_src_sel ==
1095 			(CS35L41_GPIO_CTRL_ACTV_HI | CS35L41_VALID_PDATA))
1096 		irq_pol = IRQF_TRIGGER_HIGH;
1097 
1098 	return irq_pol;
1099 }
1100 
1101 static const struct snd_soc_dai_ops cs35l41_ops = {
1102 	.startup = cs35l41_pcm_startup,
1103 	.set_fmt = cs35l41_set_dai_fmt,
1104 	.hw_params = cs35l41_pcm_hw_params,
1105 	.set_sysclk = cs35l41_dai_set_sysclk,
1106 	.set_channel_map = cs35l41_set_channel_map,
1107 };
1108 
1109 static struct snd_soc_dai_driver cs35l41_dai[] = {
1110 	{
1111 		.name = "cs35l41-pcm",
1112 		.id = 0,
1113 		.playback = {
1114 			.stream_name = "AMP Playback",
1115 			.channels_min = 1,
1116 			.channels_max = 2,
1117 			.rates = SNDRV_PCM_RATE_KNOT,
1118 			.formats = CS35L41_RX_FORMATS,
1119 		},
1120 		.capture = {
1121 			.stream_name = "AMP Capture",
1122 			.channels_min = 1,
1123 			.channels_max = 8,
1124 			.rates = SNDRV_PCM_RATE_KNOT,
1125 			.formats = CS35L41_TX_FORMATS,
1126 		},
1127 		.ops = &cs35l41_ops,
1128 		.symmetric_rate = 1,
1129 	},
1130 };
1131 
1132 static const struct snd_soc_component_driver soc_component_dev_cs35l41 = {
1133 	.name = "cs35l41-codec",
1134 
1135 	.dapm_widgets = cs35l41_dapm_widgets,
1136 	.num_dapm_widgets = ARRAY_SIZE(cs35l41_dapm_widgets),
1137 	.dapm_routes = cs35l41_audio_map,
1138 	.num_dapm_routes = ARRAY_SIZE(cs35l41_audio_map),
1139 
1140 	.controls = cs35l41_aud_controls,
1141 	.num_controls = ARRAY_SIZE(cs35l41_aud_controls),
1142 	.set_sysclk = cs35l41_component_set_sysclk,
1143 };
1144 
1145 static int cs35l41_handle_pdata(struct device *dev,
1146 				struct cs35l41_platform_data *pdata,
1147 				struct cs35l41_private *cs35l41)
1148 {
1149 	struct cs35l41_irq_cfg *irq_gpio1_config = &pdata->irq_config1;
1150 	struct cs35l41_irq_cfg *irq_gpio2_config = &pdata->irq_config2;
1151 	unsigned int val;
1152 	int ret;
1153 
1154 	ret = device_property_read_u32(dev, "cirrus,boost-peak-milliamp", &val);
1155 	if (ret >= 0)
1156 		pdata->bst_ipk = val;
1157 
1158 	ret = device_property_read_u32(dev, "cirrus,boost-ind-nanohenry", &val);
1159 	if (ret >= 0)
1160 		pdata->bst_ind = val;
1161 
1162 	ret = device_property_read_u32(dev, "cirrus,boost-cap-microfarad", &val);
1163 	if (ret >= 0)
1164 		pdata->bst_cap = val;
1165 
1166 	ret = device_property_read_u32(dev, "cirrus,asp-sdout-hiz", &val);
1167 	if (ret >= 0)
1168 		pdata->dout_hiz = val;
1169 	else
1170 		pdata->dout_hiz = -1;
1171 
1172 	/* GPIO1 Pin Config */
1173 	irq_gpio1_config->irq_pol_inv = device_property_read_bool(dev,
1174 					"cirrus,gpio1-polarity-invert");
1175 	irq_gpio1_config->irq_out_en = device_property_read_bool(dev,
1176 					"cirrus,gpio1-output-enable");
1177 	ret = device_property_read_u32(dev, "cirrus,gpio1-src-select",
1178 				       &val);
1179 	if (ret >= 0)
1180 		irq_gpio1_config->irq_src_sel = val | CS35L41_VALID_PDATA;
1181 
1182 	/* GPIO2 Pin Config */
1183 	irq_gpio2_config->irq_pol_inv = device_property_read_bool(dev,
1184 					"cirrus,gpio2-polarity-invert");
1185 	irq_gpio2_config->irq_out_en = device_property_read_bool(dev,
1186 					"cirrus,gpio2-output-enable");
1187 	ret = device_property_read_u32(dev, "cirrus,gpio2-src-select",
1188 				       &val);
1189 	if (ret >= 0)
1190 		irq_gpio2_config->irq_src_sel = val | CS35L41_VALID_PDATA;
1191 
1192 	return 0;
1193 }
1194 
1195 static const struct reg_sequence cs35l41_reva0_errata_patch[] = {
1196 	{ 0x00000040,			 0x00005555 },
1197 	{ 0x00000040,			 0x0000AAAA },
1198 	{ 0x00003854,			 0x05180240 },
1199 	{ CS35L41_VIMON_SPKMON_RESYNC,	 0x00000000 },
1200 	{ 0x00004310,			 0x00000000 },
1201 	{ CS35L41_VPVBST_FS_SEL,	 0x00000000 },
1202 	{ CS35L41_OTP_TRIM_30,		 0x9091A1C8 },
1203 	{ 0x00003014,			 0x0200EE0E },
1204 	{ CS35L41_BSTCVRT_DCM_CTRL,	 0x00000051 },
1205 	{ 0x00000054,			 0x00000004 },
1206 	{ CS35L41_IRQ1_DB3,		 0x00000000 },
1207 	{ CS35L41_IRQ2_DB3,		 0x00000000 },
1208 	{ CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
1209 	{ CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
1210 	{ 0x00000040,			 0x0000CCCC },
1211 	{ 0x00000040,			 0x00003333 },
1212 };
1213 
1214 static const struct reg_sequence cs35l41_revb0_errata_patch[] = {
1215 	{ 0x00000040,			 0x00005555 },
1216 	{ 0x00000040,			 0x0000AAAA },
1217 	{ CS35L41_VIMON_SPKMON_RESYNC,	 0x00000000 },
1218 	{ 0x00004310,			 0x00000000 },
1219 	{ CS35L41_VPVBST_FS_SEL,	 0x00000000 },
1220 	{ CS35L41_BSTCVRT_DCM_CTRL,	 0x00000051 },
1221 	{ CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
1222 	{ CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
1223 	{ 0x00000040,			 0x0000CCCC },
1224 	{ 0x00000040,			 0x00003333 },
1225 };
1226 
1227 static const struct reg_sequence cs35l41_revb2_errata_patch[] = {
1228 	{ 0x00000040,			 0x00005555 },
1229 	{ 0x00000040,			 0x0000AAAA },
1230 	{ CS35L41_VIMON_SPKMON_RESYNC,	 0x00000000 },
1231 	{ 0x00004310,			 0x00000000 },
1232 	{ CS35L41_VPVBST_FS_SEL,	 0x00000000 },
1233 	{ CS35L41_BSTCVRT_DCM_CTRL,	 0x00000051 },
1234 	{ CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
1235 	{ CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
1236 	{ 0x00000040,			 0x0000CCCC },
1237 	{ 0x00000040,			 0x00003333 },
1238 };
1239 
1240 int cs35l41_probe(struct cs35l41_private *cs35l41,
1241 		  struct cs35l41_platform_data *pdata)
1242 {
1243 	u32 regid, reg_revid, i, mtl_revid, int_status, chipid_match;
1244 	int irq_pol = 0;
1245 	int ret;
1246 
1247 	if (pdata) {
1248 		cs35l41->pdata = *pdata;
1249 	} else {
1250 		ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->pdata, cs35l41);
1251 		if (ret != 0)
1252 			return ret;
1253 	}
1254 
1255 	for (i = 0; i < CS35L41_NUM_SUPPLIES; i++)
1256 		cs35l41->supplies[i].supply = cs35l41_supplies[i];
1257 
1258 	ret = devm_regulator_bulk_get(cs35l41->dev, CS35L41_NUM_SUPPLIES,
1259 				      cs35l41->supplies);
1260 	if (ret != 0) {
1261 		dev_err(cs35l41->dev, "Failed to request core supplies: %d\n", ret);
1262 		return ret;
1263 	}
1264 
1265 	ret = regulator_bulk_enable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
1266 	if (ret != 0) {
1267 		dev_err(cs35l41->dev, "Failed to enable core supplies: %d\n", ret);
1268 		return ret;
1269 	}
1270 
1271 	/* returning NULL can be an option if in stereo mode */
1272 	cs35l41->reset_gpio = devm_gpiod_get_optional(cs35l41->dev, "reset",
1273 						      GPIOD_OUT_LOW);
1274 	if (IS_ERR(cs35l41->reset_gpio)) {
1275 		ret = PTR_ERR(cs35l41->reset_gpio);
1276 		cs35l41->reset_gpio = NULL;
1277 		if (ret == -EBUSY) {
1278 			dev_info(cs35l41->dev,
1279 				 "Reset line busy, assuming shared reset\n");
1280 		} else {
1281 			dev_err(cs35l41->dev,
1282 				"Failed to get reset GPIO: %d\n", ret);
1283 			goto err;
1284 		}
1285 	}
1286 	if (cs35l41->reset_gpio) {
1287 		/* satisfy minimum reset pulse width spec */
1288 		usleep_range(2000, 2100);
1289 		gpiod_set_value_cansleep(cs35l41->reset_gpio, 1);
1290 	}
1291 
1292 	usleep_range(2000, 2100);
1293 
1294 	ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS4,
1295 				       int_status, int_status & CS35L41_OTP_BOOT_DONE,
1296 				       1000, 100000);
1297 	if (ret) {
1298 		dev_err(cs35l41->dev,
1299 			"Failed waiting for OTP_BOOT_DONE: %d\n", ret);
1300 		goto err;
1301 	}
1302 
1303 	regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_status);
1304 	if (int_status & CS35L41_OTP_BOOT_ERR) {
1305 		dev_err(cs35l41->dev, "OTP Boot error\n");
1306 		ret = -EINVAL;
1307 		goto err;
1308 	}
1309 
1310 	ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, &regid);
1311 	if (ret < 0) {
1312 		dev_err(cs35l41->dev, "Get Device ID failed: %d\n", ret);
1313 		goto err;
1314 	}
1315 
1316 	ret = regmap_read(cs35l41->regmap, CS35L41_REVID, &reg_revid);
1317 	if (ret < 0) {
1318 		dev_err(cs35l41->dev, "Get Revision ID failed: %d\n", ret);
1319 		goto err;
1320 	}
1321 
1322 	mtl_revid = reg_revid & CS35L41_MTLREVID_MASK;
1323 
1324 	/* CS35L41 will have even MTLREVID
1325 	 * CS35L41R will have odd MTLREVID
1326 	 */
1327 	chipid_match = (mtl_revid % 2) ? CS35L41R_CHIP_ID : CS35L41_CHIP_ID;
1328 	if (regid != chipid_match) {
1329 		dev_err(cs35l41->dev, "CS35L41 Device ID (%X). Expected ID %X\n",
1330 			regid, chipid_match);
1331 		ret = -ENODEV;
1332 		goto err;
1333 	}
1334 
1335 	switch (reg_revid) {
1336 	case CS35L41_REVID_A0:
1337 		ret = regmap_register_patch(cs35l41->regmap,
1338 					    cs35l41_reva0_errata_patch,
1339 					    ARRAY_SIZE(cs35l41_reva0_errata_patch));
1340 		if (ret < 0) {
1341 			dev_err(cs35l41->dev,
1342 				"Failed to apply A0 errata patch: %d\n", ret);
1343 			goto err;
1344 		}
1345 		break;
1346 	case CS35L41_REVID_B0:
1347 		ret = regmap_register_patch(cs35l41->regmap,
1348 					    cs35l41_revb0_errata_patch,
1349 					    ARRAY_SIZE(cs35l41_revb0_errata_patch));
1350 		if (ret < 0) {
1351 			dev_err(cs35l41->dev,
1352 				"Failed to apply B0 errata patch: %d\n", ret);
1353 			goto err;
1354 		}
1355 		break;
1356 	case CS35L41_REVID_B2:
1357 		ret = regmap_register_patch(cs35l41->regmap,
1358 					    cs35l41_revb2_errata_patch,
1359 					    ARRAY_SIZE(cs35l41_revb2_errata_patch));
1360 		if (ret < 0) {
1361 			dev_err(cs35l41->dev,
1362 				"Failed to apply B2 errata patch: %d\n", ret);
1363 			goto err;
1364 		}
1365 		break;
1366 	}
1367 
1368 	irq_pol = cs35l41_irq_gpio_config(cs35l41);
1369 
1370 	/* Set interrupt masks for critical errors */
1371 	regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1,
1372 		     CS35L41_INT1_MASK_DEFAULT);
1373 
1374 	ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, cs35l41_irq,
1375 					IRQF_ONESHOT | IRQF_SHARED | irq_pol,
1376 					"cs35l41", cs35l41);
1377 
1378 	/* CS35L41 needs INT for PDN_DONE */
1379 	if (ret != 0) {
1380 		dev_err(cs35l41->dev, "Failed to request IRQ: %d\n", ret);
1381 		goto err;
1382 	}
1383 
1384 	ret = cs35l41_otp_unpack(cs35l41);
1385 	if (ret < 0) {
1386 		dev_err(cs35l41->dev, "OTP Unpack failed: %d\n", ret);
1387 		goto err;
1388 	}
1389 
1390 	ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_CCM_CORE_CTRL, 0);
1391 	if (ret < 0) {
1392 		dev_err(cs35l41->dev, "Write CCM_CORE_CTRL failed: %d\n", ret);
1393 		goto err;
1394 	}
1395 
1396 	ret = regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
1397 				 CS35L41_AMP_EN_MASK, 0);
1398 	if (ret < 0) {
1399 		dev_err(cs35l41->dev, "Write CS35L41_PWR_CTRL2 failed: %d\n", ret);
1400 		goto err;
1401 	}
1402 
1403 	ret = regmap_update_bits(cs35l41->regmap, CS35L41_AMP_GAIN_CTRL,
1404 				 CS35L41_AMP_GAIN_PCM_MASK, 0);
1405 	if (ret < 0) {
1406 		dev_err(cs35l41->dev, "Write CS35L41_AMP_GAIN_CTRL failed: %d\n", ret);
1407 		goto err;
1408 	}
1409 
1410 	ret = cs35l41_set_pdata(cs35l41);
1411 	if (ret < 0) {
1412 		dev_err(cs35l41->dev, "Set pdata failed: %d\n", ret);
1413 		goto err;
1414 	}
1415 
1416 	ret = devm_snd_soc_register_component(cs35l41->dev,
1417 					      &soc_component_dev_cs35l41,
1418 					      cs35l41_dai, ARRAY_SIZE(cs35l41_dai));
1419 	if (ret < 0) {
1420 		dev_err(cs35l41->dev, "Register codec failed: %d\n", ret);
1421 		goto err;
1422 	}
1423 
1424 	dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n",
1425 		 regid, reg_revid);
1426 
1427 	return 0;
1428 
1429 err:
1430 	regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
1431 	gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
1432 
1433 	return ret;
1434 }
1435 
1436 void cs35l41_remove(struct cs35l41_private *cs35l41)
1437 {
1438 	regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF);
1439 	regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
1440 	gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
1441 }
1442 
1443 MODULE_DESCRIPTION("ASoC CS35L41 driver");
1444 MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>");
1445 MODULE_LICENSE("GPL");
1446