1
2
3
4
5
6
7
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
27static const char * const cs35l41_supplies[CS35L41_NUM_SUPPLIES] = {
28 "VA",
29 "VP",
30};
31
32struct cs35l41_pll_sysclk_config {
33 int freq;
34 int clk_cfg;
35};
36
37static 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
104struct cs35l41_fs_mon_config {
105 int freq;
106 unsigned int fs1;
107 unsigned int fs2;
108};
109
110static 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
154static 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
161static 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
168static const unsigned char cs35l41_bst_slope_table[4] = {
169 0x75, 0x6B, 0x3B, 0x28
170};
171
172static 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
184static 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));
187static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1);
188
189static const struct snd_kcontrol_new dre_ctrl =
190 SOC_DAPM_SINGLE("Switch", CS35L41_PWR_CTRL3, 20, 1, 0);
191
192static const char * const cs35l41_pcm_sftramp_text[] = {
193 "Off", ".5ms", "1ms", "2ms", "4ms", "8ms", "15ms", "30ms"
194};
195
196static SOC_ENUM_SINGLE_DECL(pcm_sft_ramp,
197 CS35L41_AMP_DIG_VOL_CTRL, 0,
198 cs35l41_pcm_sftramp_text);
199
200static const char * const cs35l41_pcm_source_texts[] = {"ASP", "DSP"};
201static const unsigned int cs35l41_pcm_source_values[] = {0x08, 0x32};
202static 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
208static const struct snd_kcontrol_new pcm_source_mux =
209 SOC_DAPM_ENUM("PCM Source", cs35l41_pcm_source_enum);
210
211static const char * const cs35l41_tx_input_texts[] = {
212 "Zero", "ASPRX1", "ASPRX2", "VMON", "IMON",
213 "VPMON", "VBSTMON", "DSPTX1", "DSPTX2"
214};
215
216static 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
222static 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
228static const struct snd_kcontrol_new asp_tx1_mux =
229 SOC_DAPM_ENUM("ASPTX1 SRC", cs35l41_asptx1_enum);
230
231static 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
237static const struct snd_kcontrol_new asp_tx2_mux =
238 SOC_DAPM_ENUM("ASPTX2 SRC", cs35l41_asptx2_enum);
239
240static 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
246static const struct snd_kcontrol_new asp_tx3_mux =
247 SOC_DAPM_ENUM("ASPTX3 SRC", cs35l41_asptx3_enum);
248
249static 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
255static const struct snd_kcontrol_new asp_tx4_mux =
256 SOC_DAPM_ENUM("ASPTX4 SRC", cs35l41_asptx4_enum);
257
258static 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
287static 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
299static 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 bit_sum = 8;
306 u32 otp_val, otp_id_reg;
307 u32 *otp_mem;
308
309 otp_mem = kmalloc_array(CS35L41_OTP_SIZE_WORDS, sizeof(*otp_mem), GFP_KERNEL);
310 if (!otp_mem)
311 return -ENOMEM;
312
313 ret = regmap_read(cs35l41->regmap, CS35L41_OTPID, &otp_id_reg);
314 if (ret < 0) {
315 dev_err(cs35l41->dev, "Read OTP ID failed: %d\n", ret);
316 goto err_otp_unpack;
317 }
318
319 otp_map_match = cs35l41_find_otp_map(otp_id_reg);
320
321 if (!otp_map_match) {
322 dev_err(cs35l41->dev, "OTP Map matching ID %d not found\n",
323 otp_id_reg);
324 ret = -EINVAL;
325 goto err_otp_unpack;
326 }
327
328 ret = regmap_bulk_read(cs35l41->regmap, CS35L41_OTP_MEM0, otp_mem,
329 CS35L41_OTP_SIZE_WORDS);
330 if (ret < 0) {
331 dev_err(cs35l41->dev, "Read OTP Mem failed: %d\n", ret);
332 goto err_otp_unpack;
333 }
334
335 otp_map = otp_map_match->map;
336
337 bit_offset = otp_map_match->bit_offset;
338 word_offset = otp_map_match->word_offset;
339
340 ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000055);
341 if (ret < 0) {
342 dev_err(cs35l41->dev, "Write Unlock key failed 1/2: %d\n", ret);
343 goto err_otp_unpack;
344 }
345 ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000AA);
346 if (ret < 0) {
347 dev_err(cs35l41->dev, "Write Unlock key failed 2/2: %d\n", ret);
348 goto err_otp_unpack;
349 }
350
351 for (i = 0; i < otp_map_match->num_elements; i++) {
352 dev_dbg(cs35l41->dev,
353 "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d\n",
354 bit_offset, word_offset, bit_sum % 32);
355 if (bit_offset + otp_map[i].size - 1 >= 32) {
356 otp_val = (otp_mem[word_offset] &
357 GENMASK(31, bit_offset)) >>
358 bit_offset;
359 otp_val |= (otp_mem[++word_offset] &
360 GENMASK(bit_offset +
361 otp_map[i].size - 33, 0)) <<
362 (32 - bit_offset);
363 bit_offset += otp_map[i].size - 32;
364 } else {
365 otp_val = (otp_mem[word_offset] &
366 GENMASK(bit_offset + otp_map[i].size - 1,
367 bit_offset)) >> bit_offset;
368 bit_offset += otp_map[i].size;
369 }
370 bit_sum += otp_map[i].size;
371
372 if (bit_offset == 32) {
373 bit_offset = 0;
374 word_offset++;
375 }
376
377 if (otp_map[i].reg != 0) {
378 ret = regmap_update_bits(cs35l41->regmap,
379 otp_map[i].reg,
380 GENMASK(otp_map[i].shift +
381 otp_map[i].size - 1,
382 otp_map[i].shift),
383 otp_val << otp_map[i].shift);
384 if (ret < 0) {
385 dev_err(cs35l41->dev, "Write OTP val failed: %d\n",
386 ret);
387 goto err_otp_unpack;
388 }
389 }
390 }
391
392 ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000CC);
393 if (ret < 0) {
394 dev_err(cs35l41->dev, "Write Lock key failed 1/2: %d\n", ret);
395 goto err_otp_unpack;
396 }
397 ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000033);
398 if (ret < 0) {
399 dev_err(cs35l41->dev, "Write Lock key failed 2/2: %d\n", ret);
400 goto err_otp_unpack;
401 }
402 ret = 0;
403
404err_otp_unpack:
405 kfree(otp_mem);
406 return ret;
407}
408
409static irqreturn_t cs35l41_irq(int irq, void *data)
410{
411 struct cs35l41_private *cs35l41 = data;
412 unsigned int status[4] = { 0, 0, 0, 0 };
413 unsigned int masks[4] = { 0, 0, 0, 0 };
414 int ret = IRQ_NONE;
415 unsigned int i;
416
417 for (i = 0; i < ARRAY_SIZE(status); i++) {
418 regmap_read(cs35l41->regmap,
419 CS35L41_IRQ1_STATUS1 + (i * CS35L41_REGSTRIDE),
420 &status[i]);
421 regmap_read(cs35l41->regmap,
422 CS35L41_IRQ1_MASK1 + (i * CS35L41_REGSTRIDE),
423 &masks[i]);
424 }
425
426
427 if (!(status[0] & ~masks[0]) && !(status[1] & ~masks[1]) &&
428 !(status[2] & ~masks[2]) && !(status[3] & ~masks[3]))
429 return IRQ_NONE;
430
431 if (status[3] & CS35L41_OTP_BOOT_DONE) {
432 regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK4,
433 CS35L41_OTP_BOOT_DONE, CS35L41_OTP_BOOT_DONE);
434 }
435
436
437
438
439
440
441 if (status[0] & CS35L41_AMP_SHORT_ERR) {
442 dev_crit_ratelimited(cs35l41->dev, "Amp short error\n");
443 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
444 CS35L41_AMP_SHORT_ERR);
445 regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
446 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
447 CS35L41_AMP_SHORT_ERR_RLS,
448 CS35L41_AMP_SHORT_ERR_RLS);
449 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
450 CS35L41_AMP_SHORT_ERR_RLS, 0);
451 ret = IRQ_HANDLED;
452 }
453
454 if (status[0] & CS35L41_TEMP_WARN) {
455 dev_crit_ratelimited(cs35l41->dev, "Over temperature warning\n");
456 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
457 CS35L41_TEMP_WARN);
458 regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
459 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
460 CS35L41_TEMP_WARN_ERR_RLS,
461 CS35L41_TEMP_WARN_ERR_RLS);
462 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
463 CS35L41_TEMP_WARN_ERR_RLS, 0);
464 ret = IRQ_HANDLED;
465 }
466
467 if (status[0] & CS35L41_TEMP_ERR) {
468 dev_crit_ratelimited(cs35l41->dev, "Over temperature error\n");
469 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
470 CS35L41_TEMP_ERR);
471 regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
472 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
473 CS35L41_TEMP_ERR_RLS,
474 CS35L41_TEMP_ERR_RLS);
475 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
476 CS35L41_TEMP_ERR_RLS, 0);
477 ret = IRQ_HANDLED;
478 }
479
480 if (status[0] & CS35L41_BST_OVP_ERR) {
481 dev_crit_ratelimited(cs35l41->dev, "VBST Over Voltage error\n");
482 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
483 CS35L41_BST_EN_MASK, 0);
484 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
485 CS35L41_BST_OVP_ERR);
486 regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
487 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
488 CS35L41_BST_OVP_ERR_RLS,
489 CS35L41_BST_OVP_ERR_RLS);
490 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
491 CS35L41_BST_OVP_ERR_RLS, 0);
492 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
493 CS35L41_BST_EN_MASK,
494 CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
495 ret = IRQ_HANDLED;
496 }
497
498 if (status[0] & CS35L41_BST_DCM_UVP_ERR) {
499 dev_crit_ratelimited(cs35l41->dev, "DCM VBST Under Voltage Error\n");
500 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
501 CS35L41_BST_EN_MASK, 0);
502 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
503 CS35L41_BST_DCM_UVP_ERR);
504 regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
505 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
506 CS35L41_BST_UVP_ERR_RLS,
507 CS35L41_BST_UVP_ERR_RLS);
508 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
509 CS35L41_BST_UVP_ERR_RLS, 0);
510 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
511 CS35L41_BST_EN_MASK,
512 CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
513 ret = IRQ_HANDLED;
514 }
515
516 if (status[0] & CS35L41_BST_SHORT_ERR) {
517 dev_crit_ratelimited(cs35l41->dev, "LBST error: powering off!\n");
518 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
519 CS35L41_BST_EN_MASK, 0);
520 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
521 CS35L41_BST_SHORT_ERR);
522 regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
523 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
524 CS35L41_BST_SHORT_ERR_RLS,
525 CS35L41_BST_SHORT_ERR_RLS);
526 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
527 CS35L41_BST_SHORT_ERR_RLS, 0);
528 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
529 CS35L41_BST_EN_MASK,
530 CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
531 ret = IRQ_HANDLED;
532 }
533
534 return ret;
535}
536
537static const struct reg_sequence cs35l41_pup_patch[] = {
538 { 0x00000040, 0x00000055 },
539 { 0x00000040, 0x000000AA },
540 { 0x00002084, 0x002F1AA0 },
541 { 0x00000040, 0x000000CC },
542 { 0x00000040, 0x00000033 },
543};
544
545static const struct reg_sequence cs35l41_pdn_patch[] = {
546 { 0x00000040, 0x00000055 },
547 { 0x00000040, 0x000000AA },
548 { 0x00002084, 0x002F1AA3 },
549 { 0x00000040, 0x000000CC },
550 { 0x00000040, 0x00000033 },
551};
552
553static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w,
554 struct snd_kcontrol *kcontrol, int event)
555{
556 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
557 struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
558 unsigned int val;
559 int ret = 0;
560
561 switch (event) {
562 case SND_SOC_DAPM_POST_PMU:
563 regmap_multi_reg_write_bypassed(cs35l41->regmap,
564 cs35l41_pup_patch,
565 ARRAY_SIZE(cs35l41_pup_patch));
566
567 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1,
568 CS35L41_GLOBAL_EN_MASK,
569 1 << CS35L41_GLOBAL_EN_SHIFT);
570
571 usleep_range(1000, 1100);
572 break;
573 case SND_SOC_DAPM_POST_PMD:
574 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1,
575 CS35L41_GLOBAL_EN_MASK, 0);
576
577 ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
578 val, val & CS35L41_PDN_DONE_MASK,
579 1000, 100000);
580 if (ret)
581 dev_warn(cs35l41->dev, "PDN failed: %d\n", ret);
582
583 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
584 CS35L41_PDN_DONE_MASK);
585
586 regmap_multi_reg_write_bypassed(cs35l41->regmap,
587 cs35l41_pdn_patch,
588 ARRAY_SIZE(cs35l41_pdn_patch));
589 break;
590 default:
591 dev_err(cs35l41->dev, "Invalid event = 0x%x\n", event);
592 ret = -EINVAL;
593 }
594
595 return ret;
596}
597
598static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = {
599 SND_SOC_DAPM_OUTPUT("SPK"),
600
601 SND_SOC_DAPM_AIF_IN("ASPRX1", NULL, 0, CS35L41_SP_ENABLES, 16, 0),
602 SND_SOC_DAPM_AIF_IN("ASPRX2", NULL, 0, CS35L41_SP_ENABLES, 17, 0),
603 SND_SOC_DAPM_AIF_OUT("ASPTX1", NULL, 0, CS35L41_SP_ENABLES, 0, 0),
604 SND_SOC_DAPM_AIF_OUT("ASPTX2", NULL, 0, CS35L41_SP_ENABLES, 1, 0),
605 SND_SOC_DAPM_AIF_OUT("ASPTX3", NULL, 0, CS35L41_SP_ENABLES, 2, 0),
606 SND_SOC_DAPM_AIF_OUT("ASPTX4", NULL, 0, CS35L41_SP_ENABLES, 3, 0),
607
608 SND_SOC_DAPM_SIGGEN("VSENSE"),
609 SND_SOC_DAPM_SIGGEN("ISENSE"),
610 SND_SOC_DAPM_SIGGEN("VP"),
611 SND_SOC_DAPM_SIGGEN("VBST"),
612 SND_SOC_DAPM_SIGGEN("TEMP"),
613
614 SND_SOC_DAPM_ADC("VMON ADC", NULL, CS35L41_PWR_CTRL2, 12, 0),
615 SND_SOC_DAPM_ADC("IMON ADC", NULL, CS35L41_PWR_CTRL2, 13, 0),
616 SND_SOC_DAPM_ADC("VPMON ADC", NULL, CS35L41_PWR_CTRL2, 8, 0),
617 SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, CS35L41_PWR_CTRL2, 9, 0),
618 SND_SOC_DAPM_ADC("TEMPMON ADC", NULL, CS35L41_PWR_CTRL2, 10, 0),
619 SND_SOC_DAPM_ADC("CLASS H", NULL, CS35L41_PWR_CTRL3, 4, 0),
620
621 SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L41_PWR_CTRL2, 0, 0, NULL, 0,
622 cs35l41_main_amp_event,
623 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
624
625 SND_SOC_DAPM_MUX("ASP TX1 Source", SND_SOC_NOPM, 0, 0, &asp_tx1_mux),
626 SND_SOC_DAPM_MUX("ASP TX2 Source", SND_SOC_NOPM, 0, 0, &asp_tx2_mux),
627 SND_SOC_DAPM_MUX("ASP TX3 Source", SND_SOC_NOPM, 0, 0, &asp_tx3_mux),
628 SND_SOC_DAPM_MUX("ASP TX4 Source", SND_SOC_NOPM, 0, 0, &asp_tx4_mux),
629 SND_SOC_DAPM_MUX("PCM Source", SND_SOC_NOPM, 0, 0, &pcm_source_mux),
630 SND_SOC_DAPM_SWITCH("DRE", SND_SOC_NOPM, 0, 0, &dre_ctrl),
631};
632
633static const struct snd_soc_dapm_route cs35l41_audio_map[] = {
634 {"ASP TX1 Source", "VMON", "VMON ADC"},
635 {"ASP TX1 Source", "IMON", "IMON ADC"},
636 {"ASP TX1 Source", "VPMON", "VPMON ADC"},
637 {"ASP TX1 Source", "VBSTMON", "VBSTMON ADC"},
638 {"ASP TX1 Source", "ASPRX1", "ASPRX1" },
639 {"ASP TX1 Source", "ASPRX2", "ASPRX2" },
640 {"ASP TX2 Source", "VMON", "VMON ADC"},
641 {"ASP TX2 Source", "IMON", "IMON ADC"},
642 {"ASP TX2 Source", "VPMON", "VPMON ADC"},
643 {"ASP TX2 Source", "VBSTMON", "VBSTMON ADC"},
644 {"ASP TX2 Source", "ASPRX1", "ASPRX1" },
645 {"ASP TX2 Source", "ASPRX2", "ASPRX2" },
646 {"ASP TX3 Source", "VMON", "VMON ADC"},
647 {"ASP TX3 Source", "IMON", "IMON ADC"},
648 {"ASP TX3 Source", "VPMON", "VPMON ADC"},
649 {"ASP TX3 Source", "VBSTMON", "VBSTMON ADC"},
650 {"ASP TX3 Source", "ASPRX1", "ASPRX1" },
651 {"ASP TX3 Source", "ASPRX2", "ASPRX2" },
652 {"ASP TX4 Source", "VMON", "VMON ADC"},
653 {"ASP TX4 Source", "IMON", "IMON ADC"},
654 {"ASP TX4 Source", "VPMON", "VPMON ADC"},
655 {"ASP TX4 Source", "VBSTMON", "VBSTMON ADC"},
656 {"ASP TX4 Source", "ASPRX1", "ASPRX1" },
657 {"ASP TX4 Source", "ASPRX2", "ASPRX2" },
658 {"ASPTX1", NULL, "ASP TX1 Source"},
659 {"ASPTX2", NULL, "ASP TX2 Source"},
660 {"ASPTX3", NULL, "ASP TX3 Source"},
661 {"ASPTX4", NULL, "ASP TX4 Source"},
662 {"AMP Capture", NULL, "ASPTX1"},
663 {"AMP Capture", NULL, "ASPTX2"},
664 {"AMP Capture", NULL, "ASPTX3"},
665 {"AMP Capture", NULL, "ASPTX4"},
666
667 {"VMON ADC", NULL, "VSENSE"},
668 {"IMON ADC", NULL, "ISENSE"},
669 {"VPMON ADC", NULL, "VP"},
670 {"VBSTMON ADC", NULL, "VBST"},
671 {"TEMPMON ADC", NULL, "TEMP"},
672
673 {"ASPRX1", NULL, "AMP Playback"},
674 {"ASPRX2", NULL, "AMP Playback"},
675 {"DRE", "Switch", "CLASS H"},
676 {"Main AMP", NULL, "CLASS H"},
677 {"Main AMP", NULL, "DRE"},
678 {"SPK", NULL, "Main AMP"},
679
680 {"PCM Source", "ASP", "ASPRX1"},
681 {"CLASS H", NULL, "PCM Source"},
682};
683
684static int cs35l41_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_num,
685 unsigned int *tx_slot, unsigned int rx_num,
686 unsigned int *rx_slot)
687{
688 struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
689 unsigned int val, mask;
690 int i;
691
692 if (tx_num > 4 || rx_num > 2)
693 return -EINVAL;
694
695 val = 0;
696 mask = 0;
697 for (i = 0; i < rx_num; i++) {
698 dev_dbg(cs35l41->dev, "rx slot %d position = %d\n", i, rx_slot[i]);
699 val |= rx_slot[i] << (i * 8);
700 mask |= 0x3F << (i * 8);
701 }
702 regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_RX_SLOT, mask, val);
703
704 val = 0;
705 mask = 0;
706 for (i = 0; i < tx_num; i++) {
707 dev_dbg(cs35l41->dev, "tx slot %d position = %d\n", i, tx_slot[i]);
708 val |= tx_slot[i] << (i * 8);
709 mask |= 0x3F << (i * 8);
710 }
711 regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_TX_SLOT, mask, val);
712
713 return 0;
714}
715
716static int cs35l41_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
717{
718 struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
719 unsigned int daifmt = 0;
720
721 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
722 case SND_SOC_DAIFMT_CBP_CFP:
723 daifmt |= CS35L41_SCLK_MSTR_MASK | CS35L41_LRCLK_MSTR_MASK;
724 break;
725 case SND_SOC_DAIFMT_CBC_CFC:
726 break;
727 default:
728 dev_warn(cs35l41->dev, "Mixed provider/consumer mode unsupported\n");
729 return -EINVAL;
730 }
731
732 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
733 case SND_SOC_DAIFMT_DSP_A:
734 break;
735 case SND_SOC_DAIFMT_I2S:
736 daifmt |= 2 << CS35L41_ASP_FMT_SHIFT;
737 break;
738 default:
739 dev_warn(cs35l41->dev, "Invalid or unsupported DAI format\n");
740 return -EINVAL;
741 }
742
743 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
744 case SND_SOC_DAIFMT_NB_IF:
745 daifmt |= CS35L41_LRCLK_INV_MASK;
746 break;
747 case SND_SOC_DAIFMT_IB_NF:
748 daifmt |= CS35L41_SCLK_INV_MASK;
749 break;
750 case SND_SOC_DAIFMT_IB_IF:
751 daifmt |= CS35L41_LRCLK_INV_MASK | CS35L41_SCLK_INV_MASK;
752 break;
753 case SND_SOC_DAIFMT_NB_NF:
754 break;
755 default:
756 dev_warn(cs35l41->dev, "Invalid DAI clock INV\n");
757 return -EINVAL;
758 }
759
760 return regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
761 CS35L41_SCLK_MSTR_MASK | CS35L41_LRCLK_MSTR_MASK |
762 CS35L41_ASP_FMT_MASK | CS35L41_LRCLK_INV_MASK |
763 CS35L41_SCLK_INV_MASK, daifmt);
764}
765
766struct cs35l41_global_fs_config {
767 int rate;
768 int fs_cfg;
769};
770
771static const struct cs35l41_global_fs_config cs35l41_fs_rates[] = {
772 { 12000, 0x01 },
773 { 24000, 0x02 },
774 { 48000, 0x03 },
775 { 96000, 0x04 },
776 { 192000, 0x05 },
777 { 11025, 0x09 },
778 { 22050, 0x0A },
779 { 44100, 0x0B },
780 { 88200, 0x0C },
781 { 176400, 0x0D },
782 { 8000, 0x11 },
783 { 16000, 0x12 },
784 { 32000, 0x13 },
785};
786
787static int cs35l41_pcm_hw_params(struct snd_pcm_substream *substream,
788 struct snd_pcm_hw_params *params,
789 struct snd_soc_dai *dai)
790{
791 struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
792 unsigned int rate = params_rate(params);
793 u8 asp_wl;
794 int i;
795
796 for (i = 0; i < ARRAY_SIZE(cs35l41_fs_rates); i++) {
797 if (rate == cs35l41_fs_rates[i].rate)
798 break;
799 }
800
801 if (i >= ARRAY_SIZE(cs35l41_fs_rates)) {
802 dev_err(cs35l41->dev, "Unsupported rate: %u\n", rate);
803 return -EINVAL;
804 }
805
806 asp_wl = params_width(params);
807
808 if (i < ARRAY_SIZE(cs35l41_fs_rates))
809 regmap_update_bits(cs35l41->regmap, CS35L41_GLOBAL_CLK_CTRL,
810 CS35L41_GLOBAL_FS_MASK,
811 cs35l41_fs_rates[i].fs_cfg << CS35L41_GLOBAL_FS_SHIFT);
812
813 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
814 regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
815 CS35L41_ASP_WIDTH_RX_MASK,
816 asp_wl << CS35L41_ASP_WIDTH_RX_SHIFT);
817 regmap_update_bits(cs35l41->regmap, CS35L41_SP_RX_WL,
818 CS35L41_ASP_RX_WL_MASK,
819 asp_wl << CS35L41_ASP_RX_WL_SHIFT);
820 } else {
821 regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
822 CS35L41_ASP_WIDTH_TX_MASK,
823 asp_wl << CS35L41_ASP_WIDTH_TX_SHIFT);
824 regmap_update_bits(cs35l41->regmap, CS35L41_SP_TX_WL,
825 CS35L41_ASP_TX_WL_MASK,
826 asp_wl << CS35L41_ASP_TX_WL_SHIFT);
827 }
828
829 return 0;
830}
831
832static int cs35l41_get_clk_config(int freq)
833{
834 int i;
835
836 for (i = 0; i < ARRAY_SIZE(cs35l41_pll_sysclk); i++) {
837 if (cs35l41_pll_sysclk[i].freq == freq)
838 return cs35l41_pll_sysclk[i].clk_cfg;
839 }
840
841 return -EINVAL;
842}
843
844static const unsigned int cs35l41_src_rates[] = {
845 8000, 12000, 11025, 16000, 22050, 24000, 32000,
846 44100, 48000, 88200, 96000, 176400, 192000
847};
848
849static const struct snd_pcm_hw_constraint_list cs35l41_constraints = {
850 .count = ARRAY_SIZE(cs35l41_src_rates),
851 .list = cs35l41_src_rates,
852};
853
854static int cs35l41_pcm_startup(struct snd_pcm_substream *substream,
855 struct snd_soc_dai *dai)
856{
857 if (substream->runtime)
858 return snd_pcm_hw_constraint_list(substream->runtime, 0,
859 SNDRV_PCM_HW_PARAM_RATE,
860 &cs35l41_constraints);
861 return 0;
862}
863
864static int cs35l41_component_set_sysclk(struct snd_soc_component *component,
865 int clk_id, int source,
866 unsigned int freq, int dir)
867{
868 struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
869 int extclk_cfg, clksrc;
870
871 switch (clk_id) {
872 case CS35L41_CLKID_SCLK:
873 clksrc = CS35L41_PLLSRC_SCLK;
874 break;
875 case CS35L41_CLKID_LRCLK:
876 clksrc = CS35L41_PLLSRC_LRCLK;
877 break;
878 case CS35L41_CLKID_MCLK:
879 clksrc = CS35L41_PLLSRC_MCLK;
880 break;
881 default:
882 dev_err(cs35l41->dev, "Invalid CLK Config\n");
883 return -EINVAL;
884 }
885
886 extclk_cfg = cs35l41_get_clk_config(freq);
887
888 if (extclk_cfg < 0) {
889 dev_err(cs35l41->dev, "Invalid CLK Config: %d, freq: %u\n",
890 extclk_cfg, freq);
891 return -EINVAL;
892 }
893
894 regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
895 CS35L41_PLL_OPENLOOP_MASK,
896 1 << CS35L41_PLL_OPENLOOP_SHIFT);
897 regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
898 CS35L41_REFCLK_FREQ_MASK,
899 extclk_cfg << CS35L41_REFCLK_FREQ_SHIFT);
900 regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
901 CS35L41_PLL_CLK_EN_MASK,
902 0 << CS35L41_PLL_CLK_EN_SHIFT);
903 regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
904 CS35L41_PLL_CLK_SEL_MASK, clksrc);
905 regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
906 CS35L41_PLL_OPENLOOP_MASK,
907 0 << CS35L41_PLL_OPENLOOP_SHIFT);
908 regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
909 CS35L41_PLL_CLK_EN_MASK,
910 1 << CS35L41_PLL_CLK_EN_SHIFT);
911
912 return 0;
913}
914
915static int cs35l41_dai_set_sysclk(struct snd_soc_dai *dai,
916 int clk_id, unsigned int freq, int dir)
917{
918 struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
919 unsigned int fs1_val;
920 unsigned int fs2_val;
921 unsigned int val;
922 int fsindex;
923
924 fsindex = cs35l41_get_fs_mon_config_index(freq);
925 if (fsindex < 0) {
926 dev_err(cs35l41->dev, "Invalid CLK Config freq: %u\n", freq);
927 return -EINVAL;
928 }
929
930 dev_dbg(cs35l41->dev, "Set DAI sysclk %d\n", freq);
931
932 if (freq <= 6144000) {
933
934 fs1_val = cs35l41_fs_mon[fsindex].fs1;
935 fs2_val = cs35l41_fs_mon[fsindex].fs2;
936 } else {
937
938 fs1_val = 0x10;
939 fs2_val = 0x24;
940 }
941
942 val = fs1_val;
943 val |= (fs2_val << CS35L41_FS2_WINDOW_SHIFT) & CS35L41_FS2_WINDOW_MASK;
944 regmap_write(cs35l41->regmap, CS35L41_TST_FS_MON0, val);
945
946 return 0;
947}
948
949static int cs35l41_boost_config(struct cs35l41_private *cs35l41,
950 int boost_ind, int boost_cap, int boost_ipk)
951{
952 unsigned char bst_lbst_val, bst_cbst_range, bst_ipk_scaled;
953 struct regmap *regmap = cs35l41->regmap;
954 struct device *dev = cs35l41->dev;
955 int ret;
956
957 switch (boost_ind) {
958 case 1000:
959 bst_lbst_val = 0;
960 break;
961 case 1200:
962 bst_lbst_val = 1;
963 break;
964 case 1500:
965 bst_lbst_val = 2;
966 break;
967 case 2200:
968 bst_lbst_val = 3;
969 break;
970 default:
971 dev_err(dev, "Invalid boost inductor value: %d nH\n", boost_ind);
972 return -EINVAL;
973 }
974
975 switch (boost_cap) {
976 case 0 ... 19:
977 bst_cbst_range = 0;
978 break;
979 case 20 ... 50:
980 bst_cbst_range = 1;
981 break;
982 case 51 ... 100:
983 bst_cbst_range = 2;
984 break;
985 case 101 ... 200:
986 bst_cbst_range = 3;
987 break;
988 default:
989 bst_cbst_range = 4;
990 }
991
992 ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_COEFF,
993 CS35L41_BST_K1_MASK | CS35L41_BST_K2_MASK,
994 cs35l41_bst_k1_table[bst_lbst_val][bst_cbst_range]
995 << CS35L41_BST_K1_SHIFT |
996 cs35l41_bst_k2_table[bst_lbst_val][bst_cbst_range]
997 << CS35L41_BST_K2_SHIFT);
998 if (ret) {
999 dev_err(dev, "Failed to write boost coefficients: %d\n", ret);
1000 return ret;
1001 }
1002
1003 ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST,
1004 CS35L41_BST_SLOPE_MASK | CS35L41_BST_LBST_VAL_MASK,
1005 cs35l41_bst_slope_table[bst_lbst_val]
1006 << CS35L41_BST_SLOPE_SHIFT |
1007 bst_lbst_val << CS35L41_BST_LBST_VAL_SHIFT);
1008 if (ret) {
1009 dev_err(dev, "Failed to write boost slope/inductor value: %d\n", ret);
1010 return ret;
1011 }
1012
1013 if (boost_ipk < 1600 || boost_ipk > 4500) {
1014 dev_err(dev, "Invalid boost inductor peak current: %d mA\n",
1015 boost_ipk);
1016 return -EINVAL;
1017 }
1018 bst_ipk_scaled = ((boost_ipk - 1600) / 50) + 0x10;
1019
1020 ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_PEAK_CUR,
1021 CS35L41_BST_IPK_MASK,
1022 bst_ipk_scaled << CS35L41_BST_IPK_SHIFT);
1023 if (ret) {
1024 dev_err(dev, "Failed to write boost inductor peak current: %d\n", ret);
1025 return ret;
1026 }
1027
1028 return 0;
1029}
1030
1031static int cs35l41_set_pdata(struct cs35l41_private *cs35l41)
1032{
1033 int ret;
1034
1035
1036
1037 if (cs35l41->pdata.bst_ipk &&
1038 cs35l41->pdata.bst_ind && cs35l41->pdata.bst_cap) {
1039 ret = cs35l41_boost_config(cs35l41, cs35l41->pdata.bst_ind,
1040 cs35l41->pdata.bst_cap,
1041 cs35l41->pdata.bst_ipk);
1042 if (ret) {
1043 dev_err(cs35l41->dev, "Error in Boost DT config: %d\n", ret);
1044 return ret;
1045 }
1046 } else {
1047 dev_err(cs35l41->dev, "Incomplete Boost component DT config\n");
1048 return -EINVAL;
1049 }
1050
1051
1052 if (cs35l41->pdata.dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK &&
1053 cs35l41->pdata.dout_hiz >= 0)
1054 regmap_update_bits(cs35l41->regmap, CS35L41_SP_HIZ_CTRL,
1055 CS35L41_ASP_DOUT_HIZ_MASK,
1056 cs35l41->pdata.dout_hiz);
1057
1058 return 0;
1059}
1060
1061static int cs35l41_irq_gpio_config(struct cs35l41_private *cs35l41)
1062{
1063 struct cs35l41_irq_cfg *irq_gpio_cfg1 = &cs35l41->pdata.irq_config1;
1064 struct cs35l41_irq_cfg *irq_gpio_cfg2 = &cs35l41->pdata.irq_config2;
1065 int irq_pol = IRQF_TRIGGER_NONE;
1066
1067 regmap_update_bits(cs35l41->regmap, CS35L41_GPIO1_CTRL1,
1068 CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK,
1069 irq_gpio_cfg1->irq_pol_inv << CS35L41_GPIO_POL_SHIFT |
1070 !irq_gpio_cfg1->irq_out_en << CS35L41_GPIO_DIR_SHIFT);
1071
1072 regmap_update_bits(cs35l41->regmap, CS35L41_GPIO2_CTRL1,
1073 CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK,
1074 irq_gpio_cfg1->irq_pol_inv << CS35L41_GPIO_POL_SHIFT |
1075 !irq_gpio_cfg1->irq_out_en << CS35L41_GPIO_DIR_SHIFT);
1076
1077 regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL,
1078 CS35L41_GPIO1_CTRL_MASK | CS35L41_GPIO2_CTRL_MASK,
1079 irq_gpio_cfg1->irq_src_sel << CS35L41_GPIO1_CTRL_SHIFT |
1080 irq_gpio_cfg2->irq_src_sel << CS35L41_GPIO2_CTRL_SHIFT);
1081
1082 if ((irq_gpio_cfg2->irq_src_sel ==
1083 (CS35L41_GPIO_CTRL_ACTV_LO | CS35L41_VALID_PDATA)) ||
1084 (irq_gpio_cfg2->irq_src_sel ==
1085 (CS35L41_GPIO_CTRL_OPEN_INT | CS35L41_VALID_PDATA)))
1086 irq_pol = IRQF_TRIGGER_LOW;
1087 else if (irq_gpio_cfg2->irq_src_sel ==
1088 (CS35L41_GPIO_CTRL_ACTV_HI | CS35L41_VALID_PDATA))
1089 irq_pol = IRQF_TRIGGER_HIGH;
1090
1091 return irq_pol;
1092}
1093
1094static const struct snd_soc_dai_ops cs35l41_ops = {
1095 .startup = cs35l41_pcm_startup,
1096 .set_fmt = cs35l41_set_dai_fmt,
1097 .hw_params = cs35l41_pcm_hw_params,
1098 .set_sysclk = cs35l41_dai_set_sysclk,
1099 .set_channel_map = cs35l41_set_channel_map,
1100};
1101
1102static struct snd_soc_dai_driver cs35l41_dai[] = {
1103 {
1104 .name = "cs35l41-pcm",
1105 .id = 0,
1106 .playback = {
1107 .stream_name = "AMP Playback",
1108 .channels_min = 1,
1109 .channels_max = 2,
1110 .rates = SNDRV_PCM_RATE_KNOT,
1111 .formats = CS35L41_RX_FORMATS,
1112 },
1113 .capture = {
1114 .stream_name = "AMP Capture",
1115 .channels_min = 1,
1116 .channels_max = 8,
1117 .rates = SNDRV_PCM_RATE_KNOT,
1118 .formats = CS35L41_TX_FORMATS,
1119 },
1120 .ops = &cs35l41_ops,
1121 .symmetric_rate = 1,
1122 },
1123};
1124
1125static const struct snd_soc_component_driver soc_component_dev_cs35l41 = {
1126 .name = "cs35l41-codec",
1127
1128 .dapm_widgets = cs35l41_dapm_widgets,
1129 .num_dapm_widgets = ARRAY_SIZE(cs35l41_dapm_widgets),
1130 .dapm_routes = cs35l41_audio_map,
1131 .num_dapm_routes = ARRAY_SIZE(cs35l41_audio_map),
1132
1133 .controls = cs35l41_aud_controls,
1134 .num_controls = ARRAY_SIZE(cs35l41_aud_controls),
1135 .set_sysclk = cs35l41_component_set_sysclk,
1136};
1137
1138static int cs35l41_handle_pdata(struct device *dev,
1139 struct cs35l41_platform_data *pdata,
1140 struct cs35l41_private *cs35l41)
1141{
1142 struct cs35l41_irq_cfg *irq_gpio1_config = &pdata->irq_config1;
1143 struct cs35l41_irq_cfg *irq_gpio2_config = &pdata->irq_config2;
1144 unsigned int val;
1145 int ret;
1146
1147 ret = device_property_read_u32(dev, "cirrus,boost-peak-milliamp", &val);
1148 if (ret >= 0)
1149 pdata->bst_ipk = val;
1150
1151 ret = device_property_read_u32(dev, "cirrus,boost-ind-nanohenry", &val);
1152 if (ret >= 0)
1153 pdata->bst_ind = val;
1154
1155 ret = device_property_read_u32(dev, "cirrus,boost-cap-microfarad", &val);
1156 if (ret >= 0)
1157 pdata->bst_cap = val;
1158
1159 ret = device_property_read_u32(dev, "cirrus,asp-sdout-hiz", &val);
1160 if (ret >= 0)
1161 pdata->dout_hiz = val;
1162 else
1163 pdata->dout_hiz = -1;
1164
1165
1166 irq_gpio1_config->irq_pol_inv = device_property_read_bool(dev,
1167 "cirrus,gpio1-polarity-invert");
1168 irq_gpio1_config->irq_out_en = device_property_read_bool(dev,
1169 "cirrus,gpio1-output-enable");
1170 ret = device_property_read_u32(dev, "cirrus,gpio1-src-select",
1171 &val);
1172 if (ret >= 0)
1173 irq_gpio1_config->irq_src_sel = val | CS35L41_VALID_PDATA;
1174
1175
1176 irq_gpio2_config->irq_pol_inv = device_property_read_bool(dev,
1177 "cirrus,gpio2-polarity-invert");
1178 irq_gpio2_config->irq_out_en = device_property_read_bool(dev,
1179 "cirrus,gpio2-output-enable");
1180 ret = device_property_read_u32(dev, "cirrus,gpio2-src-select",
1181 &val);
1182 if (ret >= 0)
1183 irq_gpio2_config->irq_src_sel = val | CS35L41_VALID_PDATA;
1184
1185 return 0;
1186}
1187
1188static const struct reg_sequence cs35l41_reva0_errata_patch[] = {
1189 { 0x00000040, 0x00005555 },
1190 { 0x00000040, 0x0000AAAA },
1191 { 0x00003854, 0x05180240 },
1192 { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 },
1193 { 0x00004310, 0x00000000 },
1194 { CS35L41_VPVBST_FS_SEL, 0x00000000 },
1195 { CS35L41_OTP_TRIM_30, 0x9091A1C8 },
1196 { 0x00003014, 0x0200EE0E },
1197 { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 },
1198 { 0x00000054, 0x00000004 },
1199 { CS35L41_IRQ1_DB3, 0x00000000 },
1200 { CS35L41_IRQ2_DB3, 0x00000000 },
1201 { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
1202 { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
1203 { 0x00000040, 0x0000CCCC },
1204 { 0x00000040, 0x00003333 },
1205};
1206
1207static const struct reg_sequence cs35l41_revb0_errata_patch[] = {
1208 { 0x00000040, 0x00005555 },
1209 { 0x00000040, 0x0000AAAA },
1210 { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 },
1211 { 0x00004310, 0x00000000 },
1212 { CS35L41_VPVBST_FS_SEL, 0x00000000 },
1213 { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 },
1214 { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
1215 { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
1216 { 0x00000040, 0x0000CCCC },
1217 { 0x00000040, 0x00003333 },
1218};
1219
1220static const struct reg_sequence cs35l41_revb2_errata_patch[] = {
1221 { 0x00000040, 0x00005555 },
1222 { 0x00000040, 0x0000AAAA },
1223 { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 },
1224 { 0x00004310, 0x00000000 },
1225 { CS35L41_VPVBST_FS_SEL, 0x00000000 },
1226 { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 },
1227 { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
1228 { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
1229 { 0x00000040, 0x0000CCCC },
1230 { 0x00000040, 0x00003333 },
1231};
1232
1233int cs35l41_probe(struct cs35l41_private *cs35l41,
1234 struct cs35l41_platform_data *pdata)
1235{
1236 u32 regid, reg_revid, i, mtl_revid, int_status, chipid_match;
1237 int irq_pol = 0;
1238 int ret;
1239
1240 if (pdata) {
1241 cs35l41->pdata = *pdata;
1242 } else {
1243 ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->pdata, cs35l41);
1244 if (ret != 0)
1245 return ret;
1246 }
1247
1248 for (i = 0; i < CS35L41_NUM_SUPPLIES; i++)
1249 cs35l41->supplies[i].supply = cs35l41_supplies[i];
1250
1251 ret = devm_regulator_bulk_get(cs35l41->dev, CS35L41_NUM_SUPPLIES,
1252 cs35l41->supplies);
1253 if (ret != 0) {
1254 dev_err(cs35l41->dev, "Failed to request core supplies: %d\n", ret);
1255 return ret;
1256 }
1257
1258 ret = regulator_bulk_enable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
1259 if (ret != 0) {
1260 dev_err(cs35l41->dev, "Failed to enable core supplies: %d\n", ret);
1261 return ret;
1262 }
1263
1264
1265 cs35l41->reset_gpio = devm_gpiod_get_optional(cs35l41->dev, "reset",
1266 GPIOD_OUT_LOW);
1267 if (IS_ERR(cs35l41->reset_gpio)) {
1268 ret = PTR_ERR(cs35l41->reset_gpio);
1269 cs35l41->reset_gpio = NULL;
1270 if (ret == -EBUSY) {
1271 dev_info(cs35l41->dev,
1272 "Reset line busy, assuming shared reset\n");
1273 } else {
1274 dev_err(cs35l41->dev,
1275 "Failed to get reset GPIO: %d\n", ret);
1276 goto err;
1277 }
1278 }
1279 if (cs35l41->reset_gpio) {
1280
1281 usleep_range(2000, 2100);
1282 gpiod_set_value_cansleep(cs35l41->reset_gpio, 1);
1283 }
1284
1285 usleep_range(2000, 2100);
1286
1287 ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS4,
1288 int_status, int_status & CS35L41_OTP_BOOT_DONE,
1289 1000, 100000);
1290 if (ret) {
1291 dev_err(cs35l41->dev,
1292 "Failed waiting for OTP_BOOT_DONE: %d\n", ret);
1293 goto err;
1294 }
1295
1296 regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_status);
1297 if (int_status & CS35L41_OTP_BOOT_ERR) {
1298 dev_err(cs35l41->dev, "OTP Boot error\n");
1299 ret = -EINVAL;
1300 goto err;
1301 }
1302
1303 ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, ®id);
1304 if (ret < 0) {
1305 dev_err(cs35l41->dev, "Get Device ID failed: %d\n", ret);
1306 goto err;
1307 }
1308
1309 ret = regmap_read(cs35l41->regmap, CS35L41_REVID, ®_revid);
1310 if (ret < 0) {
1311 dev_err(cs35l41->dev, "Get Revision ID failed: %d\n", ret);
1312 goto err;
1313 }
1314
1315 mtl_revid = reg_revid & CS35L41_MTLREVID_MASK;
1316
1317
1318
1319
1320 chipid_match = (mtl_revid % 2) ? CS35L41R_CHIP_ID : CS35L41_CHIP_ID;
1321 if (regid != chipid_match) {
1322 dev_err(cs35l41->dev, "CS35L41 Device ID (%X). Expected ID %X\n",
1323 regid, chipid_match);
1324 ret = -ENODEV;
1325 goto err;
1326 }
1327
1328 switch (reg_revid) {
1329 case CS35L41_REVID_A0:
1330 ret = regmap_register_patch(cs35l41->regmap,
1331 cs35l41_reva0_errata_patch,
1332 ARRAY_SIZE(cs35l41_reva0_errata_patch));
1333 if (ret < 0) {
1334 dev_err(cs35l41->dev,
1335 "Failed to apply A0 errata patch: %d\n", ret);
1336 goto err;
1337 }
1338 break;
1339 case CS35L41_REVID_B0:
1340 ret = regmap_register_patch(cs35l41->regmap,
1341 cs35l41_revb0_errata_patch,
1342 ARRAY_SIZE(cs35l41_revb0_errata_patch));
1343 if (ret < 0) {
1344 dev_err(cs35l41->dev,
1345 "Failed to apply B0 errata patch: %d\n", ret);
1346 goto err;
1347 }
1348 break;
1349 case CS35L41_REVID_B2:
1350 ret = regmap_register_patch(cs35l41->regmap,
1351 cs35l41_revb2_errata_patch,
1352 ARRAY_SIZE(cs35l41_revb2_errata_patch));
1353 if (ret < 0) {
1354 dev_err(cs35l41->dev,
1355 "Failed to apply B2 errata patch: %d\n", ret);
1356 goto err;
1357 }
1358 break;
1359 }
1360
1361 irq_pol = cs35l41_irq_gpio_config(cs35l41);
1362
1363
1364 regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1,
1365 CS35L41_INT1_MASK_DEFAULT);
1366
1367 ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, cs35l41_irq,
1368 IRQF_ONESHOT | IRQF_SHARED | irq_pol,
1369 "cs35l41", cs35l41);
1370
1371
1372 if (ret != 0) {
1373 dev_err(cs35l41->dev, "Failed to request IRQ: %d\n", ret);
1374 goto err;
1375 }
1376
1377 ret = cs35l41_otp_unpack(cs35l41);
1378 if (ret < 0) {
1379 dev_err(cs35l41->dev, "OTP Unpack failed: %d\n", ret);
1380 goto err;
1381 }
1382
1383 ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_CCM_CORE_CTRL, 0);
1384 if (ret < 0) {
1385 dev_err(cs35l41->dev, "Write CCM_CORE_CTRL failed: %d\n", ret);
1386 goto err;
1387 }
1388
1389 ret = regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
1390 CS35L41_AMP_EN_MASK, 0);
1391 if (ret < 0) {
1392 dev_err(cs35l41->dev, "Write CS35L41_PWR_CTRL2 failed: %d\n", ret);
1393 goto err;
1394 }
1395
1396 ret = regmap_update_bits(cs35l41->regmap, CS35L41_AMP_GAIN_CTRL,
1397 CS35L41_AMP_GAIN_PCM_MASK, 0);
1398 if (ret < 0) {
1399 dev_err(cs35l41->dev, "Write CS35L41_AMP_GAIN_CTRL failed: %d\n", ret);
1400 goto err;
1401 }
1402
1403 ret = cs35l41_set_pdata(cs35l41);
1404 if (ret < 0) {
1405 dev_err(cs35l41->dev, "Set pdata failed: %d\n", ret);
1406 goto err;
1407 }
1408
1409 ret = devm_snd_soc_register_component(cs35l41->dev,
1410 &soc_component_dev_cs35l41,
1411 cs35l41_dai, ARRAY_SIZE(cs35l41_dai));
1412 if (ret < 0) {
1413 dev_err(cs35l41->dev, "Register codec failed: %d\n", ret);
1414 goto err;
1415 }
1416
1417 dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n",
1418 regid, reg_revid);
1419
1420 return 0;
1421
1422err:
1423 regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
1424 gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
1425
1426 return ret;
1427}
1428
1429void cs35l41_remove(struct cs35l41_private *cs35l41)
1430{
1431 regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF);
1432 regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
1433 gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
1434}
1435
1436MODULE_DESCRIPTION("ASoC CS35L41 driver");
1437MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>");
1438MODULE_LICENSE("GPL");
1439