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
41static 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
104static 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
119static 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
143static 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
158static void cs35l35_reset(struct cs35l35_private *cs35l35)
159{
160 gpiod_set_value_cansleep(desc: cs35l35->reset_gpio, value: 0);
161 usleep_range(min: 2000, max: 2100);
162 gpiod_set_value_cansleep(desc: cs35l35->reset_gpio, value: 1);
163 usleep_range(min: 1000, max: 1100);
164}
165
166static int cs35l35_wait_for_pdn(struct cs35l35_private *cs35l35)
167{
168 int ret;
169
170 if (cs35l35->pdata.ext_bst) {
171 usleep_range(min: 5000, max: 5500);
172 return 0;
173 }
174
175 reinit_completion(x: &cs35l35->pdn_done);
176
177 ret = wait_for_completion_timeout(x: &cs35l35->pdn_done,
178 timeout: msecs_to_jiffies(m: 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
187static 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(dapm: w->dapm);
191 struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(c: component);
192 int ret = 0;
193
194 switch (event) {
195 case SND_SOC_DAPM_PRE_PMU:
196 regmap_update_bits(map: cs35l35->regmap, CS35L35_CLK_CTL1,
197 CS35L35_MCLK_DIS_MASK,
198 val: 0 << CS35L35_MCLK_DIS_SHIFT);
199 regmap_update_bits(map: cs35l35->regmap, CS35L35_PWRCTL1,
200 CS35L35_DISCHG_FILT_MASK,
201 val: 0 << CS35L35_DISCHG_FILT_SHIFT);
202 regmap_update_bits(map: cs35l35->regmap, CS35L35_PWRCTL1,
203 CS35L35_PDN_ALL_MASK, val: 0);
204 break;
205 case SND_SOC_DAPM_POST_PMD:
206 regmap_update_bits(map: cs35l35->regmap, CS35L35_PWRCTL1,
207 CS35L35_DISCHG_FILT_MASK,
208 val: 1 << CS35L35_DISCHG_FILT_SHIFT);
209 regmap_update_bits(map: cs35l35->regmap, CS35L35_PWRCTL1,
210 CS35L35_PDN_ALL_MASK, val: 1);
211
212 /* Already muted, so disable volume ramp for faster shutdown */
213 regmap_update_bits(map: cs35l35->regmap, CS35L35_AMP_DIG_VOL_CTL,
214 CS35L35_AMP_DIGSFT_MASK, val: 0);
215
216 ret = cs35l35_wait_for_pdn(cs35l35);
217
218 regmap_update_bits(map: cs35l35->regmap, CS35L35_CLK_CTL1,
219 CS35L35_MCLK_DIS_MASK,
220 val: 1 << CS35L35_MCLK_DIS_SHIFT);
221
222 regmap_update_bits(map: cs35l35->regmap, CS35L35_AMP_DIG_VOL_CTL,
223 CS35L35_AMP_DIGSFT_MASK,
224 val: 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
233static 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(dapm: w->dapm);
237 struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(c: 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(map: cs35l35->regmap, CS35L35_PWRCTL2,
245 CS35L35_PDN_BST_MASK,
246 val: 0 << CS35L35_PDN_BST_FETON_SHIFT);
247 else
248 regmap_update_bits(map: cs35l35->regmap, CS35L35_PWRCTL2,
249 CS35L35_PDN_BST_MASK,
250 val: 0 << CS35L35_PDN_BST_FETOFF_SHIFT);
251 break;
252 case SND_SOC_DAPM_POST_PMU:
253 usleep_range(min: 5000, max: 5100);
254 /* If in PDM mode we must use VP for Voltage control */
255 if (cs35l35->pdm_mode)
256 regmap_update_bits(map: cs35l35->regmap,
257 CS35L35_BST_CVTR_V_CTL,
258 CS35L35_BST_CTL_MASK,
259 val: 0 << CS35L35_BST_CTL_SHIFT);
260
261 regmap_update_bits(map: cs35l35->regmap, CS35L35_PROTECT_CTL,
262 CS35L35_AMP_MUTE_MASK, val: 0);
263
264 for (i = 0; i < 2; i++)
265 regmap_bulk_read(map: cs35l35->regmap, CS35L35_INT_STATUS_1,
266 val: &reg, ARRAY_SIZE(reg));
267
268 break;
269 case SND_SOC_DAPM_PRE_PMD:
270 regmap_update_bits(map: cs35l35->regmap, CS35L35_PROTECT_CTL,
271 CS35L35_AMP_MUTE_MASK,
272 val: 1 << CS35L35_AMP_MUTE_SHIFT);
273 if (cs35l35->pdata.bst_pdn_fet_on)
274 regmap_update_bits(map: cs35l35->regmap, CS35L35_PWRCTL2,
275 CS35L35_PDN_BST_MASK,
276 val: 1 << CS35L35_PDN_BST_FETON_SHIFT);
277 else
278 regmap_update_bits(map: cs35l35->regmap, CS35L35_PWRCTL2,
279 CS35L35_PDN_BST_MASK,
280 val: 1 << CS35L35_PDN_BST_FETOFF_SHIFT);
281 break;
282 case SND_SOC_DAPM_POST_PMD:
283 usleep_range(min: 5000, max: 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(map: cs35l35->regmap,
290 CS35L35_BST_CVTR_V_CTL,
291 CS35L35_BST_CTL_MASK,
292 val: 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
302static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1);
303static DECLARE_TLV_DB_SCALE(dig_vol_tlv, -10200, 50, 0);
304
305static 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
314static 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
321static 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
346static 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
363static 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(c: component);
367
368 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
369 case SND_SOC_DAIFMT_CBP_CFP:
370 regmap_update_bits(map: cs35l35->regmap, CS35L35_CLK_CTL1,
371 CS35L35_MS_MASK, val: 1 << CS35L35_MS_SHIFT);
372 cs35l35->clock_consumer = false;
373 break;
374 case SND_SOC_DAIFMT_CBC_CFC:
375 regmap_update_bits(map: cs35l35->regmap, CS35L35_CLK_CTL1,
376 CS35L35_MS_MASK, val: 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
399struct cs35l35_sysclk_config {
400 int sysclk;
401 int srate;
402 u8 clk_cfg;
403};
404
405static 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
450static 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
462static 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(c: component);
468 struct classh_cfg *classh = &cs35l35->pdata.classh_algo;
469 int srate = params_rate(p: 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(sysclk: 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(map: cs35l35->regmap, CS35L35_CLK_CTL2,
484 CS35L35_CLK_CTL2_MASK, val: 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(map: cs35l35->regmap,
501 CS35L35_CLASS_H_FET_DRIVE_CTL,
502 CS35L35_CH_WKFET_DEL_MASK,
503 val: 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(p: 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(map: cs35l35->regmap,
532 CS35L35_AUDIN_DEPTH_CTL,
533 CS35L35_AUDIN_DEPTH_MASK,
534 val: audin_format <<
535 CS35L35_AUDIN_DEPTH_SHIFT);
536 if (cs35l35->pdata.stereo) {
537 regmap_update_bits(map: cs35l35->regmap,
538 CS35L35_AUDIN_DEPTH_CTL,
539 CS35L35_ADVIN_DEPTH_MASK,
540 val: 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(map: cs35l35->regmap,
579 CS35L35_CLK_CTL3,
580 CS35L35_SP_SCLKS_MASK, val: 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
591static const unsigned int cs35l35_src_rates[] = {
592 44100, 48000, 88200, 96000, 176400, 192000
593};
594
595static const struct snd_pcm_hw_constraint_list cs35l35_constraints = {
596 .count = ARRAY_SIZE(cs35l35_src_rates),
597 .list = cs35l35_src_rates,
598};
599
600static 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(c: component);
605
606 if (!substream->runtime)
607 return 0;
608
609 snd_pcm_hw_constraint_list(runtime: substream->runtime, cond: 0,
610 SNDRV_PCM_HW_PARAM_RATE, l: &cs35l35_constraints);
611
612 regmap_update_bits(map: cs35l35->regmap, CS35L35_AMP_INP_DRV_CTL,
613 CS35L35_PDM_MODE_MASK,
614 val: 0 << CS35L35_PDM_MODE_SHIFT);
615
616 return 0;
617}
618
619static const unsigned int cs35l35_pdm_rates[] = {
620 44100, 48000, 88200, 96000
621};
622
623static const struct snd_pcm_hw_constraint_list cs35l35_pdm_constraints = {
624 .count = ARRAY_SIZE(cs35l35_pdm_rates),
625 .list = cs35l35_pdm_rates,
626};
627
628static 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(c: component);
633
634 if (!substream->runtime)
635 return 0;
636
637 snd_pcm_hw_constraint_list(runtime: substream->runtime, cond: 0,
638 SNDRV_PCM_HW_PARAM_RATE,
639 l: &cs35l35_pdm_constraints);
640
641 regmap_update_bits(map: cs35l35->regmap, CS35L35_AMP_INP_DRV_CTL,
642 CS35L35_PDM_MODE_MASK,
643 val: 1 << CS35L35_PDM_MODE_SHIFT);
644
645 return 0;
646}
647
648static 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(c: component);
653
654 /* Need the SCLK Frequency regardless of sysclk source for I2S */
655 cs35l35->sclk = freq;
656
657 return 0;
658}
659
660static 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
667static 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
673static 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
708static 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(c: 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(map: cs35l35->regmap, CS35L35_CLK_CTL1,
750 CS35L35_CLK_SOURCE_MASK,
751 val: 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
760static 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(map: regmap, CS35L35_BST_CONV_SW_FREQ,
772 CS35L35_BST_CONV_SWFREQ_MASK, val: 0x00);
773
774 regmap_read(map: regmap, CS35L35_BST_PEAK_I, val: &bst_ipk);
775 bst_ipk &= CS35L35_BST_IPK_MASK;
776
777 switch (inductor) {
778 case 1000: /* 1 uH */
779 regmap_write(map: regmap, CS35L35_BST_CONV_COEF_1, val: 0x24);
780 regmap_write(map: regmap, CS35L35_BST_CONV_COEF_2, val: 0x24);
781 regmap_update_bits(map: regmap, CS35L35_BST_CONV_SW_FREQ,
782 CS35L35_BST_CONV_LBST_MASK, val: 0x00);
783
784 if (bst_ipk < 0x04)
785 regmap_write(map: regmap, CS35L35_BST_CONV_SLOPE_COMP, val: 0x1B);
786 else
787 regmap_write(map: regmap, CS35L35_BST_CONV_SLOPE_COMP, val: 0x4E);
788 break;
789 case 1200: /* 1.2 uH */
790 regmap_write(map: regmap, CS35L35_BST_CONV_COEF_1, val: 0x20);
791 regmap_write(map: regmap, CS35L35_BST_CONV_COEF_2, val: 0x20);
792 regmap_update_bits(map: regmap, CS35L35_BST_CONV_SW_FREQ,
793 CS35L35_BST_CONV_LBST_MASK, val: 0x01);
794
795 if (bst_ipk < 0x04)
796 regmap_write(map: regmap, CS35L35_BST_CONV_SLOPE_COMP, val: 0x1B);
797 else
798 regmap_write(map: regmap, CS35L35_BST_CONV_SLOPE_COMP, val: 0x47);
799 break;
800 case 1500: /* 1.5uH */
801 regmap_write(map: regmap, CS35L35_BST_CONV_COEF_1, val: 0x20);
802 regmap_write(map: regmap, CS35L35_BST_CONV_COEF_2, val: 0x20);
803 regmap_update_bits(map: regmap, CS35L35_BST_CONV_SW_FREQ,
804 CS35L35_BST_CONV_LBST_MASK, val: 0x02);
805
806 if (bst_ipk < 0x04)
807 regmap_write(map: regmap, CS35L35_BST_CONV_SLOPE_COMP, val: 0x1B);
808 else
809 regmap_write(map: regmap, CS35L35_BST_CONV_SLOPE_COMP, val: 0x3C);
810 break;
811 case 2200: /* 2.2uH */
812 regmap_write(map: regmap, CS35L35_BST_CONV_COEF_1, val: 0x19);
813 regmap_write(map: regmap, CS35L35_BST_CONV_COEF_2, val: 0x25);
814 regmap_update_bits(map: regmap, CS35L35_BST_CONV_SW_FREQ,
815 CS35L35_BST_CONV_LBST_MASK, val: 0x03);
816
817 if (bst_ipk < 0x04)
818 regmap_write(map: regmap, CS35L35_BST_CONV_SLOPE_COMP, val: 0x1B);
819 else
820 regmap_write(map: regmap, CS35L35_BST_CONV_SLOPE_COMP, val: 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
830static int cs35l35_component_probe(struct snd_soc_component *component)
831{
832 struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(c: 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(map: cs35l35->regmap, CS35L35_BST_CVTR_V_CTL,
840 CS35L35_BST_CTL_MASK,
841 val: cs35l35->pdata.bst_vctl);
842
843 if (cs35l35->pdata.bst_ipk)
844 regmap_update_bits(map: cs35l35->regmap, CS35L35_BST_PEAK_I,
845 CS35L35_BST_IPK_MASK,
846 val: cs35l35->pdata.bst_ipk <<
847 CS35L35_BST_IPK_SHIFT);
848
849 ret = cs35l35_boost_inductor(cs35l35, inductor: cs35l35->pdata.boost_ind);
850 if (ret)
851 return ret;
852
853 if (cs35l35->pdata.gain_zc)
854 regmap_update_bits(map: cs35l35->regmap, CS35L35_PROTECT_CTL,
855 CS35L35_AMP_GAIN_ZC_MASK,
856 val: cs35l35->pdata.gain_zc <<
857 CS35L35_AMP_GAIN_ZC_SHIFT);
858
859 if (cs35l35->pdata.aud_channel)
860 regmap_update_bits(map: cs35l35->regmap,
861 CS35L35_AUDIN_RXLOC_CTL,
862 CS35L35_AUD_IN_LR_MASK,
863 val: cs35l35->pdata.aud_channel <<
864 CS35L35_AUD_IN_LR_SHIFT);
865
866 if (cs35l35->pdata.stereo) {
867 regmap_update_bits(map: cs35l35->regmap,
868 CS35L35_ADVIN_RXLOC_CTL,
869 CS35L35_ADV_IN_LR_MASK,
870 val: cs35l35->pdata.adv_channel <<
871 CS35L35_ADV_IN_LR_SHIFT);
872 if (cs35l35->pdata.shared_bst)
873 regmap_update_bits(map: cs35l35->regmap, CS35L35_CLASS_H_CTL,
874 CS35L35_CH_STEREO_MASK,
875 val: 1 << CS35L35_CH_STEREO_SHIFT);
876 ret = snd_soc_add_component_controls(component, controls: 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(map: cs35l35->regmap, CS35L35_CLK_CTL1,
884 CS35L35_SP_DRV_MASK,
885 val: cs35l35->pdata.sp_drv_str <<
886 CS35L35_SP_DRV_SHIFT);
887 if (cs35l35->pdata.sp_drv_unused)
888 regmap_update_bits(map: cs35l35->regmap, CS35L35_SP_FMT_CTL3,
889 CS35L35_SP_I2S_DRV_MASK,
890 val: 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(map: cs35l35->regmap,
896 CS35L35_CLASS_H_CTL,
897 CS35L35_CH_BST_OVR_MASK,
898 val: classh->classh_bst_override <<
899 CS35L35_CH_BST_OVR_SHIFT);
900 if (classh->classh_bst_max_limit)
901 regmap_update_bits(map: cs35l35->regmap,
902 CS35L35_CLASS_H_CTL,
903 CS35L35_CH_BST_LIM_MASK,
904 val: classh->classh_bst_max_limit <<
905 CS35L35_CH_BST_LIM_SHIFT);
906 if (classh->classh_mem_depth)
907 regmap_update_bits(map: cs35l35->regmap,
908 CS35L35_CLASS_H_CTL,
909 CS35L35_CH_MEM_DEPTH_MASK,
910 val: classh->classh_mem_depth <<
911 CS35L35_CH_MEM_DEPTH_SHIFT);
912 if (classh->classh_headroom)
913 regmap_update_bits(map: cs35l35->regmap,
914 CS35L35_CLASS_H_HEADRM_CTL,
915 CS35L35_CH_HDRM_CTL_MASK,
916 val: classh->classh_headroom <<
917 CS35L35_CH_HDRM_CTL_SHIFT);
918 if (classh->classh_release_rate)
919 regmap_update_bits(map: cs35l35->regmap,
920 CS35L35_CLASS_H_RELEASE_RATE,
921 CS35L35_CH_REL_RATE_MASK,
922 val: classh->classh_release_rate <<
923 CS35L35_CH_REL_RATE_SHIFT);
924 if (classh->classh_wk_fet_disable)
925 regmap_update_bits(map: cs35l35->regmap,
926 CS35L35_CLASS_H_FET_DRIVE_CTL,
927 CS35L35_CH_WKFET_DIS_MASK,
928 val: classh->classh_wk_fet_disable <<
929 CS35L35_CH_WKFET_DIS_SHIFT);
930 if (classh->classh_wk_fet_delay)
931 regmap_update_bits(map: cs35l35->regmap,
932 CS35L35_CLASS_H_FET_DRIVE_CTL,
933 CS35L35_CH_WKFET_DEL_MASK,
934 val: classh->classh_wk_fet_delay <<
935 CS35L35_CH_WKFET_DEL_SHIFT);
936 if (classh->classh_wk_fet_thld)
937 regmap_update_bits(map: cs35l35->regmap,
938 CS35L35_CLASS_H_FET_DRIVE_CTL,
939 CS35L35_CH_WKFET_THLD_MASK,
940 val: classh->classh_wk_fet_thld <<
941 CS35L35_CH_WKFET_THLD_SHIFT);
942 if (classh->classh_vpch_auto)
943 regmap_update_bits(map: cs35l35->regmap,
944 CS35L35_CLASS_H_VP_CTL,
945 CS35L35_CH_VP_AUTO_MASK,
946 val: classh->classh_vpch_auto <<
947 CS35L35_CH_VP_AUTO_SHIFT);
948 if (classh->classh_vpch_rate)
949 regmap_update_bits(map: cs35l35->regmap,
950 CS35L35_CLASS_H_VP_CTL,
951 CS35L35_CH_VP_RATE_MASK,
952 val: classh->classh_vpch_rate <<
953 CS35L35_CH_VP_RATE_SHIFT);
954 if (classh->classh_vpch_man)
955 regmap_update_bits(map: cs35l35->regmap,
956 CS35L35_CLASS_H_VP_CTL,
957 CS35L35_CH_VP_MAN_MASK,
958 val: 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(map: cs35l35->regmap,
965 CS35L35_SPKMON_DEPTH_CTL,
966 CS35L35_VMON_DEPTH_MASK,
967 val: monitor_config->vmon_dpth <<
968 CS35L35_VMON_DEPTH_SHIFT);
969 regmap_update_bits(map: cs35l35->regmap,
970 CS35L35_VMON_TXLOC_CTL,
971 CS35L35_MON_TXLOC_MASK,
972 val: monitor_config->vmon_loc <<
973 CS35L35_MON_TXLOC_SHIFT);
974 regmap_update_bits(map: cs35l35->regmap,
975 CS35L35_VMON_TXLOC_CTL,
976 CS35L35_MON_FRM_MASK,
977 val: monitor_config->vmon_frm <<
978 CS35L35_MON_FRM_SHIFT);
979 }
980 if (monitor_config->imon_specs) {
981 regmap_update_bits(map: cs35l35->regmap,
982 CS35L35_SPKMON_DEPTH_CTL,
983 CS35L35_IMON_DEPTH_MASK,
984 val: monitor_config->imon_dpth <<
985 CS35L35_IMON_DEPTH_SHIFT);
986 regmap_update_bits(map: cs35l35->regmap,
987 CS35L35_IMON_TXLOC_CTL,
988 CS35L35_MON_TXLOC_MASK,
989 val: monitor_config->imon_loc <<
990 CS35L35_MON_TXLOC_SHIFT);
991 regmap_update_bits(map: cs35l35->regmap,
992 CS35L35_IMON_TXLOC_CTL,
993 CS35L35_MON_FRM_MASK,
994 val: monitor_config->imon_frm <<
995 CS35L35_MON_FRM_SHIFT);
996 regmap_update_bits(map: cs35l35->regmap,
997 CS35L35_IMON_SCALE_CTL,
998 CS35L35_IMON_SCALE_MASK,
999 val: monitor_config->imon_scale <<
1000 CS35L35_IMON_SCALE_SHIFT);
1001 }
1002 if (monitor_config->vpmon_specs) {
1003 regmap_update_bits(map: cs35l35->regmap,
1004 CS35L35_SUPMON_DEPTH_CTL,
1005 CS35L35_VPMON_DEPTH_MASK,
1006 val: monitor_config->vpmon_dpth <<
1007 CS35L35_VPMON_DEPTH_SHIFT);
1008 regmap_update_bits(map: cs35l35->regmap,
1009 CS35L35_VPMON_TXLOC_CTL,
1010 CS35L35_MON_TXLOC_MASK,
1011 val: monitor_config->vpmon_loc <<
1012 CS35L35_MON_TXLOC_SHIFT);
1013 regmap_update_bits(map: cs35l35->regmap,
1014 CS35L35_VPMON_TXLOC_CTL,
1015 CS35L35_MON_FRM_MASK,
1016 val: monitor_config->vpmon_frm <<
1017 CS35L35_MON_FRM_SHIFT);
1018 }
1019 if (monitor_config->vbstmon_specs) {
1020 regmap_update_bits(map: cs35l35->regmap,
1021 CS35L35_SUPMON_DEPTH_CTL,
1022 CS35L35_VBSTMON_DEPTH_MASK,
1023 val: monitor_config->vpmon_dpth <<
1024 CS35L35_VBSTMON_DEPTH_SHIFT);
1025 regmap_update_bits(map: cs35l35->regmap,
1026 CS35L35_VBSTMON_TXLOC_CTL,
1027 CS35L35_MON_TXLOC_MASK,
1028 val: monitor_config->vbstmon_loc <<
1029 CS35L35_MON_TXLOC_SHIFT);
1030 regmap_update_bits(map: cs35l35->regmap,
1031 CS35L35_VBSTMON_TXLOC_CTL,
1032 CS35L35_MON_FRM_MASK,
1033 val: monitor_config->vbstmon_frm <<
1034 CS35L35_MON_FRM_SHIFT);
1035 }
1036 if (monitor_config->vpbrstat_specs) {
1037 regmap_update_bits(map: cs35l35->regmap,
1038 CS35L35_SUPMON_DEPTH_CTL,
1039 CS35L35_VPBRSTAT_DEPTH_MASK,
1040 val: monitor_config->vpbrstat_dpth <<
1041 CS35L35_VPBRSTAT_DEPTH_SHIFT);
1042 regmap_update_bits(map: cs35l35->regmap,
1043 CS35L35_VPBR_STATUS_TXLOC_CTL,
1044 CS35L35_MON_TXLOC_MASK,
1045 val: monitor_config->vpbrstat_loc <<
1046 CS35L35_MON_TXLOC_SHIFT);
1047 regmap_update_bits(map: cs35l35->regmap,
1048 CS35L35_VPBR_STATUS_TXLOC_CTL,
1049 CS35L35_MON_FRM_MASK,
1050 val: monitor_config->vpbrstat_frm <<
1051 CS35L35_MON_FRM_SHIFT);
1052 }
1053 if (monitor_config->zerofill_specs) {
1054 regmap_update_bits(map: cs35l35->regmap,
1055 CS35L35_SUPMON_DEPTH_CTL,
1056 CS35L35_ZEROFILL_DEPTH_MASK,
1057 val: monitor_config->zerofill_dpth <<
1058 CS35L35_ZEROFILL_DEPTH_SHIFT);
1059 regmap_update_bits(map: cs35l35->regmap,
1060 CS35L35_ZERO_FILL_LOC_CTL,
1061 CS35L35_MON_TXLOC_MASK,
1062 val: monitor_config->zerofill_loc <<
1063 CS35L35_MON_TXLOC_SHIFT);
1064 regmap_update_bits(map: cs35l35->regmap,
1065 CS35L35_ZERO_FILL_LOC_CTL,
1066 CS35L35_MON_FRM_MASK,
1067 val: monitor_config->zerofill_frm <<
1068 CS35L35_MON_FRM_SHIFT);
1069 }
1070 }
1071
1072 return 0;
1073}
1074
1075static 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
1089static 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
1104static 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(map: cs35l35->regmap, CS35L35_INT_STATUS_4, val: &sticky4);
1112 regmap_read(map: cs35l35->regmap, CS35L35_INT_STATUS_3, val: &sticky3);
1113 regmap_read(map: cs35l35->regmap, CS35L35_INT_STATUS_2, val: &sticky2);
1114 regmap_read(map: cs35l35->regmap, CS35L35_INT_STATUS_1, val: &sticky1);
1115
1116 regmap_read(map: cs35l35->regmap, CS35L35_INT_MASK_4, val: &mask4);
1117 regmap_read(map: cs35l35->regmap, CS35L35_INT_MASK_3, val: &mask3);
1118 regmap_read(map: cs35l35->regmap, CS35L35_INT_MASK_2, val: &mask2);
1119 regmap_read(map: cs35l35->regmap, CS35L35_INT_MASK_1, val: &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(map: cs35l35->regmap, CS35L35_INT_STATUS_1, val: &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(map: cs35l35->regmap,
1140 CS35L35_PROT_RELEASE_CTL,
1141 CS35L35_CAL_ERR_RLS, val: 0);
1142 regmap_update_bits(map: cs35l35->regmap,
1143 CS35L35_PROT_RELEASE_CTL,
1144 CS35L35_CAL_ERR_RLS,
1145 CS35L35_CAL_ERR_RLS);
1146 regmap_update_bits(map: cs35l35->regmap,
1147 CS35L35_PROT_RELEASE_CTL,
1148 CS35L35_CAL_ERR_RLS, val: 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(map: cs35l35->regmap,
1158 CS35L35_PROT_RELEASE_CTL,
1159 CS35L35_SHORT_RLS, val: 0);
1160 regmap_update_bits(map: cs35l35->regmap,
1161 CS35L35_PROT_RELEASE_CTL,
1162 CS35L35_SHORT_RLS,
1163 CS35L35_SHORT_RLS);
1164 regmap_update_bits(map: cs35l35->regmap,
1165 CS35L35_PROT_RELEASE_CTL,
1166 CS35L35_SHORT_RLS, val: 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(map: cs35l35->regmap,
1177 CS35L35_PROT_RELEASE_CTL,
1178 CS35L35_OTW_RLS, val: 0);
1179 regmap_update_bits(map: cs35l35->regmap,
1180 CS35L35_PROT_RELEASE_CTL,
1181 CS35L35_OTW_RLS,
1182 CS35L35_OTW_RLS);
1183 regmap_update_bits(map: cs35l35->regmap,
1184 CS35L35_PROT_RELEASE_CTL,
1185 CS35L35_OTW_RLS, val: 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(map: cs35l35->regmap,
1195 CS35L35_PROT_RELEASE_CTL,
1196 CS35L35_OTE_RLS, val: 0);
1197 regmap_update_bits(map: cs35l35->regmap,
1198 CS35L35_PROT_RELEASE_CTL,
1199 CS35L35_OTE_RLS,
1200 CS35L35_OTE_RLS);
1201 regmap_update_bits(map: cs35l35->regmap,
1202 CS35L35_PROT_RELEASE_CTL,
1203 CS35L35_OTE_RLS, val: 0);
1204 }
1205 }
1206
1207 if (sticky3 & CS35L35_BST_HIGH) {
1208 dev_crit(cs35l35->dev, "VBST error: powering off!\n");
1209 regmap_update_bits(map: cs35l35->regmap, CS35L35_PWRCTL2,
1210 CS35L35_PDN_AMP, CS35L35_PDN_AMP);
1211 regmap_update_bits(map: 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(map: cs35l35->regmap, CS35L35_PWRCTL2,
1218 CS35L35_PDN_AMP, CS35L35_PDN_AMP);
1219 regmap_update_bits(map: 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
1236static 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 propname: "cirrus,boost-pdn-fet-on");
1254
1255 ret = of_property_read_u32(np, propname: "cirrus,boost-ctl-millivolt", out_value: &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, propname: "cirrus,boost-peak-milliamp", out_value: &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, propname: "cirrus,boost-ind-nanohenry", out_value: &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, propname: "cirrus,sp-drv-strength", out_value: &val32) >= 0)
1285 pdata->sp_drv_str = val32;
1286 if (of_property_read_u32(np, propname: "cirrus,sp-drv-unused", out_value: &val32) >= 0)
1287 pdata->sp_drv_unused = val32 | CS35L35_VALID_PDATA;
1288
1289 pdata->stereo = of_property_read_bool(np, propname: "cirrus,stereo-config");
1290
1291 if (pdata->stereo) {
1292 ret = of_property_read_u32(np, propname: "cirrus,audio-channel", out_value: &val32);
1293 if (ret >= 0)
1294 pdata->aud_channel = val32;
1295
1296 ret = of_property_read_u32(np, propname: "cirrus,advisory-channel",
1297 out_value: &val32);
1298 if (ret >= 0)
1299 pdata->adv_channel = val32;
1300
1301 pdata->shared_bst = of_property_read_bool(np,
1302 propname: "cirrus,shared-boost");
1303 }
1304
1305 pdata->ext_bst = of_property_read_bool(np, propname: "cirrus,external-boost");
1306
1307 pdata->gain_zc = of_property_read_bool(np, propname: "cirrus,amp-gain-zc");
1308
1309 classh = of_get_child_by_name(node: np, name: "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, propname: "cirrus,classh-bst-overide");
1315
1316 ret = of_property_read_u32(np: classh,
1317 propname: "cirrus,classh-bst-max-limit",
1318 out_value: &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(np: classh,
1325 propname: "cirrus,classh-bst-max-limit",
1326 out_value: &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(np: classh, propname: "cirrus,classh-mem-depth",
1333 out_value: &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(np: classh, propname: "cirrus,classh-release-rate",
1340 out_value: &val32);
1341 if (ret >= 0)
1342 classh_config->classh_release_rate = val32;
1343
1344 ret = of_property_read_u32(np: classh, propname: "cirrus,classh-headroom",
1345 out_value: &val32);
1346 if (ret >= 0) {
1347 val32 |= CS35L35_VALID_PDATA;
1348 classh_config->classh_headroom = val32;
1349 }
1350
1351 ret = of_property_read_u32(np: classh,
1352 propname: "cirrus,classh-wk-fet-disable",
1353 out_value: &val32);
1354 if (ret >= 0)
1355 classh_config->classh_wk_fet_disable = val32;
1356
1357 ret = of_property_read_u32(np: classh, propname: "cirrus,classh-wk-fet-delay",
1358 out_value: &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(np: classh, propname: "cirrus,classh-wk-fet-thld",
1365 out_value: &val32);
1366 if (ret >= 0)
1367 classh_config->classh_wk_fet_thld = val32;
1368
1369 ret = of_property_read_u32(np: classh, propname: "cirrus,classh-vpch-auto",
1370 out_value: &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(np: classh, propname: "cirrus,classh-vpch-rate",
1377 out_value: &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(np: classh, propname: "cirrus,classh-vpch-man",
1384 out_value: &val32);
1385 if (ret >= 0)
1386 classh_config->classh_vpch_man = val32;
1387 }
1388 of_node_put(node: classh);
1389
1390 /* frame depth location */
1391 signal_format = of_get_child_by_name(node: np, name: "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(np: signal_format, propname: "cirrus,imon",
1395 out_values: monitor_array, sz: 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(np: signal_format, propname: "cirrus,vmon",
1404 out_values: monitor_array, sz: 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(np: signal_format, propname: "cirrus,vpmon",
1412 out_values: monitor_array, sz: 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(np: signal_format, propname: "cirrus,vbstmon",
1420 out_values: monitor_array, sz: 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(np: signal_format, propname: "cirrus,vpbrstat",
1428 out_values: monitor_array, sz: 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(np: signal_format, propname: "cirrus,zerofill",
1436 out_values: monitor_array, sz: 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(node: signal_format);
1445
1446 return 0;
1447}
1448
1449/* Errata Rev A0 */
1450static 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
1465static 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, size: sizeof(struct cs35l35_private), GFP_KERNEL);
1475 if (!cs35l35)
1476 return -ENOMEM;
1477
1478 cs35l35->dev = dev;
1479
1480 i2c_set_clientdata(client: i2c_client, data: cs35l35);
1481 cs35l35->regmap = devm_regmap_init_i2c(i2c_client, &cs35l35_regmap);
1482 if (IS_ERR(ptr: cs35l35->regmap)) {
1483 ret = PTR_ERR(ptr: 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, num_consumers: cs35l35->num_supplies,
1494 consumers: 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, size: 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(num_consumers: cs35l35->num_supplies,
1517 consumers: 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, con_id: "reset",
1525 flags: GPIOD_OUT_LOW);
1526 if (IS_ERR(ptr: cs35l35->reset_gpio)) {
1527 ret = PTR_ERR(ptr: 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(x: &cs35l35->pdn_done);
1541
1542 ret = devm_request_threaded_irq(dev, irq: i2c_client->irq, NULL, thread_fn: cs35l35_irq,
1543 IRQF_ONESHOT | IRQF_TRIGGER_LOW |
1544 IRQF_SHARED, devname: "cs35l35", dev_id: 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(regmap: 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(map: cs35l35->regmap, CS35L35_REV_ID, val: &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(map: cs35l35->regmap, regs: 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(map: cs35l35->regmap, CS35L35_INT_MASK_1,
1582 CS35L35_INT1_CRIT_MASK);
1583 regmap_write(map: cs35l35->regmap, CS35L35_INT_MASK_2,
1584 CS35L35_INT2_CRIT_MASK);
1585 regmap_write(map: cs35l35->regmap, CS35L35_INT_MASK_3,
1586 CS35L35_INT3_CRIT_MASK);
1587 regmap_write(map: cs35l35->regmap, CS35L35_INT_MASK_4,
1588 CS35L35_INT4_CRIT_MASK);
1589
1590 regmap_update_bits(map: 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(map: cs35l35->regmap, CS35L35_PWRCTL2,
1596 CS35L35_PDN_BST_MASK,
1597 val: 1 << CS35L35_PDN_BST_FETON_SHIFT);
1598 else
1599 regmap_update_bits(map: cs35l35->regmap, CS35L35_PWRCTL2,
1600 CS35L35_PDN_BST_MASK,
1601 val: 1 << CS35L35_PDN_BST_FETOFF_SHIFT);
1602
1603 regmap_update_bits(map: cs35l35->regmap, CS35L35_PWRCTL3,
1604 CS35L35_PWR3_PDN_MASK,
1605 CS35L35_PWR3_PDN_MASK);
1606
1607 regmap_update_bits(map: cs35l35->regmap, CS35L35_PROTECT_CTL,
1608 CS35L35_AMP_MUTE_MASK, val: 1 << CS35L35_AMP_MUTE_SHIFT);
1609
1610 ret = devm_snd_soc_register_component(dev, component_driver: &soc_component_dev_cs35l35,
1611 dai_drv: 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
1619err:
1620 regulator_bulk_disable(num_consumers: cs35l35->num_supplies,
1621 consumers: cs35l35->supplies);
1622 gpiod_set_value_cansleep(desc: cs35l35->reset_gpio, value: 0);
1623
1624 return ret;
1625}
1626
1627static void cs35l35_i2c_remove(struct i2c_client *i2c_client)
1628{
1629 struct cs35l35_private *cs35l35 = i2c_get_clientdata(client: i2c_client);
1630
1631 regulator_bulk_disable(num_consumers: cs35l35->num_supplies, consumers: cs35l35->supplies);
1632 gpiod_set_value_cansleep(desc: cs35l35->reset_gpio, value: 0);
1633}
1634
1635static const struct of_device_id cs35l35_of_match[] = {
1636 {.compatible = "cirrus,cs35l35"},
1637 {},
1638};
1639MODULE_DEVICE_TABLE(of, cs35l35_of_match);
1640
1641static const struct i2c_device_id cs35l35_id[] = {
1642 {"cs35l35", 0},
1643 {}
1644};
1645
1646MODULE_DEVICE_TABLE(i2c, cs35l35_id);
1647
1648static 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
1658module_i2c_driver(cs35l35_i2c_driver);
1659
1660MODULE_DESCRIPTION("ASoC CS35L35 driver");
1661MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
1662MODULE_LICENSE("GPL");
1663

source code of linux/sound/soc/codecs/cs35l35.c