Merge branch 'for-5.16' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie...
[platform/kernel/linux-starfive.git] / sound / soc / codecs / cs35l41.c
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 int cs35l41_dsp_preload_ev(struct snd_soc_dapm_widget *w,
201                                   struct snd_kcontrol *kcontrol, int event)
202 {
203         int ret;
204
205         switch (event) {
206         case SND_SOC_DAPM_PRE_PMU:
207                 return wm_adsp_early_event(w, kcontrol, event);
208         case SND_SOC_DAPM_PRE_PMD:
209                 ret = wm_adsp_early_event(w, kcontrol, event);
210                 if (ret)
211                         return ret;
212
213                 return wm_adsp_event(w, kcontrol, event);
214         default:
215                 return 0;
216         }
217 }
218
219 static bool cs35l41_check_cspl_mbox_sts(enum cs35l41_cspl_mbox_cmd cmd,
220                                         enum cs35l41_cspl_mbox_status sts)
221 {
222         switch (cmd) {
223         case CSPL_MBOX_CMD_NONE:
224         case CSPL_MBOX_CMD_UNKNOWN_CMD:
225                 return true;
226         case CSPL_MBOX_CMD_PAUSE:
227                 return (sts == CSPL_MBOX_STS_PAUSED);
228         case CSPL_MBOX_CMD_RESUME:
229                 return (sts == CSPL_MBOX_STS_RUNNING);
230         case CSPL_MBOX_CMD_REINIT:
231                 return (sts == CSPL_MBOX_STS_RUNNING);
232         case CSPL_MBOX_CMD_STOP_PRE_REINIT:
233                 return (sts == CSPL_MBOX_STS_RDY_FOR_REINIT);
234         default:
235                 return false;
236         }
237 }
238
239 static int cs35l41_set_cspl_mbox_cmd(struct cs35l41_private *cs35l41,
240                                      enum cs35l41_cspl_mbox_cmd cmd)
241 {
242         unsigned int sts = 0, i;
243         int ret;
244
245         // Set mailbox cmd
246         ret = regmap_write(cs35l41->regmap, CS35L41_DSP_VIRT1_MBOX_1, cmd);
247         if (ret < 0) {
248                 dev_err(cs35l41->dev, "Failed to write MBOX: %d\n", ret);
249                 return ret;
250         }
251
252         // Read mailbox status and verify it is appropriate for the given cmd
253         for (i = 0; i < 5; i++) {
254                 usleep_range(1000, 1100);
255
256                 ret = regmap_read(cs35l41->regmap, CS35L41_DSP_MBOX_2, &sts);
257                 if (ret < 0) {
258                         dev_err(cs35l41->dev, "Failed to read MBOX STS: %d\n", ret);
259                         continue;
260                 }
261
262                 if (!cs35l41_check_cspl_mbox_sts(cmd, sts)) {
263                         dev_dbg(cs35l41->dev,
264                                 "[%u] cmd %u returned invalid sts %u",
265                                 i, cmd, sts);
266                 } else {
267                         return 0;
268                 }
269         }
270
271         dev_err(cs35l41->dev,
272                 "Failed to set mailbox cmd %u (status %u)\n",
273                 cmd, sts);
274
275         return -ENOMSG;
276 }
277
278 static int cs35l41_dsp_audio_ev(struct snd_soc_dapm_widget *w,
279                                 struct snd_kcontrol *kcontrol, int event)
280 {
281         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
282         struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
283         unsigned int fw_status;
284         int ret;
285
286         switch (event) {
287         case SND_SOC_DAPM_POST_PMU:
288                 if (!cs35l41->dsp.cs_dsp.running)
289                         return wm_adsp_event(w, kcontrol, event);
290
291                 ret = regmap_read(cs35l41->regmap, CS35L41_DSP_MBOX_2, &fw_status);
292                 if (ret < 0) {
293                         dev_err(cs35l41->dev,
294                                 "Failed to read firmware status: %d\n", ret);
295                         return ret;
296                 }
297
298                 switch (fw_status) {
299                 case CSPL_MBOX_STS_RUNNING:
300                 case CSPL_MBOX_STS_PAUSED:
301                         break;
302                 default:
303                         dev_err(cs35l41->dev, "Firmware status is invalid: %u\n",
304                                 fw_status);
305                         return -EINVAL;
306                 }
307
308                 return cs35l41_set_cspl_mbox_cmd(cs35l41, CSPL_MBOX_CMD_RESUME);
309         case SND_SOC_DAPM_PRE_PMD:
310                 return cs35l41_set_cspl_mbox_cmd(cs35l41, CSPL_MBOX_CMD_PAUSE);
311         default:
312                 return 0;
313         }
314 }
315
316 static const char * const cs35l41_pcm_source_texts[] = {"ASP", "DSP"};
317 static const unsigned int cs35l41_pcm_source_values[] = {0x08, 0x32};
318 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_pcm_source_enum,
319                                   CS35L41_DAC_PCM1_SRC,
320                                   0, CS35L41_ASP_SOURCE_MASK,
321                                   cs35l41_pcm_source_texts,
322                                   cs35l41_pcm_source_values);
323
324 static const struct snd_kcontrol_new pcm_source_mux =
325         SOC_DAPM_ENUM("PCM Source", cs35l41_pcm_source_enum);
326
327 static const char * const cs35l41_tx_input_texts[] = {
328         "Zero", "ASPRX1", "ASPRX2", "VMON", "IMON",
329         "VPMON", "VBSTMON", "DSPTX1", "DSPTX2"
330 };
331
332 static const unsigned int cs35l41_tx_input_values[] = {
333         0x00, CS35L41_INPUT_SRC_ASPRX1, CS35L41_INPUT_SRC_ASPRX2,
334         CS35L41_INPUT_SRC_VMON, CS35L41_INPUT_SRC_IMON, CS35L41_INPUT_SRC_VPMON,
335         CS35L41_INPUT_SRC_VBSTMON, CS35L41_INPUT_DSP_TX1, CS35L41_INPUT_DSP_TX2
336 };
337
338 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx1_enum,
339                                   CS35L41_ASP_TX1_SRC,
340                                   0, CS35L41_ASP_SOURCE_MASK,
341                                   cs35l41_tx_input_texts,
342                                   cs35l41_tx_input_values);
343
344 static const struct snd_kcontrol_new asp_tx1_mux =
345         SOC_DAPM_ENUM("ASPTX1 SRC", cs35l41_asptx1_enum);
346
347 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx2_enum,
348                                   CS35L41_ASP_TX2_SRC,
349                                   0, CS35L41_ASP_SOURCE_MASK,
350                                   cs35l41_tx_input_texts,
351                                   cs35l41_tx_input_values);
352
353 static const struct snd_kcontrol_new asp_tx2_mux =
354         SOC_DAPM_ENUM("ASPTX2 SRC", cs35l41_asptx2_enum);
355
356 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx3_enum,
357                                   CS35L41_ASP_TX3_SRC,
358                                   0, CS35L41_ASP_SOURCE_MASK,
359                                   cs35l41_tx_input_texts,
360                                   cs35l41_tx_input_values);
361
362 static const struct snd_kcontrol_new asp_tx3_mux =
363         SOC_DAPM_ENUM("ASPTX3 SRC", cs35l41_asptx3_enum);
364
365 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx4_enum,
366                                   CS35L41_ASP_TX4_SRC,
367                                   0, CS35L41_ASP_SOURCE_MASK,
368                                   cs35l41_tx_input_texts,
369                                   cs35l41_tx_input_values);
370
371 static const struct snd_kcontrol_new asp_tx4_mux =
372         SOC_DAPM_ENUM("ASPTX4 SRC", cs35l41_asptx4_enum);
373
374 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_dsprx1_enum,
375                                   CS35L41_DSP1_RX1_SRC,
376                                   0, CS35L41_ASP_SOURCE_MASK,
377                                   cs35l41_tx_input_texts,
378                                   cs35l41_tx_input_values);
379
380 static const struct snd_kcontrol_new dsp_rx1_mux =
381         SOC_DAPM_ENUM("DSPRX1 SRC", cs35l41_dsprx1_enum);
382
383 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_dsprx2_enum,
384                                   CS35L41_DSP1_RX2_SRC,
385                                   0, CS35L41_ASP_SOURCE_MASK,
386                                   cs35l41_tx_input_texts,
387                                   cs35l41_tx_input_values);
388
389 static const struct snd_kcontrol_new dsp_rx2_mux =
390         SOC_DAPM_ENUM("DSPRX2 SRC", cs35l41_dsprx2_enum);
391
392 static const struct snd_kcontrol_new cs35l41_aud_controls[] = {
393         SOC_SINGLE_SX_TLV("Digital PCM Volume", CS35L41_AMP_DIG_VOL_CTRL,
394                           3, 0x4CF, 0x391, dig_vol_tlv),
395         SOC_SINGLE_TLV("Analog PCM Volume", CS35L41_AMP_GAIN_CTRL, 5, 0x14, 0,
396                        amp_gain_tlv),
397         SOC_ENUM("PCM Soft Ramp", pcm_sft_ramp),
398         SOC_SINGLE("HW Noise Gate Enable", CS35L41_NG_CFG, 8, 63, 0),
399         SOC_SINGLE("HW Noise Gate Delay", CS35L41_NG_CFG, 4, 7, 0),
400         SOC_SINGLE("HW Noise Gate Threshold", CS35L41_NG_CFG, 0, 7, 0),
401         SOC_SINGLE("Aux Noise Gate CH1 Enable",
402                    CS35L41_MIXER_NGATE_CH1_CFG, 16, 1, 0),
403         SOC_SINGLE("Aux Noise Gate CH1 Entry Delay",
404                    CS35L41_MIXER_NGATE_CH1_CFG, 8, 15, 0),
405         SOC_SINGLE("Aux Noise Gate CH1 Threshold",
406                    CS35L41_MIXER_NGATE_CH1_CFG, 0, 7, 0),
407         SOC_SINGLE("Aux Noise Gate CH2 Entry Delay",
408                    CS35L41_MIXER_NGATE_CH2_CFG, 8, 15, 0),
409         SOC_SINGLE("Aux Noise Gate CH2 Enable",
410                    CS35L41_MIXER_NGATE_CH2_CFG, 16, 1, 0),
411         SOC_SINGLE("Aux Noise Gate CH2 Threshold",
412                    CS35L41_MIXER_NGATE_CH2_CFG, 0, 7, 0),
413         SOC_SINGLE("SCLK Force", CS35L41_SP_FORMAT, CS35L41_SCLK_FRC_SHIFT, 1, 0),
414         SOC_SINGLE("LRCLK Force", CS35L41_SP_FORMAT, CS35L41_LRCLK_FRC_SHIFT, 1, 0),
415         SOC_SINGLE("Invert Class D", CS35L41_AMP_DIG_VOL_CTRL,
416                    CS35L41_AMP_INV_PCM_SHIFT, 1, 0),
417         SOC_SINGLE("Amp Gain ZC", CS35L41_AMP_GAIN_CTRL,
418                    CS35L41_AMP_GAIN_ZC_SHIFT, 1, 0),
419         WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
420         WM_ADSP_FW_CONTROL("DSP1", 0),
421 };
422
423 static const struct cs35l41_otp_map_element_t *cs35l41_find_otp_map(u32 otp_id)
424 {
425         int i;
426
427         for (i = 0; i < ARRAY_SIZE(cs35l41_otp_map_map); i++) {
428                 if (cs35l41_otp_map_map[i].id == otp_id)
429                         return &cs35l41_otp_map_map[i];
430         }
431
432         return NULL;
433 }
434
435 static int cs35l41_otp_unpack(void *data)
436 {
437         const struct cs35l41_otp_map_element_t *otp_map_match;
438         const struct cs35l41_otp_packed_element_t *otp_map;
439         struct cs35l41_private *cs35l41 = data;
440         int bit_offset, word_offset, ret, i;
441         unsigned int bit_sum = 8;
442         u32 otp_val, otp_id_reg;
443         u32 *otp_mem;
444
445         otp_mem = kmalloc_array(CS35L41_OTP_SIZE_WORDS, sizeof(*otp_mem), GFP_KERNEL);
446         if (!otp_mem)
447                 return -ENOMEM;
448
449         ret = regmap_read(cs35l41->regmap, CS35L41_OTPID, &otp_id_reg);
450         if (ret < 0) {
451                 dev_err(cs35l41->dev, "Read OTP ID failed: %d\n", ret);
452                 goto err_otp_unpack;
453         }
454
455         otp_map_match = cs35l41_find_otp_map(otp_id_reg);
456
457         if (!otp_map_match) {
458                 dev_err(cs35l41->dev, "OTP Map matching ID %d not found\n",
459                         otp_id_reg);
460                 ret = -EINVAL;
461                 goto err_otp_unpack;
462         }
463
464         ret = regmap_bulk_read(cs35l41->regmap, CS35L41_OTP_MEM0, otp_mem,
465                                CS35L41_OTP_SIZE_WORDS);
466         if (ret < 0) {
467                 dev_err(cs35l41->dev, "Read OTP Mem failed: %d\n", ret);
468                 goto err_otp_unpack;
469         }
470
471         otp_map = otp_map_match->map;
472
473         bit_offset = otp_map_match->bit_offset;
474         word_offset = otp_map_match->word_offset;
475
476         ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000055);
477         if (ret < 0) {
478                 dev_err(cs35l41->dev, "Write Unlock key failed 1/2: %d\n", ret);
479                 goto err_otp_unpack;
480         }
481         ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000AA);
482         if (ret < 0) {
483                 dev_err(cs35l41->dev, "Write Unlock key failed 2/2: %d\n", ret);
484                 goto err_otp_unpack;
485         }
486
487         for (i = 0; i < otp_map_match->num_elements; i++) {
488                 dev_dbg(cs35l41->dev,
489                         "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d\n",
490                         bit_offset, word_offset, bit_sum % 32);
491                 if (bit_offset + otp_map[i].size - 1 >= 32) {
492                         otp_val = (otp_mem[word_offset] &
493                                         GENMASK(31, bit_offset)) >>
494                                         bit_offset;
495                         otp_val |= (otp_mem[++word_offset] &
496                                         GENMASK(bit_offset +
497                                                 otp_map[i].size - 33, 0)) <<
498                                         (32 - bit_offset);
499                         bit_offset += otp_map[i].size - 32;
500                 } else {
501                         otp_val = (otp_mem[word_offset] &
502                                 GENMASK(bit_offset + otp_map[i].size - 1,
503                                         bit_offset)) >> bit_offset;
504                         bit_offset += otp_map[i].size;
505                 }
506                 bit_sum += otp_map[i].size;
507
508                 if (bit_offset == 32) {
509                         bit_offset = 0;
510                         word_offset++;
511                 }
512
513                 if (otp_map[i].reg != 0) {
514                         ret = regmap_update_bits(cs35l41->regmap,
515                                                  otp_map[i].reg,
516                                                  GENMASK(otp_map[i].shift +
517                                                          otp_map[i].size - 1,
518                                                  otp_map[i].shift),
519                                                  otp_val << otp_map[i].shift);
520                         if (ret < 0) {
521                                 dev_err(cs35l41->dev, "Write OTP val failed: %d\n",
522                                         ret);
523                                 goto err_otp_unpack;
524                         }
525                 }
526         }
527
528         ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000CC);
529         if (ret < 0) {
530                 dev_err(cs35l41->dev, "Write Lock key failed 1/2: %d\n", ret);
531                 goto err_otp_unpack;
532         }
533         ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000033);
534         if (ret < 0) {
535                 dev_err(cs35l41->dev, "Write Lock key failed 2/2: %d\n", ret);
536                 goto err_otp_unpack;
537         }
538         ret = 0;
539
540 err_otp_unpack:
541         kfree(otp_mem);
542         return ret;
543 }
544
545 static irqreturn_t cs35l41_irq(int irq, void *data)
546 {
547         struct cs35l41_private *cs35l41 = data;
548         unsigned int status[4] = { 0, 0, 0, 0 };
549         unsigned int masks[4] = { 0, 0, 0, 0 };
550         int ret = IRQ_NONE;
551         unsigned int i;
552
553         for (i = 0; i < ARRAY_SIZE(status); i++) {
554                 regmap_read(cs35l41->regmap,
555                             CS35L41_IRQ1_STATUS1 + (i * CS35L41_REGSTRIDE),
556                             &status[i]);
557                 regmap_read(cs35l41->regmap,
558                             CS35L41_IRQ1_MASK1 + (i * CS35L41_REGSTRIDE),
559                             &masks[i]);
560         }
561
562         /* Check to see if unmasked bits are active */
563         if (!(status[0] & ~masks[0]) && !(status[1] & ~masks[1]) &&
564             !(status[2] & ~masks[2]) && !(status[3] & ~masks[3]))
565                 return IRQ_NONE;
566
567         if (status[3] & CS35L41_OTP_BOOT_DONE) {
568                 regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK4,
569                                    CS35L41_OTP_BOOT_DONE, CS35L41_OTP_BOOT_DONE);
570         }
571
572         /*
573          * The following interrupts require a
574          * protection release cycle to get the
575          * speaker out of Safe-Mode.
576          */
577         if (status[0] & CS35L41_AMP_SHORT_ERR) {
578                 dev_crit_ratelimited(cs35l41->dev, "Amp short error\n");
579                 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
580                              CS35L41_AMP_SHORT_ERR);
581                 regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
582                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
583                                    CS35L41_AMP_SHORT_ERR_RLS,
584                                    CS35L41_AMP_SHORT_ERR_RLS);
585                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
586                                    CS35L41_AMP_SHORT_ERR_RLS, 0);
587                 ret = IRQ_HANDLED;
588         }
589
590         if (status[0] & CS35L41_TEMP_WARN) {
591                 dev_crit_ratelimited(cs35l41->dev, "Over temperature warning\n");
592                 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
593                              CS35L41_TEMP_WARN);
594                 regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
595                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
596                                    CS35L41_TEMP_WARN_ERR_RLS,
597                                    CS35L41_TEMP_WARN_ERR_RLS);
598                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
599                                    CS35L41_TEMP_WARN_ERR_RLS, 0);
600                 ret = IRQ_HANDLED;
601         }
602
603         if (status[0] & CS35L41_TEMP_ERR) {
604                 dev_crit_ratelimited(cs35l41->dev, "Over temperature error\n");
605                 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
606                              CS35L41_TEMP_ERR);
607                 regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
608                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
609                                    CS35L41_TEMP_ERR_RLS,
610                                    CS35L41_TEMP_ERR_RLS);
611                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
612                                    CS35L41_TEMP_ERR_RLS, 0);
613                 ret = IRQ_HANDLED;
614         }
615
616         if (status[0] & CS35L41_BST_OVP_ERR) {
617                 dev_crit_ratelimited(cs35l41->dev, "VBST Over Voltage error\n");
618                 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
619                                    CS35L41_BST_EN_MASK, 0);
620                 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
621                              CS35L41_BST_OVP_ERR);
622                 regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
623                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
624                                    CS35L41_BST_OVP_ERR_RLS,
625                                    CS35L41_BST_OVP_ERR_RLS);
626                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
627                                    CS35L41_BST_OVP_ERR_RLS, 0);
628                 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
629                                    CS35L41_BST_EN_MASK,
630                                    CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
631                 ret = IRQ_HANDLED;
632         }
633
634         if (status[0] & CS35L41_BST_DCM_UVP_ERR) {
635                 dev_crit_ratelimited(cs35l41->dev, "DCM VBST Under Voltage Error\n");
636                 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
637                                    CS35L41_BST_EN_MASK, 0);
638                 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
639                              CS35L41_BST_DCM_UVP_ERR);
640                 regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
641                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
642                                    CS35L41_BST_UVP_ERR_RLS,
643                                    CS35L41_BST_UVP_ERR_RLS);
644                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
645                                    CS35L41_BST_UVP_ERR_RLS, 0);
646                 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
647                                    CS35L41_BST_EN_MASK,
648                                    CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
649                 ret = IRQ_HANDLED;
650         }
651
652         if (status[0] & CS35L41_BST_SHORT_ERR) {
653                 dev_crit_ratelimited(cs35l41->dev, "LBST error: powering off!\n");
654                 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
655                                    CS35L41_BST_EN_MASK, 0);
656                 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
657                              CS35L41_BST_SHORT_ERR);
658                 regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
659                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
660                                    CS35L41_BST_SHORT_ERR_RLS,
661                                    CS35L41_BST_SHORT_ERR_RLS);
662                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
663                                    CS35L41_BST_SHORT_ERR_RLS, 0);
664                 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
665                                    CS35L41_BST_EN_MASK,
666                                    CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
667                 ret = IRQ_HANDLED;
668         }
669
670         return ret;
671 }
672
673 static const struct reg_sequence cs35l41_pup_patch[] = {
674         { 0x00000040, 0x00000055 },
675         { 0x00000040, 0x000000AA },
676         { 0x00002084, 0x002F1AA0 },
677         { 0x00000040, 0x000000CC },
678         { 0x00000040, 0x00000033 },
679 };
680
681 static const struct reg_sequence cs35l41_pdn_patch[] = {
682         { 0x00000040, 0x00000055 },
683         { 0x00000040, 0x000000AA },
684         { 0x00002084, 0x002F1AA3 },
685         { 0x00000040, 0x000000CC },
686         { 0x00000040, 0x00000033 },
687 };
688
689 static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w,
690                                   struct snd_kcontrol *kcontrol, int event)
691 {
692         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
693         struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
694         unsigned int val;
695         int ret = 0;
696
697         switch (event) {
698         case SND_SOC_DAPM_POST_PMU:
699                 regmap_multi_reg_write_bypassed(cs35l41->regmap,
700                                                 cs35l41_pup_patch,
701                                                 ARRAY_SIZE(cs35l41_pup_patch));
702
703                 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1,
704                                    CS35L41_GLOBAL_EN_MASK,
705                                    1 << CS35L41_GLOBAL_EN_SHIFT);
706
707                 usleep_range(1000, 1100);
708                 break;
709         case SND_SOC_DAPM_POST_PMD:
710                 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1,
711                                    CS35L41_GLOBAL_EN_MASK, 0);
712
713                 ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
714                                                val, val &  CS35L41_PDN_DONE_MASK,
715                                                1000, 100000);
716                 if (ret)
717                         dev_warn(cs35l41->dev, "PDN failed: %d\n", ret);
718
719                 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
720                              CS35L41_PDN_DONE_MASK);
721
722                 regmap_multi_reg_write_bypassed(cs35l41->regmap,
723                                                 cs35l41_pdn_patch,
724                                                 ARRAY_SIZE(cs35l41_pdn_patch));
725                 break;
726         default:
727                 dev_err(cs35l41->dev, "Invalid event = 0x%x\n", event);
728                 ret = -EINVAL;
729         }
730
731         return ret;
732 }
733
734 static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = {
735         SND_SOC_DAPM_SPK("DSP1 Preload", NULL),
736         SND_SOC_DAPM_SUPPLY_S("DSP1 Preloader", 100, SND_SOC_NOPM, 0, 0,
737                               cs35l41_dsp_preload_ev,
738                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
739         SND_SOC_DAPM_OUT_DRV_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0,
740                                cs35l41_dsp_audio_ev,
741                                SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
742
743         SND_SOC_DAPM_OUTPUT("SPK"),
744
745         SND_SOC_DAPM_AIF_IN("ASPRX1", NULL, 0, CS35L41_SP_ENABLES, 16, 0),
746         SND_SOC_DAPM_AIF_IN("ASPRX2", NULL, 0, CS35L41_SP_ENABLES, 17, 0),
747         SND_SOC_DAPM_AIF_OUT("ASPTX1", NULL, 0, CS35L41_SP_ENABLES, 0, 0),
748         SND_SOC_DAPM_AIF_OUT("ASPTX2", NULL, 0, CS35L41_SP_ENABLES, 1, 0),
749         SND_SOC_DAPM_AIF_OUT("ASPTX3", NULL, 0, CS35L41_SP_ENABLES, 2, 0),
750         SND_SOC_DAPM_AIF_OUT("ASPTX4", NULL, 0, CS35L41_SP_ENABLES, 3, 0),
751
752         SND_SOC_DAPM_SIGGEN("VSENSE"),
753         SND_SOC_DAPM_SIGGEN("ISENSE"),
754         SND_SOC_DAPM_SIGGEN("VP"),
755         SND_SOC_DAPM_SIGGEN("VBST"),
756         SND_SOC_DAPM_SIGGEN("TEMP"),
757
758         SND_SOC_DAPM_SUPPLY("VMON", CS35L41_PWR_CTRL2, 12, 0, NULL, 0),
759         SND_SOC_DAPM_SUPPLY("IMON", CS35L41_PWR_CTRL2, 13, 0, NULL, 0),
760         SND_SOC_DAPM_SUPPLY("VPMON", CS35L41_PWR_CTRL2, 8, 0, NULL, 0),
761         SND_SOC_DAPM_SUPPLY("VBSTMON", CS35L41_PWR_CTRL2, 9, 0, NULL, 0),
762         SND_SOC_DAPM_SUPPLY("TEMPMON", CS35L41_PWR_CTRL2, 10, 0, NULL, 0),
763
764         SND_SOC_DAPM_ADC("VMON ADC", NULL, SND_SOC_NOPM, 0, 0),
765         SND_SOC_DAPM_ADC("IMON ADC", NULL, SND_SOC_NOPM, 0, 0),
766         SND_SOC_DAPM_ADC("VPMON ADC", NULL, SND_SOC_NOPM, 0, 0),
767         SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, SND_SOC_NOPM, 0, 0),
768         SND_SOC_DAPM_ADC("TEMPMON ADC", NULL, SND_SOC_NOPM, 0, 0),
769
770         SND_SOC_DAPM_ADC("CLASS H", NULL, CS35L41_PWR_CTRL3, 4, 0),
771
772         SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L41_PWR_CTRL2, 0, 0, NULL, 0,
773                                cs35l41_main_amp_event,
774                                SND_SOC_DAPM_POST_PMD |  SND_SOC_DAPM_POST_PMU),
775
776         SND_SOC_DAPM_MUX("ASP TX1 Source", SND_SOC_NOPM, 0, 0, &asp_tx1_mux),
777         SND_SOC_DAPM_MUX("ASP TX2 Source", SND_SOC_NOPM, 0, 0, &asp_tx2_mux),
778         SND_SOC_DAPM_MUX("ASP TX3 Source", SND_SOC_NOPM, 0, 0, &asp_tx3_mux),
779         SND_SOC_DAPM_MUX("ASP TX4 Source", SND_SOC_NOPM, 0, 0, &asp_tx4_mux),
780         SND_SOC_DAPM_MUX("DSP RX1 Source", SND_SOC_NOPM, 0, 0, &dsp_rx1_mux),
781         SND_SOC_DAPM_MUX("DSP RX2 Source", SND_SOC_NOPM, 0, 0, &dsp_rx2_mux),
782         SND_SOC_DAPM_MUX("PCM Source", SND_SOC_NOPM, 0, 0, &pcm_source_mux),
783         SND_SOC_DAPM_SWITCH("DRE", SND_SOC_NOPM, 0, 0, &dre_ctrl),
784 };
785
786 static const struct snd_soc_dapm_route cs35l41_audio_map[] = {
787         {"DSP RX1 Source", "ASPRX1", "ASPRX1"},
788         {"DSP RX1 Source", "ASPRX2", "ASPRX2"},
789         {"DSP RX2 Source", "ASPRX1", "ASPRX1"},
790         {"DSP RX2 Source", "ASPRX2", "ASPRX2"},
791
792         {"DSP1", NULL, "DSP RX1 Source"},
793         {"DSP1", NULL, "DSP RX2 Source"},
794
795         {"ASP TX1 Source", "VMON", "VMON ADC"},
796         {"ASP TX1 Source", "IMON", "IMON ADC"},
797         {"ASP TX1 Source", "VPMON", "VPMON ADC"},
798         {"ASP TX1 Source", "VBSTMON", "VBSTMON ADC"},
799         {"ASP TX1 Source", "DSPTX1", "DSP1"},
800         {"ASP TX1 Source", "DSPTX2", "DSP1"},
801         {"ASP TX1 Source", "ASPRX1", "ASPRX1" },
802         {"ASP TX1 Source", "ASPRX2", "ASPRX2" },
803         {"ASP TX2 Source", "VMON", "VMON ADC"},
804         {"ASP TX2 Source", "IMON", "IMON ADC"},
805         {"ASP TX2 Source", "VPMON", "VPMON ADC"},
806         {"ASP TX2 Source", "VBSTMON", "VBSTMON ADC"},
807         {"ASP TX2 Source", "DSPTX1", "DSP1"},
808         {"ASP TX2 Source", "DSPTX2", "DSP1"},
809         {"ASP TX2 Source", "ASPRX1", "ASPRX1" },
810         {"ASP TX2 Source", "ASPRX2", "ASPRX2" },
811         {"ASP TX3 Source", "VMON", "VMON ADC"},
812         {"ASP TX3 Source", "IMON", "IMON ADC"},
813         {"ASP TX3 Source", "VPMON", "VPMON ADC"},
814         {"ASP TX3 Source", "VBSTMON", "VBSTMON ADC"},
815         {"ASP TX3 Source", "DSPTX1", "DSP1"},
816         {"ASP TX3 Source", "DSPTX2", "DSP1"},
817         {"ASP TX3 Source", "ASPRX1", "ASPRX1" },
818         {"ASP TX3 Source", "ASPRX2", "ASPRX2" },
819         {"ASP TX4 Source", "VMON", "VMON ADC"},
820         {"ASP TX4 Source", "IMON", "IMON ADC"},
821         {"ASP TX4 Source", "VPMON", "VPMON ADC"},
822         {"ASP TX4 Source", "VBSTMON", "VBSTMON ADC"},
823         {"ASP TX4 Source", "DSPTX1", "DSP1"},
824         {"ASP TX4 Source", "DSPTX2", "DSP1"},
825         {"ASP TX4 Source", "ASPRX1", "ASPRX1" },
826         {"ASP TX4 Source", "ASPRX2", "ASPRX2" },
827         {"ASPTX1", NULL, "ASP TX1 Source"},
828         {"ASPTX2", NULL, "ASP TX2 Source"},
829         {"ASPTX3", NULL, "ASP TX3 Source"},
830         {"ASPTX4", NULL, "ASP TX4 Source"},
831         {"AMP Capture", NULL, "ASPTX1"},
832         {"AMP Capture", NULL, "ASPTX2"},
833         {"AMP Capture", NULL, "ASPTX3"},
834         {"AMP Capture", NULL, "ASPTX4"},
835
836         {"DSP1", NULL, "VMON"},
837         {"DSP1", NULL, "IMON"},
838         {"DSP1", NULL, "VPMON"},
839         {"DSP1", NULL, "VBSTMON"},
840         {"DSP1", NULL, "TEMPMON"},
841
842         {"VMON ADC", NULL, "VMON"},
843         {"IMON ADC", NULL, "IMON"},
844         {"VPMON ADC", NULL, "VPMON"},
845         {"VBSTMON ADC", NULL, "VBSTMON"},
846         {"TEMPMON ADC", NULL, "TEMPMON"},
847
848         {"VMON ADC", NULL, "VSENSE"},
849         {"IMON ADC", NULL, "ISENSE"},
850         {"VPMON ADC", NULL, "VP"},
851         {"VBSTMON ADC", NULL, "VBST"},
852         {"TEMPMON ADC", NULL, "TEMP"},
853
854         {"DSP1 Preload", NULL, "DSP1 Preloader"},
855         {"DSP1", NULL, "DSP1 Preloader"},
856
857         {"ASPRX1", NULL, "AMP Playback"},
858         {"ASPRX2", NULL, "AMP Playback"},
859         {"DRE", "Switch", "CLASS H"},
860         {"Main AMP", NULL, "CLASS H"},
861         {"Main AMP", NULL, "DRE"},
862         {"SPK", NULL, "Main AMP"},
863
864         {"PCM Source", "ASP", "ASPRX1"},
865         {"PCM Source", "DSP", "DSP1"},
866         {"CLASS H", NULL, "PCM Source"},
867 };
868
869 static const struct cs_dsp_region cs35l41_dsp1_regions[] = {
870         { .type = WMFW_HALO_PM_PACKED,  .base = CS35L41_DSP1_PMEM_0 },
871         { .type = WMFW_HALO_XM_PACKED,  .base = CS35L41_DSP1_XMEM_PACK_0 },
872         { .type = WMFW_HALO_YM_PACKED,  .base = CS35L41_DSP1_YMEM_PACK_0 },
873         {. type = WMFW_ADSP2_XM,        .base = CS35L41_DSP1_XMEM_UNPACK24_0},
874         {. type = WMFW_ADSP2_YM,        .base = CS35L41_DSP1_YMEM_UNPACK24_0},
875 };
876
877 static int cs35l41_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_num,
878                                    unsigned int *tx_slot, unsigned int rx_num,
879                                    unsigned int *rx_slot)
880 {
881         struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
882         unsigned int val, mask;
883         int i;
884
885         if (tx_num > 4 || rx_num > 2)
886                 return -EINVAL;
887
888         val = 0;
889         mask = 0;
890         for (i = 0; i < rx_num; i++) {
891                 dev_dbg(cs35l41->dev, "rx slot %d position = %d\n", i, rx_slot[i]);
892                 val |= rx_slot[i] << (i * 8);
893                 mask |= 0x3F << (i * 8);
894         }
895         regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_RX_SLOT, mask, val);
896
897         val = 0;
898         mask = 0;
899         for (i = 0; i < tx_num; i++) {
900                 dev_dbg(cs35l41->dev, "tx slot %d position = %d\n", i, tx_slot[i]);
901                 val |= tx_slot[i] << (i * 8);
902                 mask |= 0x3F << (i * 8);
903         }
904         regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_TX_SLOT, mask, val);
905
906         return 0;
907 }
908
909 static int cs35l41_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
910 {
911         struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
912         unsigned int daifmt = 0;
913
914         switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
915         case SND_SOC_DAIFMT_CBP_CFP:
916                 daifmt |= CS35L41_SCLK_MSTR_MASK | CS35L41_LRCLK_MSTR_MASK;
917                 break;
918         case SND_SOC_DAIFMT_CBC_CFC:
919                 break;
920         default:
921                 dev_warn(cs35l41->dev, "Mixed provider/consumer mode unsupported\n");
922                 return -EINVAL;
923         }
924
925         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
926         case SND_SOC_DAIFMT_DSP_A:
927                 break;
928         case SND_SOC_DAIFMT_I2S:
929                 daifmt |= 2 << CS35L41_ASP_FMT_SHIFT;
930                 break;
931         default:
932                 dev_warn(cs35l41->dev, "Invalid or unsupported DAI format\n");
933                 return -EINVAL;
934         }
935
936         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
937         case SND_SOC_DAIFMT_NB_IF:
938                 daifmt |= CS35L41_LRCLK_INV_MASK;
939                 break;
940         case SND_SOC_DAIFMT_IB_NF:
941                 daifmt |= CS35L41_SCLK_INV_MASK;
942                 break;
943         case SND_SOC_DAIFMT_IB_IF:
944                 daifmt |= CS35L41_LRCLK_INV_MASK | CS35L41_SCLK_INV_MASK;
945                 break;
946         case SND_SOC_DAIFMT_NB_NF:
947                 break;
948         default:
949                 dev_warn(cs35l41->dev, "Invalid DAI clock INV\n");
950                 return -EINVAL;
951         }
952
953         return regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
954                                   CS35L41_SCLK_MSTR_MASK | CS35L41_LRCLK_MSTR_MASK |
955                                   CS35L41_ASP_FMT_MASK | CS35L41_LRCLK_INV_MASK |
956                                   CS35L41_SCLK_INV_MASK, daifmt);
957 }
958
959 struct cs35l41_global_fs_config {
960         int rate;
961         int fs_cfg;
962 };
963
964 static const struct cs35l41_global_fs_config cs35l41_fs_rates[] = {
965         { 12000,        0x01 },
966         { 24000,        0x02 },
967         { 48000,        0x03 },
968         { 96000,        0x04 },
969         { 192000,       0x05 },
970         { 11025,        0x09 },
971         { 22050,        0x0A },
972         { 44100,        0x0B },
973         { 88200,        0x0C },
974         { 176400,       0x0D },
975         { 8000,         0x11 },
976         { 16000,        0x12 },
977         { 32000,        0x13 },
978 };
979
980 static int cs35l41_pcm_hw_params(struct snd_pcm_substream *substream,
981                                  struct snd_pcm_hw_params *params,
982                                  struct snd_soc_dai *dai)
983 {
984         struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
985         unsigned int rate = params_rate(params);
986         u8 asp_wl;
987         int i;
988
989         for (i = 0; i < ARRAY_SIZE(cs35l41_fs_rates); i++) {
990                 if (rate == cs35l41_fs_rates[i].rate)
991                         break;
992         }
993
994         if (i >= ARRAY_SIZE(cs35l41_fs_rates)) {
995                 dev_err(cs35l41->dev, "Unsupported rate: %u\n", rate);
996                 return -EINVAL;
997         }
998
999         asp_wl = params_width(params);
1000
1001         if (i < ARRAY_SIZE(cs35l41_fs_rates))
1002                 regmap_update_bits(cs35l41->regmap, CS35L41_GLOBAL_CLK_CTRL,
1003                                    CS35L41_GLOBAL_FS_MASK,
1004                                    cs35l41_fs_rates[i].fs_cfg << CS35L41_GLOBAL_FS_SHIFT);
1005
1006         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1007                 regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
1008                                    CS35L41_ASP_WIDTH_RX_MASK,
1009                                    asp_wl << CS35L41_ASP_WIDTH_RX_SHIFT);
1010                 regmap_update_bits(cs35l41->regmap, CS35L41_SP_RX_WL,
1011                                    CS35L41_ASP_RX_WL_MASK,
1012                                    asp_wl << CS35L41_ASP_RX_WL_SHIFT);
1013         } else {
1014                 regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
1015                                    CS35L41_ASP_WIDTH_TX_MASK,
1016                                    asp_wl << CS35L41_ASP_WIDTH_TX_SHIFT);
1017                 regmap_update_bits(cs35l41->regmap, CS35L41_SP_TX_WL,
1018                                    CS35L41_ASP_TX_WL_MASK,
1019                                    asp_wl << CS35L41_ASP_TX_WL_SHIFT);
1020         }
1021
1022         return 0;
1023 }
1024
1025 static int cs35l41_get_clk_config(int freq)
1026 {
1027         int i;
1028
1029         for (i = 0; i < ARRAY_SIZE(cs35l41_pll_sysclk); i++) {
1030                 if (cs35l41_pll_sysclk[i].freq == freq)
1031                         return cs35l41_pll_sysclk[i].clk_cfg;
1032         }
1033
1034         return -EINVAL;
1035 }
1036
1037 static const unsigned int cs35l41_src_rates[] = {
1038         8000, 12000, 11025, 16000, 22050, 24000, 32000,
1039         44100, 48000, 88200, 96000, 176400, 192000
1040 };
1041
1042 static const struct snd_pcm_hw_constraint_list cs35l41_constraints = {
1043         .count = ARRAY_SIZE(cs35l41_src_rates),
1044         .list = cs35l41_src_rates,
1045 };
1046
1047 static int cs35l41_pcm_startup(struct snd_pcm_substream *substream,
1048                                struct snd_soc_dai *dai)
1049 {
1050         if (substream->runtime)
1051                 return snd_pcm_hw_constraint_list(substream->runtime, 0,
1052                                                   SNDRV_PCM_HW_PARAM_RATE,
1053                                                   &cs35l41_constraints);
1054         return 0;
1055 }
1056
1057 static int cs35l41_component_set_sysclk(struct snd_soc_component *component,
1058                                         int clk_id, int source,
1059                                         unsigned int freq, int dir)
1060 {
1061         struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
1062         int extclk_cfg, clksrc;
1063
1064         switch (clk_id) {
1065         case CS35L41_CLKID_SCLK:
1066                 clksrc = CS35L41_PLLSRC_SCLK;
1067                 break;
1068         case CS35L41_CLKID_LRCLK:
1069                 clksrc = CS35L41_PLLSRC_LRCLK;
1070                 break;
1071         case CS35L41_CLKID_MCLK:
1072                 clksrc = CS35L41_PLLSRC_MCLK;
1073                 break;
1074         default:
1075                 dev_err(cs35l41->dev, "Invalid CLK Config\n");
1076                 return -EINVAL;
1077         }
1078
1079         extclk_cfg = cs35l41_get_clk_config(freq);
1080
1081         if (extclk_cfg < 0) {
1082                 dev_err(cs35l41->dev, "Invalid CLK Config: %d, freq: %u\n",
1083                         extclk_cfg, freq);
1084                 return -EINVAL;
1085         }
1086
1087         regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
1088                            CS35L41_PLL_OPENLOOP_MASK,
1089                            1 << CS35L41_PLL_OPENLOOP_SHIFT);
1090         regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
1091                            CS35L41_REFCLK_FREQ_MASK,
1092                            extclk_cfg << CS35L41_REFCLK_FREQ_SHIFT);
1093         regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
1094                            CS35L41_PLL_CLK_EN_MASK,
1095                            0 << CS35L41_PLL_CLK_EN_SHIFT);
1096         regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
1097                            CS35L41_PLL_CLK_SEL_MASK, clksrc);
1098         regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
1099                            CS35L41_PLL_OPENLOOP_MASK,
1100                            0 << CS35L41_PLL_OPENLOOP_SHIFT);
1101         regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
1102                            CS35L41_PLL_CLK_EN_MASK,
1103                            1 << CS35L41_PLL_CLK_EN_SHIFT);
1104
1105         return 0;
1106 }
1107
1108 static int cs35l41_dai_set_sysclk(struct snd_soc_dai *dai,
1109                                   int clk_id, unsigned int freq, int dir)
1110 {
1111         struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
1112         unsigned int fs1_val;
1113         unsigned int fs2_val;
1114         unsigned int val;
1115         int fsindex;
1116
1117         fsindex = cs35l41_get_fs_mon_config_index(freq);
1118         if (fsindex < 0) {
1119                 dev_err(cs35l41->dev, "Invalid CLK Config freq: %u\n", freq);
1120                 return -EINVAL;
1121         }
1122
1123         dev_dbg(cs35l41->dev, "Set DAI sysclk %d\n", freq);
1124
1125         if (freq <= 6144000) {
1126                 /* Use the lookup table */
1127                 fs1_val = cs35l41_fs_mon[fsindex].fs1;
1128                 fs2_val = cs35l41_fs_mon[fsindex].fs2;
1129         } else {
1130                 /* Use hard-coded values */
1131                 fs1_val = 0x10;
1132                 fs2_val = 0x24;
1133         }
1134
1135         val = fs1_val;
1136         val |= (fs2_val << CS35L41_FS2_WINDOW_SHIFT) & CS35L41_FS2_WINDOW_MASK;
1137         regmap_write(cs35l41->regmap, CS35L41_TST_FS_MON0, val);
1138
1139         return 0;
1140 }
1141
1142 static int cs35l41_boost_config(struct cs35l41_private *cs35l41,
1143                                 int boost_ind, int boost_cap, int boost_ipk)
1144 {
1145         unsigned char bst_lbst_val, bst_cbst_range, bst_ipk_scaled;
1146         struct regmap *regmap = cs35l41->regmap;
1147         struct device *dev = cs35l41->dev;
1148         int ret;
1149
1150         switch (boost_ind) {
1151         case 1000:      /* 1.0 uH */
1152                 bst_lbst_val = 0;
1153                 break;
1154         case 1200:      /* 1.2 uH */
1155                 bst_lbst_val = 1;
1156                 break;
1157         case 1500:      /* 1.5 uH */
1158                 bst_lbst_val = 2;
1159                 break;
1160         case 2200:      /* 2.2 uH */
1161                 bst_lbst_val = 3;
1162                 break;
1163         default:
1164                 dev_err(dev, "Invalid boost inductor value: %d nH\n", boost_ind);
1165                 return -EINVAL;
1166         }
1167
1168         switch (boost_cap) {
1169         case 0 ... 19:
1170                 bst_cbst_range = 0;
1171                 break;
1172         case 20 ... 50:
1173                 bst_cbst_range = 1;
1174                 break;
1175         case 51 ... 100:
1176                 bst_cbst_range = 2;
1177                 break;
1178         case 101 ... 200:
1179                 bst_cbst_range = 3;
1180                 break;
1181         default:        /* 201 uF and greater */
1182                 bst_cbst_range = 4;
1183         }
1184
1185         ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_COEFF,
1186                                  CS35L41_BST_K1_MASK | CS35L41_BST_K2_MASK,
1187                                  cs35l41_bst_k1_table[bst_lbst_val][bst_cbst_range]
1188                                         << CS35L41_BST_K1_SHIFT |
1189                                  cs35l41_bst_k2_table[bst_lbst_val][bst_cbst_range]
1190                                         << CS35L41_BST_K2_SHIFT);
1191         if (ret) {
1192                 dev_err(dev, "Failed to write boost coefficients: %d\n", ret);
1193                 return ret;
1194         }
1195
1196         ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST,
1197                                  CS35L41_BST_SLOPE_MASK | CS35L41_BST_LBST_VAL_MASK,
1198                                  cs35l41_bst_slope_table[bst_lbst_val]
1199                                         << CS35L41_BST_SLOPE_SHIFT |
1200                                  bst_lbst_val << CS35L41_BST_LBST_VAL_SHIFT);
1201         if (ret) {
1202                 dev_err(dev, "Failed to write boost slope/inductor value: %d\n", ret);
1203                 return ret;
1204         }
1205
1206         if (boost_ipk < 1600 || boost_ipk > 4500) {
1207                 dev_err(dev, "Invalid boost inductor peak current: %d mA\n",
1208                         boost_ipk);
1209                 return -EINVAL;
1210         }
1211         bst_ipk_scaled = ((boost_ipk - 1600) / 50) + 0x10;
1212
1213         ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_PEAK_CUR,
1214                                  CS35L41_BST_IPK_MASK,
1215                                  bst_ipk_scaled << CS35L41_BST_IPK_SHIFT);
1216         if (ret) {
1217                 dev_err(dev, "Failed to write boost inductor peak current: %d\n", ret);
1218                 return ret;
1219         }
1220
1221         return 0;
1222 }
1223
1224 static int cs35l41_set_pdata(struct cs35l41_private *cs35l41)
1225 {
1226         int ret;
1227
1228         /* Set Platform Data */
1229         /* Required */
1230         if (cs35l41->pdata.bst_ipk &&
1231             cs35l41->pdata.bst_ind && cs35l41->pdata.bst_cap) {
1232                 ret = cs35l41_boost_config(cs35l41, cs35l41->pdata.bst_ind,
1233                                            cs35l41->pdata.bst_cap,
1234                                            cs35l41->pdata.bst_ipk);
1235                 if (ret) {
1236                         dev_err(cs35l41->dev, "Error in Boost DT config: %d\n", ret);
1237                         return ret;
1238                 }
1239         } else {
1240                 dev_err(cs35l41->dev, "Incomplete Boost component DT config\n");
1241                 return -EINVAL;
1242         }
1243
1244         /* Optional */
1245         if (cs35l41->pdata.dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK &&
1246             cs35l41->pdata.dout_hiz >= 0)
1247                 regmap_update_bits(cs35l41->regmap, CS35L41_SP_HIZ_CTRL,
1248                                    CS35L41_ASP_DOUT_HIZ_MASK,
1249                                    cs35l41->pdata.dout_hiz);
1250
1251         return 0;
1252 }
1253
1254 static int cs35l41_irq_gpio_config(struct cs35l41_private *cs35l41)
1255 {
1256         struct cs35l41_irq_cfg *irq_gpio_cfg1 = &cs35l41->pdata.irq_config1;
1257         struct cs35l41_irq_cfg *irq_gpio_cfg2 = &cs35l41->pdata.irq_config2;
1258         int irq_pol = IRQF_TRIGGER_NONE;
1259
1260         regmap_update_bits(cs35l41->regmap, CS35L41_GPIO1_CTRL1,
1261                            CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK,
1262                            irq_gpio_cfg1->irq_pol_inv << CS35L41_GPIO_POL_SHIFT |
1263                            !irq_gpio_cfg1->irq_out_en << CS35L41_GPIO_DIR_SHIFT);
1264
1265         regmap_update_bits(cs35l41->regmap, CS35L41_GPIO2_CTRL1,
1266                            CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK,
1267                            irq_gpio_cfg1->irq_pol_inv << CS35L41_GPIO_POL_SHIFT |
1268                            !irq_gpio_cfg1->irq_out_en << CS35L41_GPIO_DIR_SHIFT);
1269
1270         regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL,
1271                            CS35L41_GPIO1_CTRL_MASK | CS35L41_GPIO2_CTRL_MASK,
1272                            irq_gpio_cfg1->irq_src_sel << CS35L41_GPIO1_CTRL_SHIFT |
1273                            irq_gpio_cfg2->irq_src_sel << CS35L41_GPIO2_CTRL_SHIFT);
1274
1275         if ((irq_gpio_cfg2->irq_src_sel ==
1276                         (CS35L41_GPIO_CTRL_ACTV_LO | CS35L41_VALID_PDATA)) ||
1277                 (irq_gpio_cfg2->irq_src_sel ==
1278                         (CS35L41_GPIO_CTRL_OPEN_INT | CS35L41_VALID_PDATA)))
1279                 irq_pol = IRQF_TRIGGER_LOW;
1280         else if (irq_gpio_cfg2->irq_src_sel ==
1281                         (CS35L41_GPIO_CTRL_ACTV_HI | CS35L41_VALID_PDATA))
1282                 irq_pol = IRQF_TRIGGER_HIGH;
1283
1284         return irq_pol;
1285 }
1286
1287 static int cs35l41_component_probe(struct snd_soc_component *component)
1288 {
1289         struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
1290
1291         return wm_adsp2_component_probe(&cs35l41->dsp, component);
1292 }
1293
1294 static void cs35l41_component_remove(struct snd_soc_component *component)
1295 {
1296         struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
1297
1298         wm_adsp2_component_remove(&cs35l41->dsp, component);
1299 }
1300
1301 static const struct snd_soc_dai_ops cs35l41_ops = {
1302         .startup = cs35l41_pcm_startup,
1303         .set_fmt = cs35l41_set_dai_fmt,
1304         .hw_params = cs35l41_pcm_hw_params,
1305         .set_sysclk = cs35l41_dai_set_sysclk,
1306         .set_channel_map = cs35l41_set_channel_map,
1307 };
1308
1309 static struct snd_soc_dai_driver cs35l41_dai[] = {
1310         {
1311                 .name = "cs35l41-pcm",
1312                 .id = 0,
1313                 .playback = {
1314                         .stream_name = "AMP Playback",
1315                         .channels_min = 1,
1316                         .channels_max = 2,
1317                         .rates = SNDRV_PCM_RATE_KNOT,
1318                         .formats = CS35L41_RX_FORMATS,
1319                 },
1320                 .capture = {
1321                         .stream_name = "AMP Capture",
1322                         .channels_min = 1,
1323                         .channels_max = 8,
1324                         .rates = SNDRV_PCM_RATE_KNOT,
1325                         .formats = CS35L41_TX_FORMATS,
1326                 },
1327                 .ops = &cs35l41_ops,
1328                 .symmetric_rate = 1,
1329         },
1330 };
1331
1332 static const struct snd_soc_component_driver soc_component_dev_cs35l41 = {
1333         .name = "cs35l41-codec",
1334         .probe = cs35l41_component_probe,
1335         .remove = cs35l41_component_remove,
1336
1337         .dapm_widgets = cs35l41_dapm_widgets,
1338         .num_dapm_widgets = ARRAY_SIZE(cs35l41_dapm_widgets),
1339         .dapm_routes = cs35l41_audio_map,
1340         .num_dapm_routes = ARRAY_SIZE(cs35l41_audio_map),
1341
1342         .controls = cs35l41_aud_controls,
1343         .num_controls = ARRAY_SIZE(cs35l41_aud_controls),
1344         .set_sysclk = cs35l41_component_set_sysclk,
1345 };
1346
1347 static int cs35l41_handle_pdata(struct device *dev,
1348                                 struct cs35l41_platform_data *pdata,
1349                                 struct cs35l41_private *cs35l41)
1350 {
1351         struct cs35l41_irq_cfg *irq_gpio1_config = &pdata->irq_config1;
1352         struct cs35l41_irq_cfg *irq_gpio2_config = &pdata->irq_config2;
1353         unsigned int val;
1354         int ret;
1355
1356         ret = device_property_read_u32(dev, "cirrus,boost-peak-milliamp", &val);
1357         if (ret >= 0)
1358                 pdata->bst_ipk = val;
1359
1360         ret = device_property_read_u32(dev, "cirrus,boost-ind-nanohenry", &val);
1361         if (ret >= 0)
1362                 pdata->bst_ind = val;
1363
1364         ret = device_property_read_u32(dev, "cirrus,boost-cap-microfarad", &val);
1365         if (ret >= 0)
1366                 pdata->bst_cap = val;
1367
1368         ret = device_property_read_u32(dev, "cirrus,asp-sdout-hiz", &val);
1369         if (ret >= 0)
1370                 pdata->dout_hiz = val;
1371         else
1372                 pdata->dout_hiz = -1;
1373
1374         /* GPIO1 Pin Config */
1375         irq_gpio1_config->irq_pol_inv = device_property_read_bool(dev,
1376                                         "cirrus,gpio1-polarity-invert");
1377         irq_gpio1_config->irq_out_en = device_property_read_bool(dev,
1378                                         "cirrus,gpio1-output-enable");
1379         ret = device_property_read_u32(dev, "cirrus,gpio1-src-select",
1380                                        &val);
1381         if (ret >= 0)
1382                 irq_gpio1_config->irq_src_sel = val | CS35L41_VALID_PDATA;
1383
1384         /* GPIO2 Pin Config */
1385         irq_gpio2_config->irq_pol_inv = device_property_read_bool(dev,
1386                                         "cirrus,gpio2-polarity-invert");
1387         irq_gpio2_config->irq_out_en = device_property_read_bool(dev,
1388                                         "cirrus,gpio2-output-enable");
1389         ret = device_property_read_u32(dev, "cirrus,gpio2-src-select",
1390                                        &val);
1391         if (ret >= 0)
1392                 irq_gpio2_config->irq_src_sel = val | CS35L41_VALID_PDATA;
1393
1394         return 0;
1395 }
1396
1397 static const struct reg_sequence cs35l41_reva0_errata_patch[] = {
1398         { 0x00000040,                    0x00005555 },
1399         { 0x00000040,                    0x0000AAAA },
1400         { 0x00003854,                    0x05180240 },
1401         { CS35L41_VIMON_SPKMON_RESYNC,   0x00000000 },
1402         { 0x00004310,                    0x00000000 },
1403         { CS35L41_VPVBST_FS_SEL,         0x00000000 },
1404         { CS35L41_OTP_TRIM_30,           0x9091A1C8 },
1405         { 0x00003014,                    0x0200EE0E },
1406         { CS35L41_BSTCVRT_DCM_CTRL,      0x00000051 },
1407         { 0x00000054,                    0x00000004 },
1408         { CS35L41_IRQ1_DB3,              0x00000000 },
1409         { CS35L41_IRQ2_DB3,              0x00000000 },
1410         { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
1411         { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
1412         { 0x00000040,                    0x0000CCCC },
1413         { 0x00000040,                    0x00003333 },
1414 };
1415
1416 static const struct reg_sequence cs35l41_revb0_errata_patch[] = {
1417         { 0x00000040,                    0x00005555 },
1418         { 0x00000040,                    0x0000AAAA },
1419         { CS35L41_VIMON_SPKMON_RESYNC,   0x00000000 },
1420         { 0x00004310,                    0x00000000 },
1421         { CS35L41_VPVBST_FS_SEL,         0x00000000 },
1422         { CS35L41_BSTCVRT_DCM_CTRL,      0x00000051 },
1423         { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
1424         { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
1425         { 0x00000040,                    0x0000CCCC },
1426         { 0x00000040,                    0x00003333 },
1427 };
1428
1429 static const struct reg_sequence cs35l41_revb2_errata_patch[] = {
1430         { 0x00000040,                    0x00005555 },
1431         { 0x00000040,                    0x0000AAAA },
1432         { CS35L41_VIMON_SPKMON_RESYNC,   0x00000000 },
1433         { 0x00004310,                    0x00000000 },
1434         { CS35L41_VPVBST_FS_SEL,         0x00000000 },
1435         { CS35L41_BSTCVRT_DCM_CTRL,      0x00000051 },
1436         { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
1437         { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
1438         { 0x00000040,                    0x0000CCCC },
1439         { 0x00000040,                    0x00003333 },
1440 };
1441
1442 static const struct reg_sequence cs35l41_fs_errata_patch[] = {
1443         { CS35L41_DSP1_RX1_RATE,        0x00000001 },
1444         { CS35L41_DSP1_RX2_RATE,        0x00000001 },
1445         { CS35L41_DSP1_RX3_RATE,        0x00000001 },
1446         { CS35L41_DSP1_RX4_RATE,        0x00000001 },
1447         { CS35L41_DSP1_RX5_RATE,        0x00000001 },
1448         { CS35L41_DSP1_RX6_RATE,        0x00000001 },
1449         { CS35L41_DSP1_RX7_RATE,        0x00000001 },
1450         { CS35L41_DSP1_RX8_RATE,        0x00000001 },
1451         { CS35L41_DSP1_TX1_RATE,        0x00000001 },
1452         { CS35L41_DSP1_TX2_RATE,        0x00000001 },
1453         { CS35L41_DSP1_TX3_RATE,        0x00000001 },
1454         { CS35L41_DSP1_TX4_RATE,        0x00000001 },
1455         { CS35L41_DSP1_TX5_RATE,        0x00000001 },
1456         { CS35L41_DSP1_TX6_RATE,        0x00000001 },
1457         { CS35L41_DSP1_TX7_RATE,        0x00000001 },
1458         { CS35L41_DSP1_TX8_RATE,        0x00000001 },
1459 };
1460
1461 static int cs35l41_dsp_init(struct cs35l41_private *cs35l41)
1462 {
1463         struct wm_adsp *dsp;
1464         int ret;
1465
1466         dsp = &cs35l41->dsp;
1467         dsp->part = "cs35l41";
1468         dsp->cs_dsp.num = 1;
1469         dsp->cs_dsp.type = WMFW_HALO;
1470         dsp->cs_dsp.rev = 0;
1471         dsp->fw = 9; /* 9 is WM_ADSP_FW_SPK_PROT in wm_adsp.c */
1472         dsp->cs_dsp.dev = cs35l41->dev;
1473         dsp->cs_dsp.regmap = cs35l41->regmap;
1474         dsp->cs_dsp.base = CS35L41_DSP1_CTRL_BASE;
1475         dsp->cs_dsp.base_sysinfo = CS35L41_DSP1_SYS_ID;
1476         dsp->cs_dsp.mem = cs35l41_dsp1_regions;
1477         dsp->cs_dsp.num_mems = ARRAY_SIZE(cs35l41_dsp1_regions);
1478         dsp->cs_dsp.lock_regions = 0xFFFFFFFF;
1479
1480         ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_fs_errata_patch,
1481                                      ARRAY_SIZE(cs35l41_fs_errata_patch));
1482         if (ret < 0) {
1483                 dev_err(cs35l41->dev, "Failed to write fs errata: %d\n", ret);
1484                 return ret;
1485         }
1486
1487         ret = wm_halo_init(dsp);
1488         if (ret) {
1489                 dev_err(cs35l41->dev, "wm_halo_init failed: %d\n", ret);
1490                 return ret;
1491         }
1492
1493         ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX5_SRC,
1494                            CS35L41_INPUT_SRC_VPMON);
1495         if (ret < 0) {
1496                 dev_err(cs35l41->dev, "Write INPUT_SRC_VPMON failed: %d\n", ret);
1497                 goto err_dsp;
1498         }
1499         ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX6_SRC,
1500                            CS35L41_INPUT_SRC_CLASSH);
1501         if (ret < 0) {
1502                 dev_err(cs35l41->dev, "Write INPUT_SRC_CLASSH failed: %d\n", ret);
1503                 goto err_dsp;
1504         }
1505         ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX7_SRC,
1506                            CS35L41_INPUT_SRC_TEMPMON);
1507         if (ret < 0) {
1508                 dev_err(cs35l41->dev, "Write INPUT_SRC_TEMPMON failed: %d\n", ret);
1509                 goto err_dsp;
1510         }
1511         ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX8_SRC,
1512                            CS35L41_INPUT_SRC_RSVD);
1513         if (ret < 0) {
1514                 dev_err(cs35l41->dev, "Write INPUT_SRC_RSVD failed: %d\n", ret);
1515                 goto err_dsp;
1516         }
1517
1518         return 0;
1519
1520 err_dsp:
1521         wm_adsp2_remove(dsp);
1522
1523         return ret;
1524 }
1525
1526 int cs35l41_probe(struct cs35l41_private *cs35l41,
1527                   struct cs35l41_platform_data *pdata)
1528 {
1529         u32 regid, reg_revid, i, mtl_revid, int_status, chipid_match;
1530         int irq_pol = 0;
1531         int ret;
1532
1533         if (pdata) {
1534                 cs35l41->pdata = *pdata;
1535         } else {
1536                 ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->pdata, cs35l41);
1537                 if (ret != 0)
1538                         return ret;
1539         }
1540
1541         for (i = 0; i < CS35L41_NUM_SUPPLIES; i++)
1542                 cs35l41->supplies[i].supply = cs35l41_supplies[i];
1543
1544         ret = devm_regulator_bulk_get(cs35l41->dev, CS35L41_NUM_SUPPLIES,
1545                                       cs35l41->supplies);
1546         if (ret != 0) {
1547                 dev_err(cs35l41->dev, "Failed to request core supplies: %d\n", ret);
1548                 return ret;
1549         }
1550
1551         ret = regulator_bulk_enable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
1552         if (ret != 0) {
1553                 dev_err(cs35l41->dev, "Failed to enable core supplies: %d\n", ret);
1554                 return ret;
1555         }
1556
1557         /* returning NULL can be an option if in stereo mode */
1558         cs35l41->reset_gpio = devm_gpiod_get_optional(cs35l41->dev, "reset",
1559                                                       GPIOD_OUT_LOW);
1560         if (IS_ERR(cs35l41->reset_gpio)) {
1561                 ret = PTR_ERR(cs35l41->reset_gpio);
1562                 cs35l41->reset_gpio = NULL;
1563                 if (ret == -EBUSY) {
1564                         dev_info(cs35l41->dev,
1565                                  "Reset line busy, assuming shared reset\n");
1566                 } else {
1567                         dev_err(cs35l41->dev,
1568                                 "Failed to get reset GPIO: %d\n", ret);
1569                         goto err;
1570                 }
1571         }
1572         if (cs35l41->reset_gpio) {
1573                 /* satisfy minimum reset pulse width spec */
1574                 usleep_range(2000, 2100);
1575                 gpiod_set_value_cansleep(cs35l41->reset_gpio, 1);
1576         }
1577
1578         usleep_range(2000, 2100);
1579
1580         ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS4,
1581                                        int_status, int_status & CS35L41_OTP_BOOT_DONE,
1582                                        1000, 100000);
1583         if (ret) {
1584                 dev_err(cs35l41->dev,
1585                         "Failed waiting for OTP_BOOT_DONE: %d\n", ret);
1586                 goto err;
1587         }
1588
1589         regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_status);
1590         if (int_status & CS35L41_OTP_BOOT_ERR) {
1591                 dev_err(cs35l41->dev, "OTP Boot error\n");
1592                 ret = -EINVAL;
1593                 goto err;
1594         }
1595
1596         ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, &regid);
1597         if (ret < 0) {
1598                 dev_err(cs35l41->dev, "Get Device ID failed: %d\n", ret);
1599                 goto err;
1600         }
1601
1602         ret = regmap_read(cs35l41->regmap, CS35L41_REVID, &reg_revid);
1603         if (ret < 0) {
1604                 dev_err(cs35l41->dev, "Get Revision ID failed: %d\n", ret);
1605                 goto err;
1606         }
1607
1608         mtl_revid = reg_revid & CS35L41_MTLREVID_MASK;
1609
1610         /* CS35L41 will have even MTLREVID
1611          * CS35L41R will have odd MTLREVID
1612          */
1613         chipid_match = (mtl_revid % 2) ? CS35L41R_CHIP_ID : CS35L41_CHIP_ID;
1614         if (regid != chipid_match) {
1615                 dev_err(cs35l41->dev, "CS35L41 Device ID (%X). Expected ID %X\n",
1616                         regid, chipid_match);
1617                 ret = -ENODEV;
1618                 goto err;
1619         }
1620
1621         switch (reg_revid) {
1622         case CS35L41_REVID_A0:
1623                 ret = regmap_register_patch(cs35l41->regmap,
1624                                             cs35l41_reva0_errata_patch,
1625                                             ARRAY_SIZE(cs35l41_reva0_errata_patch));
1626                 if (ret < 0) {
1627                         dev_err(cs35l41->dev,
1628                                 "Failed to apply A0 errata patch: %d\n", ret);
1629                         goto err;
1630                 }
1631                 break;
1632         case CS35L41_REVID_B0:
1633                 ret = regmap_register_patch(cs35l41->regmap,
1634                                             cs35l41_revb0_errata_patch,
1635                                             ARRAY_SIZE(cs35l41_revb0_errata_patch));
1636                 if (ret < 0) {
1637                         dev_err(cs35l41->dev,
1638                                 "Failed to apply B0 errata patch: %d\n", ret);
1639                         goto err;
1640                 }
1641                 break;
1642         case CS35L41_REVID_B2:
1643                 ret = regmap_register_patch(cs35l41->regmap,
1644                                             cs35l41_revb2_errata_patch,
1645                                             ARRAY_SIZE(cs35l41_revb2_errata_patch));
1646                 if (ret < 0) {
1647                         dev_err(cs35l41->dev,
1648                                 "Failed to apply B2 errata patch: %d\n", ret);
1649                         goto err;
1650                 }
1651                 break;
1652         }
1653
1654         irq_pol = cs35l41_irq_gpio_config(cs35l41);
1655
1656         /* Set interrupt masks for critical errors */
1657         regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1,
1658                      CS35L41_INT1_MASK_DEFAULT);
1659
1660         ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, cs35l41_irq,
1661                                         IRQF_ONESHOT | IRQF_SHARED | irq_pol,
1662                                         "cs35l41", cs35l41);
1663
1664         /* CS35L41 needs INT for PDN_DONE */
1665         if (ret != 0) {
1666                 dev_err(cs35l41->dev, "Failed to request IRQ: %d\n", ret);
1667                 goto err;
1668         }
1669
1670         ret = cs35l41_otp_unpack(cs35l41);
1671         if (ret < 0) {
1672                 dev_err(cs35l41->dev, "OTP Unpack failed: %d\n", ret);
1673                 goto err;
1674         }
1675
1676         ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_CCM_CORE_CTRL, 0);
1677         if (ret < 0) {
1678                 dev_err(cs35l41->dev, "Write CCM_CORE_CTRL failed: %d\n", ret);
1679                 goto err;
1680         }
1681
1682         ret = regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
1683                                  CS35L41_AMP_EN_MASK, 0);
1684         if (ret < 0) {
1685                 dev_err(cs35l41->dev, "Write CS35L41_PWR_CTRL2 failed: %d\n", ret);
1686                 goto err;
1687         }
1688
1689         ret = regmap_update_bits(cs35l41->regmap, CS35L41_AMP_GAIN_CTRL,
1690                                  CS35L41_AMP_GAIN_PCM_MASK, 0);
1691         if (ret < 0) {
1692                 dev_err(cs35l41->dev, "Write CS35L41_AMP_GAIN_CTRL failed: %d\n", ret);
1693                 goto err;
1694         }
1695
1696         ret = cs35l41_set_pdata(cs35l41);
1697         if (ret < 0) {
1698                 dev_err(cs35l41->dev, "Set pdata failed: %d\n", ret);
1699                 goto err;
1700         }
1701
1702         ret = cs35l41_dsp_init(cs35l41);
1703         if (ret < 0)
1704                 goto err;
1705
1706         ret = devm_snd_soc_register_component(cs35l41->dev,
1707                                               &soc_component_dev_cs35l41,
1708                                               cs35l41_dai, ARRAY_SIZE(cs35l41_dai));
1709         if (ret < 0) {
1710                 dev_err(cs35l41->dev, "Register codec failed: %d\n", ret);
1711                 goto err_dsp;
1712         }
1713
1714         dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n",
1715                  regid, reg_revid);
1716
1717         return 0;
1718
1719 err_dsp:
1720         wm_adsp2_remove(&cs35l41->dsp);
1721 err:
1722         regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
1723         gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
1724
1725         return ret;
1726 }
1727 EXPORT_SYMBOL_GPL(cs35l41_probe);
1728
1729 void cs35l41_remove(struct cs35l41_private *cs35l41)
1730 {
1731         regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF);
1732         wm_adsp2_remove(&cs35l41->dsp);
1733         regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
1734         gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
1735 }
1736 EXPORT_SYMBOL_GPL(cs35l41_remove);
1737
1738 MODULE_DESCRIPTION("ASoC CS35L41 driver");
1739 MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>");
1740 MODULE_LICENSE("GPL");