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