zonefs: convert zonefs to use the new mount api
[sfrench/cifs-2.6.git] / sound / soc / codecs / cs35l45.c
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // cs35l45.c - CS35L45 ALSA SoC audio driver
4 //
5 // Copyright 2019-2022 Cirrus Logic, Inc.
6 //
7 // Author: James Schulman <james.schulman@cirrus.com>
8
9 #include <linux/gpio/consumer.h>
10 #include <linux/module.h>
11 #include <linux/pm_runtime.h>
12 #include <linux/property.h>
13 #include <linux/firmware.h>
14 #include <linux/regulator/consumer.h>
15 #include <sound/core.h>
16 #include <sound/pcm.h>
17 #include <sound/pcm_params.h>
18 #include <sound/soc.h>
19 #include <sound/tlv.h>
20
21 #include "cs35l45.h"
22
23 static bool cs35l45_check_cspl_mbox_sts(const enum cs35l45_cspl_mboxcmd cmd,
24                                         enum cs35l45_cspl_mboxstate sts)
25 {
26         switch (cmd) {
27         case CSPL_MBOX_CMD_NONE:
28         case CSPL_MBOX_CMD_UNKNOWN_CMD:
29                 return true;
30         case CSPL_MBOX_CMD_PAUSE:
31         case CSPL_MBOX_CMD_OUT_OF_HIBERNATE:
32                 return (sts == CSPL_MBOX_STS_PAUSED);
33         case CSPL_MBOX_CMD_RESUME:
34                 return (sts == CSPL_MBOX_STS_RUNNING);
35         case CSPL_MBOX_CMD_REINIT:
36                 return (sts == CSPL_MBOX_STS_RUNNING);
37         case CSPL_MBOX_CMD_STOP_PRE_REINIT:
38                 return (sts == CSPL_MBOX_STS_RDY_FOR_REINIT);
39         case CSPL_MBOX_CMD_HIBERNATE:
40                 return (sts == CSPL_MBOX_STS_HIBERNATE);
41         default:
42                 return false;
43         }
44 }
45
46 static int cs35l45_set_cspl_mbox_cmd(struct cs35l45_private *cs35l45,
47                                       struct regmap *regmap,
48                                       const enum cs35l45_cspl_mboxcmd cmd)
49 {
50         unsigned int sts = 0, i;
51         int ret;
52
53         if (!cs35l45->dsp.cs_dsp.running) {
54                 dev_err(cs35l45->dev, "DSP not running\n");
55                 return -EPERM;
56         }
57
58         // Set mailbox cmd
59         ret = regmap_write(regmap, CS35L45_DSP_VIRT1_MBOX_1, cmd);
60         if (ret < 0) {
61                 if (cmd != CSPL_MBOX_CMD_OUT_OF_HIBERNATE)
62                         dev_err(cs35l45->dev, "Failed to write MBOX: %d\n", ret);
63                 return ret;
64         }
65
66         // Read mailbox status and verify it is appropriate for the given cmd
67         for (i = 0; i < 5; i++) {
68                 usleep_range(1000, 1100);
69
70                 ret = regmap_read(regmap, CS35L45_DSP_MBOX_2, &sts);
71                 if (ret < 0) {
72                         dev_err(cs35l45->dev, "Failed to read MBOX STS: %d\n", ret);
73                         continue;
74                 }
75
76                 if (!cs35l45_check_cspl_mbox_sts(cmd, sts))
77                         dev_dbg(cs35l45->dev, "[%u] cmd %u returned invalid sts %u", i, cmd, sts);
78                 else
79                         return 0;
80         }
81
82         if (cmd != CSPL_MBOX_CMD_OUT_OF_HIBERNATE)
83                 dev_err(cs35l45->dev, "Failed to set mailbox cmd %u (status %u)\n", cmd, sts);
84
85         return -ENOMSG;
86 }
87
88 static int cs35l45_global_en_ev(struct snd_soc_dapm_widget *w,
89                                 struct snd_kcontrol *kcontrol, int event)
90 {
91         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
92         struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(component);
93
94         dev_dbg(cs35l45->dev, "%s event : %x\n", __func__, event);
95
96         switch (event) {
97         case SND_SOC_DAPM_POST_PMU:
98                 regmap_write(cs35l45->regmap, CS35L45_GLOBAL_ENABLES,
99                              CS35L45_GLOBAL_EN_MASK);
100
101                 usleep_range(CS35L45_POST_GLOBAL_EN_US, CS35L45_POST_GLOBAL_EN_US + 100);
102                 break;
103         case SND_SOC_DAPM_PRE_PMD:
104                 usleep_range(CS35L45_PRE_GLOBAL_DIS_US, CS35L45_PRE_GLOBAL_DIS_US + 100);
105
106                 regmap_write(cs35l45->regmap, CS35L45_GLOBAL_ENABLES, 0);
107                 break;
108         default:
109                 break;
110         }
111
112         return 0;
113 }
114
115 static int cs35l45_dsp_preload_ev(struct snd_soc_dapm_widget *w,
116                                   struct snd_kcontrol *kcontrol, int event)
117 {
118         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
119         struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(component);
120         int ret;
121
122         switch (event) {
123         case SND_SOC_DAPM_PRE_PMU:
124                 if (cs35l45->dsp.cs_dsp.booted)
125                         return 0;
126
127                 return wm_adsp_early_event(w, kcontrol, event);
128         case SND_SOC_DAPM_POST_PMU:
129                 if (cs35l45->dsp.cs_dsp.running)
130                         return 0;
131
132                 regmap_set_bits(cs35l45->regmap, CS35L45_PWRMGT_CTL,
133                                    CS35L45_MEM_RDY_MASK);
134
135                 return wm_adsp_event(w, kcontrol, event);
136         case SND_SOC_DAPM_PRE_PMD:
137                 if (cs35l45->dsp.preloaded)
138                         return 0;
139
140                 if (cs35l45->dsp.cs_dsp.running) {
141                         ret = wm_adsp_event(w, kcontrol, event);
142                         if (ret)
143                                 return ret;
144                 }
145
146                 return wm_adsp_early_event(w, kcontrol, event);
147         default:
148                 return 0;
149         }
150 }
151
152 static int cs35l45_dsp_audio_ev(struct snd_soc_dapm_widget *w,
153                                 struct snd_kcontrol *kcontrol, int event)
154 {
155         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
156         struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(component);
157
158         switch (event) {
159         case SND_SOC_DAPM_POST_PMU:
160                 return cs35l45_set_cspl_mbox_cmd(cs35l45, cs35l45->regmap,
161                                                  CSPL_MBOX_CMD_RESUME);
162         case SND_SOC_DAPM_PRE_PMD:
163                 return cs35l45_set_cspl_mbox_cmd(cs35l45, cs35l45->regmap,
164                                                  CSPL_MBOX_CMD_PAUSE);
165         default:
166                 return 0;
167         }
168
169         return 0;
170 }
171
172 static int cs35l45_activate_ctl(struct snd_soc_component *component,
173                                 const char *ctl_name, bool active)
174 {
175         struct snd_card *card = component->card->snd_card;
176         struct snd_kcontrol *kcontrol;
177         struct snd_kcontrol_volatile *vd;
178         unsigned int index_offset;
179         char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
180
181         if (component->name_prefix)
182                 snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s",
183                          component->name_prefix, ctl_name);
184         else
185                 snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s", ctl_name);
186
187         kcontrol = snd_soc_card_get_kcontrol(component->card, name);
188         if (!kcontrol) {
189                 dev_err(component->dev, "Can't find kcontrol %s\n", name);
190                 return -EINVAL;
191         }
192
193         index_offset = snd_ctl_get_ioff(kcontrol, &kcontrol->id);
194         vd = &kcontrol->vd[index_offset];
195         if (active)
196                 vd->access |= SNDRV_CTL_ELEM_ACCESS_WRITE;
197         else
198                 vd->access &= ~SNDRV_CTL_ELEM_ACCESS_WRITE;
199
200         snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, &kcontrol->id);
201
202         return 0;
203 }
204
205 static int cs35l45_amplifier_mode_get(struct snd_kcontrol *kcontrol,
206                                       struct snd_ctl_elem_value *ucontrol)
207 {
208         struct snd_soc_component *component =
209                         snd_soc_kcontrol_component(kcontrol);
210         struct cs35l45_private *cs35l45 =
211                         snd_soc_component_get_drvdata(component);
212
213         ucontrol->value.integer.value[0] = cs35l45->amplifier_mode;
214
215         return 0;
216 }
217
218 static int cs35l45_amplifier_mode_put(struct snd_kcontrol *kcontrol,
219                                       struct snd_ctl_elem_value *ucontrol)
220 {
221         struct snd_soc_component *component =
222                         snd_soc_kcontrol_component(kcontrol);
223         struct cs35l45_private *cs35l45 =
224                         snd_soc_component_get_drvdata(component);
225         struct snd_soc_dapm_context *dapm =
226                         snd_soc_component_get_dapm(component);
227         unsigned int amp_state;
228         int ret;
229
230         if ((ucontrol->value.integer.value[0] == cs35l45->amplifier_mode) ||
231             (ucontrol->value.integer.value[0] > AMP_MODE_RCV))
232                 return 0;
233
234         snd_soc_dapm_mutex_lock(dapm);
235
236         ret = regmap_read(cs35l45->regmap, CS35L45_BLOCK_ENABLES, &amp_state);
237         if (ret < 0) {
238                 dev_err(cs35l45->dev, "Failed to read AMP state: %d\n", ret);
239                 snd_soc_dapm_mutex_unlock(dapm);
240                 return ret;
241         }
242
243         regmap_clear_bits(cs35l45->regmap, CS35L45_BLOCK_ENABLES,
244                                   CS35L45_AMP_EN_MASK);
245         snd_soc_component_disable_pin_unlocked(component, "SPK");
246         snd_soc_dapm_sync_unlocked(dapm);
247
248         if (ucontrol->value.integer.value[0] == AMP_MODE_SPK) {
249                 regmap_clear_bits(cs35l45->regmap, CS35L45_BLOCK_ENABLES,
250                                   CS35L45_RCV_EN_MASK);
251
252                 regmap_update_bits(cs35l45->regmap, CS35L45_BLOCK_ENABLES,
253                                    CS35L45_BST_EN_MASK,
254                                    CS35L45_BST_ENABLE << CS35L45_BST_EN_SHIFT);
255
256                 regmap_update_bits(cs35l45->regmap, CS35L45_HVLV_CONFIG,
257                                    CS35L45_HVLV_MODE_MASK,
258                                    CS35L45_HVLV_OPERATION <<
259                                    CS35L45_HVLV_MODE_SHIFT);
260
261                 ret = cs35l45_activate_ctl(component, "Analog PCM Volume", true);
262                 if (ret < 0)
263                         dev_err(cs35l45->dev,
264                                 "Unable to deactivate ctl (%d)\n", ret);
265
266         } else  /* AMP_MODE_RCV */ {
267                 regmap_set_bits(cs35l45->regmap, CS35L45_BLOCK_ENABLES,
268                                 CS35L45_RCV_EN_MASK);
269
270                 regmap_update_bits(cs35l45->regmap, CS35L45_BLOCK_ENABLES,
271                                    CS35L45_BST_EN_MASK,
272                                    CS35L45_BST_DISABLE_FET_OFF <<
273                                    CS35L45_BST_EN_SHIFT);
274
275                 regmap_update_bits(cs35l45->regmap, CS35L45_HVLV_CONFIG,
276                                    CS35L45_HVLV_MODE_MASK,
277                                    CS35L45_FORCE_LV_OPERATION <<
278                                    CS35L45_HVLV_MODE_SHIFT);
279
280                 regmap_clear_bits(cs35l45->regmap,
281                                   CS35L45_BLOCK_ENABLES2,
282                                   CS35L45_AMP_DRE_EN_MASK);
283
284                 regmap_update_bits(cs35l45->regmap, CS35L45_AMP_GAIN,
285                                    CS35L45_AMP_GAIN_PCM_MASK,
286                                    CS35L45_AMP_GAIN_PCM_13DBV <<
287                                    CS35L45_AMP_GAIN_PCM_SHIFT);
288
289                 ret = cs35l45_activate_ctl(component, "Analog PCM Volume", false);
290                 if (ret < 0)
291                         dev_err(cs35l45->dev,
292                                 "Unable to deactivate ctl (%d)\n", ret);
293         }
294
295         if (amp_state & CS35L45_AMP_EN_MASK)
296                 regmap_set_bits(cs35l45->regmap, CS35L45_BLOCK_ENABLES,
297                                 CS35L45_AMP_EN_MASK);
298
299         snd_soc_component_enable_pin_unlocked(component, "SPK");
300         snd_soc_dapm_sync_unlocked(dapm);
301         snd_soc_dapm_mutex_unlock(dapm);
302
303         cs35l45->amplifier_mode = ucontrol->value.integer.value[0];
304
305         return 1;
306 }
307
308 static const char * const cs35l45_asp_tx_txt[] = {
309         "Zero", "ASP_RX1", "ASP_RX2",
310         "VMON", "IMON", "ERR_VOL",
311         "VDD_BATTMON", "VDD_BSTMON",
312         "DSP_TX1", "DSP_TX2",
313         "Interpolator", "IL_TARGET",
314 };
315
316 static const unsigned int cs35l45_asp_tx_val[] = {
317         CS35L45_PCM_SRC_ZERO, CS35L45_PCM_SRC_ASP_RX1, CS35L45_PCM_SRC_ASP_RX2,
318         CS35L45_PCM_SRC_VMON, CS35L45_PCM_SRC_IMON, CS35L45_PCM_SRC_ERR_VOL,
319         CS35L45_PCM_SRC_VDD_BATTMON, CS35L45_PCM_SRC_VDD_BSTMON,
320         CS35L45_PCM_SRC_DSP_TX1, CS35L45_PCM_SRC_DSP_TX2,
321         CS35L45_PCM_SRC_INTERPOLATOR, CS35L45_PCM_SRC_IL_TARGET,
322 };
323
324 static const struct soc_enum cs35l45_asp_tx_enums[] = {
325         SOC_VALUE_ENUM_SINGLE(CS35L45_ASPTX1_INPUT, 0, CS35L45_PCM_SRC_MASK,
326                               ARRAY_SIZE(cs35l45_asp_tx_txt), cs35l45_asp_tx_txt,
327                               cs35l45_asp_tx_val),
328         SOC_VALUE_ENUM_SINGLE(CS35L45_ASPTX2_INPUT, 0, CS35L45_PCM_SRC_MASK,
329                               ARRAY_SIZE(cs35l45_asp_tx_txt), cs35l45_asp_tx_txt,
330                               cs35l45_asp_tx_val),
331         SOC_VALUE_ENUM_SINGLE(CS35L45_ASPTX3_INPUT, 0, CS35L45_PCM_SRC_MASK,
332                               ARRAY_SIZE(cs35l45_asp_tx_txt), cs35l45_asp_tx_txt,
333                               cs35l45_asp_tx_val),
334         SOC_VALUE_ENUM_SINGLE(CS35L45_ASPTX4_INPUT, 0, CS35L45_PCM_SRC_MASK,
335                               ARRAY_SIZE(cs35l45_asp_tx_txt), cs35l45_asp_tx_txt,
336                               cs35l45_asp_tx_val),
337         SOC_VALUE_ENUM_SINGLE(CS35L45_ASPTX5_INPUT, 0, CS35L45_PCM_SRC_MASK,
338                               ARRAY_SIZE(cs35l45_asp_tx_txt), cs35l45_asp_tx_txt,
339                               cs35l45_asp_tx_val),
340 };
341
342 static const char * const cs35l45_dsp_rx_txt[] = {
343         "Zero", "ASP_RX1", "ASP_RX2",
344         "VMON", "IMON", "ERR_VOL",
345         "CLASSH_TGT", "VDD_BATTMON",
346         "VDD_BSTMON", "TEMPMON",
347 };
348
349 static const unsigned int cs35l45_dsp_rx_val[] = {
350         CS35L45_PCM_SRC_ZERO, CS35L45_PCM_SRC_ASP_RX1, CS35L45_PCM_SRC_ASP_RX2,
351         CS35L45_PCM_SRC_VMON, CS35L45_PCM_SRC_IMON, CS35L45_PCM_SRC_ERR_VOL,
352         CS35L45_PCM_SRC_CLASSH_TGT, CS35L45_PCM_SRC_VDD_BATTMON,
353         CS35L45_PCM_SRC_VDD_BSTMON, CS35L45_PCM_SRC_TEMPMON,
354 };
355
356 static const struct soc_enum cs35l45_dsp_rx_enums[] = {
357         SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX1_INPUT, 0, CS35L45_PCM_SRC_MASK,
358                               ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
359                               cs35l45_dsp_rx_val),
360         SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX2_INPUT, 0, CS35L45_PCM_SRC_MASK,
361                               ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
362                               cs35l45_dsp_rx_val),
363         SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX3_INPUT, 0, CS35L45_PCM_SRC_MASK,
364                               ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
365                               cs35l45_dsp_rx_val),
366         SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX4_INPUT, 0, CS35L45_PCM_SRC_MASK,
367                               ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
368                               cs35l45_dsp_rx_val),
369         SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX5_INPUT, 0, CS35L45_PCM_SRC_MASK,
370                               ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
371                               cs35l45_dsp_rx_val),
372         SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX6_INPUT, 0, CS35L45_PCM_SRC_MASK,
373                               ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
374                               cs35l45_dsp_rx_val),
375         SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX7_INPUT, 0, CS35L45_PCM_SRC_MASK,
376                               ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
377                               cs35l45_dsp_rx_val),
378         SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX8_INPUT, 0, CS35L45_PCM_SRC_MASK,
379                               ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
380                               cs35l45_dsp_rx_val),
381 };
382
383 static const char * const cs35l45_dac_txt[] = {
384         "Zero", "ASP_RX1", "ASP_RX2", "DSP_TX1", "DSP_TX2"
385 };
386
387 static const unsigned int cs35l45_dac_val[] = {
388         CS35L45_PCM_SRC_ZERO, CS35L45_PCM_SRC_ASP_RX1, CS35L45_PCM_SRC_ASP_RX2,
389         CS35L45_PCM_SRC_DSP_TX1, CS35L45_PCM_SRC_DSP_TX2
390 };
391
392 static const struct soc_enum cs35l45_dacpcm_enums[] = {
393         SOC_VALUE_ENUM_SINGLE(CS35L45_DACPCM1_INPUT, 0, CS35L45_PCM_SRC_MASK,
394                               ARRAY_SIZE(cs35l45_dac_txt), cs35l45_dac_txt,
395                               cs35l45_dac_val),
396 };
397
398 static const struct snd_kcontrol_new cs35l45_asp_muxes[] = {
399         SOC_DAPM_ENUM("ASP_TX1 Source", cs35l45_asp_tx_enums[0]),
400         SOC_DAPM_ENUM("ASP_TX2 Source", cs35l45_asp_tx_enums[1]),
401         SOC_DAPM_ENUM("ASP_TX3 Source", cs35l45_asp_tx_enums[2]),
402         SOC_DAPM_ENUM("ASP_TX4 Source", cs35l45_asp_tx_enums[3]),
403         SOC_DAPM_ENUM("ASP_TX5 Source", cs35l45_asp_tx_enums[4]),
404 };
405
406 static const struct snd_kcontrol_new cs35l45_dsp_muxes[] = {
407         SOC_DAPM_ENUM("DSP_RX1 Source", cs35l45_dsp_rx_enums[0]),
408         SOC_DAPM_ENUM("DSP_RX2 Source", cs35l45_dsp_rx_enums[1]),
409         SOC_DAPM_ENUM("DSP_RX3 Source", cs35l45_dsp_rx_enums[2]),
410         SOC_DAPM_ENUM("DSP_RX4 Source", cs35l45_dsp_rx_enums[3]),
411         SOC_DAPM_ENUM("DSP_RX5 Source", cs35l45_dsp_rx_enums[4]),
412         SOC_DAPM_ENUM("DSP_RX6 Source", cs35l45_dsp_rx_enums[5]),
413         SOC_DAPM_ENUM("DSP_RX7 Source", cs35l45_dsp_rx_enums[6]),
414         SOC_DAPM_ENUM("DSP_RX8 Source", cs35l45_dsp_rx_enums[7]),
415 };
416
417 static const struct snd_kcontrol_new cs35l45_dac_muxes[] = {
418         SOC_DAPM_ENUM("DACPCM Source", cs35l45_dacpcm_enums[0]),
419 };
420 static const struct snd_kcontrol_new amp_en_ctl =
421         SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
422
423 static const struct snd_soc_dapm_widget cs35l45_dapm_widgets[] = {
424         SND_SOC_DAPM_SPK("DSP1 Preload", NULL),
425         SND_SOC_DAPM_SUPPLY_S("DSP1 Preloader", 100, SND_SOC_NOPM, 0, 0,
426                                 cs35l45_dsp_preload_ev,
427                                 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
428         SND_SOC_DAPM_OUT_DRV_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0,
429                                 cs35l45_dsp_audio_ev,
430                                 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
431         SND_SOC_DAPM_SUPPLY("GLOBAL_EN", SND_SOC_NOPM, 0, 0,
432                             cs35l45_global_en_ev,
433                             SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
434         SND_SOC_DAPM_SUPPLY("ASP_EN", CS35L45_BLOCK_ENABLES2, CS35L45_ASP_EN_SHIFT, 0, NULL, 0),
435
436         SND_SOC_DAPM_SIGGEN("VMON_SRC"),
437         SND_SOC_DAPM_SIGGEN("IMON_SRC"),
438         SND_SOC_DAPM_SIGGEN("TEMPMON_SRC"),
439         SND_SOC_DAPM_SIGGEN("VDD_BATTMON_SRC"),
440         SND_SOC_DAPM_SIGGEN("VDD_BSTMON_SRC"),
441         SND_SOC_DAPM_SIGGEN("ERR_VOL"),
442         SND_SOC_DAPM_SIGGEN("AMP_INTP"),
443         SND_SOC_DAPM_SIGGEN("IL_TARGET"),
444
445         SND_SOC_DAPM_SUPPLY("VMON_EN", CS35L45_BLOCK_ENABLES, CS35L45_VMON_EN_SHIFT, 0, NULL, 0),
446         SND_SOC_DAPM_SUPPLY("IMON_EN", CS35L45_BLOCK_ENABLES, CS35L45_IMON_EN_SHIFT, 0, NULL, 0),
447         SND_SOC_DAPM_SUPPLY("TEMPMON_EN", CS35L45_BLOCK_ENABLES, CS35L45_TEMPMON_EN_SHIFT, 0, NULL, 0),
448         SND_SOC_DAPM_SUPPLY("VDD_BATTMON_EN", CS35L45_BLOCK_ENABLES, CS35L45_VDD_BATTMON_EN_SHIFT, 0, NULL, 0),
449         SND_SOC_DAPM_SUPPLY("VDD_BSTMON_EN", CS35L45_BLOCK_ENABLES, CS35L45_VDD_BSTMON_EN_SHIFT, 0, NULL, 0),
450
451         SND_SOC_DAPM_ADC("VMON", NULL, SND_SOC_NOPM, 0, 0),
452         SND_SOC_DAPM_ADC("IMON", NULL, SND_SOC_NOPM, 0, 0),
453         SND_SOC_DAPM_ADC("TEMPMON", NULL, SND_SOC_NOPM, 0, 0),
454         SND_SOC_DAPM_ADC("VDD_BATTMON", NULL, SND_SOC_NOPM, 0, 0),
455         SND_SOC_DAPM_ADC("VDD_BSTMON", NULL, SND_SOC_NOPM, 0, 0),
456
457
458         SND_SOC_DAPM_AIF_IN("ASP_RX1", NULL, 0, CS35L45_ASP_ENABLES1, CS35L45_ASP_RX1_EN_SHIFT, 0),
459         SND_SOC_DAPM_AIF_IN("ASP_RX2", NULL, 1, CS35L45_ASP_ENABLES1, CS35L45_ASP_RX2_EN_SHIFT, 0),
460
461         SND_SOC_DAPM_AIF_OUT("ASP_TX1", NULL, 0, CS35L45_ASP_ENABLES1, CS35L45_ASP_TX1_EN_SHIFT, 0),
462         SND_SOC_DAPM_AIF_OUT("ASP_TX2", NULL, 1, CS35L45_ASP_ENABLES1, CS35L45_ASP_TX2_EN_SHIFT, 0),
463         SND_SOC_DAPM_AIF_OUT("ASP_TX3", NULL, 2, CS35L45_ASP_ENABLES1, CS35L45_ASP_TX3_EN_SHIFT, 0),
464         SND_SOC_DAPM_AIF_OUT("ASP_TX4", NULL, 3, CS35L45_ASP_ENABLES1, CS35L45_ASP_TX4_EN_SHIFT, 0),
465         SND_SOC_DAPM_AIF_OUT("ASP_TX5", NULL, 3, CS35L45_ASP_ENABLES1, CS35L45_ASP_TX5_EN_SHIFT, 0),
466
467         SND_SOC_DAPM_MUX("ASP_TX1 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[0]),
468         SND_SOC_DAPM_MUX("ASP_TX2 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[1]),
469         SND_SOC_DAPM_MUX("ASP_TX3 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[2]),
470         SND_SOC_DAPM_MUX("ASP_TX4 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[3]),
471         SND_SOC_DAPM_MUX("ASP_TX5 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[4]),
472
473         SND_SOC_DAPM_MUX("DSP_RX1 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[0]),
474         SND_SOC_DAPM_MUX("DSP_RX2 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[1]),
475         SND_SOC_DAPM_MUX("DSP_RX3 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[2]),
476         SND_SOC_DAPM_MUX("DSP_RX4 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[3]),
477         SND_SOC_DAPM_MUX("DSP_RX5 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[4]),
478         SND_SOC_DAPM_MUX("DSP_RX6 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[5]),
479         SND_SOC_DAPM_MUX("DSP_RX7 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[6]),
480         SND_SOC_DAPM_MUX("DSP_RX8 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[7]),
481
482         SND_SOC_DAPM_MUX("DACPCM Source", SND_SOC_NOPM, 0, 0, &cs35l45_dac_muxes[0]),
483
484         SND_SOC_DAPM_SWITCH("AMP Enable", SND_SOC_NOPM, 0, 0, &amp_en_ctl),
485
486         SND_SOC_DAPM_OUT_DRV("AMP", SND_SOC_NOPM, 0, 0, NULL, 0),
487
488         SND_SOC_DAPM_OUTPUT("SPK"),
489 };
490
491 #define CS35L45_ASP_MUX_ROUTE(name) \
492         { name" Source", "ASP_RX1",      "ASP_RX1" }, \
493         { name" Source", "ASP_RX2",      "ASP_RX2" }, \
494         { name" Source", "DSP_TX1",      "DSP1" }, \
495         { name" Source", "DSP_TX2",      "DSP1" }, \
496         { name" Source", "VMON",         "VMON" }, \
497         { name" Source", "IMON",         "IMON" }, \
498         { name" Source", "ERR_VOL",      "ERR_VOL" }, \
499         { name" Source", "VDD_BATTMON",  "VDD_BATTMON" }, \
500         { name" Source", "VDD_BSTMON",   "VDD_BSTMON" }, \
501         { name" Source", "Interpolator", "AMP_INTP" }, \
502         { name" Source", "IL_TARGET",    "IL_TARGET" }
503
504 #define CS35L45_DSP_MUX_ROUTE(name) \
505         { name" Source", "ASP_RX1",     "ASP_RX1" }, \
506         { name" Source", "ASP_RX2",     "ASP_RX2" }
507
508 #define CS35L45_DAC_MUX_ROUTE(name) \
509         { name" Source", "ASP_RX1",     "ASP_RX1" }, \
510         { name" Source", "ASP_RX2",     "ASP_RX2" }, \
511         { name" Source", "DSP_TX1",     "DSP1" }, \
512         { name" Source", "DSP_TX2",     "DSP1" }
513
514 static const struct snd_soc_dapm_route cs35l45_dapm_routes[] = {
515         /* Feedback */
516         { "VMON", NULL, "VMON_SRC" },
517         { "IMON", NULL, "IMON_SRC" },
518         { "TEMPMON", NULL, "TEMPMON_SRC" },
519         { "VDD_BATTMON", NULL, "VDD_BATTMON_SRC" },
520         { "VDD_BSTMON", NULL, "VDD_BSTMON_SRC" },
521
522         { "VMON", NULL, "VMON_EN" },
523         { "IMON", NULL, "IMON_EN" },
524         { "TEMPMON", NULL, "TEMPMON_EN" },
525         { "VDD_BATTMON", NULL, "VDD_BATTMON_EN" },
526         { "VDD_BSTMON", NULL, "VDD_BSTMON_EN" },
527
528         { "Capture", NULL, "ASP_TX1"},
529         { "Capture", NULL, "ASP_TX2"},
530         { "Capture", NULL, "ASP_TX3"},
531         { "Capture", NULL, "ASP_TX4"},
532         { "Capture", NULL, "ASP_TX5"},
533         { "ASP_TX1", NULL, "ASP_TX1 Source"},
534         { "ASP_TX2", NULL, "ASP_TX2 Source"},
535         { "ASP_TX3", NULL, "ASP_TX3 Source"},
536         { "ASP_TX4", NULL, "ASP_TX4 Source"},
537         { "ASP_TX5", NULL, "ASP_TX5 Source"},
538
539         { "ASP_TX1", NULL, "ASP_EN" },
540         { "ASP_TX2", NULL, "ASP_EN" },
541         { "ASP_TX3", NULL, "ASP_EN" },
542         { "ASP_TX4", NULL, "ASP_EN" },
543         { "ASP_TX1", NULL, "GLOBAL_EN" },
544         { "ASP_TX2", NULL, "GLOBAL_EN" },
545         { "ASP_TX3", NULL, "GLOBAL_EN" },
546         { "ASP_TX4", NULL, "GLOBAL_EN" },
547         { "ASP_TX5", NULL, "GLOBAL_EN" },
548
549         CS35L45_ASP_MUX_ROUTE("ASP_TX1"),
550         CS35L45_ASP_MUX_ROUTE("ASP_TX2"),
551         CS35L45_ASP_MUX_ROUTE("ASP_TX3"),
552         CS35L45_ASP_MUX_ROUTE("ASP_TX4"),
553         CS35L45_ASP_MUX_ROUTE("ASP_TX5"),
554
555         /* Playback */
556         { "ASP_RX1", NULL, "Playback" },
557         { "ASP_RX2", NULL, "Playback" },
558         { "ASP_RX1", NULL, "ASP_EN" },
559         { "ASP_RX2", NULL, "ASP_EN" },
560
561         { "AMP", NULL, "DACPCM Source"},
562         { "AMP", NULL, "GLOBAL_EN"},
563
564         CS35L45_DSP_MUX_ROUTE("DSP_RX1"),
565         CS35L45_DSP_MUX_ROUTE("DSP_RX2"),
566         CS35L45_DSP_MUX_ROUTE("DSP_RX3"),
567         CS35L45_DSP_MUX_ROUTE("DSP_RX4"),
568         CS35L45_DSP_MUX_ROUTE("DSP_RX5"),
569         CS35L45_DSP_MUX_ROUTE("DSP_RX6"),
570         CS35L45_DSP_MUX_ROUTE("DSP_RX7"),
571         CS35L45_DSP_MUX_ROUTE("DSP_RX8"),
572
573         {"DSP1", NULL, "DSP_RX1 Source"},
574         {"DSP1", NULL, "DSP_RX2 Source"},
575         {"DSP1", NULL, "DSP_RX3 Source"},
576         {"DSP1", NULL, "DSP_RX4 Source"},
577         {"DSP1", NULL, "DSP_RX5 Source"},
578         {"DSP1", NULL, "DSP_RX6 Source"},
579         {"DSP1", NULL, "DSP_RX7 Source"},
580         {"DSP1", NULL, "DSP_RX8 Source"},
581
582         {"DSP1", NULL, "VMON_EN"},
583         {"DSP1", NULL, "IMON_EN"},
584         {"DSP1", NULL, "VDD_BATTMON_EN"},
585         {"DSP1", NULL, "VDD_BSTMON_EN"},
586         {"DSP1", NULL, "TEMPMON_EN"},
587
588         {"DSP1 Preload", NULL, "DSP1 Preloader"},
589         {"DSP1", NULL, "DSP1 Preloader"},
590
591         CS35L45_DAC_MUX_ROUTE("DACPCM"),
592
593         { "AMP Enable", "Switch", "AMP" },
594         { "SPK", NULL, "AMP Enable"},
595 };
596
597 static const char * const amplifier_mode_texts[] = {"SPK", "RCV"};
598 static SOC_ENUM_SINGLE_DECL(amplifier_mode_enum, SND_SOC_NOPM, 0,
599                             amplifier_mode_texts);
600 static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 1000, 300, 0);
601 static const DECLARE_TLV_DB_SCALE(cs35l45_dig_pcm_vol_tlv, -10225, 25, true);
602
603 static const struct snd_kcontrol_new cs35l45_controls[] = {
604         SOC_ENUM_EXT("Amplifier Mode", amplifier_mode_enum,
605                      cs35l45_amplifier_mode_get, cs35l45_amplifier_mode_put),
606         SOC_SINGLE_TLV("Analog PCM Volume", CS35L45_AMP_GAIN,
607                         CS35L45_AMP_GAIN_PCM_SHIFT,
608                         CS35L45_AMP_GAIN_PCM_MASK >> CS35L45_AMP_GAIN_PCM_SHIFT,
609                         0, amp_gain_tlv),
610         /* Ignore bit 0: it is beyond the resolution of TLV_DB_SCALE */
611         SOC_SINGLE_S_TLV("Digital PCM Volume",
612                          CS35L45_AMP_PCM_CONTROL,
613                          CS35L45_AMP_VOL_PCM_SHIFT + 1,
614                          -409, 48,
615                          (CS35L45_AMP_VOL_PCM_WIDTH - 1) - 1,
616                          0, cs35l45_dig_pcm_vol_tlv),
617         WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
618         WM_ADSP_FW_CONTROL("DSP1", 0),
619 };
620
621 static int cs35l45_set_pll(struct cs35l45_private *cs35l45, unsigned int freq)
622 {
623         unsigned int val;
624         int freq_id;
625
626         freq_id = cs35l45_get_clk_freq_id(freq);
627         if (freq_id < 0) {
628                 dev_err(cs35l45->dev, "Invalid freq: %u\n", freq);
629                 return -EINVAL;
630         }
631
632         regmap_read(cs35l45->regmap, CS35L45_REFCLK_INPUT, &val);
633         val = (val & CS35L45_PLL_REFCLK_FREQ_MASK) >> CS35L45_PLL_REFCLK_FREQ_SHIFT;
634         if (val == freq_id)
635                 return 0;
636
637         regmap_set_bits(cs35l45->regmap, CS35L45_REFCLK_INPUT, CS35L45_PLL_OPEN_LOOP_MASK);
638         regmap_update_bits(cs35l45->regmap, CS35L45_REFCLK_INPUT,
639                            CS35L45_PLL_REFCLK_FREQ_MASK,
640                            freq_id << CS35L45_PLL_REFCLK_FREQ_SHIFT);
641         regmap_clear_bits(cs35l45->regmap, CS35L45_REFCLK_INPUT, CS35L45_PLL_REFCLK_EN_MASK);
642         regmap_clear_bits(cs35l45->regmap, CS35L45_REFCLK_INPUT, CS35L45_PLL_OPEN_LOOP_MASK);
643         regmap_set_bits(cs35l45->regmap, CS35L45_REFCLK_INPUT, CS35L45_PLL_REFCLK_EN_MASK);
644
645         return 0;
646 }
647
648 static int cs35l45_asp_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
649 {
650         struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(codec_dai->component);
651         unsigned int asp_fmt, fsync_inv, bclk_inv;
652
653         switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
654         case SND_SOC_DAIFMT_CBC_CFC:
655                 break;
656         default:
657                 dev_err(cs35l45->dev, "Invalid DAI clocking\n");
658                 return -EINVAL;
659         }
660
661         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
662         case SND_SOC_DAIFMT_DSP_A:
663                 asp_fmt = CS35l45_ASP_FMT_DSP_A;
664                 break;
665         case SND_SOC_DAIFMT_I2S:
666                 asp_fmt = CS35L45_ASP_FMT_I2S;
667                 break;
668         default:
669                 dev_err(cs35l45->dev, "Invalid DAI format\n");
670                 return -EINVAL;
671         }
672
673         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
674         case SND_SOC_DAIFMT_NB_IF:
675                 fsync_inv = 1;
676                 bclk_inv = 0;
677                 break;
678         case SND_SOC_DAIFMT_IB_NF:
679                 fsync_inv = 0;
680                 bclk_inv = 1;
681                 break;
682         case SND_SOC_DAIFMT_IB_IF:
683                 fsync_inv = 1;
684                 bclk_inv = 1;
685                 break;
686         case SND_SOC_DAIFMT_NB_NF:
687                 fsync_inv = 0;
688                 bclk_inv = 0;
689                 break;
690         default:
691                 dev_warn(cs35l45->dev, "Invalid DAI clock polarity\n");
692                 return -EINVAL;
693         }
694
695         regmap_update_bits(cs35l45->regmap, CS35L45_ASP_CONTROL2,
696                            CS35L45_ASP_FMT_MASK |
697                            CS35L45_ASP_FSYNC_INV_MASK |
698                            CS35L45_ASP_BCLK_INV_MASK,
699                            (asp_fmt << CS35L45_ASP_FMT_SHIFT) |
700                            (fsync_inv << CS35L45_ASP_FSYNC_INV_SHIFT) |
701                            (bclk_inv << CS35L45_ASP_BCLK_INV_SHIFT));
702
703         return 0;
704 }
705
706 static int cs35l45_asp_hw_params(struct snd_pcm_substream *substream,
707                                  struct snd_pcm_hw_params *params,
708                                  struct snd_soc_dai *dai)
709 {
710         struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(dai->component);
711         unsigned int asp_width, asp_wl, global_fs, slot_multiple, asp_fmt;
712         int bclk;
713
714         switch (params_rate(params)) {
715         case 44100:
716                 global_fs = CS35L45_44P100_KHZ;
717                 break;
718         case 48000:
719                 global_fs = CS35L45_48P0_KHZ;
720                 break;
721         case 88200:
722                 global_fs = CS35L45_88P200_KHZ;
723                 break;
724         case 96000:
725                 global_fs = CS35L45_96P0_KHZ;
726                 break;
727         default:
728                 dev_warn(cs35l45->dev, "Unsupported sample rate (%d)\n",
729                          params_rate(params));
730                 return -EINVAL;
731         }
732
733         regmap_update_bits(cs35l45->regmap, CS35L45_GLOBAL_SAMPLE_RATE,
734                            CS35L45_GLOBAL_FS_MASK,
735                            global_fs << CS35L45_GLOBAL_FS_SHIFT);
736
737         asp_wl = params_width(params);
738
739         if (cs35l45->slot_width)
740                 asp_width = cs35l45->slot_width;
741         else
742                 asp_width = params_width(params);
743
744         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
745                 regmap_update_bits(cs35l45->regmap, CS35L45_ASP_CONTROL2,
746                                    CS35L45_ASP_WIDTH_RX_MASK,
747                                    asp_width << CS35L45_ASP_WIDTH_RX_SHIFT);
748
749                 regmap_update_bits(cs35l45->regmap, CS35L45_ASP_DATA_CONTROL5,
750                                    CS35L45_ASP_WL_MASK,
751                                    asp_wl << CS35L45_ASP_WL_SHIFT);
752         } else {
753                 regmap_update_bits(cs35l45->regmap, CS35L45_ASP_CONTROL2,
754                                    CS35L45_ASP_WIDTH_TX_MASK,
755                                    asp_width << CS35L45_ASP_WIDTH_TX_SHIFT);
756
757                 regmap_update_bits(cs35l45->regmap, CS35L45_ASP_DATA_CONTROL1,
758                                    CS35L45_ASP_WL_MASK,
759                                    asp_wl << CS35L45_ASP_WL_SHIFT);
760         }
761
762         if (cs35l45->sysclk_set)
763                 return 0;
764
765         /* I2S always has an even number of channels */
766         regmap_read(cs35l45->regmap, CS35L45_ASP_CONTROL2, &asp_fmt);
767         asp_fmt = (asp_fmt & CS35L45_ASP_FMT_MASK) >> CS35L45_ASP_FMT_SHIFT;
768         if (asp_fmt == CS35L45_ASP_FMT_I2S)
769                 slot_multiple = 2;
770         else
771                 slot_multiple = 1;
772
773         bclk = snd_soc_tdm_params_to_bclk(params, asp_width,
774                                           cs35l45->slot_count, slot_multiple);
775
776         return cs35l45_set_pll(cs35l45, bclk);
777 }
778
779 static int cs35l45_asp_set_tdm_slot(struct snd_soc_dai *dai,
780                                     unsigned int tx_mask, unsigned int rx_mask,
781                                     int slots, int slot_width)
782 {
783         struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(dai->component);
784
785         if (slot_width && ((slot_width < 16) || (slot_width > 128)))
786                 return -EINVAL;
787
788         cs35l45->slot_width = slot_width;
789         cs35l45->slot_count = slots;
790
791         return 0;
792 }
793
794 static int cs35l45_asp_set_sysclk(struct snd_soc_dai *dai,
795                                   int clk_id, unsigned int freq, int dir)
796 {
797         struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(dai->component);
798         int ret;
799
800         if (clk_id != 0) {
801                 dev_err(cs35l45->dev, "Invalid clk_id %d\n", clk_id);
802                 return -EINVAL;
803         }
804
805         cs35l45->sysclk_set = false;
806         if (freq == 0)
807                 return 0;
808
809         ret = cs35l45_set_pll(cs35l45, freq);
810         if (ret < 0)
811                 return -EINVAL;
812
813         cs35l45->sysclk_set = true;
814
815         return 0;
816 }
817
818 static int cs35l45_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
819 {
820         struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(dai->component);
821         unsigned int global_fs, val, hpf_tune;
822
823         if (mute)
824                 return 0;
825
826         regmap_read(cs35l45->regmap, CS35L45_GLOBAL_SAMPLE_RATE, &global_fs);
827         global_fs = (global_fs & CS35L45_GLOBAL_FS_MASK) >> CS35L45_GLOBAL_FS_SHIFT;
828         switch (global_fs) {
829         case CS35L45_44P100_KHZ:
830                 hpf_tune = CS35L45_HPF_44P1;
831                 break;
832         case CS35L45_88P200_KHZ:
833                 hpf_tune = CS35L45_HPF_88P2;
834                 break;
835         default:
836                 hpf_tune = CS35l45_HPF_DEFAULT;
837                 break;
838         }
839
840         regmap_read(cs35l45->regmap, CS35L45_AMP_PCM_HPF_TST, &val);
841         if (val != hpf_tune) {
842                 struct reg_sequence hpf_override_seq[] = {
843                         { 0x00000040,                   0x00000055 },
844                         { 0x00000040,                   0x000000AA },
845                         { 0x00000044,                   0x00000055 },
846                         { 0x00000044,                   0x000000AA },
847                         { CS35L45_AMP_PCM_HPF_TST,      hpf_tune },
848                         { 0x00000040,                   0x00000000 },
849                         { 0x00000044,                   0x00000000 },
850                 };
851                 regmap_multi_reg_write(cs35l45->regmap, hpf_override_seq,
852                                        ARRAY_SIZE(hpf_override_seq));
853         }
854
855         return 0;
856 }
857
858 static const struct snd_soc_dai_ops cs35l45_asp_dai_ops = {
859         .set_fmt = cs35l45_asp_set_fmt,
860         .hw_params = cs35l45_asp_hw_params,
861         .set_tdm_slot = cs35l45_asp_set_tdm_slot,
862         .set_sysclk = cs35l45_asp_set_sysclk,
863         .mute_stream = cs35l45_mute_stream,
864 };
865
866 static struct snd_soc_dai_driver cs35l45_dai[] = {
867         {
868                 .name = "cs35l45",
869                 .playback = {
870                         .stream_name = "Playback",
871                         .channels_min = 1,
872                         .channels_max = 2,
873                         .rates = CS35L45_RATES,
874                         .formats = CS35L45_FORMATS,
875                 },
876                 .capture = {
877                         .stream_name = "Capture",
878                         .channels_min = 1,
879                         .channels_max = 5,
880                         .rates = CS35L45_RATES,
881                         .formats = CS35L45_FORMATS,
882                 },
883                 .symmetric_rate = true,
884                 .symmetric_sample_bits = true,
885                 .ops = &cs35l45_asp_dai_ops,
886         },
887 };
888
889 static int cs35l45_component_probe(struct snd_soc_component *component)
890 {
891         struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(component);
892
893         return wm_adsp2_component_probe(&cs35l45->dsp, component);
894 }
895
896 static void cs35l45_component_remove(struct snd_soc_component *component)
897 {
898         struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(component);
899
900         wm_adsp2_component_remove(&cs35l45->dsp, component);
901 }
902
903 static const struct snd_soc_component_driver cs35l45_component = {
904         .probe = cs35l45_component_probe,
905         .remove = cs35l45_component_remove,
906
907         .dapm_widgets = cs35l45_dapm_widgets,
908         .num_dapm_widgets = ARRAY_SIZE(cs35l45_dapm_widgets),
909
910         .dapm_routes = cs35l45_dapm_routes,
911         .num_dapm_routes = ARRAY_SIZE(cs35l45_dapm_routes),
912
913         .controls = cs35l45_controls,
914         .num_controls = ARRAY_SIZE(cs35l45_controls),
915
916         .name = "cs35l45",
917
918         .endianness = 1,
919 };
920
921 static void cs35l45_setup_hibernate(struct cs35l45_private *cs35l45)
922 {
923         unsigned int wksrc;
924
925         if (cs35l45->bus_type == CONTROL_BUS_I2C)
926                 wksrc = CS35L45_WKSRC_I2C;
927         else
928                 wksrc = CS35L45_WKSRC_SPI;
929
930         regmap_update_bits(cs35l45->regmap, CS35L45_WAKESRC_CTL,
931                            CS35L45_WKSRC_EN_MASK,
932                            wksrc << CS35L45_WKSRC_EN_SHIFT);
933
934         regmap_set_bits(cs35l45->regmap, CS35L45_WAKESRC_CTL,
935                            CS35L45_UPDT_WKCTL_MASK);
936
937         regmap_update_bits(cs35l45->regmap, CS35L45_WKI2C_CTL,
938                            CS35L45_WKI2C_ADDR_MASK, cs35l45->i2c_addr);
939
940         regmap_set_bits(cs35l45->regmap, CS35L45_WKI2C_CTL,
941                            CS35L45_UPDT_WKI2C_MASK);
942 }
943
944 static int cs35l45_enter_hibernate(struct cs35l45_private *cs35l45)
945 {
946         dev_dbg(cs35l45->dev, "Enter hibernate\n");
947
948         cs35l45_setup_hibernate(cs35l45);
949
950         regmap_set_bits(cs35l45->regmap, CS35L45_IRQ1_MASK_2, CS35L45_DSP_VIRT2_MBOX_MASK);
951
952         // Don't wait for ACK since bus activity would wake the device
953         regmap_write(cs35l45->regmap, CS35L45_DSP_VIRT1_MBOX_1, CSPL_MBOX_CMD_HIBERNATE);
954
955         return 0;
956 }
957
958 static int cs35l45_exit_hibernate(struct cs35l45_private *cs35l45)
959 {
960         const int wake_retries = 20;
961         const int sleep_retries = 5;
962         int ret, i, j;
963
964         for (i = 0; i < sleep_retries; i++) {
965                 dev_dbg(cs35l45->dev, "Exit hibernate\n");
966
967                 for (j = 0; j < wake_retries; j++) {
968                         ret = cs35l45_set_cspl_mbox_cmd(cs35l45, cs35l45->regmap,
969                                           CSPL_MBOX_CMD_OUT_OF_HIBERNATE);
970                         if (!ret) {
971                                 dev_dbg(cs35l45->dev, "Wake success at cycle: %d\n", j);
972                                 regmap_clear_bits(cs35l45->regmap, CS35L45_IRQ1_MASK_2,
973                                                  CS35L45_DSP_VIRT2_MBOX_MASK);
974                                 return 0;
975                         }
976                         usleep_range(100, 200);
977                 }
978
979                 dev_err(cs35l45->dev, "Wake failed, re-enter hibernate: %d\n", ret);
980
981                 cs35l45_setup_hibernate(cs35l45);
982         }
983
984         dev_err(cs35l45->dev, "Timed out waking device\n");
985
986         return -ETIMEDOUT;
987 }
988
989 static int cs35l45_runtime_suspend(struct device *dev)
990 {
991         struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);
992
993         if (!cs35l45->dsp.preloaded || !cs35l45->dsp.cs_dsp.running)
994                 return 0;
995
996         cs35l45_enter_hibernate(cs35l45);
997
998         regcache_cache_only(cs35l45->regmap, true);
999         regcache_mark_dirty(cs35l45->regmap);
1000
1001         dev_dbg(cs35l45->dev, "Runtime suspended\n");
1002
1003         return 0;
1004 }
1005
1006 static int cs35l45_runtime_resume(struct device *dev)
1007 {
1008         struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);
1009         int ret;
1010
1011         if (!cs35l45->dsp.preloaded || !cs35l45->dsp.cs_dsp.running)
1012                 return 0;
1013
1014         dev_dbg(cs35l45->dev, "Runtime resume\n");
1015
1016         regcache_cache_only(cs35l45->regmap, false);
1017
1018         ret = cs35l45_exit_hibernate(cs35l45);
1019         if (ret)
1020                 return ret;
1021
1022         ret = regcache_sync(cs35l45->regmap);
1023         if (ret != 0)
1024                 dev_warn(cs35l45->dev, "regcache_sync failed: %d\n", ret);
1025
1026         /* Clear global error status */
1027         regmap_clear_bits(cs35l45->regmap, CS35L45_ERROR_RELEASE, CS35L45_GLOBAL_ERR_RLS_MASK);
1028         regmap_set_bits(cs35l45->regmap, CS35L45_ERROR_RELEASE, CS35L45_GLOBAL_ERR_RLS_MASK);
1029         regmap_clear_bits(cs35l45->regmap, CS35L45_ERROR_RELEASE, CS35L45_GLOBAL_ERR_RLS_MASK);
1030         return ret;
1031 }
1032
1033 static int cs35l45_sys_suspend(struct device *dev)
1034 {
1035         struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);
1036
1037         dev_dbg(cs35l45->dev, "System suspend, disabling IRQ\n");
1038         disable_irq(cs35l45->irq);
1039
1040         return 0;
1041 }
1042
1043 static int cs35l45_sys_suspend_noirq(struct device *dev)
1044 {
1045         struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);
1046
1047         dev_dbg(cs35l45->dev, "Late system suspend, reenabling IRQ\n");
1048         enable_irq(cs35l45->irq);
1049
1050         return 0;
1051 }
1052
1053 static int cs35l45_sys_resume_noirq(struct device *dev)
1054 {
1055         struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);
1056
1057         dev_dbg(cs35l45->dev, "Early system resume, disabling IRQ\n");
1058         disable_irq(cs35l45->irq);
1059
1060         return 0;
1061 }
1062
1063 static int cs35l45_sys_resume(struct device *dev)
1064 {
1065         struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);
1066
1067         dev_dbg(cs35l45->dev, "System resume, reenabling IRQ\n");
1068         enable_irq(cs35l45->irq);
1069
1070         return 0;
1071 }
1072
1073 static int cs35l45_apply_property_config(struct cs35l45_private *cs35l45)
1074 {
1075         struct device_node *node = cs35l45->dev->of_node;
1076         unsigned int gpio_regs[] = {CS35L45_GPIO1_CTRL1, CS35L45_GPIO2_CTRL1,
1077                                     CS35L45_GPIO3_CTRL1};
1078         unsigned int pad_regs[] = {CS35L45_SYNC_GPIO1,
1079                                    CS35L45_INTB_GPIO2_MCLK_REF, CS35L45_GPIO3};
1080         struct device_node *child;
1081         unsigned int val;
1082         char of_name[32];
1083         int ret, i;
1084
1085         if (!node)
1086                 return 0;
1087
1088         for (i = 0; i < CS35L45_NUM_GPIOS; i++) {
1089                 sprintf(of_name, "cirrus,gpio-ctrl%d", i + 1);
1090                 child = of_get_child_by_name(node, of_name);
1091                 if (!child)
1092                         continue;
1093
1094                 ret = of_property_read_u32(child, "gpio-dir", &val);
1095                 if (!ret)
1096                         regmap_update_bits(cs35l45->regmap, gpio_regs[i],
1097                                            CS35L45_GPIO_DIR_MASK,
1098                                            val << CS35L45_GPIO_DIR_SHIFT);
1099
1100                 ret = of_property_read_u32(child, "gpio-lvl", &val);
1101                 if (!ret)
1102                         regmap_update_bits(cs35l45->regmap, gpio_regs[i],
1103                                            CS35L45_GPIO_LVL_MASK,
1104                                            val << CS35L45_GPIO_LVL_SHIFT);
1105
1106                 ret = of_property_read_u32(child, "gpio-op-cfg", &val);
1107                 if (!ret)
1108                         regmap_update_bits(cs35l45->regmap, gpio_regs[i],
1109                                            CS35L45_GPIO_OP_CFG_MASK,
1110                                            val << CS35L45_GPIO_OP_CFG_SHIFT);
1111
1112                 ret = of_property_read_u32(child, "gpio-pol", &val);
1113                 if (!ret)
1114                         regmap_update_bits(cs35l45->regmap, gpio_regs[i],
1115                                            CS35L45_GPIO_POL_MASK,
1116                                            val << CS35L45_GPIO_POL_SHIFT);
1117
1118                 ret = of_property_read_u32(child, "gpio-ctrl", &val);
1119                 if (!ret)
1120                         regmap_update_bits(cs35l45->regmap, pad_regs[i],
1121                                            CS35L45_GPIO_CTRL_MASK,
1122                                            val << CS35L45_GPIO_CTRL_SHIFT);
1123
1124                 ret = of_property_read_u32(child, "gpio-invert", &val);
1125                 if (!ret) {
1126                         regmap_update_bits(cs35l45->regmap, pad_regs[i],
1127                                            CS35L45_GPIO_INVERT_MASK,
1128                                            val << CS35L45_GPIO_INVERT_SHIFT);
1129                         if (i == 1)
1130                                 cs35l45->irq_invert = val;
1131                 }
1132
1133                 of_node_put(child);
1134         }
1135
1136         if (device_property_read_u32(cs35l45->dev,
1137                                      "cirrus,asp-sdout-hiz-ctrl", &val) == 0) {
1138                 regmap_update_bits(cs35l45->regmap, CS35L45_ASP_CONTROL3,
1139                                    CS35L45_ASP_DOUT_HIZ_CTRL_MASK,
1140                                    val << CS35L45_ASP_DOUT_HIZ_CTRL_SHIFT);
1141         }
1142
1143         return 0;
1144 }
1145
1146 static int cs35l45_dsp_virt2_mbox3_irq_handle(struct cs35l45_private *cs35l45,
1147                                               const unsigned int cmd,
1148                                               unsigned int data)
1149 {
1150         static char *speak_status = "Unknown";
1151
1152         switch (cmd) {
1153         case EVENT_SPEAKER_STATUS:
1154                 switch (data) {
1155                 case 1:
1156                         speak_status = "All Clear";
1157                         break;
1158                 case 2:
1159                         speak_status = "Open Circuit";
1160                         break;
1161                 case 4:
1162                         speak_status = "Short Circuit";
1163                         break;
1164                 }
1165
1166                 dev_info(cs35l45->dev, "MBOX event (SPEAKER_STATUS): %s\n",
1167                          speak_status);
1168                 break;
1169         case EVENT_BOOT_DONE:
1170                 dev_dbg(cs35l45->dev, "MBOX event (BOOT_DONE)\n");
1171                 break;
1172         default:
1173                 dev_err(cs35l45->dev, "MBOX event not supported %u\n", cmd);
1174                 return -EINVAL;
1175         }
1176
1177         return 0;
1178 }
1179
1180 static irqreturn_t cs35l45_dsp_virt2_mbox_cb(int irq, void *data)
1181 {
1182         struct cs35l45_private *cs35l45 = data;
1183         unsigned int mbox_val;
1184         int ret = 0;
1185
1186         ret = regmap_read(cs35l45->regmap, CS35L45_DSP_VIRT2_MBOX_3, &mbox_val);
1187         if (!ret && mbox_val)
1188                 cs35l45_dsp_virt2_mbox3_irq_handle(cs35l45, mbox_val & CS35L45_MBOX3_CMD_MASK,
1189                                 (mbox_val & CS35L45_MBOX3_DATA_MASK) >> CS35L45_MBOX3_DATA_SHIFT);
1190
1191         /* Handle DSP trace log IRQ */
1192         ret = regmap_read(cs35l45->regmap, CS35L45_DSP_VIRT2_MBOX_4, &mbox_val);
1193         if (!ret && mbox_val != 0) {
1194                 dev_err(cs35l45->dev, "Spurious DSP MBOX4 IRQ\n");
1195         }
1196
1197         return IRQ_RETVAL(ret);
1198 }
1199
1200 static irqreturn_t cs35l45_pll_unlock(int irq, void *data)
1201 {
1202         struct cs35l45_private *cs35l45 = data;
1203
1204         dev_dbg(cs35l45->dev, "PLL unlock detected!");
1205
1206         return IRQ_HANDLED;
1207 }
1208
1209 static irqreturn_t cs35l45_pll_lock(int irq, void *data)
1210 {
1211         struct cs35l45_private *cs35l45 = data;
1212
1213         dev_dbg(cs35l45->dev, "PLL lock detected!");
1214
1215         return IRQ_HANDLED;
1216 }
1217
1218 static irqreturn_t cs35l45_spk_safe_err(int irq, void *data);
1219
1220 static const struct cs35l45_irq cs35l45_irqs[] = {
1221         CS35L45_IRQ(AMP_SHORT_ERR, "Amplifier short error", cs35l45_spk_safe_err),
1222         CS35L45_IRQ(UVLO_VDDBATT_ERR, "VDDBATT undervoltage error", cs35l45_spk_safe_err),
1223         CS35L45_IRQ(BST_SHORT_ERR, "Boost inductor error", cs35l45_spk_safe_err),
1224         CS35L45_IRQ(BST_UVP_ERR, "Boost undervoltage error", cs35l45_spk_safe_err),
1225         CS35L45_IRQ(TEMP_ERR, "Overtemperature error", cs35l45_spk_safe_err),
1226         CS35L45_IRQ(AMP_CAL_ERR, "Amplifier calibration error", cs35l45_spk_safe_err),
1227         CS35L45_IRQ(UVLO_VDDLV_ERR, "LV threshold detector error", cs35l45_spk_safe_err),
1228         CS35L45_IRQ(GLOBAL_ERROR, "Global error", cs35l45_spk_safe_err),
1229         CS35L45_IRQ(DSP_WDT_EXPIRE, "DSP Watchdog Timer", cs35l45_spk_safe_err),
1230         CS35L45_IRQ(PLL_UNLOCK_FLAG_RISE, "PLL unlock", cs35l45_pll_unlock),
1231         CS35L45_IRQ(PLL_LOCK_FLAG, "PLL lock", cs35l45_pll_lock),
1232         CS35L45_IRQ(DSP_VIRT2_MBOX, "DSP virtual MBOX 2 write flag", cs35l45_dsp_virt2_mbox_cb),
1233 };
1234
1235 static irqreturn_t cs35l45_spk_safe_err(int irq, void *data)
1236 {
1237         struct cs35l45_private *cs35l45 = data;
1238         int i;
1239
1240         i = irq - regmap_irq_get_virq(cs35l45->irq_data, 0);
1241
1242         if (i < 0 || i >= ARRAY_SIZE(cs35l45_irqs))
1243                 dev_err(cs35l45->dev, "Unspecified global error condition (%d) detected!\n", irq);
1244         else
1245                 dev_err(cs35l45->dev, "%s condition detected!\n", cs35l45_irqs[i].name);
1246
1247         return IRQ_HANDLED;
1248 }
1249
1250 static const struct regmap_irq cs35l45_reg_irqs[] = {
1251         CS35L45_REG_IRQ(IRQ1_EINT_1, AMP_SHORT_ERR),
1252         CS35L45_REG_IRQ(IRQ1_EINT_1, UVLO_VDDBATT_ERR),
1253         CS35L45_REG_IRQ(IRQ1_EINT_1, BST_SHORT_ERR),
1254         CS35L45_REG_IRQ(IRQ1_EINT_1, BST_UVP_ERR),
1255         CS35L45_REG_IRQ(IRQ1_EINT_1, TEMP_ERR),
1256         CS35L45_REG_IRQ(IRQ1_EINT_3, AMP_CAL_ERR),
1257         CS35L45_REG_IRQ(IRQ1_EINT_18, UVLO_VDDLV_ERR),
1258         CS35L45_REG_IRQ(IRQ1_EINT_18, GLOBAL_ERROR),
1259         CS35L45_REG_IRQ(IRQ1_EINT_2, DSP_WDT_EXPIRE),
1260         CS35L45_REG_IRQ(IRQ1_EINT_3, PLL_UNLOCK_FLAG_RISE),
1261         CS35L45_REG_IRQ(IRQ1_EINT_3, PLL_LOCK_FLAG),
1262         CS35L45_REG_IRQ(IRQ1_EINT_2, DSP_VIRT2_MBOX),
1263 };
1264
1265 static const struct regmap_irq_chip cs35l45_regmap_irq_chip = {
1266         .name = "cs35l45 IRQ1 Controller",
1267         .main_status = CS35L45_IRQ1_STATUS,
1268         .status_base = CS35L45_IRQ1_EINT_1,
1269         .mask_base = CS35L45_IRQ1_MASK_1,
1270         .ack_base = CS35L45_IRQ1_EINT_1,
1271         .num_regs = 18,
1272         .irqs = cs35l45_reg_irqs,
1273         .num_irqs = ARRAY_SIZE(cs35l45_reg_irqs),
1274         .runtime_pm = true,
1275 };
1276
1277 static int cs35l45_initialize(struct cs35l45_private *cs35l45)
1278 {
1279         struct device *dev = cs35l45->dev;
1280         unsigned int dev_id[5];
1281         unsigned int sts;
1282         int ret;
1283
1284         ret = regmap_read_poll_timeout(cs35l45->regmap, CS35L45_IRQ1_EINT_4, sts,
1285                                        (sts & CS35L45_OTP_BOOT_DONE_STS_MASK),
1286                                        1000, 5000);
1287         if (ret < 0) {
1288                 dev_err(cs35l45->dev, "Timeout waiting for OTP boot\n");
1289                 return ret;
1290         }
1291
1292         ret = regmap_bulk_read(cs35l45->regmap, CS35L45_DEVID, dev_id, ARRAY_SIZE(dev_id));
1293         if (ret) {
1294                 dev_err(cs35l45->dev, "Get Device ID failed: %d\n", ret);
1295                 return ret;
1296         }
1297
1298         switch (dev_id[0]) {
1299         case 0x35A450:
1300         case 0x35A460:
1301                 break;
1302         default:
1303                 dev_err(cs35l45->dev, "Bad DEVID 0x%x\n", dev_id[0]);
1304                 return -ENODEV;
1305         }
1306
1307         dev_info(cs35l45->dev, "Cirrus Logic CS35L45: REVID %02X OTPID %02X\n",
1308                  dev_id[1], dev_id[4]);
1309
1310         regmap_write(cs35l45->regmap, CS35L45_IRQ1_EINT_4,
1311                      CS35L45_OTP_BOOT_DONE_STS_MASK | CS35L45_OTP_BUSY_MASK);
1312
1313         ret = cs35l45_apply_patch(cs35l45);
1314         if (ret < 0) {
1315                 dev_err(dev, "Failed to apply init patch %d\n", ret);
1316                 return ret;
1317         }
1318
1319         ret = cs35l45_apply_property_config(cs35l45);
1320         if (ret < 0)
1321                 return ret;
1322
1323         cs35l45->amplifier_mode = AMP_MODE_SPK;
1324
1325         return 0;
1326 }
1327
1328 static const struct reg_sequence cs35l45_fs_errata_patch[] = {
1329         {0x02B80080,                    0x00000001},
1330         {0x02B80088,                    0x00000001},
1331         {0x02B80090,                    0x00000001},
1332         {0x02B80098,                    0x00000001},
1333         {0x02B800A0,                    0x00000001},
1334         {0x02B800A8,                    0x00000001},
1335         {0x02B800B0,                    0x00000001},
1336         {0x02B800B8,                    0x00000001},
1337         {0x02B80280,                    0x00000001},
1338         {0x02B80288,                    0x00000001},
1339         {0x02B80290,                    0x00000001},
1340         {0x02B80298,                    0x00000001},
1341         {0x02B802A0,                    0x00000001},
1342         {0x02B802A8,                    0x00000001},
1343         {0x02B802B0,                    0x00000001},
1344         {0x02B802B8,                    0x00000001},
1345 };
1346
1347 static const struct cs_dsp_region cs35l45_dsp1_regions[] = {
1348         { .type = WMFW_HALO_PM_PACKED,  .base = CS35L45_DSP1_PMEM_0 },
1349         { .type = WMFW_HALO_XM_PACKED,  .base = CS35L45_DSP1_XMEM_PACK_0 },
1350         { .type = WMFW_HALO_YM_PACKED,  .base = CS35L45_DSP1_YMEM_PACK_0 },
1351         {. type = WMFW_ADSP2_XM,        .base = CS35L45_DSP1_XMEM_UNPACK24_0},
1352         {. type = WMFW_ADSP2_YM,        .base = CS35L45_DSP1_YMEM_UNPACK24_0},
1353 };
1354
1355 static int cs35l45_dsp_init(struct cs35l45_private *cs35l45)
1356 {
1357         struct wm_adsp *dsp = &cs35l45->dsp;
1358         int ret;
1359
1360         dsp->part = "cs35l45";
1361         dsp->fw = 9; /* 9 is WM_ADSP_FW_SPK_PROT in wm_adsp.c */
1362         dsp->toggle_preload = true;
1363         dsp->cs_dsp.num = 1;
1364         dsp->cs_dsp.type = WMFW_HALO;
1365         dsp->cs_dsp.rev = 0;
1366         dsp->cs_dsp.dev = cs35l45->dev;
1367         dsp->cs_dsp.regmap = cs35l45->regmap;
1368         dsp->cs_dsp.base = CS35L45_DSP1_CLOCK_FREQ;
1369         dsp->cs_dsp.base_sysinfo = CS35L45_DSP1_SYS_ID;
1370         dsp->cs_dsp.mem = cs35l45_dsp1_regions;
1371         dsp->cs_dsp.num_mems = ARRAY_SIZE(cs35l45_dsp1_regions);
1372         dsp->cs_dsp.lock_regions = 0xFFFFFFFF;
1373
1374         ret = wm_halo_init(dsp);
1375
1376         regmap_multi_reg_write(cs35l45->regmap, cs35l45_fs_errata_patch,
1377                                                    ARRAY_SIZE(cs35l45_fs_errata_patch));
1378
1379         return ret;
1380 }
1381
1382 int cs35l45_probe(struct cs35l45_private *cs35l45)
1383 {
1384         struct device *dev = cs35l45->dev;
1385         unsigned long irq_pol = IRQF_ONESHOT | IRQF_SHARED;
1386         int ret, i, irq;
1387
1388         cs35l45->vdd_batt = devm_regulator_get(dev, "vdd-batt");
1389         if (IS_ERR(cs35l45->vdd_batt))
1390                 return dev_err_probe(dev, PTR_ERR(cs35l45->vdd_batt),
1391                                      "Failed to request vdd-batt\n");
1392
1393         cs35l45->vdd_a = devm_regulator_get(dev, "vdd-a");
1394         if (IS_ERR(cs35l45->vdd_a))
1395                 return dev_err_probe(dev, PTR_ERR(cs35l45->vdd_a),
1396                                      "Failed to request vdd-a\n");
1397
1398         /* VDD_BATT must always be enabled before other supplies */
1399         ret = regulator_enable(cs35l45->vdd_batt);
1400         if (ret < 0)
1401                 return dev_err_probe(dev, ret, "Failed to enable vdd-batt\n");
1402
1403         ret = regulator_enable(cs35l45->vdd_a);
1404         if (ret < 0)
1405                 return dev_err_probe(dev, ret, "Failed to enable vdd-a\n");
1406
1407         /* If reset is shared only one instance can claim it */
1408         cs35l45->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
1409         if (IS_ERR(cs35l45->reset_gpio)) {
1410                 ret = PTR_ERR(cs35l45->reset_gpio);
1411                 cs35l45->reset_gpio = NULL;
1412                 if (ret == -EBUSY) {
1413                         dev_dbg(dev, "Reset line busy, assuming shared reset\n");
1414                 } else {
1415                         dev_err_probe(dev, ret, "Failed to get reset GPIO\n");
1416                         goto err;
1417                 }
1418         }
1419
1420         if (cs35l45->reset_gpio) {
1421                 usleep_range(CS35L45_RESET_HOLD_US, CS35L45_RESET_HOLD_US + 100);
1422                 gpiod_set_value_cansleep(cs35l45->reset_gpio, 1);
1423         }
1424
1425         usleep_range(CS35L45_RESET_US, CS35L45_RESET_US + 100);
1426
1427         ret = cs35l45_initialize(cs35l45);
1428         if (ret < 0)
1429                 goto err_reset;
1430
1431         ret = cs35l45_dsp_init(cs35l45);
1432         if (ret < 0)
1433                 goto err_reset;
1434
1435         pm_runtime_set_autosuspend_delay(cs35l45->dev, 3000);
1436         pm_runtime_use_autosuspend(cs35l45->dev);
1437         pm_runtime_mark_last_busy(cs35l45->dev);
1438         pm_runtime_set_active(cs35l45->dev);
1439         pm_runtime_get_noresume(cs35l45->dev);
1440         pm_runtime_enable(cs35l45->dev);
1441
1442         if (cs35l45->irq) {
1443                 if (cs35l45->irq_invert)
1444                         irq_pol |= IRQF_TRIGGER_HIGH;
1445                 else
1446                         irq_pol |= IRQF_TRIGGER_LOW;
1447
1448                 ret = devm_regmap_add_irq_chip(dev, cs35l45->regmap, cs35l45->irq, irq_pol, 0,
1449                                                &cs35l45_regmap_irq_chip, &cs35l45->irq_data);
1450                 if (ret) {
1451                         dev_err(dev, "Failed to register IRQ chip: %d\n", ret);
1452                         goto err_dsp;
1453                 }
1454
1455                 for (i = 0; i < ARRAY_SIZE(cs35l45_irqs); i++) {
1456                         irq = regmap_irq_get_virq(cs35l45->irq_data, cs35l45_irqs[i].irq);
1457                         if (irq < 0) {
1458                                 dev_err(dev, "Failed to get %s\n", cs35l45_irqs[i].name);
1459                                 ret = irq;
1460                                 goto err_dsp;
1461                         }
1462
1463                         ret = devm_request_threaded_irq(dev, irq, NULL, cs35l45_irqs[i].handler,
1464                                                         irq_pol, cs35l45_irqs[i].name, cs35l45);
1465                         if (ret) {
1466                                 dev_err(dev, "Failed to request IRQ %s: %d\n",
1467                                         cs35l45_irqs[i].name, ret);
1468                                 goto err_dsp;
1469                         }
1470                 }
1471         }
1472
1473         ret = devm_snd_soc_register_component(dev, &cs35l45_component,
1474                                               cs35l45_dai,
1475                                               ARRAY_SIZE(cs35l45_dai));
1476         if (ret < 0)
1477                 goto err_dsp;
1478
1479         pm_runtime_put_autosuspend(cs35l45->dev);
1480
1481         return 0;
1482
1483 err_dsp:
1484         pm_runtime_disable(cs35l45->dev);
1485         pm_runtime_put_noidle(cs35l45->dev);
1486         wm_adsp2_remove(&cs35l45->dsp);
1487
1488 err_reset:
1489         gpiod_set_value_cansleep(cs35l45->reset_gpio, 0);
1490 err:
1491         regulator_disable(cs35l45->vdd_a);
1492         regulator_disable(cs35l45->vdd_batt);
1493
1494         return ret;
1495 }
1496 EXPORT_SYMBOL_NS_GPL(cs35l45_probe, SND_SOC_CS35L45);
1497
1498 void cs35l45_remove(struct cs35l45_private *cs35l45)
1499 {
1500         pm_runtime_get_sync(cs35l45->dev);
1501         pm_runtime_disable(cs35l45->dev);
1502         wm_adsp2_remove(&cs35l45->dsp);
1503
1504         gpiod_set_value_cansleep(cs35l45->reset_gpio, 0);
1505
1506         pm_runtime_put_noidle(cs35l45->dev);
1507         regulator_disable(cs35l45->vdd_a);
1508         /* VDD_BATT must be the last to power-off */
1509         regulator_disable(cs35l45->vdd_batt);
1510 }
1511 EXPORT_SYMBOL_NS_GPL(cs35l45_remove, SND_SOC_CS35L45);
1512
1513 EXPORT_GPL_DEV_PM_OPS(cs35l45_pm_ops) = {
1514         RUNTIME_PM_OPS(cs35l45_runtime_suspend, cs35l45_runtime_resume, NULL)
1515
1516         SYSTEM_SLEEP_PM_OPS(cs35l45_sys_suspend, cs35l45_sys_resume)
1517         NOIRQ_SYSTEM_SLEEP_PM_OPS(cs35l45_sys_suspend_noirq, cs35l45_sys_resume_noirq)
1518 };
1519
1520 MODULE_DESCRIPTION("ASoC CS35L45 driver");
1521 MODULE_AUTHOR("James Schulman, Cirrus Logic Inc, <james.schulman@cirrus.com>");
1522 MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
1523 MODULE_LICENSE("GPL");