Merge tag 'trace-v5.19-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[linux-2.6-microblaze.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/pm_runtime.h>
17 #include <linux/property.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 int cs35l41_get_fs_mon_config_index(int freq)
155 {
156         int i;
157
158         for (i = 0; i < ARRAY_SIZE(cs35l41_fs_mon); i++) {
159                 if (cs35l41_fs_mon[i].freq == freq)
160                         return i;
161         }
162
163         return -EINVAL;
164 }
165
166 static const DECLARE_TLV_DB_RANGE(dig_vol_tlv,
167                 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
168                 1, 913, TLV_DB_MINMAX_ITEM(-10200, 1200));
169 static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1);
170
171 static const struct snd_kcontrol_new dre_ctrl =
172         SOC_DAPM_SINGLE("Switch", CS35L41_PWR_CTRL3, 20, 1, 0);
173
174 static const char * const cs35l41_pcm_sftramp_text[] =  {
175         "Off", ".5ms", "1ms", "2ms", "4ms", "8ms", "15ms", "30ms"
176 };
177
178 static SOC_ENUM_SINGLE_DECL(pcm_sft_ramp,
179                             CS35L41_AMP_DIG_VOL_CTRL, 0,
180                             cs35l41_pcm_sftramp_text);
181
182 static int cs35l41_dsp_preload_ev(struct snd_soc_dapm_widget *w,
183                                   struct snd_kcontrol *kcontrol, int event)
184 {
185         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
186         struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
187         int ret;
188
189         switch (event) {
190         case SND_SOC_DAPM_PRE_PMU:
191                 if (cs35l41->dsp.cs_dsp.booted)
192                         return 0;
193
194                 return wm_adsp_early_event(w, kcontrol, event);
195         case SND_SOC_DAPM_PRE_PMD:
196                 if (cs35l41->dsp.preloaded)
197                         return 0;
198
199                 if (cs35l41->dsp.cs_dsp.running) {
200                         ret = wm_adsp_event(w, kcontrol, event);
201                         if (ret)
202                                 return ret;
203                 }
204
205                 return wm_adsp_early_event(w, kcontrol, event);
206         default:
207                 return 0;
208         }
209 }
210
211 static int cs35l41_dsp_audio_ev(struct snd_soc_dapm_widget *w,
212                                 struct snd_kcontrol *kcontrol, int event)
213 {
214         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
215         struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
216         unsigned int fw_status;
217         int ret;
218
219         switch (event) {
220         case SND_SOC_DAPM_POST_PMU:
221                 if (!cs35l41->dsp.cs_dsp.running)
222                         return wm_adsp_event(w, kcontrol, event);
223
224                 ret = regmap_read(cs35l41->regmap, CS35L41_DSP_MBOX_2, &fw_status);
225                 if (ret < 0) {
226                         dev_err(cs35l41->dev,
227                                 "Failed to read firmware status: %d\n", ret);
228                         return ret;
229                 }
230
231                 switch (fw_status) {
232                 case CSPL_MBOX_STS_RUNNING:
233                 case CSPL_MBOX_STS_PAUSED:
234                         break;
235                 default:
236                         dev_err(cs35l41->dev, "Firmware status is invalid: %u\n",
237                                 fw_status);
238                         return -EINVAL;
239                 }
240
241                 return cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap,
242                                                  CSPL_MBOX_CMD_RESUME);
243         case SND_SOC_DAPM_PRE_PMD:
244                 return cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap,
245                                                  CSPL_MBOX_CMD_PAUSE);
246         default:
247                 return 0;
248         }
249 }
250
251 static const char * const cs35l41_pcm_source_texts[] = {"ASP", "DSP"};
252 static const unsigned int cs35l41_pcm_source_values[] = {0x08, 0x32};
253 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_pcm_source_enum,
254                                   CS35L41_DAC_PCM1_SRC,
255                                   0, CS35L41_ASP_SOURCE_MASK,
256                                   cs35l41_pcm_source_texts,
257                                   cs35l41_pcm_source_values);
258
259 static const struct snd_kcontrol_new pcm_source_mux =
260         SOC_DAPM_ENUM("PCM Source", cs35l41_pcm_source_enum);
261
262 static const char * const cs35l41_tx_input_texts[] = {
263         "Zero", "ASPRX1", "ASPRX2", "VMON", "IMON",
264         "VPMON", "VBSTMON", "DSPTX1", "DSPTX2"
265 };
266
267 static const unsigned int cs35l41_tx_input_values[] = {
268         0x00, CS35L41_INPUT_SRC_ASPRX1, CS35L41_INPUT_SRC_ASPRX2,
269         CS35L41_INPUT_SRC_VMON, CS35L41_INPUT_SRC_IMON, CS35L41_INPUT_SRC_VPMON,
270         CS35L41_INPUT_SRC_VBSTMON, CS35L41_INPUT_DSP_TX1, CS35L41_INPUT_DSP_TX2
271 };
272
273 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx1_enum,
274                                   CS35L41_ASP_TX1_SRC,
275                                   0, CS35L41_ASP_SOURCE_MASK,
276                                   cs35l41_tx_input_texts,
277                                   cs35l41_tx_input_values);
278
279 static const struct snd_kcontrol_new asp_tx1_mux =
280         SOC_DAPM_ENUM("ASPTX1 SRC", cs35l41_asptx1_enum);
281
282 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx2_enum,
283                                   CS35L41_ASP_TX2_SRC,
284                                   0, CS35L41_ASP_SOURCE_MASK,
285                                   cs35l41_tx_input_texts,
286                                   cs35l41_tx_input_values);
287
288 static const struct snd_kcontrol_new asp_tx2_mux =
289         SOC_DAPM_ENUM("ASPTX2 SRC", cs35l41_asptx2_enum);
290
291 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx3_enum,
292                                   CS35L41_ASP_TX3_SRC,
293                                   0, CS35L41_ASP_SOURCE_MASK,
294                                   cs35l41_tx_input_texts,
295                                   cs35l41_tx_input_values);
296
297 static const struct snd_kcontrol_new asp_tx3_mux =
298         SOC_DAPM_ENUM("ASPTX3 SRC", cs35l41_asptx3_enum);
299
300 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx4_enum,
301                                   CS35L41_ASP_TX4_SRC,
302                                   0, CS35L41_ASP_SOURCE_MASK,
303                                   cs35l41_tx_input_texts,
304                                   cs35l41_tx_input_values);
305
306 static const struct snd_kcontrol_new asp_tx4_mux =
307         SOC_DAPM_ENUM("ASPTX4 SRC", cs35l41_asptx4_enum);
308
309 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_dsprx1_enum,
310                                   CS35L41_DSP1_RX1_SRC,
311                                   0, CS35L41_ASP_SOURCE_MASK,
312                                   cs35l41_tx_input_texts,
313                                   cs35l41_tx_input_values);
314
315 static const struct snd_kcontrol_new dsp_rx1_mux =
316         SOC_DAPM_ENUM("DSPRX1 SRC", cs35l41_dsprx1_enum);
317
318 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_dsprx2_enum,
319                                   CS35L41_DSP1_RX2_SRC,
320                                   0, CS35L41_ASP_SOURCE_MASK,
321                                   cs35l41_tx_input_texts,
322                                   cs35l41_tx_input_values);
323
324 static const struct snd_kcontrol_new dsp_rx2_mux =
325         SOC_DAPM_ENUM("DSPRX2 SRC", cs35l41_dsprx2_enum);
326
327 static const struct snd_kcontrol_new cs35l41_aud_controls[] = {
328         SOC_SINGLE_SX_TLV("Digital PCM Volume", CS35L41_AMP_DIG_VOL_CTRL,
329                           3, 0x4CF, 0x391, dig_vol_tlv),
330         SOC_SINGLE_TLV("Analog PCM Volume", CS35L41_AMP_GAIN_CTRL, 5, 0x14, 0,
331                        amp_gain_tlv),
332         SOC_ENUM("PCM Soft Ramp", pcm_sft_ramp),
333         SOC_SINGLE("HW Noise Gate Enable", CS35L41_NG_CFG, 8, 63, 0),
334         SOC_SINGLE("HW Noise Gate Delay", CS35L41_NG_CFG, 4, 7, 0),
335         SOC_SINGLE("HW Noise Gate Threshold", CS35L41_NG_CFG, 0, 7, 0),
336         SOC_SINGLE("Aux Noise Gate CH1 Switch",
337                    CS35L41_MIXER_NGATE_CH1_CFG, 16, 1, 0),
338         SOC_SINGLE("Aux Noise Gate CH1 Entry Delay",
339                    CS35L41_MIXER_NGATE_CH1_CFG, 8, 15, 0),
340         SOC_SINGLE("Aux Noise Gate CH1 Threshold",
341                    CS35L41_MIXER_NGATE_CH1_CFG, 0, 7, 0),
342         SOC_SINGLE("Aux Noise Gate CH2 Entry Delay",
343                    CS35L41_MIXER_NGATE_CH2_CFG, 8, 15, 0),
344         SOC_SINGLE("Aux Noise Gate CH2 Switch",
345                    CS35L41_MIXER_NGATE_CH2_CFG, 16, 1, 0),
346         SOC_SINGLE("Aux Noise Gate CH2 Threshold",
347                    CS35L41_MIXER_NGATE_CH2_CFG, 0, 7, 0),
348         SOC_SINGLE("SCLK Force Switch", CS35L41_SP_FORMAT, CS35L41_SCLK_FRC_SHIFT, 1, 0),
349         SOC_SINGLE("LRCLK Force Switch", CS35L41_SP_FORMAT, CS35L41_LRCLK_FRC_SHIFT, 1, 0),
350         SOC_SINGLE("Invert Class D Switch", CS35L41_AMP_DIG_VOL_CTRL,
351                    CS35L41_AMP_INV_PCM_SHIFT, 1, 0),
352         SOC_SINGLE("Amp Gain ZC Switch", CS35L41_AMP_GAIN_CTRL,
353                    CS35L41_AMP_GAIN_ZC_SHIFT, 1, 0),
354         WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
355         WM_ADSP_FW_CONTROL("DSP1", 0),
356 };
357
358 static irqreturn_t cs35l41_irq(int irq, void *data)
359 {
360         struct cs35l41_private *cs35l41 = data;
361         unsigned int status[4] = { 0, 0, 0, 0 };
362         unsigned int masks[4] = { 0, 0, 0, 0 };
363         int ret = IRQ_NONE;
364         unsigned int i;
365
366         pm_runtime_get_sync(cs35l41->dev);
367
368         for (i = 0; i < ARRAY_SIZE(status); i++) {
369                 regmap_read(cs35l41->regmap,
370                             CS35L41_IRQ1_STATUS1 + (i * CS35L41_REGSTRIDE),
371                             &status[i]);
372                 regmap_read(cs35l41->regmap,
373                             CS35L41_IRQ1_MASK1 + (i * CS35L41_REGSTRIDE),
374                             &masks[i]);
375         }
376
377         /* Check to see if unmasked bits are active */
378         if (!(status[0] & ~masks[0]) && !(status[1] & ~masks[1]) &&
379             !(status[2] & ~masks[2]) && !(status[3] & ~masks[3]))
380                 goto done;
381
382         if (status[3] & CS35L41_OTP_BOOT_DONE) {
383                 regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK4,
384                                    CS35L41_OTP_BOOT_DONE, CS35L41_OTP_BOOT_DONE);
385         }
386
387         /*
388          * The following interrupts require a
389          * protection release cycle to get the
390          * speaker out of Safe-Mode.
391          */
392         if (status[0] & CS35L41_AMP_SHORT_ERR) {
393                 dev_crit_ratelimited(cs35l41->dev, "Amp short error\n");
394                 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
395                              CS35L41_AMP_SHORT_ERR);
396                 regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
397                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
398                                    CS35L41_AMP_SHORT_ERR_RLS,
399                                    CS35L41_AMP_SHORT_ERR_RLS);
400                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
401                                    CS35L41_AMP_SHORT_ERR_RLS, 0);
402                 ret = IRQ_HANDLED;
403         }
404
405         if (status[0] & CS35L41_TEMP_WARN) {
406                 dev_crit_ratelimited(cs35l41->dev, "Over temperature warning\n");
407                 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
408                              CS35L41_TEMP_WARN);
409                 regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
410                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
411                                    CS35L41_TEMP_WARN_ERR_RLS,
412                                    CS35L41_TEMP_WARN_ERR_RLS);
413                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
414                                    CS35L41_TEMP_WARN_ERR_RLS, 0);
415                 ret = IRQ_HANDLED;
416         }
417
418         if (status[0] & CS35L41_TEMP_ERR) {
419                 dev_crit_ratelimited(cs35l41->dev, "Over temperature error\n");
420                 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
421                              CS35L41_TEMP_ERR);
422                 regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
423                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
424                                    CS35L41_TEMP_ERR_RLS,
425                                    CS35L41_TEMP_ERR_RLS);
426                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
427                                    CS35L41_TEMP_ERR_RLS, 0);
428                 ret = IRQ_HANDLED;
429         }
430
431         if (status[0] & CS35L41_BST_OVP_ERR) {
432                 dev_crit_ratelimited(cs35l41->dev, "VBST Over Voltage error\n");
433                 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
434                                    CS35L41_BST_EN_MASK, 0);
435                 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
436                              CS35L41_BST_OVP_ERR);
437                 regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
438                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
439                                    CS35L41_BST_OVP_ERR_RLS,
440                                    CS35L41_BST_OVP_ERR_RLS);
441                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
442                                    CS35L41_BST_OVP_ERR_RLS, 0);
443                 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
444                                    CS35L41_BST_EN_MASK,
445                                    CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
446                 ret = IRQ_HANDLED;
447         }
448
449         if (status[0] & CS35L41_BST_DCM_UVP_ERR) {
450                 dev_crit_ratelimited(cs35l41->dev, "DCM VBST Under Voltage Error\n");
451                 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
452                                    CS35L41_BST_EN_MASK, 0);
453                 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
454                              CS35L41_BST_DCM_UVP_ERR);
455                 regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
456                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
457                                    CS35L41_BST_UVP_ERR_RLS,
458                                    CS35L41_BST_UVP_ERR_RLS);
459                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
460                                    CS35L41_BST_UVP_ERR_RLS, 0);
461                 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
462                                    CS35L41_BST_EN_MASK,
463                                    CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
464                 ret = IRQ_HANDLED;
465         }
466
467         if (status[0] & CS35L41_BST_SHORT_ERR) {
468                 dev_crit_ratelimited(cs35l41->dev, "LBST error: powering off!\n");
469                 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
470                                    CS35L41_BST_EN_MASK, 0);
471                 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
472                              CS35L41_BST_SHORT_ERR);
473                 regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
474                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
475                                    CS35L41_BST_SHORT_ERR_RLS,
476                                    CS35L41_BST_SHORT_ERR_RLS);
477                 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
478                                    CS35L41_BST_SHORT_ERR_RLS, 0);
479                 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
480                                    CS35L41_BST_EN_MASK,
481                                    CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
482                 ret = IRQ_HANDLED;
483         }
484
485 done:
486         pm_runtime_mark_last_busy(cs35l41->dev);
487         pm_runtime_put_autosuspend(cs35l41->dev);
488
489         return ret;
490 }
491
492 static const struct reg_sequence cs35l41_pup_patch[] = {
493         { CS35L41_TEST_KEY_CTL, 0x00000055 },
494         { CS35L41_TEST_KEY_CTL, 0x000000AA },
495         { 0x00002084, 0x002F1AA0 },
496         { CS35L41_TEST_KEY_CTL, 0x000000CC },
497         { CS35L41_TEST_KEY_CTL, 0x00000033 },
498 };
499
500 static const struct reg_sequence cs35l41_pdn_patch[] = {
501         { CS35L41_TEST_KEY_CTL, 0x00000055 },
502         { CS35L41_TEST_KEY_CTL, 0x000000AA },
503         { 0x00002084, 0x002F1AA3 },
504         { CS35L41_TEST_KEY_CTL, 0x000000CC },
505         { CS35L41_TEST_KEY_CTL, 0x00000033 },
506 };
507
508 static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w,
509                                   struct snd_kcontrol *kcontrol, int event)
510 {
511         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
512         struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
513         unsigned int val;
514         int ret = 0;
515
516         switch (event) {
517         case SND_SOC_DAPM_PRE_PMU:
518                 regmap_multi_reg_write_bypassed(cs35l41->regmap,
519                                                 cs35l41_pup_patch,
520                                                 ARRAY_SIZE(cs35l41_pup_patch));
521
522                 cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 1);
523                 break;
524         case SND_SOC_DAPM_POST_PMD:
525                 cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 0);
526
527                 ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
528                                                val, val &  CS35L41_PDN_DONE_MASK,
529                                                1000, 100000);
530                 if (ret)
531                         dev_warn(cs35l41->dev, "PDN failed: %d\n", ret);
532
533                 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
534                              CS35L41_PDN_DONE_MASK);
535
536                 regmap_multi_reg_write_bypassed(cs35l41->regmap,
537                                                 cs35l41_pdn_patch,
538                                                 ARRAY_SIZE(cs35l41_pdn_patch));
539                 break;
540         default:
541                 dev_err(cs35l41->dev, "Invalid event = 0x%x\n", event);
542                 ret = -EINVAL;
543         }
544
545         return ret;
546 }
547
548 static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = {
549         SND_SOC_DAPM_SPK("DSP1 Preload", NULL),
550         SND_SOC_DAPM_SUPPLY_S("DSP1 Preloader", 100, SND_SOC_NOPM, 0, 0,
551                               cs35l41_dsp_preload_ev,
552                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
553         SND_SOC_DAPM_OUT_DRV_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0,
554                                cs35l41_dsp_audio_ev,
555                                SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
556
557         SND_SOC_DAPM_OUTPUT("SPK"),
558
559         SND_SOC_DAPM_AIF_IN("ASPRX1", NULL, 0, CS35L41_SP_ENABLES, 16, 0),
560         SND_SOC_DAPM_AIF_IN("ASPRX2", NULL, 0, CS35L41_SP_ENABLES, 17, 0),
561         SND_SOC_DAPM_AIF_OUT("ASPTX1", NULL, 0, CS35L41_SP_ENABLES, 0, 0),
562         SND_SOC_DAPM_AIF_OUT("ASPTX2", NULL, 0, CS35L41_SP_ENABLES, 1, 0),
563         SND_SOC_DAPM_AIF_OUT("ASPTX3", NULL, 0, CS35L41_SP_ENABLES, 2, 0),
564         SND_SOC_DAPM_AIF_OUT("ASPTX4", NULL, 0, CS35L41_SP_ENABLES, 3, 0),
565
566         SND_SOC_DAPM_SIGGEN("VSENSE"),
567         SND_SOC_DAPM_SIGGEN("ISENSE"),
568         SND_SOC_DAPM_SIGGEN("VP"),
569         SND_SOC_DAPM_SIGGEN("VBST"),
570         SND_SOC_DAPM_SIGGEN("TEMP"),
571
572         SND_SOC_DAPM_SUPPLY("VMON", CS35L41_PWR_CTRL2, 12, 0, NULL, 0),
573         SND_SOC_DAPM_SUPPLY("IMON", CS35L41_PWR_CTRL2, 13, 0, NULL, 0),
574         SND_SOC_DAPM_SUPPLY("VPMON", CS35L41_PWR_CTRL2, 8, 0, NULL, 0),
575         SND_SOC_DAPM_SUPPLY("VBSTMON", CS35L41_PWR_CTRL2, 9, 0, NULL, 0),
576         SND_SOC_DAPM_SUPPLY("TEMPMON", CS35L41_PWR_CTRL2, 10, 0, NULL, 0),
577
578         SND_SOC_DAPM_ADC("VMON ADC", NULL, SND_SOC_NOPM, 0, 0),
579         SND_SOC_DAPM_ADC("IMON ADC", NULL, SND_SOC_NOPM, 0, 0),
580         SND_SOC_DAPM_ADC("VPMON ADC", NULL, SND_SOC_NOPM, 0, 0),
581         SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, SND_SOC_NOPM, 0, 0),
582         SND_SOC_DAPM_ADC("TEMPMON ADC", NULL, SND_SOC_NOPM, 0, 0),
583
584         SND_SOC_DAPM_ADC("CLASS H", NULL, CS35L41_PWR_CTRL3, 4, 0),
585
586         SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L41_PWR_CTRL2, 0, 0, NULL, 0,
587                                cs35l41_main_amp_event,
588                                SND_SOC_DAPM_POST_PMD |  SND_SOC_DAPM_PRE_PMU),
589
590         SND_SOC_DAPM_MUX("ASP TX1 Source", SND_SOC_NOPM, 0, 0, &asp_tx1_mux),
591         SND_SOC_DAPM_MUX("ASP TX2 Source", SND_SOC_NOPM, 0, 0, &asp_tx2_mux),
592         SND_SOC_DAPM_MUX("ASP TX3 Source", SND_SOC_NOPM, 0, 0, &asp_tx3_mux),
593         SND_SOC_DAPM_MUX("ASP TX4 Source", SND_SOC_NOPM, 0, 0, &asp_tx4_mux),
594         SND_SOC_DAPM_MUX("DSP RX1 Source", SND_SOC_NOPM, 0, 0, &dsp_rx1_mux),
595         SND_SOC_DAPM_MUX("DSP RX2 Source", SND_SOC_NOPM, 0, 0, &dsp_rx2_mux),
596         SND_SOC_DAPM_MUX("PCM Source", SND_SOC_NOPM, 0, 0, &pcm_source_mux),
597         SND_SOC_DAPM_SWITCH("DRE", SND_SOC_NOPM, 0, 0, &dre_ctrl),
598 };
599
600 static const struct snd_soc_dapm_route cs35l41_audio_map[] = {
601         {"DSP RX1 Source", "ASPRX1", "ASPRX1"},
602         {"DSP RX1 Source", "ASPRX2", "ASPRX2"},
603         {"DSP RX2 Source", "ASPRX1", "ASPRX1"},
604         {"DSP RX2 Source", "ASPRX2", "ASPRX2"},
605
606         {"DSP1", NULL, "DSP RX1 Source"},
607         {"DSP1", NULL, "DSP RX2 Source"},
608
609         {"ASP TX1 Source", "VMON", "VMON ADC"},
610         {"ASP TX1 Source", "IMON", "IMON ADC"},
611         {"ASP TX1 Source", "VPMON", "VPMON ADC"},
612         {"ASP TX1 Source", "VBSTMON", "VBSTMON ADC"},
613         {"ASP TX1 Source", "DSPTX1", "DSP1"},
614         {"ASP TX1 Source", "DSPTX2", "DSP1"},
615         {"ASP TX1 Source", "ASPRX1", "ASPRX1" },
616         {"ASP TX1 Source", "ASPRX2", "ASPRX2" },
617         {"ASP TX2 Source", "VMON", "VMON ADC"},
618         {"ASP TX2 Source", "IMON", "IMON ADC"},
619         {"ASP TX2 Source", "VPMON", "VPMON ADC"},
620         {"ASP TX2 Source", "VBSTMON", "VBSTMON ADC"},
621         {"ASP TX2 Source", "DSPTX1", "DSP1"},
622         {"ASP TX2 Source", "DSPTX2", "DSP1"},
623         {"ASP TX2 Source", "ASPRX1", "ASPRX1" },
624         {"ASP TX2 Source", "ASPRX2", "ASPRX2" },
625         {"ASP TX3 Source", "VMON", "VMON ADC"},
626         {"ASP TX3 Source", "IMON", "IMON ADC"},
627         {"ASP TX3 Source", "VPMON", "VPMON ADC"},
628         {"ASP TX3 Source", "VBSTMON", "VBSTMON ADC"},
629         {"ASP TX3 Source", "DSPTX1", "DSP1"},
630         {"ASP TX3 Source", "DSPTX2", "DSP1"},
631         {"ASP TX3 Source", "ASPRX1", "ASPRX1" },
632         {"ASP TX3 Source", "ASPRX2", "ASPRX2" },
633         {"ASP TX4 Source", "VMON", "VMON ADC"},
634         {"ASP TX4 Source", "IMON", "IMON ADC"},
635         {"ASP TX4 Source", "VPMON", "VPMON ADC"},
636         {"ASP TX4 Source", "VBSTMON", "VBSTMON ADC"},
637         {"ASP TX4 Source", "DSPTX1", "DSP1"},
638         {"ASP TX4 Source", "DSPTX2", "DSP1"},
639         {"ASP TX4 Source", "ASPRX1", "ASPRX1" },
640         {"ASP TX4 Source", "ASPRX2", "ASPRX2" },
641         {"ASPTX1", NULL, "ASP TX1 Source"},
642         {"ASPTX2", NULL, "ASP TX2 Source"},
643         {"ASPTX3", NULL, "ASP TX3 Source"},
644         {"ASPTX4", NULL, "ASP TX4 Source"},
645         {"AMP Capture", NULL, "ASPTX1"},
646         {"AMP Capture", NULL, "ASPTX2"},
647         {"AMP Capture", NULL, "ASPTX3"},
648         {"AMP Capture", NULL, "ASPTX4"},
649
650         {"DSP1", NULL, "VMON"},
651         {"DSP1", NULL, "IMON"},
652         {"DSP1", NULL, "VPMON"},
653         {"DSP1", NULL, "VBSTMON"},
654         {"DSP1", NULL, "TEMPMON"},
655
656         {"VMON ADC", NULL, "VMON"},
657         {"IMON ADC", NULL, "IMON"},
658         {"VPMON ADC", NULL, "VPMON"},
659         {"VBSTMON ADC", NULL, "VBSTMON"},
660         {"TEMPMON ADC", NULL, "TEMPMON"},
661
662         {"VMON ADC", NULL, "VSENSE"},
663         {"IMON ADC", NULL, "ISENSE"},
664         {"VPMON ADC", NULL, "VP"},
665         {"VBSTMON ADC", NULL, "VBST"},
666         {"TEMPMON ADC", NULL, "TEMP"},
667
668         {"DSP1 Preload", NULL, "DSP1 Preloader"},
669         {"DSP1", NULL, "DSP1 Preloader"},
670
671         {"ASPRX1", NULL, "AMP Playback"},
672         {"ASPRX2", NULL, "AMP Playback"},
673         {"DRE", "Switch", "CLASS H"},
674         {"Main AMP", NULL, "CLASS H"},
675         {"Main AMP", NULL, "DRE"},
676         {"SPK", NULL, "Main AMP"},
677
678         {"PCM Source", "ASP", "ASPRX1"},
679         {"PCM Source", "DSP", "DSP1"},
680         {"CLASS H", NULL, "PCM Source"},
681 };
682
683 static int cs35l41_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_n,
684                                    unsigned int *tx_slot, unsigned int rx_n, unsigned int *rx_slot)
685 {
686         struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
687
688         return cs35l41_set_channels(cs35l41->dev, cs35l41->regmap, tx_n, tx_slot, rx_n, rx_slot);
689 }
690
691 static int cs35l41_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
692 {
693         struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
694         unsigned int daifmt = 0;
695
696         switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
697         case SND_SOC_DAIFMT_CBP_CFP:
698                 daifmt |= CS35L41_SCLK_MSTR_MASK | CS35L41_LRCLK_MSTR_MASK;
699                 break;
700         case SND_SOC_DAIFMT_CBC_CFC:
701                 break;
702         default:
703                 dev_warn(cs35l41->dev, "Mixed provider/consumer mode unsupported\n");
704                 return -EINVAL;
705         }
706
707         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
708         case SND_SOC_DAIFMT_DSP_A:
709                 break;
710         case SND_SOC_DAIFMT_I2S:
711                 daifmt |= 2 << CS35L41_ASP_FMT_SHIFT;
712                 break;
713         default:
714                 dev_warn(cs35l41->dev, "Invalid or unsupported DAI format\n");
715                 return -EINVAL;
716         }
717
718         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
719         case SND_SOC_DAIFMT_NB_IF:
720                 daifmt |= CS35L41_LRCLK_INV_MASK;
721                 break;
722         case SND_SOC_DAIFMT_IB_NF:
723                 daifmt |= CS35L41_SCLK_INV_MASK;
724                 break;
725         case SND_SOC_DAIFMT_IB_IF:
726                 daifmt |= CS35L41_LRCLK_INV_MASK | CS35L41_SCLK_INV_MASK;
727                 break;
728         case SND_SOC_DAIFMT_NB_NF:
729                 break;
730         default:
731                 dev_warn(cs35l41->dev, "Invalid DAI clock INV\n");
732                 return -EINVAL;
733         }
734
735         return regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
736                                   CS35L41_SCLK_MSTR_MASK | CS35L41_LRCLK_MSTR_MASK |
737                                   CS35L41_ASP_FMT_MASK | CS35L41_LRCLK_INV_MASK |
738                                   CS35L41_SCLK_INV_MASK, daifmt);
739 }
740
741 struct cs35l41_global_fs_config {
742         int rate;
743         int fs_cfg;
744 };
745
746 static const struct cs35l41_global_fs_config cs35l41_fs_rates[] = {
747         { 12000,        0x01 },
748         { 24000,        0x02 },
749         { 48000,        0x03 },
750         { 96000,        0x04 },
751         { 192000,       0x05 },
752         { 11025,        0x09 },
753         { 22050,        0x0A },
754         { 44100,        0x0B },
755         { 88200,        0x0C },
756         { 176400,       0x0D },
757         { 8000,         0x11 },
758         { 16000,        0x12 },
759         { 32000,        0x13 },
760 };
761
762 static int cs35l41_pcm_hw_params(struct snd_pcm_substream *substream,
763                                  struct snd_pcm_hw_params *params,
764                                  struct snd_soc_dai *dai)
765 {
766         struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
767         unsigned int rate = params_rate(params);
768         u8 asp_wl;
769         int i;
770
771         for (i = 0; i < ARRAY_SIZE(cs35l41_fs_rates); i++) {
772                 if (rate == cs35l41_fs_rates[i].rate)
773                         break;
774         }
775
776         if (i >= ARRAY_SIZE(cs35l41_fs_rates)) {
777                 dev_err(cs35l41->dev, "Unsupported rate: %u\n", rate);
778                 return -EINVAL;
779         }
780
781         asp_wl = params_width(params);
782
783         if (i < ARRAY_SIZE(cs35l41_fs_rates))
784                 regmap_update_bits(cs35l41->regmap, CS35L41_GLOBAL_CLK_CTRL,
785                                    CS35L41_GLOBAL_FS_MASK,
786                                    cs35l41_fs_rates[i].fs_cfg << CS35L41_GLOBAL_FS_SHIFT);
787
788         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
789                 regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
790                                    CS35L41_ASP_WIDTH_RX_MASK,
791                                    asp_wl << CS35L41_ASP_WIDTH_RX_SHIFT);
792                 regmap_update_bits(cs35l41->regmap, CS35L41_SP_RX_WL,
793                                    CS35L41_ASP_RX_WL_MASK,
794                                    asp_wl << CS35L41_ASP_RX_WL_SHIFT);
795         } else {
796                 regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
797                                    CS35L41_ASP_WIDTH_TX_MASK,
798                                    asp_wl << CS35L41_ASP_WIDTH_TX_SHIFT);
799                 regmap_update_bits(cs35l41->regmap, CS35L41_SP_TX_WL,
800                                    CS35L41_ASP_TX_WL_MASK,
801                                    asp_wl << CS35L41_ASP_TX_WL_SHIFT);
802         }
803
804         return 0;
805 }
806
807 static int cs35l41_get_clk_config(int freq)
808 {
809         int i;
810
811         for (i = 0; i < ARRAY_SIZE(cs35l41_pll_sysclk); i++) {
812                 if (cs35l41_pll_sysclk[i].freq == freq)
813                         return cs35l41_pll_sysclk[i].clk_cfg;
814         }
815
816         return -EINVAL;
817 }
818
819 static const unsigned int cs35l41_src_rates[] = {
820         8000, 12000, 11025, 16000, 22050, 24000, 32000,
821         44100, 48000, 88200, 96000, 176400, 192000
822 };
823
824 static const struct snd_pcm_hw_constraint_list cs35l41_constraints = {
825         .count = ARRAY_SIZE(cs35l41_src_rates),
826         .list = cs35l41_src_rates,
827 };
828
829 static int cs35l41_pcm_startup(struct snd_pcm_substream *substream,
830                                struct snd_soc_dai *dai)
831 {
832         if (substream->runtime)
833                 return snd_pcm_hw_constraint_list(substream->runtime, 0,
834                                                   SNDRV_PCM_HW_PARAM_RATE,
835                                                   &cs35l41_constraints);
836         return 0;
837 }
838
839 static int cs35l41_component_set_sysclk(struct snd_soc_component *component,
840                                         int clk_id, int source,
841                                         unsigned int freq, int dir)
842 {
843         struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
844         int extclk_cfg, clksrc;
845
846         switch (clk_id) {
847         case CS35L41_CLKID_SCLK:
848                 clksrc = CS35L41_PLLSRC_SCLK;
849                 break;
850         case CS35L41_CLKID_LRCLK:
851                 clksrc = CS35L41_PLLSRC_LRCLK;
852                 break;
853         case CS35L41_CLKID_MCLK:
854                 clksrc = CS35L41_PLLSRC_MCLK;
855                 break;
856         default:
857                 dev_err(cs35l41->dev, "Invalid CLK Config\n");
858                 return -EINVAL;
859         }
860
861         extclk_cfg = cs35l41_get_clk_config(freq);
862
863         if (extclk_cfg < 0) {
864                 dev_err(cs35l41->dev, "Invalid CLK Config: %d, freq: %u\n",
865                         extclk_cfg, freq);
866                 return -EINVAL;
867         }
868
869         regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
870                            CS35L41_PLL_OPENLOOP_MASK,
871                            1 << CS35L41_PLL_OPENLOOP_SHIFT);
872         regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
873                            CS35L41_REFCLK_FREQ_MASK,
874                            extclk_cfg << CS35L41_REFCLK_FREQ_SHIFT);
875         regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
876                            CS35L41_PLL_CLK_EN_MASK,
877                            0 << CS35L41_PLL_CLK_EN_SHIFT);
878         regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
879                            CS35L41_PLL_CLK_SEL_MASK, clksrc);
880         regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
881                            CS35L41_PLL_OPENLOOP_MASK,
882                            0 << CS35L41_PLL_OPENLOOP_SHIFT);
883         regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
884                            CS35L41_PLL_CLK_EN_MASK,
885                            1 << CS35L41_PLL_CLK_EN_SHIFT);
886
887         return 0;
888 }
889
890 static int cs35l41_dai_set_sysclk(struct snd_soc_dai *dai,
891                                   int clk_id, unsigned int freq, int dir)
892 {
893         struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
894         unsigned int fs1_val;
895         unsigned int fs2_val;
896         unsigned int val;
897         int fsindex;
898
899         fsindex = cs35l41_get_fs_mon_config_index(freq);
900         if (fsindex < 0) {
901                 dev_err(cs35l41->dev, "Invalid CLK Config freq: %u\n", freq);
902                 return -EINVAL;
903         }
904
905         dev_dbg(cs35l41->dev, "Set DAI sysclk %d\n", freq);
906
907         if (freq <= 6144000) {
908                 /* Use the lookup table */
909                 fs1_val = cs35l41_fs_mon[fsindex].fs1;
910                 fs2_val = cs35l41_fs_mon[fsindex].fs2;
911         } else {
912                 /* Use hard-coded values */
913                 fs1_val = 0x10;
914                 fs2_val = 0x24;
915         }
916
917         val = fs1_val;
918         val |= (fs2_val << CS35L41_FS2_WINDOW_SHIFT) & CS35L41_FS2_WINDOW_MASK;
919         regmap_write(cs35l41->regmap, CS35L41_TST_FS_MON0, val);
920
921         return 0;
922 }
923
924 static int cs35l41_set_pdata(struct cs35l41_private *cs35l41)
925 {
926         struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
927         int ret;
928
929         if (!hw_cfg->valid)
930                 return -EINVAL;
931
932         if (hw_cfg->bst_type == CS35L41_EXT_BOOST_NO_VSPK_SWITCH)
933                 return -EINVAL;
934
935         /* Required */
936         ret = cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, hw_cfg);
937         if (ret)
938                 return ret;
939
940         /* Optional */
941         if (hw_cfg->dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK && hw_cfg->dout_hiz >= 0)
942                 regmap_update_bits(cs35l41->regmap, CS35L41_SP_HIZ_CTRL, CS35L41_ASP_DOUT_HIZ_MASK,
943                                    hw_cfg->dout_hiz);
944
945         return 0;
946 }
947
948 static const struct snd_soc_dapm_route cs35l41_ext_bst_routes[] = {
949         {"Main AMP", NULL, "VSPK"},
950 };
951
952 static const struct snd_soc_dapm_widget cs35l41_ext_bst_widget[] = {
953         SND_SOC_DAPM_SUPPLY("VSPK", CS35L41_GPIO1_CTRL1, CS35L41_GPIO_LVL_SHIFT, 0, NULL, 0),
954 };
955
956 static int cs35l41_component_probe(struct snd_soc_component *component)
957 {
958         struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
959         struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
960         int ret;
961
962         if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) {
963                 ret = snd_soc_dapm_new_controls(dapm, cs35l41_ext_bst_widget,
964                                                 ARRAY_SIZE(cs35l41_ext_bst_widget));
965                 if (ret)
966                         return ret;
967
968                 ret = snd_soc_dapm_add_routes(dapm, cs35l41_ext_bst_routes,
969                                               ARRAY_SIZE(cs35l41_ext_bst_routes));
970                 if (ret)
971                         return ret;
972         }
973
974         return wm_adsp2_component_probe(&cs35l41->dsp, component);
975 }
976
977 static void cs35l41_component_remove(struct snd_soc_component *component)
978 {
979         struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
980
981         wm_adsp2_component_remove(&cs35l41->dsp, component);
982 }
983
984 static const struct snd_soc_dai_ops cs35l41_ops = {
985         .startup = cs35l41_pcm_startup,
986         .set_fmt = cs35l41_set_dai_fmt,
987         .hw_params = cs35l41_pcm_hw_params,
988         .set_sysclk = cs35l41_dai_set_sysclk,
989         .set_channel_map = cs35l41_set_channel_map,
990 };
991
992 static struct snd_soc_dai_driver cs35l41_dai[] = {
993         {
994                 .name = "cs35l41-pcm",
995                 .id = 0,
996                 .playback = {
997                         .stream_name = "AMP Playback",
998                         .channels_min = 1,
999                         .channels_max = 2,
1000                         .rates = SNDRV_PCM_RATE_KNOT,
1001                         .formats = CS35L41_RX_FORMATS,
1002                 },
1003                 .capture = {
1004                         .stream_name = "AMP Capture",
1005                         .channels_min = 1,
1006                         .channels_max = 4,
1007                         .rates = SNDRV_PCM_RATE_KNOT,
1008                         .formats = CS35L41_TX_FORMATS,
1009                 },
1010                 .ops = &cs35l41_ops,
1011                 .symmetric_rate = 1,
1012         },
1013 };
1014
1015 static const struct snd_soc_component_driver soc_component_dev_cs35l41 = {
1016         .name = "cs35l41-codec",
1017         .probe = cs35l41_component_probe,
1018         .remove = cs35l41_component_remove,
1019
1020         .dapm_widgets = cs35l41_dapm_widgets,
1021         .num_dapm_widgets = ARRAY_SIZE(cs35l41_dapm_widgets),
1022         .dapm_routes = cs35l41_audio_map,
1023         .num_dapm_routes = ARRAY_SIZE(cs35l41_audio_map),
1024
1025         .controls = cs35l41_aud_controls,
1026         .num_controls = ARRAY_SIZE(cs35l41_aud_controls),
1027         .set_sysclk = cs35l41_component_set_sysclk,
1028
1029         .endianness = 1,
1030 };
1031
1032 static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_hw_cfg *hw_cfg)
1033 {
1034         struct cs35l41_gpio_cfg *gpio1 = &hw_cfg->gpio1;
1035         struct cs35l41_gpio_cfg *gpio2 = &hw_cfg->gpio2;
1036         unsigned int val;
1037         int ret;
1038
1039         ret = device_property_read_u32(dev, "cirrus,boost-type", &val);
1040         if (ret >= 0)
1041                 hw_cfg->bst_type = val;
1042
1043         ret = device_property_read_u32(dev, "cirrus,boost-peak-milliamp", &val);
1044         if (ret >= 0)
1045                 hw_cfg->bst_ipk = val;
1046         else
1047                 hw_cfg->bst_ipk = -1;
1048
1049         ret = device_property_read_u32(dev, "cirrus,boost-ind-nanohenry", &val);
1050         if (ret >= 0)
1051                 hw_cfg->bst_ind = val;
1052         else
1053                 hw_cfg->bst_ind = -1;
1054
1055         ret = device_property_read_u32(dev, "cirrus,boost-cap-microfarad", &val);
1056         if (ret >= 0)
1057                 hw_cfg->bst_cap = val;
1058         else
1059                 hw_cfg->bst_cap = -1;
1060
1061         ret = device_property_read_u32(dev, "cirrus,asp-sdout-hiz", &val);
1062         if (ret >= 0)
1063                 hw_cfg->dout_hiz = val;
1064         else
1065                 hw_cfg->dout_hiz = -1;
1066
1067         /* GPIO1 Pin Config */
1068         gpio1->pol_inv = device_property_read_bool(dev, "cirrus,gpio1-polarity-invert");
1069         gpio1->out_en = device_property_read_bool(dev, "cirrus,gpio1-output-enable");
1070         ret = device_property_read_u32(dev, "cirrus,gpio1-src-select", &val);
1071         if (ret >= 0) {
1072                 gpio1->func = val;
1073                 gpio1->valid = true;
1074         }
1075
1076         /* GPIO2 Pin Config */
1077         gpio2->pol_inv = device_property_read_bool(dev, "cirrus,gpio2-polarity-invert");
1078         gpio2->out_en = device_property_read_bool(dev, "cirrus,gpio2-output-enable");
1079         ret = device_property_read_u32(dev, "cirrus,gpio2-src-select", &val);
1080         if (ret >= 0) {
1081                 gpio2->func = val;
1082                 gpio2->valid = true;
1083         }
1084
1085         hw_cfg->valid = true;
1086
1087         return 0;
1088 }
1089
1090 static int cs35l41_dsp_init(struct cs35l41_private *cs35l41)
1091 {
1092         struct wm_adsp *dsp;
1093         int ret;
1094
1095         dsp = &cs35l41->dsp;
1096         dsp->part = "cs35l41";
1097         dsp->fw = 9; /* 9 is WM_ADSP_FW_SPK_PROT in wm_adsp.c */
1098         dsp->toggle_preload = true;
1099
1100         cs35l41_configure_cs_dsp(cs35l41->dev, cs35l41->regmap, &dsp->cs_dsp);
1101
1102         ret = cs35l41_write_fs_errata(cs35l41->dev, cs35l41->regmap);
1103         if (ret < 0)
1104                 return ret;
1105
1106         ret = wm_halo_init(dsp);
1107         if (ret) {
1108                 dev_err(cs35l41->dev, "wm_halo_init failed: %d\n", ret);
1109                 return ret;
1110         }
1111
1112         ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX5_SRC,
1113                            CS35L41_INPUT_SRC_VPMON);
1114         if (ret < 0) {
1115                 dev_err(cs35l41->dev, "Write INPUT_SRC_VPMON failed: %d\n", ret);
1116                 goto err_dsp;
1117         }
1118         ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX6_SRC,
1119                            CS35L41_INPUT_SRC_CLASSH);
1120         if (ret < 0) {
1121                 dev_err(cs35l41->dev, "Write INPUT_SRC_CLASSH failed: %d\n", ret);
1122                 goto err_dsp;
1123         }
1124         ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX7_SRC,
1125                            CS35L41_INPUT_SRC_TEMPMON);
1126         if (ret < 0) {
1127                 dev_err(cs35l41->dev, "Write INPUT_SRC_TEMPMON failed: %d\n", ret);
1128                 goto err_dsp;
1129         }
1130         ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX8_SRC,
1131                            CS35L41_INPUT_SRC_RSVD);
1132         if (ret < 0) {
1133                 dev_err(cs35l41->dev, "Write INPUT_SRC_RSVD failed: %d\n", ret);
1134                 goto err_dsp;
1135         }
1136
1137         return 0;
1138
1139 err_dsp:
1140         wm_adsp2_remove(dsp);
1141
1142         return ret;
1143 }
1144
1145 int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *hw_cfg)
1146 {
1147         u32 regid, reg_revid, i, mtl_revid, int_status, chipid_match;
1148         int irq_pol = 0;
1149         int ret;
1150
1151         if (hw_cfg) {
1152                 cs35l41->hw_cfg = *hw_cfg;
1153         } else {
1154                 ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->hw_cfg);
1155                 if (ret != 0)
1156                         return ret;
1157         }
1158
1159         for (i = 0; i < CS35L41_NUM_SUPPLIES; i++)
1160                 cs35l41->supplies[i].supply = cs35l41_supplies[i];
1161
1162         ret = devm_regulator_bulk_get(cs35l41->dev, CS35L41_NUM_SUPPLIES,
1163                                       cs35l41->supplies);
1164         if (ret != 0) {
1165                 dev_err(cs35l41->dev, "Failed to request core supplies: %d\n", ret);
1166                 return ret;
1167         }
1168
1169         ret = regulator_bulk_enable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
1170         if (ret != 0) {
1171                 dev_err(cs35l41->dev, "Failed to enable core supplies: %d\n", ret);
1172                 return ret;
1173         }
1174
1175         /* returning NULL can be an option if in stereo mode */
1176         cs35l41->reset_gpio = devm_gpiod_get_optional(cs35l41->dev, "reset",
1177                                                       GPIOD_OUT_LOW);
1178         if (IS_ERR(cs35l41->reset_gpio)) {
1179                 ret = PTR_ERR(cs35l41->reset_gpio);
1180                 cs35l41->reset_gpio = NULL;
1181                 if (ret == -EBUSY) {
1182                         dev_info(cs35l41->dev,
1183                                  "Reset line busy, assuming shared reset\n");
1184                 } else {
1185                         dev_err(cs35l41->dev,
1186                                 "Failed to get reset GPIO: %d\n", ret);
1187                         goto err;
1188                 }
1189         }
1190         if (cs35l41->reset_gpio) {
1191                 /* satisfy minimum reset pulse width spec */
1192                 usleep_range(2000, 2100);
1193                 gpiod_set_value_cansleep(cs35l41->reset_gpio, 1);
1194         }
1195
1196         usleep_range(2000, 2100);
1197
1198         ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS4,
1199                                        int_status, int_status & CS35L41_OTP_BOOT_DONE,
1200                                        1000, 100000);
1201         if (ret) {
1202                 dev_err(cs35l41->dev,
1203                         "Failed waiting for OTP_BOOT_DONE: %d\n", ret);
1204                 goto err;
1205         }
1206
1207         regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_status);
1208         if (int_status & CS35L41_OTP_BOOT_ERR) {
1209                 dev_err(cs35l41->dev, "OTP Boot error\n");
1210                 ret = -EINVAL;
1211                 goto err;
1212         }
1213
1214         ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, &regid);
1215         if (ret < 0) {
1216                 dev_err(cs35l41->dev, "Get Device ID failed: %d\n", ret);
1217                 goto err;
1218         }
1219
1220         ret = regmap_read(cs35l41->regmap, CS35L41_REVID, &reg_revid);
1221         if (ret < 0) {
1222                 dev_err(cs35l41->dev, "Get Revision ID failed: %d\n", ret);
1223                 goto err;
1224         }
1225
1226         mtl_revid = reg_revid & CS35L41_MTLREVID_MASK;
1227
1228         /* CS35L41 will have even MTLREVID
1229          * CS35L41R will have odd MTLREVID
1230          */
1231         chipid_match = (mtl_revid % 2) ? CS35L41R_CHIP_ID : CS35L41_CHIP_ID;
1232         if (regid != chipid_match) {
1233                 dev_err(cs35l41->dev, "CS35L41 Device ID (%X). Expected ID %X\n",
1234                         regid, chipid_match);
1235                 ret = -ENODEV;
1236                 goto err;
1237         }
1238
1239         cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap);
1240
1241         ret = cs35l41_register_errata_patch(cs35l41->dev, cs35l41->regmap, reg_revid);
1242         if (ret)
1243                 goto err;
1244
1245         ret = cs35l41_otp_unpack(cs35l41->dev, cs35l41->regmap);
1246         if (ret < 0) {
1247                 dev_err(cs35l41->dev, "OTP Unpack failed: %d\n", ret);
1248                 goto err;
1249         }
1250
1251         cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap);
1252
1253         irq_pol = cs35l41_gpio_config(cs35l41->regmap, &cs35l41->hw_cfg);
1254
1255         /* Set interrupt masks for critical errors */
1256         regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1,
1257                      CS35L41_INT1_MASK_DEFAULT);
1258
1259         ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, cs35l41_irq,
1260                                         IRQF_ONESHOT | IRQF_SHARED | irq_pol,
1261                                         "cs35l41", cs35l41);
1262         if (ret != 0) {
1263                 dev_err(cs35l41->dev, "Failed to request IRQ: %d\n", ret);
1264                 goto err;
1265         }
1266
1267         ret = cs35l41_set_pdata(cs35l41);
1268         if (ret < 0) {
1269                 dev_err(cs35l41->dev, "Set pdata failed: %d\n", ret);
1270                 goto err;
1271         }
1272
1273         ret = cs35l41_dsp_init(cs35l41);
1274         if (ret < 0)
1275                 goto err;
1276
1277         pm_runtime_set_autosuspend_delay(cs35l41->dev, 3000);
1278         pm_runtime_use_autosuspend(cs35l41->dev);
1279         pm_runtime_mark_last_busy(cs35l41->dev);
1280         pm_runtime_set_active(cs35l41->dev);
1281         pm_runtime_get_noresume(cs35l41->dev);
1282         pm_runtime_enable(cs35l41->dev);
1283
1284         ret = devm_snd_soc_register_component(cs35l41->dev,
1285                                               &soc_component_dev_cs35l41,
1286                                               cs35l41_dai, ARRAY_SIZE(cs35l41_dai));
1287         if (ret < 0) {
1288                 dev_err(cs35l41->dev, "Register codec failed: %d\n", ret);
1289                 goto err_pm;
1290         }
1291
1292         pm_runtime_put_autosuspend(cs35l41->dev);
1293
1294         dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n",
1295                  regid, reg_revid);
1296
1297         return 0;
1298
1299 err_pm:
1300         pm_runtime_disable(cs35l41->dev);
1301         pm_runtime_put_noidle(cs35l41->dev);
1302
1303         wm_adsp2_remove(&cs35l41->dsp);
1304 err:
1305         cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type);
1306         regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
1307         gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
1308
1309         return ret;
1310 }
1311 EXPORT_SYMBOL_GPL(cs35l41_probe);
1312
1313 void cs35l41_remove(struct cs35l41_private *cs35l41)
1314 {
1315         pm_runtime_get_sync(cs35l41->dev);
1316         pm_runtime_disable(cs35l41->dev);
1317
1318         regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF);
1319         wm_adsp2_remove(&cs35l41->dsp);
1320         cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type);
1321
1322         pm_runtime_put_noidle(cs35l41->dev);
1323
1324         regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
1325         gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
1326 }
1327 EXPORT_SYMBOL_GPL(cs35l41_remove);
1328
1329 static int __maybe_unused cs35l41_runtime_suspend(struct device *dev)
1330 {
1331         struct cs35l41_private *cs35l41 = dev_get_drvdata(dev);
1332
1333         dev_dbg(cs35l41->dev, "Runtime suspend\n");
1334
1335         if (!cs35l41->dsp.preloaded || !cs35l41->dsp.cs_dsp.running)
1336                 return 0;
1337
1338         dev_dbg(cs35l41->dev, "Enter hibernate\n");
1339
1340         cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type);
1341         regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0088);
1342         regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0188);
1343
1344         // Don't wait for ACK since bus activity would wake the device
1345         regmap_write(cs35l41->regmap, CS35L41_DSP_VIRT1_MBOX_1,
1346                      CSPL_MBOX_CMD_HIBERNATE);
1347
1348         regcache_cache_only(cs35l41->regmap, true);
1349         regcache_mark_dirty(cs35l41->regmap);
1350
1351         return 0;
1352 }
1353
1354 static void cs35l41_wait_for_pwrmgt_sts(struct cs35l41_private *cs35l41)
1355 {
1356         const int pwrmgt_retries = 10;
1357         unsigned int sts;
1358         int i, ret;
1359
1360         for (i = 0; i < pwrmgt_retries; i++) {
1361                 ret = regmap_read(cs35l41->regmap, CS35L41_PWRMGT_STS, &sts);
1362                 if (ret)
1363                         dev_err(cs35l41->dev, "Failed to read PWRMGT_STS: %d\n", ret);
1364                 else if (!(sts & CS35L41_WR_PEND_STS_MASK))
1365                         return;
1366
1367                 udelay(20);
1368         }
1369
1370         dev_err(cs35l41->dev, "Timed out reading PWRMGT_STS\n");
1371 }
1372
1373 static int cs35l41_exit_hibernate(struct cs35l41_private *cs35l41)
1374 {
1375         const int wake_retries = 20;
1376         const int sleep_retries = 5;
1377         int ret, i, j;
1378
1379         for (i = 0; i < sleep_retries; i++) {
1380                 dev_dbg(cs35l41->dev, "Exit hibernate\n");
1381
1382                 for (j = 0; j < wake_retries; j++) {
1383                         ret = cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap,
1384                                                         CSPL_MBOX_CMD_OUT_OF_HIBERNATE);
1385                         if (!ret)
1386                                 break;
1387
1388                         usleep_range(100, 200);
1389                 }
1390
1391                 if (j < wake_retries) {
1392                         dev_dbg(cs35l41->dev, "Wake success at cycle: %d\n", j);
1393                         return 0;
1394                 }
1395
1396                 dev_err(cs35l41->dev, "Wake failed, re-enter hibernate: %d\n", ret);
1397
1398                 cs35l41_wait_for_pwrmgt_sts(cs35l41);
1399                 regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0088);
1400
1401                 cs35l41_wait_for_pwrmgt_sts(cs35l41);
1402                 regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0188);
1403
1404                 cs35l41_wait_for_pwrmgt_sts(cs35l41);
1405                 regmap_write(cs35l41->regmap, CS35L41_PWRMGT_CTL, 0x3);
1406         }
1407
1408         dev_err(cs35l41->dev, "Timed out waking device\n");
1409
1410         return -ETIMEDOUT;
1411 }
1412
1413 static int __maybe_unused cs35l41_runtime_resume(struct device *dev)
1414 {
1415         struct cs35l41_private *cs35l41 = dev_get_drvdata(dev);
1416         int ret;
1417
1418         dev_dbg(cs35l41->dev, "Runtime resume\n");
1419
1420         if (!cs35l41->dsp.preloaded || !cs35l41->dsp.cs_dsp.running)
1421                 return 0;
1422
1423         regcache_cache_only(cs35l41->regmap, false);
1424
1425         ret = cs35l41_exit_hibernate(cs35l41);
1426         if (ret)
1427                 return ret;
1428
1429         /* Test key needs to be unlocked to allow the OTP settings to re-apply */
1430         cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap);
1431         ret = regcache_sync(cs35l41->regmap);
1432         cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap);
1433         if (ret) {
1434                 dev_err(cs35l41->dev, "Failed to restore register cache: %d\n", ret);
1435                 return ret;
1436         }
1437         cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, &cs35l41->hw_cfg);
1438
1439         return 0;
1440 }
1441
1442 static int __maybe_unused cs35l41_sys_suspend(struct device *dev)
1443 {
1444         struct cs35l41_private *cs35l41 = dev_get_drvdata(dev);
1445
1446         dev_dbg(cs35l41->dev, "System suspend, disabling IRQ\n");
1447         disable_irq(cs35l41->irq);
1448
1449         return 0;
1450 }
1451
1452 static int __maybe_unused cs35l41_sys_suspend_noirq(struct device *dev)
1453 {
1454         struct cs35l41_private *cs35l41 = dev_get_drvdata(dev);
1455
1456         dev_dbg(cs35l41->dev, "Late system suspend, reenabling IRQ\n");
1457         enable_irq(cs35l41->irq);
1458
1459         return 0;
1460 }
1461
1462 static int __maybe_unused cs35l41_sys_resume_noirq(struct device *dev)
1463 {
1464         struct cs35l41_private *cs35l41 = dev_get_drvdata(dev);
1465
1466         dev_dbg(cs35l41->dev, "Early system resume, disabling IRQ\n");
1467         disable_irq(cs35l41->irq);
1468
1469         return 0;
1470 }
1471
1472 static int __maybe_unused cs35l41_sys_resume(struct device *dev)
1473 {
1474         struct cs35l41_private *cs35l41 = dev_get_drvdata(dev);
1475
1476         dev_dbg(cs35l41->dev, "System resume, reenabling IRQ\n");
1477         enable_irq(cs35l41->irq);
1478
1479         return 0;
1480 }
1481
1482 const struct dev_pm_ops cs35l41_pm_ops = {
1483         SET_RUNTIME_PM_OPS(cs35l41_runtime_suspend, cs35l41_runtime_resume, NULL)
1484
1485         SET_SYSTEM_SLEEP_PM_OPS(cs35l41_sys_suspend, cs35l41_sys_resume)
1486         SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(cs35l41_sys_suspend_noirq, cs35l41_sys_resume_noirq)
1487 };
1488 EXPORT_SYMBOL_GPL(cs35l41_pm_ops);
1489
1490 MODULE_DESCRIPTION("ASoC CS35L41 driver");
1491 MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>");
1492 MODULE_LICENSE("GPL");