~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/codecs/cs35l35.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * cs35l35.c -- CS35L35 ALSA SoC audio driver
  4  *
  5  * Copyright 2017 Cirrus Logic, Inc.
  6  *
  7  * Author: Brian Austin <brian.austin@cirrus.com>
  8  */
  9 
 10 #include <linux/module.h>
 11 #include <linux/moduleparam.h>
 12 #include <linux/kernel.h>
 13 #include <linux/init.h>
 14 #include <linux/delay.h>
 15 #include <linux/i2c.h>
 16 #include <linux/slab.h>
 17 #include <linux/platform_device.h>
 18 #include <linux/regulator/consumer.h>
 19 #include <linux/gpio/consumer.h>
 20 #include <linux/of.h>
 21 #include <linux/regmap.h>
 22 #include <sound/core.h>
 23 #include <sound/pcm.h>
 24 #include <sound/pcm_params.h>
 25 #include <sound/soc.h>
 26 #include <sound/soc-dapm.h>
 27 #include <sound/initval.h>
 28 #include <sound/tlv.h>
 29 #include <sound/cs35l35.h>
 30 #include <linux/completion.h>
 31 
 32 #include "cs35l35.h"
 33 #include "cirrus_legacy.h"
 34 
 35 /*
 36  * Some fields take zero as a valid value so use a high bit flag that won't
 37  * get written to the device to mark those.
 38  */
 39 #define CS35L35_VALID_PDATA 0x80000000
 40 
 41 static const struct reg_default cs35l35_reg[] = {
 42         {CS35L35_PWRCTL1,               0x01},
 43         {CS35L35_PWRCTL2,               0x11},
 44         {CS35L35_PWRCTL3,               0x00},
 45         {CS35L35_CLK_CTL1,              0x04},
 46         {CS35L35_CLK_CTL2,              0x12},
 47         {CS35L35_CLK_CTL3,              0xCF},
 48         {CS35L35_SP_FMT_CTL1,           0x20},
 49         {CS35L35_SP_FMT_CTL2,           0x00},
 50         {CS35L35_SP_FMT_CTL3,           0x02},
 51         {CS35L35_MAG_COMP_CTL,          0x00},
 52         {CS35L35_AMP_INP_DRV_CTL,       0x01},
 53         {CS35L35_AMP_DIG_VOL_CTL,       0x12},
 54         {CS35L35_AMP_DIG_VOL,           0x00},
 55         {CS35L35_ADV_DIG_VOL,           0x00},
 56         {CS35L35_PROTECT_CTL,           0x06},
 57         {CS35L35_AMP_GAIN_AUD_CTL,      0x13},
 58         {CS35L35_AMP_GAIN_PDM_CTL,      0x00},
 59         {CS35L35_AMP_GAIN_ADV_CTL,      0x00},
 60         {CS35L35_GPI_CTL,               0x00},
 61         {CS35L35_BST_CVTR_V_CTL,        0x00},
 62         {CS35L35_BST_PEAK_I,            0x07},
 63         {CS35L35_BST_RAMP_CTL,          0x85},
 64         {CS35L35_BST_CONV_COEF_1,       0x24},
 65         {CS35L35_BST_CONV_COEF_2,       0x24},
 66         {CS35L35_BST_CONV_SLOPE_COMP,   0x4E},
 67         {CS35L35_BST_CONV_SW_FREQ,      0x04},
 68         {CS35L35_CLASS_H_CTL,           0x0B},
 69         {CS35L35_CLASS_H_HEADRM_CTL,    0x0B},
 70         {CS35L35_CLASS_H_RELEASE_RATE,  0x08},
 71         {CS35L35_CLASS_H_FET_DRIVE_CTL, 0x41},
 72         {CS35L35_CLASS_H_VP_CTL,        0xC5},
 73         {CS35L35_VPBR_CTL,              0x0A},
 74         {CS35L35_VPBR_VOL_CTL,          0x90},
 75         {CS35L35_VPBR_TIMING_CTL,       0x6A},
 76         {CS35L35_VPBR_MODE_VOL_CTL,     0x00},
 77         {CS35L35_SPKR_MON_CTL,          0xC0},
 78         {CS35L35_IMON_SCALE_CTL,        0x30},
 79         {CS35L35_AUDIN_RXLOC_CTL,       0x00},
 80         {CS35L35_ADVIN_RXLOC_CTL,       0x80},
 81         {CS35L35_VMON_TXLOC_CTL,        0x00},
 82         {CS35L35_IMON_TXLOC_CTL,        0x80},
 83         {CS35L35_VPMON_TXLOC_CTL,       0x04},
 84         {CS35L35_VBSTMON_TXLOC_CTL,     0x84},
 85         {CS35L35_VPBR_STATUS_TXLOC_CTL, 0x04},
 86         {CS35L35_ZERO_FILL_LOC_CTL,     0x00},
 87         {CS35L35_AUDIN_DEPTH_CTL,       0x0F},
 88         {CS35L35_SPKMON_DEPTH_CTL,      0x0F},
 89         {CS35L35_SUPMON_DEPTH_CTL,      0x0F},
 90         {CS35L35_ZEROFILL_DEPTH_CTL,    0x00},
 91         {CS35L35_MULT_DEV_SYNCH1,       0x02},
 92         {CS35L35_MULT_DEV_SYNCH2,       0x80},
 93         {CS35L35_PROT_RELEASE_CTL,      0x00},
 94         {CS35L35_DIAG_MODE_REG_LOCK,    0x00},
 95         {CS35L35_DIAG_MODE_CTL_1,       0x40},
 96         {CS35L35_DIAG_MODE_CTL_2,       0x00},
 97         {CS35L35_INT_MASK_1,            0xFF},
 98         {CS35L35_INT_MASK_2,            0xFF},
 99         {CS35L35_INT_MASK_3,            0xFF},
100         {CS35L35_INT_MASK_4,            0xFF},
101 
102 };
103 
104 static bool cs35l35_volatile_register(struct device *dev, unsigned int reg)
105 {
106         switch (reg) {
107         case CS35L35_INT_STATUS_1:
108         case CS35L35_INT_STATUS_2:
109         case CS35L35_INT_STATUS_3:
110         case CS35L35_INT_STATUS_4:
111         case CS35L35_PLL_STATUS:
112         case CS35L35_OTP_TRIM_STATUS:
113                 return true;
114         default:
115                 return false;
116         }
117 }
118 
119 static bool cs35l35_readable_register(struct device *dev, unsigned int reg)
120 {
121         switch (reg) {
122         case CS35L35_DEVID_AB ... CS35L35_PWRCTL3:
123         case CS35L35_CLK_CTL1 ... CS35L35_SP_FMT_CTL3:
124         case CS35L35_MAG_COMP_CTL ... CS35L35_AMP_GAIN_AUD_CTL:
125         case CS35L35_AMP_GAIN_PDM_CTL ... CS35L35_BST_PEAK_I:
126         case CS35L35_BST_RAMP_CTL ... CS35L35_BST_CONV_SW_FREQ:
127         case CS35L35_CLASS_H_CTL ... CS35L35_CLASS_H_VP_CTL:
128         case CS35L35_CLASS_H_STATUS:
129         case CS35L35_VPBR_CTL ... CS35L35_VPBR_MODE_VOL_CTL:
130         case CS35L35_VPBR_ATTEN_STATUS:
131         case CS35L35_SPKR_MON_CTL:
132         case CS35L35_IMON_SCALE_CTL ... CS35L35_ZEROFILL_DEPTH_CTL:
133         case CS35L35_MULT_DEV_SYNCH1 ... CS35L35_PROT_RELEASE_CTL:
134         case CS35L35_DIAG_MODE_REG_LOCK ... CS35L35_DIAG_MODE_CTL_2:
135         case CS35L35_INT_MASK_1 ... CS35L35_PLL_STATUS:
136         case CS35L35_OTP_TRIM_STATUS:
137                 return true;
138         default:
139                 return false;
140         }
141 }
142 
143 static bool cs35l35_precious_register(struct device *dev, unsigned int reg)
144 {
145         switch (reg) {
146         case CS35L35_INT_STATUS_1:
147         case CS35L35_INT_STATUS_2:
148         case CS35L35_INT_STATUS_3:
149         case CS35L35_INT_STATUS_4:
150         case CS35L35_PLL_STATUS:
151         case CS35L35_OTP_TRIM_STATUS:
152                 return true;
153         default:
154                 return false;
155         }
156 }
157 
158 static void cs35l35_reset(struct cs35l35_private *cs35l35)
159 {
160         gpiod_set_value_cansleep(cs35l35->reset_gpio, 0);
161         usleep_range(2000, 2100);
162         gpiod_set_value_cansleep(cs35l35->reset_gpio, 1);
163         usleep_range(1000, 1100);
164 }
165 
166 static int cs35l35_wait_for_pdn(struct cs35l35_private *cs35l35)
167 {
168         int ret;
169 
170         if (cs35l35->pdata.ext_bst) {
171                 usleep_range(5000, 5500);
172                 return 0;
173         }
174 
175         reinit_completion(&cs35l35->pdn_done);
176 
177         ret = wait_for_completion_timeout(&cs35l35->pdn_done,
178                                           msecs_to_jiffies(100));
179         if (ret == 0) {
180                 dev_err(cs35l35->dev, "PDN_DONE did not complete\n");
181                 return -ETIMEDOUT;
182         }
183 
184         return 0;
185 }
186 
187 static int cs35l35_sdin_event(struct snd_soc_dapm_widget *w,
188                 struct snd_kcontrol *kcontrol, int event)
189 {
190         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
191         struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
192         int ret = 0;
193 
194         switch (event) {
195         case SND_SOC_DAPM_PRE_PMU:
196                 regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
197                                         CS35L35_MCLK_DIS_MASK,
198                                         0 << CS35L35_MCLK_DIS_SHIFT);
199                 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
200                                         CS35L35_DISCHG_FILT_MASK,
201                                         0 << CS35L35_DISCHG_FILT_SHIFT);
202                 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
203                                         CS35L35_PDN_ALL_MASK, 0);
204                 break;
205         case SND_SOC_DAPM_POST_PMD:
206                 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
207                                         CS35L35_DISCHG_FILT_MASK,
208                                         1 << CS35L35_DISCHG_FILT_SHIFT);
209                 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
210                                           CS35L35_PDN_ALL_MASK, 1);
211 
212                 /* Already muted, so disable volume ramp for faster shutdown */
213                 regmap_update_bits(cs35l35->regmap, CS35L35_AMP_DIG_VOL_CTL,
214                                    CS35L35_AMP_DIGSFT_MASK, 0);
215 
216                 ret = cs35l35_wait_for_pdn(cs35l35);
217 
218                 regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
219                                         CS35L35_MCLK_DIS_MASK,
220                                         1 << CS35L35_MCLK_DIS_SHIFT);
221 
222                 regmap_update_bits(cs35l35->regmap, CS35L35_AMP_DIG_VOL_CTL,
223                                    CS35L35_AMP_DIGSFT_MASK,
224                                    1 << CS35L35_AMP_DIGSFT_SHIFT);
225                 break;
226         default:
227                 dev_err(component->dev, "Invalid event = 0x%x\n", event);
228                 ret = -EINVAL;
229         }
230         return ret;
231 }
232 
233 static int cs35l35_main_amp_event(struct snd_soc_dapm_widget *w,
234                 struct snd_kcontrol *kcontrol, int event)
235 {
236         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
237         struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
238         unsigned int reg[4];
239         int i;
240 
241         switch (event) {
242         case SND_SOC_DAPM_PRE_PMU:
243                 if (cs35l35->pdata.bst_pdn_fet_on)
244                         regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
245                                 CS35L35_PDN_BST_MASK,
246                                 0 << CS35L35_PDN_BST_FETON_SHIFT);
247                 else
248                         regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
249                                 CS35L35_PDN_BST_MASK,
250                                 0 << CS35L35_PDN_BST_FETOFF_SHIFT);
251                 break;
252         case SND_SOC_DAPM_POST_PMU:
253                 usleep_range(5000, 5100);
254                 /* If in PDM mode we must use VP for Voltage control */
255                 if (cs35l35->pdm_mode)
256                         regmap_update_bits(cs35l35->regmap,
257                                         CS35L35_BST_CVTR_V_CTL,
258                                         CS35L35_BST_CTL_MASK,
259                                         0 << CS35L35_BST_CTL_SHIFT);
260 
261                 regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,
262                         CS35L35_AMP_MUTE_MASK, 0);
263 
264                 for (i = 0; i < 2; i++)
265                         regmap_bulk_read(cs35l35->regmap, CS35L35_INT_STATUS_1,
266                                         &reg, ARRAY_SIZE(reg));
267 
268                 break;
269         case SND_SOC_DAPM_PRE_PMD:
270                 regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,
271                                 CS35L35_AMP_MUTE_MASK,
272                                 1 << CS35L35_AMP_MUTE_SHIFT);
273                 if (cs35l35->pdata.bst_pdn_fet_on)
274                         regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
275                                 CS35L35_PDN_BST_MASK,
276                                 1 << CS35L35_PDN_BST_FETON_SHIFT);
277                 else
278                         regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
279                                 CS35L35_PDN_BST_MASK,
280                                 1 << CS35L35_PDN_BST_FETOFF_SHIFT);
281                 break;
282         case SND_SOC_DAPM_POST_PMD:
283                 usleep_range(5000, 5100);
284                 /*
285                  * If PDM mode we should switch back to pdata value
286                  * for Voltage control when we go down
287                  */
288                 if (cs35l35->pdm_mode)
289                         regmap_update_bits(cs35l35->regmap,
290                                         CS35L35_BST_CVTR_V_CTL,
291                                         CS35L35_BST_CTL_MASK,
292                                         cs35l35->pdata.bst_vctl
293                                         << CS35L35_BST_CTL_SHIFT);
294 
295                 break;
296         default:
297                 dev_err(component->dev, "Invalid event = 0x%x\n", event);
298         }
299         return 0;
300 }
301 
302 static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1);
303 static DECLARE_TLV_DB_SCALE(dig_vol_tlv, -10200, 50, 0);
304 
305 static const struct snd_kcontrol_new cs35l35_aud_controls[] = {
306         SOC_SINGLE_SX_TLV("Digital Audio Volume", CS35L35_AMP_DIG_VOL,
307                       0, 0x34, 0xE4, dig_vol_tlv),
308         SOC_SINGLE_TLV("Analog Audio Volume", CS35L35_AMP_GAIN_AUD_CTL, 0, 19, 0,
309                         amp_gain_tlv),
310         SOC_SINGLE_TLV("PDM Volume", CS35L35_AMP_GAIN_PDM_CTL, 0, 19, 0,
311                         amp_gain_tlv),
312 };
313 
314 static const struct snd_kcontrol_new cs35l35_adv_controls[] = {
315         SOC_SINGLE_SX_TLV("Digital Advisory Volume", CS35L35_ADV_DIG_VOL,
316                       0, 0x34, 0xE4, dig_vol_tlv),
317         SOC_SINGLE_TLV("Analog Advisory Volume", CS35L35_AMP_GAIN_ADV_CTL, 0, 19, 0,
318                         amp_gain_tlv),
319 };
320 
321 static const struct snd_soc_dapm_widget cs35l35_dapm_widgets[] = {
322         SND_SOC_DAPM_AIF_IN_E("SDIN", NULL, 0, CS35L35_PWRCTL3, 1, 1,
323                                 cs35l35_sdin_event, SND_SOC_DAPM_PRE_PMU |
324                                 SND_SOC_DAPM_POST_PMD),
325         SND_SOC_DAPM_AIF_OUT("SDOUT", NULL, 0, CS35L35_PWRCTL3, 2, 1),
326 
327         SND_SOC_DAPM_OUTPUT("SPK"),
328 
329         SND_SOC_DAPM_INPUT("VP"),
330         SND_SOC_DAPM_INPUT("VBST"),
331         SND_SOC_DAPM_INPUT("ISENSE"),
332         SND_SOC_DAPM_INPUT("VSENSE"),
333 
334         SND_SOC_DAPM_ADC("VMON ADC", NULL, CS35L35_PWRCTL2, 7, 1),
335         SND_SOC_DAPM_ADC("IMON ADC", NULL, CS35L35_PWRCTL2, 6, 1),
336         SND_SOC_DAPM_ADC("VPMON ADC", NULL, CS35L35_PWRCTL3, 3, 1),
337         SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, CS35L35_PWRCTL3, 4, 1),
338         SND_SOC_DAPM_ADC("CLASS H", NULL, CS35L35_PWRCTL2, 5, 1),
339 
340         SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L35_PWRCTL2, 0, 1, NULL, 0,
341                 cs35l35_main_amp_event, SND_SOC_DAPM_PRE_PMU |
342                                 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU |
343                                 SND_SOC_DAPM_PRE_PMD),
344 };
345 
346 static const struct snd_soc_dapm_route cs35l35_audio_map[] = {
347         {"VPMON ADC", NULL, "VP"},
348         {"VBSTMON ADC", NULL, "VBST"},
349         {"IMON ADC", NULL, "ISENSE"},
350         {"VMON ADC", NULL, "VSENSE"},
351         {"SDOUT", NULL, "IMON ADC"},
352         {"SDOUT", NULL, "VMON ADC"},
353         {"SDOUT", NULL, "VBSTMON ADC"},
354         {"SDOUT", NULL, "VPMON ADC"},
355         {"AMP Capture", NULL, "SDOUT"},
356 
357         {"SDIN", NULL, "AMP Playback"},
358         {"CLASS H", NULL, "SDIN"},
359         {"Main AMP", NULL, "CLASS H"},
360         {"SPK", NULL, "Main AMP"},
361 };
362 
363 static int cs35l35_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
364 {
365         struct snd_soc_component *component = codec_dai->component;
366         struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
367 
368         switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
369         case SND_SOC_DAIFMT_CBP_CFP:
370                 regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
371                                     CS35L35_MS_MASK, 1 << CS35L35_MS_SHIFT);
372                 cs35l35->clock_consumer = false;
373                 break;
374         case SND_SOC_DAIFMT_CBC_CFC:
375                 regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
376                                     CS35L35_MS_MASK, 0 << CS35L35_MS_SHIFT);
377                 cs35l35->clock_consumer = true;
378                 break;
379         default:
380                 return -EINVAL;
381         }
382 
383         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
384         case SND_SOC_DAIFMT_I2S:
385                 cs35l35->i2s_mode = true;
386                 cs35l35->pdm_mode = false;
387                 break;
388         case SND_SOC_DAIFMT_PDM:
389                 cs35l35->pdm_mode = true;
390                 cs35l35->i2s_mode = false;
391                 break;
392         default:
393                 return -EINVAL;
394         }
395 
396         return 0;
397 }
398 
399 struct cs35l35_sysclk_config {
400         int sysclk;
401         int srate;
402         u8 clk_cfg;
403 };
404 
405 static struct cs35l35_sysclk_config cs35l35_clk_ctl[] = {
406 
407         /* SYSCLK, Sample Rate, Serial Port Cfg */
408         {5644800, 44100, 0x00},
409         {5644800, 88200, 0x40},
410         {6144000, 48000, 0x10},
411         {6144000, 96000, 0x50},
412         {11289600, 44100, 0x01},
413         {11289600, 88200, 0x41},
414         {11289600, 176400, 0x81},
415         {12000000, 44100, 0x03},
416         {12000000, 48000, 0x13},
417         {12000000, 88200, 0x43},
418         {12000000, 96000, 0x53},
419         {12000000, 176400, 0x83},
420         {12000000, 192000, 0x93},
421         {12288000, 48000, 0x11},
422         {12288000, 96000, 0x51},
423         {12288000, 192000, 0x91},
424         {13000000, 44100, 0x07},
425         {13000000, 48000, 0x17},
426         {13000000, 88200, 0x47},
427         {13000000, 96000, 0x57},
428         {13000000, 176400, 0x87},
429         {13000000, 192000, 0x97},
430         {22579200, 44100, 0x02},
431         {22579200, 88200, 0x42},
432         {22579200, 176400, 0x82},
433         {24000000, 44100, 0x0B},
434         {24000000, 48000, 0x1B},
435         {24000000, 88200, 0x4B},
436         {24000000, 96000, 0x5B},
437         {24000000, 176400, 0x8B},
438         {24000000, 192000, 0x9B},
439         {24576000, 48000, 0x12},
440         {24576000, 96000, 0x52},
441         {24576000, 192000, 0x92},
442         {26000000, 44100, 0x0F},
443         {26000000, 48000, 0x1F},
444         {26000000, 88200, 0x4F},
445         {26000000, 96000, 0x5F},
446         {26000000, 176400, 0x8F},
447         {26000000, 192000, 0x9F},
448 };
449 
450 static int cs35l35_get_clk_config(int sysclk, int srate)
451 {
452         int i;
453 
454         for (i = 0; i < ARRAY_SIZE(cs35l35_clk_ctl); i++) {
455                 if (cs35l35_clk_ctl[i].sysclk == sysclk &&
456                         cs35l35_clk_ctl[i].srate == srate)
457                         return cs35l35_clk_ctl[i].clk_cfg;
458         }
459         return -EINVAL;
460 }
461 
462 static int cs35l35_hw_params(struct snd_pcm_substream *substream,
463                                  struct snd_pcm_hw_params *params,
464                                  struct snd_soc_dai *dai)
465 {
466         struct snd_soc_component *component = dai->component;
467         struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
468         struct classh_cfg *classh = &cs35l35->pdata.classh_algo;
469         int srate = params_rate(params);
470         int ret = 0;
471         u8 sp_sclks;
472         int audin_format;
473         int errata_chk;
474 
475         int clk_ctl = cs35l35_get_clk_config(cs35l35->sysclk, srate);
476 
477         if (clk_ctl < 0) {
478                 dev_err(component->dev, "Invalid CLK:Rate %d:%d\n",
479                         cs35l35->sysclk, srate);
480                 return -EINVAL;
481         }
482 
483         ret = regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL2,
484                           CS35L35_CLK_CTL2_MASK, clk_ctl);
485         if (ret != 0) {
486                 dev_err(component->dev, "Failed to set port config %d\n", ret);
487                 return ret;
488         }
489 
490         /*
491          * Rev A0 Errata
492          * When configured for the weak-drive detection path (CH_WKFET_DIS = 0)
493          * the Class H algorithm does not enable weak-drive operation for
494          * nonzero values of CH_WKFET_DELAY if SP_RATE = 01 or 10
495          */
496         errata_chk = (clk_ctl & CS35L35_SP_RATE_MASK) >> CS35L35_SP_RATE_SHIFT;
497 
498         if (classh->classh_wk_fet_disable == 0x00 &&
499                 (errata_chk == 0x01 || errata_chk == 0x02)) {
500                 ret = regmap_update_bits(cs35l35->regmap,
501                                         CS35L35_CLASS_H_FET_DRIVE_CTL,
502                                         CS35L35_CH_WKFET_DEL_MASK,
503                                         0 << CS35L35_CH_WKFET_DEL_SHIFT);
504                 if (ret != 0) {
505                         dev_err(component->dev, "Failed to set fet config %d\n",
506                                 ret);
507                         return ret;
508                 }
509         }
510 
511         /*
512          * You can pull more Monitor data from the SDOUT pin than going to SDIN
513          * Just make sure your SCLK is fast enough to fill the frame
514          */
515         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
516                 switch (params_width(params)) {
517                 case 8:
518                         audin_format = CS35L35_SDIN_DEPTH_8;
519                         break;
520                 case 16:
521                         audin_format = CS35L35_SDIN_DEPTH_16;
522                         break;
523                 case 24:
524                         audin_format = CS35L35_SDIN_DEPTH_24;
525                         break;
526                 default:
527                         dev_err(component->dev, "Unsupported Width %d\n",
528                                 params_width(params));
529                         return -EINVAL;
530                 }
531                 regmap_update_bits(cs35l35->regmap,
532                                 CS35L35_AUDIN_DEPTH_CTL,
533                                 CS35L35_AUDIN_DEPTH_MASK,
534                                 audin_format <<
535                                 CS35L35_AUDIN_DEPTH_SHIFT);
536                 if (cs35l35->pdata.stereo) {
537                         regmap_update_bits(cs35l35->regmap,
538                                         CS35L35_AUDIN_DEPTH_CTL,
539                                         CS35L35_ADVIN_DEPTH_MASK,
540                                         audin_format <<
541                                         CS35L35_ADVIN_DEPTH_SHIFT);
542                 }
543         }
544 
545         if (cs35l35->i2s_mode) {
546                 /* We have to take the SCLK to derive num sclks
547                  * to configure the CLOCK_CTL3 register correctly
548                  */
549                 if ((cs35l35->sclk / srate) % 4) {
550                         dev_err(component->dev, "Unsupported sclk/fs ratio %d:%d\n",
551                                         cs35l35->sclk, srate);
552                         return -EINVAL;
553                 }
554                 sp_sclks = ((cs35l35->sclk / srate) / 4) - 1;
555 
556                 /* Only certain ratios supported when device is a clock consumer */
557                 if (cs35l35->clock_consumer) {
558                         switch (sp_sclks) {
559                         case CS35L35_SP_SCLKS_32FS:
560                         case CS35L35_SP_SCLKS_48FS:
561                         case CS35L35_SP_SCLKS_64FS:
562                                 break;
563                         default:
564                                 dev_err(component->dev, "ratio not supported\n");
565                                 return -EINVAL;
566                         }
567                 } else {
568                         /* Only certain ratios supported when device is a clock provider */
569                         switch (sp_sclks) {
570                         case CS35L35_SP_SCLKS_32FS:
571                         case CS35L35_SP_SCLKS_64FS:
572                                 break;
573                         default:
574                                 dev_err(component->dev, "ratio not supported\n");
575                                 return -EINVAL;
576                         }
577                 }
578                 ret = regmap_update_bits(cs35l35->regmap,
579                                         CS35L35_CLK_CTL3,
580                                         CS35L35_SP_SCLKS_MASK, sp_sclks <<
581                                         CS35L35_SP_SCLKS_SHIFT);
582                 if (ret != 0) {
583                         dev_err(component->dev, "Failed to set fsclk %d\n", ret);
584                         return ret;
585                 }
586         }
587 
588         return ret;
589 }
590 
591 static const unsigned int cs35l35_src_rates[] = {
592         44100, 48000, 88200, 96000, 176400, 192000
593 };
594 
595 static const struct snd_pcm_hw_constraint_list cs35l35_constraints = {
596         .count  = ARRAY_SIZE(cs35l35_src_rates),
597         .list   = cs35l35_src_rates,
598 };
599 
600 static int cs35l35_pcm_startup(struct snd_pcm_substream *substream,
601                                struct snd_soc_dai *dai)
602 {
603         struct snd_soc_component *component = dai->component;
604         struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
605 
606         if (!substream->runtime)
607                 return 0;
608 
609         snd_pcm_hw_constraint_list(substream->runtime, 0,
610                                 SNDRV_PCM_HW_PARAM_RATE, &cs35l35_constraints);
611 
612         regmap_update_bits(cs35l35->regmap, CS35L35_AMP_INP_DRV_CTL,
613                                         CS35L35_PDM_MODE_MASK,
614                                         0 << CS35L35_PDM_MODE_SHIFT);
615 
616         return 0;
617 }
618 
619 static const unsigned int cs35l35_pdm_rates[] = {
620         44100, 48000, 88200, 96000
621 };
622 
623 static const struct snd_pcm_hw_constraint_list cs35l35_pdm_constraints = {
624         .count  = ARRAY_SIZE(cs35l35_pdm_rates),
625         .list   = cs35l35_pdm_rates,
626 };
627 
628 static int cs35l35_pdm_startup(struct snd_pcm_substream *substream,
629                                struct snd_soc_dai *dai)
630 {
631         struct snd_soc_component *component = dai->component;
632         struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
633 
634         if (!substream->runtime)
635                 return 0;
636 
637         snd_pcm_hw_constraint_list(substream->runtime, 0,
638                                 SNDRV_PCM_HW_PARAM_RATE,
639                                 &cs35l35_pdm_constraints);
640 
641         regmap_update_bits(cs35l35->regmap, CS35L35_AMP_INP_DRV_CTL,
642                                         CS35L35_PDM_MODE_MASK,
643                                         1 << CS35L35_PDM_MODE_SHIFT);
644 
645         return 0;
646 }
647 
648 static int cs35l35_dai_set_sysclk(struct snd_soc_dai *dai,
649                                 int clk_id, unsigned int freq, int dir)
650 {
651         struct snd_soc_component *component = dai->component;
652         struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
653 
654         /* Need the SCLK Frequency regardless of sysclk source for I2S */
655         cs35l35->sclk = freq;
656 
657         return 0;
658 }
659 
660 static const struct snd_soc_dai_ops cs35l35_ops = {
661         .startup = cs35l35_pcm_startup,
662         .set_fmt = cs35l35_set_dai_fmt,
663         .hw_params = cs35l35_hw_params,
664         .set_sysclk = cs35l35_dai_set_sysclk,
665 };
666 
667 static const struct snd_soc_dai_ops cs35l35_pdm_ops = {
668         .startup = cs35l35_pdm_startup,
669         .set_fmt = cs35l35_set_dai_fmt,
670         .hw_params = cs35l35_hw_params,
671 };
672 
673 static struct snd_soc_dai_driver cs35l35_dai[] = {
674         {
675                 .name = "cs35l35-pcm",
676                 .id = 0,
677                 .playback = {
678                         .stream_name = "AMP Playback",
679                         .channels_min = 1,
680                         .channels_max = 8,
681                         .rates = SNDRV_PCM_RATE_KNOT,
682                         .formats = CS35L35_FORMATS,
683                 },
684                 .capture = {
685                         .stream_name = "AMP Capture",
686                         .channels_min = 1,
687                         .channels_max = 8,
688                         .rates = SNDRV_PCM_RATE_KNOT,
689                         .formats = CS35L35_FORMATS,
690                 },
691                 .ops = &cs35l35_ops,
692                 .symmetric_rate = 1,
693         },
694         {
695                 .name = "cs35l35-pdm",
696                 .id = 1,
697                 .playback = {
698                         .stream_name = "PDM Playback",
699                         .channels_min = 1,
700                         .channels_max = 2,
701                         .rates = SNDRV_PCM_RATE_KNOT,
702                         .formats = CS35L35_FORMATS,
703                 },
704                 .ops = &cs35l35_pdm_ops,
705         },
706 };
707 
708 static int cs35l35_component_set_sysclk(struct snd_soc_component *component,
709                                 int clk_id, int source, unsigned int freq,
710                                 int dir)
711 {
712         struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
713         int clksrc;
714         int ret = 0;
715 
716         switch (clk_id) {
717         case 0:
718                 clksrc = CS35L35_CLK_SOURCE_MCLK;
719                 break;
720         case 1:
721                 clksrc = CS35L35_CLK_SOURCE_SCLK;
722                 break;
723         case 2:
724                 clksrc = CS35L35_CLK_SOURCE_PDM;
725                 break;
726         default:
727                 dev_err(component->dev, "Invalid CLK Source\n");
728                 return -EINVAL;
729         }
730 
731         switch (freq) {
732         case 5644800:
733         case 6144000:
734         case 11289600:
735         case 12000000:
736         case 12288000:
737         case 13000000:
738         case 22579200:
739         case 24000000:
740         case 24576000:
741         case 26000000:
742                 cs35l35->sysclk = freq;
743                 break;
744         default:
745                 dev_err(component->dev, "Invalid CLK Frequency Input : %d\n", freq);
746                 return -EINVAL;
747         }
748 
749         ret = regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
750                                 CS35L35_CLK_SOURCE_MASK,
751                                 clksrc << CS35L35_CLK_SOURCE_SHIFT);
752         if (ret != 0) {
753                 dev_err(component->dev, "Failed to set sysclk %d\n", ret);
754                 return ret;
755         }
756 
757         return ret;
758 }
759 
760 static int cs35l35_boost_inductor(struct cs35l35_private *cs35l35,
761                                   int inductor)
762 {
763         struct regmap *regmap = cs35l35->regmap;
764         unsigned int bst_ipk = 0;
765 
766         /*
767          * Digital Boost Converter Configuration for feedback,
768          * ramping, switching frequency, and estimation block seeding.
769          */
770 
771         regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,
772                            CS35L35_BST_CONV_SWFREQ_MASK, 0x00);
773 
774         regmap_read(regmap, CS35L35_BST_PEAK_I, &bst_ipk);
775         bst_ipk &= CS35L35_BST_IPK_MASK;
776 
777         switch (inductor) {
778         case 1000: /* 1 uH */
779                 regmap_write(regmap, CS35L35_BST_CONV_COEF_1, 0x24);
780                 regmap_write(regmap, CS35L35_BST_CONV_COEF_2, 0x24);
781                 regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,
782                                    CS35L35_BST_CONV_LBST_MASK, 0x00);
783 
784                 if (bst_ipk < 0x04)
785                         regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x1B);
786                 else
787                         regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x4E);
788                 break;
789         case 1200: /* 1.2 uH */
790                 regmap_write(regmap, CS35L35_BST_CONV_COEF_1, 0x20);
791                 regmap_write(regmap, CS35L35_BST_CONV_COEF_2, 0x20);
792                 regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,
793                                    CS35L35_BST_CONV_LBST_MASK, 0x01);
794 
795                 if (bst_ipk < 0x04)
796                         regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x1B);
797                 else
798                         regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x47);
799                 break;
800         case 1500: /* 1.5uH */
801                 regmap_write(regmap, CS35L35_BST_CONV_COEF_1, 0x20);
802                 regmap_write(regmap, CS35L35_BST_CONV_COEF_2, 0x20);
803                 regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,
804                                    CS35L35_BST_CONV_LBST_MASK, 0x02);
805 
806                 if (bst_ipk < 0x04)
807                         regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x1B);
808                 else
809                         regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x3C);
810                 break;
811         case 2200: /* 2.2uH */
812                 regmap_write(regmap, CS35L35_BST_CONV_COEF_1, 0x19);
813                 regmap_write(regmap, CS35L35_BST_CONV_COEF_2, 0x25);
814                 regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,
815                                    CS35L35_BST_CONV_LBST_MASK, 0x03);
816 
817                 if (bst_ipk < 0x04)
818                         regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x1B);
819                 else
820                         regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x23);
821                 break;
822         default:
823                 dev_err(cs35l35->dev, "Invalid Inductor Value %d uH\n",
824                         inductor);
825                 return -EINVAL;
826         }
827         return 0;
828 }
829 
830 static int cs35l35_component_probe(struct snd_soc_component *component)
831 {
832         struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
833         struct classh_cfg *classh = &cs35l35->pdata.classh_algo;
834         struct monitor_cfg *monitor_config = &cs35l35->pdata.mon_cfg;
835         int ret;
836 
837         /* Set Platform Data */
838         if (cs35l35->pdata.bst_vctl)
839                 regmap_update_bits(cs35l35->regmap, CS35L35_BST_CVTR_V_CTL,
840                                 CS35L35_BST_CTL_MASK,
841                                 cs35l35->pdata.bst_vctl);
842 
843         if (cs35l35->pdata.bst_ipk)
844                 regmap_update_bits(cs35l35->regmap, CS35L35_BST_PEAK_I,
845                                 CS35L35_BST_IPK_MASK,
846                                 cs35l35->pdata.bst_ipk <<
847                                 CS35L35_BST_IPK_SHIFT);
848 
849         ret = cs35l35_boost_inductor(cs35l35, cs35l35->pdata.boost_ind);
850         if (ret)
851                 return ret;
852 
853         if (cs35l35->pdata.gain_zc)
854                 regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,
855                                 CS35L35_AMP_GAIN_ZC_MASK,
856                                 cs35l35->pdata.gain_zc <<
857                                 CS35L35_AMP_GAIN_ZC_SHIFT);
858 
859         if (cs35l35->pdata.aud_channel)
860                 regmap_update_bits(cs35l35->regmap,
861                                 CS35L35_AUDIN_RXLOC_CTL,
862                                 CS35L35_AUD_IN_LR_MASK,
863                                 cs35l35->pdata.aud_channel <<
864                                 CS35L35_AUD_IN_LR_SHIFT);
865 
866         if (cs35l35->pdata.stereo) {
867                 regmap_update_bits(cs35l35->regmap,
868                                 CS35L35_ADVIN_RXLOC_CTL,
869                                 CS35L35_ADV_IN_LR_MASK,
870                                 cs35l35->pdata.adv_channel <<
871                                 CS35L35_ADV_IN_LR_SHIFT);
872                 if (cs35l35->pdata.shared_bst)
873                         regmap_update_bits(cs35l35->regmap, CS35L35_CLASS_H_CTL,
874                                         CS35L35_CH_STEREO_MASK,
875                                         1 << CS35L35_CH_STEREO_SHIFT);
876                 ret = snd_soc_add_component_controls(component, cs35l35_adv_controls,
877                                         ARRAY_SIZE(cs35l35_adv_controls));
878                 if (ret)
879                         return ret;
880         }
881 
882         if (cs35l35->pdata.sp_drv_str)
883                 regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
884                                 CS35L35_SP_DRV_MASK,
885                                 cs35l35->pdata.sp_drv_str <<
886                                 CS35L35_SP_DRV_SHIFT);
887         if (cs35l35->pdata.sp_drv_unused)
888                 regmap_update_bits(cs35l35->regmap, CS35L35_SP_FMT_CTL3,
889                                    CS35L35_SP_I2S_DRV_MASK,
890                                    cs35l35->pdata.sp_drv_unused <<
891                                    CS35L35_SP_I2S_DRV_SHIFT);
892 
893         if (classh->classh_algo_enable) {
894                 if (classh->classh_bst_override)
895                         regmap_update_bits(cs35l35->regmap,
896                                         CS35L35_CLASS_H_CTL,
897                                         CS35L35_CH_BST_OVR_MASK,
898                                         classh->classh_bst_override <<
899                                         CS35L35_CH_BST_OVR_SHIFT);
900                 if (classh->classh_bst_max_limit)
901                         regmap_update_bits(cs35l35->regmap,
902                                         CS35L35_CLASS_H_CTL,
903                                         CS35L35_CH_BST_LIM_MASK,
904                                         classh->classh_bst_max_limit <<
905                                         CS35L35_CH_BST_LIM_SHIFT);
906                 if (classh->classh_mem_depth)
907                         regmap_update_bits(cs35l35->regmap,
908                                         CS35L35_CLASS_H_CTL,
909                                         CS35L35_CH_MEM_DEPTH_MASK,
910                                         classh->classh_mem_depth <<
911                                         CS35L35_CH_MEM_DEPTH_SHIFT);
912                 if (classh->classh_headroom)
913                         regmap_update_bits(cs35l35->regmap,
914                                         CS35L35_CLASS_H_HEADRM_CTL,
915                                         CS35L35_CH_HDRM_CTL_MASK,
916                                         classh->classh_headroom <<
917                                         CS35L35_CH_HDRM_CTL_SHIFT);
918                 if (classh->classh_release_rate)
919                         regmap_update_bits(cs35l35->regmap,
920                                         CS35L35_CLASS_H_RELEASE_RATE,
921                                         CS35L35_CH_REL_RATE_MASK,
922                                         classh->classh_release_rate <<
923                                         CS35L35_CH_REL_RATE_SHIFT);
924                 if (classh->classh_wk_fet_disable)
925                         regmap_update_bits(cs35l35->regmap,
926                                         CS35L35_CLASS_H_FET_DRIVE_CTL,
927                                         CS35L35_CH_WKFET_DIS_MASK,
928                                         classh->classh_wk_fet_disable <<
929                                         CS35L35_CH_WKFET_DIS_SHIFT);
930                 if (classh->classh_wk_fet_delay)
931                         regmap_update_bits(cs35l35->regmap,
932                                         CS35L35_CLASS_H_FET_DRIVE_CTL,
933                                         CS35L35_CH_WKFET_DEL_MASK,
934                                         classh->classh_wk_fet_delay <<
935                                         CS35L35_CH_WKFET_DEL_SHIFT);
936                 if (classh->classh_wk_fet_thld)
937                         regmap_update_bits(cs35l35->regmap,
938                                         CS35L35_CLASS_H_FET_DRIVE_CTL,
939                                         CS35L35_CH_WKFET_THLD_MASK,
940                                         classh->classh_wk_fet_thld <<
941                                         CS35L35_CH_WKFET_THLD_SHIFT);
942                 if (classh->classh_vpch_auto)
943                         regmap_update_bits(cs35l35->regmap,
944                                         CS35L35_CLASS_H_VP_CTL,
945                                         CS35L35_CH_VP_AUTO_MASK,
946                                         classh->classh_vpch_auto <<
947                                         CS35L35_CH_VP_AUTO_SHIFT);
948                 if (classh->classh_vpch_rate)
949                         regmap_update_bits(cs35l35->regmap,
950                                         CS35L35_CLASS_H_VP_CTL,
951                                         CS35L35_CH_VP_RATE_MASK,
952                                         classh->classh_vpch_rate <<
953                                         CS35L35_CH_VP_RATE_SHIFT);
954                 if (classh->classh_vpch_man)
955                         regmap_update_bits(cs35l35->regmap,
956                                         CS35L35_CLASS_H_VP_CTL,
957                                         CS35L35_CH_VP_MAN_MASK,
958                                         classh->classh_vpch_man <<
959                                         CS35L35_CH_VP_MAN_SHIFT);
960         }
961 
962         if (monitor_config->is_present) {
963                 if (monitor_config->vmon_specs) {
964                         regmap_update_bits(cs35l35->regmap,
965                                         CS35L35_SPKMON_DEPTH_CTL,
966                                         CS35L35_VMON_DEPTH_MASK,
967                                         monitor_config->vmon_dpth <<
968                                         CS35L35_VMON_DEPTH_SHIFT);
969                         regmap_update_bits(cs35l35->regmap,
970                                         CS35L35_VMON_TXLOC_CTL,
971                                         CS35L35_MON_TXLOC_MASK,
972                                         monitor_config->vmon_loc <<
973                                         CS35L35_MON_TXLOC_SHIFT);
974                         regmap_update_bits(cs35l35->regmap,
975                                         CS35L35_VMON_TXLOC_CTL,
976                                         CS35L35_MON_FRM_MASK,
977                                         monitor_config->vmon_frm <<
978                                         CS35L35_MON_FRM_SHIFT);
979                 }
980                 if (monitor_config->imon_specs) {
981                         regmap_update_bits(cs35l35->regmap,
982                                         CS35L35_SPKMON_DEPTH_CTL,
983                                         CS35L35_IMON_DEPTH_MASK,
984                                         monitor_config->imon_dpth <<
985                                         CS35L35_IMON_DEPTH_SHIFT);
986                         regmap_update_bits(cs35l35->regmap,
987                                         CS35L35_IMON_TXLOC_CTL,
988                                         CS35L35_MON_TXLOC_MASK,
989                                         monitor_config->imon_loc <<
990                                         CS35L35_MON_TXLOC_SHIFT);
991                         regmap_update_bits(cs35l35->regmap,
992                                         CS35L35_IMON_TXLOC_CTL,
993                                         CS35L35_MON_FRM_MASK,
994                                         monitor_config->imon_frm <<
995                                         CS35L35_MON_FRM_SHIFT);
996                         regmap_update_bits(cs35l35->regmap,
997                                         CS35L35_IMON_SCALE_CTL,
998                                         CS35L35_IMON_SCALE_MASK,
999                                         monitor_config->imon_scale <<
1000                                         CS35L35_IMON_SCALE_SHIFT);
1001                 }
1002                 if (monitor_config->vpmon_specs) {
1003                         regmap_update_bits(cs35l35->regmap,
1004                                         CS35L35_SUPMON_DEPTH_CTL,
1005                                         CS35L35_VPMON_DEPTH_MASK,
1006                                         monitor_config->vpmon_dpth <<
1007                                         CS35L35_VPMON_DEPTH_SHIFT);
1008                         regmap_update_bits(cs35l35->regmap,
1009                                         CS35L35_VPMON_TXLOC_CTL,
1010                                         CS35L35_MON_TXLOC_MASK,
1011                                         monitor_config->vpmon_loc <<
1012                                         CS35L35_MON_TXLOC_SHIFT);
1013                         regmap_update_bits(cs35l35->regmap,
1014                                         CS35L35_VPMON_TXLOC_CTL,
1015                                         CS35L35_MON_FRM_MASK,
1016                                         monitor_config->vpmon_frm <<
1017                                         CS35L35_MON_FRM_SHIFT);
1018                 }
1019                 if (monitor_config->vbstmon_specs) {
1020                         regmap_update_bits(cs35l35->regmap,
1021                                         CS35L35_SUPMON_DEPTH_CTL,
1022                                         CS35L35_VBSTMON_DEPTH_MASK,
1023                                         monitor_config->vpmon_dpth <<
1024                                         CS35L35_VBSTMON_DEPTH_SHIFT);
1025                         regmap_update_bits(cs35l35->regmap,
1026                                         CS35L35_VBSTMON_TXLOC_CTL,
1027                                         CS35L35_MON_TXLOC_MASK,
1028                                         monitor_config->vbstmon_loc <<
1029                                         CS35L35_MON_TXLOC_SHIFT);
1030                         regmap_update_bits(cs35l35->regmap,
1031                                         CS35L35_VBSTMON_TXLOC_CTL,
1032                                         CS35L35_MON_FRM_MASK,
1033                                         monitor_config->vbstmon_frm <<
1034                                         CS35L35_MON_FRM_SHIFT);
1035                 }
1036                 if (monitor_config->vpbrstat_specs) {
1037                         regmap_update_bits(cs35l35->regmap,
1038                                         CS35L35_SUPMON_DEPTH_CTL,
1039                                         CS35L35_VPBRSTAT_DEPTH_MASK,
1040                                         monitor_config->vpbrstat_dpth <<
1041                                         CS35L35_VPBRSTAT_DEPTH_SHIFT);
1042                         regmap_update_bits(cs35l35->regmap,
1043                                         CS35L35_VPBR_STATUS_TXLOC_CTL,
1044                                         CS35L35_MON_TXLOC_MASK,
1045                                         monitor_config->vpbrstat_loc <<
1046                                         CS35L35_MON_TXLOC_SHIFT);
1047                         regmap_update_bits(cs35l35->regmap,
1048                                         CS35L35_VPBR_STATUS_TXLOC_CTL,
1049                                         CS35L35_MON_FRM_MASK,
1050                                         monitor_config->vpbrstat_frm <<
1051                                         CS35L35_MON_FRM_SHIFT);
1052                 }
1053                 if (monitor_config->zerofill_specs) {
1054                         regmap_update_bits(cs35l35->regmap,
1055                                         CS35L35_SUPMON_DEPTH_CTL,
1056                                         CS35L35_ZEROFILL_DEPTH_MASK,
1057                                         monitor_config->zerofill_dpth <<
1058                                         CS35L35_ZEROFILL_DEPTH_SHIFT);
1059                         regmap_update_bits(cs35l35->regmap,
1060                                         CS35L35_ZERO_FILL_LOC_CTL,
1061                                         CS35L35_MON_TXLOC_MASK,
1062                                         monitor_config->zerofill_loc <<
1063                                         CS35L35_MON_TXLOC_SHIFT);
1064                         regmap_update_bits(cs35l35->regmap,
1065                                         CS35L35_ZERO_FILL_LOC_CTL,
1066                                         CS35L35_MON_FRM_MASK,
1067                                         monitor_config->zerofill_frm <<
1068                                         CS35L35_MON_FRM_SHIFT);
1069                 }
1070         }
1071 
1072         return 0;
1073 }
1074 
1075 static const struct snd_soc_component_driver soc_component_dev_cs35l35 = {
1076         .probe                  = cs35l35_component_probe,
1077         .set_sysclk             = cs35l35_component_set_sysclk,
1078         .dapm_widgets           = cs35l35_dapm_widgets,
1079         .num_dapm_widgets       = ARRAY_SIZE(cs35l35_dapm_widgets),
1080         .dapm_routes            = cs35l35_audio_map,
1081         .num_dapm_routes        = ARRAY_SIZE(cs35l35_audio_map),
1082         .controls               = cs35l35_aud_controls,
1083         .num_controls           = ARRAY_SIZE(cs35l35_aud_controls),
1084         .idle_bias_on           = 1,
1085         .use_pmdown_time        = 1,
1086         .endianness             = 1,
1087 };
1088 
1089 static const struct regmap_config cs35l35_regmap = {
1090         .reg_bits = 8,
1091         .val_bits = 8,
1092 
1093         .max_register = CS35L35_MAX_REGISTER,
1094         .reg_defaults = cs35l35_reg,
1095         .num_reg_defaults = ARRAY_SIZE(cs35l35_reg),
1096         .volatile_reg = cs35l35_volatile_register,
1097         .readable_reg = cs35l35_readable_register,
1098         .precious_reg = cs35l35_precious_register,
1099         .cache_type = REGCACHE_MAPLE,
1100         .use_single_read = true,
1101         .use_single_write = true,
1102 };
1103 
1104 static irqreturn_t cs35l35_irq(int irq, void *data)
1105 {
1106         struct cs35l35_private *cs35l35 = data;
1107         unsigned int sticky1, sticky2, sticky3, sticky4;
1108         unsigned int mask1, mask2, mask3, mask4, current1;
1109 
1110         /* ack the irq by reading all status registers */
1111         regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_4, &sticky4);
1112         regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_3, &sticky3);
1113         regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_2, &sticky2);
1114         regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_1, &sticky1);
1115 
1116         regmap_read(cs35l35->regmap, CS35L35_INT_MASK_4, &mask4);
1117         regmap_read(cs35l35->regmap, CS35L35_INT_MASK_3, &mask3);
1118         regmap_read(cs35l35->regmap, CS35L35_INT_MASK_2, &mask2);
1119         regmap_read(cs35l35->regmap, CS35L35_INT_MASK_1, &mask1);
1120 
1121         /* Check to see if unmasked bits are active */
1122         if (!(sticky1 & ~mask1) && !(sticky2 & ~mask2) && !(sticky3 & ~mask3)
1123                         && !(sticky4 & ~mask4))
1124                 return IRQ_NONE;
1125 
1126         if (sticky2 & CS35L35_PDN_DONE)
1127                 complete(&cs35l35->pdn_done);
1128 
1129         /* read the current values */
1130         regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_1, &current1);
1131 
1132         /* handle the interrupts */
1133         if (sticky1 & CS35L35_CAL_ERR) {
1134                 dev_crit(cs35l35->dev, "Calibration Error\n");
1135 
1136                 /* error is no longer asserted; safe to reset */
1137                 if (!(current1 & CS35L35_CAL_ERR)) {
1138                         pr_debug("%s : Cal error release\n", __func__);
1139                         regmap_update_bits(cs35l35->regmap,
1140                                         CS35L35_PROT_RELEASE_CTL,
1141                                         CS35L35_CAL_ERR_RLS, 0);
1142                         regmap_update_bits(cs35l35->regmap,
1143                                         CS35L35_PROT_RELEASE_CTL,
1144                                         CS35L35_CAL_ERR_RLS,
1145                                         CS35L35_CAL_ERR_RLS);
1146                         regmap_update_bits(cs35l35->regmap,
1147                                         CS35L35_PROT_RELEASE_CTL,
1148                                         CS35L35_CAL_ERR_RLS, 0);
1149                 }
1150         }
1151 
1152         if (sticky1 & CS35L35_AMP_SHORT) {
1153                 dev_crit(cs35l35->dev, "AMP Short Error\n");
1154                 /* error is no longer asserted; safe to reset */
1155                 if (!(current1 & CS35L35_AMP_SHORT)) {
1156                         dev_dbg(cs35l35->dev, "Amp short error release\n");
1157                         regmap_update_bits(cs35l35->regmap,
1158                                         CS35L35_PROT_RELEASE_CTL,
1159                                         CS35L35_SHORT_RLS, 0);
1160                         regmap_update_bits(cs35l35->regmap,
1161                                         CS35L35_PROT_RELEASE_CTL,
1162                                         CS35L35_SHORT_RLS,
1163                                         CS35L35_SHORT_RLS);
1164                         regmap_update_bits(cs35l35->regmap,
1165                                         CS35L35_PROT_RELEASE_CTL,
1166                                         CS35L35_SHORT_RLS, 0);
1167                 }
1168         }
1169 
1170         if (sticky1 & CS35L35_OTW) {
1171                 dev_warn(cs35l35->dev, "Over temperature warning\n");
1172 
1173                 /* error is no longer asserted; safe to reset */
1174                 if (!(current1 & CS35L35_OTW)) {
1175                         dev_dbg(cs35l35->dev, "Over temperature warn release\n");
1176                         regmap_update_bits(cs35l35->regmap,
1177                                         CS35L35_PROT_RELEASE_CTL,
1178                                         CS35L35_OTW_RLS, 0);
1179                         regmap_update_bits(cs35l35->regmap,
1180                                         CS35L35_PROT_RELEASE_CTL,
1181                                         CS35L35_OTW_RLS,
1182                                         CS35L35_OTW_RLS);
1183                         regmap_update_bits(cs35l35->regmap,
1184                                         CS35L35_PROT_RELEASE_CTL,
1185                                         CS35L35_OTW_RLS, 0);
1186                 }
1187         }
1188 
1189         if (sticky1 & CS35L35_OTE) {
1190                 dev_crit(cs35l35->dev, "Over temperature error\n");
1191                 /* error is no longer asserted; safe to reset */
1192                 if (!(current1 & CS35L35_OTE)) {
1193                         dev_dbg(cs35l35->dev, "Over temperature error release\n");
1194                         regmap_update_bits(cs35l35->regmap,
1195                                         CS35L35_PROT_RELEASE_CTL,
1196                                         CS35L35_OTE_RLS, 0);
1197                         regmap_update_bits(cs35l35->regmap,
1198                                         CS35L35_PROT_RELEASE_CTL,
1199                                         CS35L35_OTE_RLS,
1200                                         CS35L35_OTE_RLS);
1201                         regmap_update_bits(cs35l35->regmap,
1202                                         CS35L35_PROT_RELEASE_CTL,
1203                                         CS35L35_OTE_RLS, 0);
1204                 }
1205         }
1206 
1207         if (sticky3 & CS35L35_BST_HIGH) {
1208                 dev_crit(cs35l35->dev, "VBST error: powering off!\n");
1209                 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1210                         CS35L35_PDN_AMP, CS35L35_PDN_AMP);
1211                 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
1212                         CS35L35_PDN_ALL, CS35L35_PDN_ALL);
1213         }
1214 
1215         if (sticky3 & CS35L35_LBST_SHORT) {
1216                 dev_crit(cs35l35->dev, "LBST error: powering off!\n");
1217                 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1218                         CS35L35_PDN_AMP, CS35L35_PDN_AMP);
1219                 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
1220                         CS35L35_PDN_ALL, CS35L35_PDN_ALL);
1221         }
1222 
1223         if (sticky2 & CS35L35_VPBR_ERR)
1224                 dev_dbg(cs35l35->dev, "Error: Reactive Brownout\n");
1225 
1226         if (sticky4 & CS35L35_VMON_OVFL)
1227                 dev_dbg(cs35l35->dev, "Error: VMON overflow\n");
1228 
1229         if (sticky4 & CS35L35_IMON_OVFL)
1230                 dev_dbg(cs35l35->dev, "Error: IMON overflow\n");
1231 
1232         return IRQ_HANDLED;
1233 }
1234 
1235 
1236 static int cs35l35_handle_of_data(struct i2c_client *i2c_client,
1237                                 struct cs35l35_platform_data *pdata)
1238 {
1239         struct device_node *np = i2c_client->dev.of_node;
1240         struct device_node *classh, *signal_format;
1241         struct classh_cfg *classh_config = &pdata->classh_algo;
1242         struct monitor_cfg *monitor_config = &pdata->mon_cfg;
1243         unsigned int val32 = 0;
1244         u8 monitor_array[4];
1245         const int imon_array_size = ARRAY_SIZE(monitor_array);
1246         const int mon_array_size = imon_array_size - 1;
1247         int ret = 0;
1248 
1249         if (!np)
1250                 return 0;
1251 
1252         pdata->bst_pdn_fet_on = of_property_read_bool(np,
1253                                         "cirrus,boost-pdn-fet-on");
1254 
1255         ret = of_property_read_u32(np, "cirrus,boost-ctl-millivolt", &val32);
1256         if (ret >= 0) {
1257                 if (val32 < 2600 || val32 > 9000) {
1258                         dev_err(&i2c_client->dev,
1259                                 "Invalid Boost Voltage %d mV\n", val32);
1260                         return -EINVAL;
1261                 }
1262                 pdata->bst_vctl = ((val32 - 2600) / 100) + 1;
1263         }
1264 
1265         ret = of_property_read_u32(np, "cirrus,boost-peak-milliamp", &val32);
1266         if (ret >= 0) {
1267                 if (val32 < 1680 || val32 > 4480) {
1268                         dev_err(&i2c_client->dev,
1269                                 "Invalid Boost Peak Current %u mA\n", val32);
1270                         return -EINVAL;
1271                 }
1272 
1273                 pdata->bst_ipk = ((val32 - 1680) / 110) | CS35L35_VALID_PDATA;
1274         }
1275 
1276         ret = of_property_read_u32(np, "cirrus,boost-ind-nanohenry", &val32);
1277         if (ret >= 0) {
1278                 pdata->boost_ind = val32;
1279         } else {
1280                 dev_err(&i2c_client->dev, "Inductor not specified.\n");
1281                 return -EINVAL;
1282         }
1283 
1284         if (of_property_read_u32(np, "cirrus,sp-drv-strength", &val32) >= 0)
1285                 pdata->sp_drv_str = val32;
1286         if (of_property_read_u32(np, "cirrus,sp-drv-unused", &val32) >= 0)
1287                 pdata->sp_drv_unused = val32 | CS35L35_VALID_PDATA;
1288 
1289         pdata->stereo = of_property_read_bool(np, "cirrus,stereo-config");
1290 
1291         if (pdata->stereo) {
1292                 ret = of_property_read_u32(np, "cirrus,audio-channel", &val32);
1293                 if (ret >= 0)
1294                         pdata->aud_channel = val32;
1295 
1296                 ret = of_property_read_u32(np, "cirrus,advisory-channel",
1297                                            &val32);
1298                 if (ret >= 0)
1299                         pdata->adv_channel = val32;
1300 
1301                 pdata->shared_bst = of_property_read_bool(np,
1302                                                 "cirrus,shared-boost");
1303         }
1304 
1305         pdata->ext_bst = of_property_read_bool(np, "cirrus,external-boost");
1306 
1307         pdata->gain_zc = of_property_read_bool(np, "cirrus,amp-gain-zc");
1308 
1309         classh = of_get_child_by_name(np, "cirrus,classh-internal-algo");
1310         classh_config->classh_algo_enable = (classh != NULL);
1311 
1312         if (classh_config->classh_algo_enable) {
1313                 classh_config->classh_bst_override =
1314                         of_property_read_bool(np, "cirrus,classh-bst-overide");
1315 
1316                 ret = of_property_read_u32(classh,
1317                                            "cirrus,classh-bst-max-limit",
1318                                            &val32);
1319                 if (ret >= 0) {
1320                         val32 |= CS35L35_VALID_PDATA;
1321                         classh_config->classh_bst_max_limit = val32;
1322                 }
1323 
1324                 ret = of_property_read_u32(classh,
1325                                            "cirrus,classh-bst-max-limit",
1326                                            &val32);
1327                 if (ret >= 0) {
1328                         val32 |= CS35L35_VALID_PDATA;
1329                         classh_config->classh_bst_max_limit = val32;
1330                 }
1331 
1332                 ret = of_property_read_u32(classh, "cirrus,classh-mem-depth",
1333                                            &val32);
1334                 if (ret >= 0) {
1335                         val32 |= CS35L35_VALID_PDATA;
1336                         classh_config->classh_mem_depth = val32;
1337                 }
1338 
1339                 ret = of_property_read_u32(classh, "cirrus,classh-release-rate",
1340                                            &val32);
1341                 if (ret >= 0)
1342                         classh_config->classh_release_rate = val32;
1343 
1344                 ret = of_property_read_u32(classh, "cirrus,classh-headroom",
1345                                            &val32);
1346                 if (ret >= 0) {
1347                         val32 |= CS35L35_VALID_PDATA;
1348                         classh_config->classh_headroom = val32;
1349                 }
1350 
1351                 ret = of_property_read_u32(classh,
1352                                            "cirrus,classh-wk-fet-disable",
1353                                            &val32);
1354                 if (ret >= 0)
1355                         classh_config->classh_wk_fet_disable = val32;
1356 
1357                 ret = of_property_read_u32(classh, "cirrus,classh-wk-fet-delay",
1358                                            &val32);
1359                 if (ret >= 0) {
1360                         val32 |= CS35L35_VALID_PDATA;
1361                         classh_config->classh_wk_fet_delay = val32;
1362                 }
1363 
1364                 ret = of_property_read_u32(classh, "cirrus,classh-wk-fet-thld",
1365                                            &val32);
1366                 if (ret >= 0)
1367                         classh_config->classh_wk_fet_thld = val32;
1368 
1369                 ret = of_property_read_u32(classh, "cirrus,classh-vpch-auto",
1370                                            &val32);
1371                 if (ret >= 0) {
1372                         val32 |= CS35L35_VALID_PDATA;
1373                         classh_config->classh_vpch_auto = val32;
1374                 }
1375 
1376                 ret = of_property_read_u32(classh, "cirrus,classh-vpch-rate",
1377                                            &val32);
1378                 if (ret >= 0) {
1379                         val32 |= CS35L35_VALID_PDATA;
1380                         classh_config->classh_vpch_rate = val32;
1381                 }
1382 
1383                 ret = of_property_read_u32(classh, "cirrus,classh-vpch-man",
1384                                            &val32);
1385                 if (ret >= 0)
1386                         classh_config->classh_vpch_man = val32;
1387         }
1388         of_node_put(classh);
1389 
1390         /* frame depth location */
1391         signal_format = of_get_child_by_name(np, "cirrus,monitor-signal-format");
1392         monitor_config->is_present = signal_format ? true : false;
1393         if (monitor_config->is_present) {
1394                 ret = of_property_read_u8_array(signal_format, "cirrus,imon",
1395                                                 monitor_array, imon_array_size);
1396                 if (!ret) {
1397                         monitor_config->imon_specs = true;
1398                         monitor_config->imon_dpth = monitor_array[0];
1399                         monitor_config->imon_loc = monitor_array[1];
1400                         monitor_config->imon_frm = monitor_array[2];
1401                         monitor_config->imon_scale = monitor_array[3];
1402                 }
1403                 ret = of_property_read_u8_array(signal_format, "cirrus,vmon",
1404                                                 monitor_array, mon_array_size);
1405                 if (!ret) {
1406                         monitor_config->vmon_specs = true;
1407                         monitor_config->vmon_dpth = monitor_array[0];
1408                         monitor_config->vmon_loc = monitor_array[1];
1409                         monitor_config->vmon_frm = monitor_array[2];
1410                 }
1411                 ret = of_property_read_u8_array(signal_format, "cirrus,vpmon",
1412                                                 monitor_array, mon_array_size);
1413                 if (!ret) {
1414                         monitor_config->vpmon_specs = true;
1415                         monitor_config->vpmon_dpth = monitor_array[0];
1416                         monitor_config->vpmon_loc = monitor_array[1];
1417                         monitor_config->vpmon_frm = monitor_array[2];
1418                 }
1419                 ret = of_property_read_u8_array(signal_format, "cirrus,vbstmon",
1420                                                 monitor_array, mon_array_size);
1421                 if (!ret) {
1422                         monitor_config->vbstmon_specs = true;
1423                         monitor_config->vbstmon_dpth = monitor_array[0];
1424                         monitor_config->vbstmon_loc = monitor_array[1];
1425                         monitor_config->vbstmon_frm = monitor_array[2];
1426                 }
1427                 ret = of_property_read_u8_array(signal_format, "cirrus,vpbrstat",
1428                                                 monitor_array, mon_array_size);
1429                 if (!ret) {
1430                         monitor_config->vpbrstat_specs = true;
1431                         monitor_config->vpbrstat_dpth = monitor_array[0];
1432                         monitor_config->vpbrstat_loc = monitor_array[1];
1433                         monitor_config->vpbrstat_frm = monitor_array[2];
1434                 }
1435                 ret = of_property_read_u8_array(signal_format, "cirrus,zerofill",
1436                                                 monitor_array, mon_array_size);
1437                 if (!ret) {
1438                         monitor_config->zerofill_specs = true;
1439                         monitor_config->zerofill_dpth = monitor_array[0];
1440                         monitor_config->zerofill_loc = monitor_array[1];
1441                         monitor_config->zerofill_frm = monitor_array[2];
1442                 }
1443         }
1444         of_node_put(signal_format);
1445 
1446         return 0;
1447 }
1448 
1449 /* Errata Rev A0 */
1450 static const struct reg_sequence cs35l35_errata_patch[] = {
1451 
1452         { 0x7F, 0x99 },
1453         { 0x00, 0x99 },
1454         { 0x52, 0x22 },
1455         { 0x04, 0x14 },
1456         { 0x6D, 0x44 },
1457         { 0x24, 0x10 },
1458         { 0x58, 0xC4 },
1459         { 0x00, 0x98 },
1460         { 0x18, 0x08 },
1461         { 0x00, 0x00 },
1462         { 0x7F, 0x00 },
1463 };
1464 
1465 static int cs35l35_i2c_probe(struct i2c_client *i2c_client)
1466 {
1467         struct cs35l35_private *cs35l35;
1468         struct device *dev = &i2c_client->dev;
1469         struct cs35l35_platform_data *pdata = dev_get_platdata(dev);
1470         int i, devid;
1471         int ret;
1472         unsigned int reg;
1473 
1474         cs35l35 = devm_kzalloc(dev, sizeof(struct cs35l35_private), GFP_KERNEL);
1475         if (!cs35l35)
1476                 return -ENOMEM;
1477 
1478         cs35l35->dev = dev;
1479 
1480         i2c_set_clientdata(i2c_client, cs35l35);
1481         cs35l35->regmap = devm_regmap_init_i2c(i2c_client, &cs35l35_regmap);
1482         if (IS_ERR(cs35l35->regmap)) {
1483                 ret = PTR_ERR(cs35l35->regmap);
1484                 dev_err(dev, "regmap_init() failed: %d\n", ret);
1485                 return ret;
1486         }
1487 
1488         for (i = 0; i < ARRAY_SIZE(cs35l35_supplies); i++)
1489                 cs35l35->supplies[i].supply = cs35l35_supplies[i];
1490 
1491         cs35l35->num_supplies = ARRAY_SIZE(cs35l35_supplies);
1492 
1493         ret = devm_regulator_bulk_get(dev, cs35l35->num_supplies,
1494                                       cs35l35->supplies);
1495         if (ret != 0) {
1496                 dev_err(dev, "Failed to request core supplies: %d\n", ret);
1497                 return ret;
1498         }
1499 
1500         if (pdata) {
1501                 cs35l35->pdata = *pdata;
1502         } else {
1503                 pdata = devm_kzalloc(dev, sizeof(struct cs35l35_platform_data),
1504                                      GFP_KERNEL);
1505                 if (!pdata)
1506                         return -ENOMEM;
1507                 if (i2c_client->dev.of_node) {
1508                         ret = cs35l35_handle_of_data(i2c_client, pdata);
1509                         if (ret != 0)
1510                                 return ret;
1511 
1512                 }
1513                 cs35l35->pdata = *pdata;
1514         }
1515 
1516         ret = regulator_bulk_enable(cs35l35->num_supplies,
1517                                         cs35l35->supplies);
1518         if (ret != 0) {
1519                 dev_err(dev, "Failed to enable core supplies: %d\n", ret);
1520                 return ret;
1521         }
1522 
1523         /* returning NULL can be valid if in stereo mode */
1524         cs35l35->reset_gpio = devm_gpiod_get_optional(dev, "reset",
1525                                                       GPIOD_OUT_LOW);
1526         if (IS_ERR(cs35l35->reset_gpio)) {
1527                 ret = PTR_ERR(cs35l35->reset_gpio);
1528                 cs35l35->reset_gpio = NULL;
1529                 if (ret == -EBUSY) {
1530                         dev_info(dev,
1531                                  "Reset line busy, assuming shared reset\n");
1532                 } else {
1533                         dev_err(dev, "Failed to get reset GPIO: %d\n", ret);
1534                         goto err;
1535                 }
1536         }
1537 
1538         cs35l35_reset(cs35l35);
1539 
1540         init_completion(&cs35l35->pdn_done);
1541 
1542         ret = devm_request_threaded_irq(dev, i2c_client->irq, NULL, cs35l35_irq,
1543                                         IRQF_ONESHOT | IRQF_TRIGGER_LOW |
1544                                         IRQF_SHARED, "cs35l35", cs35l35);
1545         if (ret != 0) {
1546                 dev_err(dev, "Failed to request IRQ: %d\n", ret);
1547                 goto err;
1548         }
1549         /* initialize codec */
1550         devid = cirrus_read_device_id(cs35l35->regmap, CS35L35_DEVID_AB);
1551         if (devid < 0) {
1552                 ret = devid;
1553                 dev_err(dev, "Failed to read device ID: %d\n", ret);
1554                 goto err;
1555         }
1556 
1557         if (devid != CS35L35_CHIP_ID) {
1558                 dev_err(dev, "CS35L35 Device ID (%X). Expected ID %X\n",
1559                         devid, CS35L35_CHIP_ID);
1560                 ret = -ENODEV;
1561                 goto err;
1562         }
1563 
1564         ret = regmap_read(cs35l35->regmap, CS35L35_REV_ID, &reg);
1565         if (ret < 0) {
1566                 dev_err(dev, "Get Revision ID failed: %d\n", ret);
1567                 goto err;
1568         }
1569 
1570         ret = regmap_register_patch(cs35l35->regmap, cs35l35_errata_patch,
1571                                     ARRAY_SIZE(cs35l35_errata_patch));
1572         if (ret < 0) {
1573                 dev_err(dev, "Failed to apply errata patch: %d\n", ret);
1574                 goto err;
1575         }
1576 
1577         dev_info(dev, "Cirrus Logic CS35L35 (%x), Revision: %02X\n",
1578                  devid, reg & 0xFF);
1579 
1580         /* Set the INT Masks for critical errors */
1581         regmap_write(cs35l35->regmap, CS35L35_INT_MASK_1,
1582                                 CS35L35_INT1_CRIT_MASK);
1583         regmap_write(cs35l35->regmap, CS35L35_INT_MASK_2,
1584                                 CS35L35_INT2_CRIT_MASK);
1585         regmap_write(cs35l35->regmap, CS35L35_INT_MASK_3,
1586                                 CS35L35_INT3_CRIT_MASK);
1587         regmap_write(cs35l35->regmap, CS35L35_INT_MASK_4,
1588                                 CS35L35_INT4_CRIT_MASK);
1589 
1590         regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1591                         CS35L35_PWR2_PDN_MASK,
1592                         CS35L35_PWR2_PDN_MASK);
1593 
1594         if (cs35l35->pdata.bst_pdn_fet_on)
1595                 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1596                                         CS35L35_PDN_BST_MASK,
1597                                         1 << CS35L35_PDN_BST_FETON_SHIFT);
1598         else
1599                 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1600                                         CS35L35_PDN_BST_MASK,
1601                                         1 << CS35L35_PDN_BST_FETOFF_SHIFT);
1602 
1603         regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL3,
1604                         CS35L35_PWR3_PDN_MASK,
1605                         CS35L35_PWR3_PDN_MASK);
1606 
1607         regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,
1608                 CS35L35_AMP_MUTE_MASK, 1 << CS35L35_AMP_MUTE_SHIFT);
1609 
1610         ret = devm_snd_soc_register_component(dev, &soc_component_dev_cs35l35,
1611                                         cs35l35_dai, ARRAY_SIZE(cs35l35_dai));
1612         if (ret < 0) {
1613                 dev_err(dev, "Failed to register component: %d\n", ret);
1614                 goto err;
1615         }
1616 
1617         return 0;
1618 
1619 err:
1620         regulator_bulk_disable(cs35l35->num_supplies,
1621                                cs35l35->supplies);
1622         gpiod_set_value_cansleep(cs35l35->reset_gpio, 0);
1623 
1624         return ret;
1625 }
1626 
1627 static void cs35l35_i2c_remove(struct i2c_client *i2c_client)
1628 {
1629         struct cs35l35_private *cs35l35 = i2c_get_clientdata(i2c_client);
1630 
1631         regulator_bulk_disable(cs35l35->num_supplies, cs35l35->supplies);
1632         gpiod_set_value_cansleep(cs35l35->reset_gpio, 0);
1633 }
1634 
1635 static const struct of_device_id cs35l35_of_match[] = {
1636         {.compatible = "cirrus,cs35l35"},
1637         {},
1638 };
1639 MODULE_DEVICE_TABLE(of, cs35l35_of_match);
1640 
1641 static const struct i2c_device_id cs35l35_id[] = {
1642         {"cs35l35"},
1643         {}
1644 };
1645 
1646 MODULE_DEVICE_TABLE(i2c, cs35l35_id);
1647 
1648 static struct i2c_driver cs35l35_i2c_driver = {
1649         .driver = {
1650                 .name = "cs35l35",
1651                 .of_match_table = cs35l35_of_match,
1652         },
1653         .id_table = cs35l35_id,
1654         .probe = cs35l35_i2c_probe,
1655         .remove = cs35l35_i2c_remove,
1656 };
1657 
1658 module_i2c_driver(cs35l35_i2c_driver);
1659 
1660 MODULE_DESCRIPTION("ASoC CS35L35 driver");
1661 MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
1662 MODULE_LICENSE("GPL");
1663 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php