2 * cs35l34.c -- CS35l34 ALSA SoC audio driver
4 * Copyright 2016 Cirrus Logic, Inc.
6 * Author: Paul Handrigan <Paul.Handrigan@cirrus.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
14 #include <linux/module.h>
15 #include <linux/moduleparam.h>
16 #include <linux/kernel.h>
17 #include <linux/init.h>
18 #include <linux/delay.h>
19 #include <linux/i2c.h>
20 #include <linux/slab.h>
21 #include <linux/workqueue.h>
22 #include <linux/platform_device.h>
23 #include <linux/regulator/consumer.h>
24 #include <linux/regulator/machine.h>
25 #include <linux/pm_runtime.h>
26 #include <linux/of_device.h>
27 #include <linux/of_gpio.h>
28 #include <linux/of_irq.h>
29 #include <sound/core.h>
30 #include <sound/pcm.h>
31 #include <sound/pcm_params.h>
32 #include <sound/soc.h>
33 #include <sound/soc-dapm.h>
34 #include <linux/gpio.h>
35 #include <linux/gpio/consumer.h>
36 #include <sound/initval.h>
37 #include <sound/tlv.h>
38 #include <sound/cs35l34.h>
42 #define PDN_DONE_ATTEMPTS 10
43 #define CS35L34_START_DELAY 50
45 struct cs35l34_private
{
46 struct snd_soc_codec
*codec
;
47 struct cs35l34_platform_data pdata
;
48 struct regmap
*regmap
;
49 struct regulator_bulk_data core_supplies
[2];
50 int num_core_supplies
;
53 struct gpio_desc
*reset_gpio
; /* Active-low reset GPIO */
56 static const struct reg_default cs35l34_reg
[] = {
57 {CS35L34_PWRCTL1
, 0x01},
58 {CS35L34_PWRCTL2
, 0x19},
59 {CS35L34_PWRCTL3
, 0x01},
60 {CS35L34_ADSP_CLK_CTL
, 0x08},
61 {CS35L34_MCLK_CTL
, 0x11},
62 {CS35L34_AMP_INP_DRV_CTL
, 0x01},
63 {CS35L34_AMP_DIG_VOL_CTL
, 0x12},
64 {CS35L34_AMP_DIG_VOL
, 0x00},
65 {CS35L34_AMP_ANLG_GAIN_CTL
, 0x0F},
66 {CS35L34_PROTECT_CTL
, 0x06},
67 {CS35L34_AMP_KEEP_ALIVE_CTL
, 0x04},
68 {CS35L34_BST_CVTR_V_CTL
, 0x00},
69 {CS35L34_BST_PEAK_I
, 0x10},
70 {CS35L34_BST_RAMP_CTL
, 0x87},
71 {CS35L34_BST_CONV_COEF_1
, 0x24},
72 {CS35L34_BST_CONV_COEF_2
, 0x24},
73 {CS35L34_BST_CONV_SLOPE_COMP
, 0x4E},
74 {CS35L34_BST_CONV_SW_FREQ
, 0x08},
75 {CS35L34_CLASS_H_CTL
, 0x0D},
76 {CS35L34_CLASS_H_HEADRM_CTL
, 0x0D},
77 {CS35L34_CLASS_H_RELEASE_RATE
, 0x08},
78 {CS35L34_CLASS_H_FET_DRIVE_CTL
, 0x41},
79 {CS35L34_CLASS_H_STATUS
, 0x05},
80 {CS35L34_VPBR_CTL
, 0x0A},
81 {CS35L34_VPBR_VOL_CTL
, 0x90},
82 {CS35L34_VPBR_TIMING_CTL
, 0x6A},
83 {CS35L34_PRED_MAX_ATTEN_SPK_LOAD
, 0x95},
84 {CS35L34_PRED_BROWNOUT_THRESH
, 0x1C},
85 {CS35L34_PRED_BROWNOUT_VOL_CTL
, 0x00},
86 {CS35L34_PRED_BROWNOUT_RATE_CTL
, 0x10},
87 {CS35L34_PRED_WAIT_CTL
, 0x10},
88 {CS35L34_PRED_ZVP_INIT_IMP_CTL
, 0x08},
89 {CS35L34_PRED_MAN_SAFE_VPI_CTL
, 0x80},
90 {CS35L34_VPBR_ATTEN_STATUS
, 0x00},
91 {CS35L34_PRED_BRWNOUT_ATT_STATUS
, 0x00},
92 {CS35L34_SPKR_MON_CTL
, 0xC6},
93 {CS35L34_ADSP_I2S_CTL
, 0x00},
94 {CS35L34_ADSP_TDM_CTL
, 0x00},
95 {CS35L34_TDM_TX_CTL_1_VMON
, 0x00},
96 {CS35L34_TDM_TX_CTL_2_IMON
, 0x04},
97 {CS35L34_TDM_TX_CTL_3_VPMON
, 0x03},
98 {CS35L34_TDM_TX_CTL_4_VBSTMON
, 0x07},
99 {CS35L34_TDM_TX_CTL_5_FLAG1
, 0x08},
100 {CS35L34_TDM_TX_CTL_6_FLAG2
, 0x09},
101 {CS35L34_TDM_TX_SLOT_EN_1
, 0x00},
102 {CS35L34_TDM_TX_SLOT_EN_2
, 0x00},
103 {CS35L34_TDM_TX_SLOT_EN_3
, 0x00},
104 {CS35L34_TDM_TX_SLOT_EN_4
, 0x00},
105 {CS35L34_TDM_RX_CTL_1_AUDIN
, 0x40},
106 {CS35L34_TDM_RX_CTL_3_ALIVE
, 0x04},
107 {CS35L34_MULT_DEV_SYNCH1
, 0x00},
108 {CS35L34_MULT_DEV_SYNCH2
, 0x80},
109 {CS35L34_PROT_RELEASE_CTL
, 0x00},
110 {CS35L34_DIAG_MODE_REG_LOCK
, 0x00},
111 {CS35L34_DIAG_MODE_CTL_1
, 0x00},
112 {CS35L34_DIAG_MODE_CTL_2
, 0x00},
113 {CS35L34_INT_MASK_1
, 0xFF},
114 {CS35L34_INT_MASK_2
, 0xFF},
115 {CS35L34_INT_MASK_3
, 0xFF},
116 {CS35L34_INT_MASK_4
, 0xFF},
117 {CS35L34_INT_STATUS_1
, 0x30},
118 {CS35L34_INT_STATUS_2
, 0x05},
119 {CS35L34_INT_STATUS_3
, 0x00},
120 {CS35L34_INT_STATUS_4
, 0x00},
121 {CS35L34_OTP_TRIM_STATUS
, 0x00},
124 static bool cs35l34_volatile_register(struct device
*dev
, unsigned int reg
)
127 case CS35L34_DEVID_AB
:
128 case CS35L34_DEVID_CD
:
129 case CS35L34_DEVID_E
:
132 case CS35L34_INT_STATUS_1
:
133 case CS35L34_INT_STATUS_2
:
134 case CS35L34_INT_STATUS_3
:
135 case CS35L34_INT_STATUS_4
:
136 case CS35L34_CLASS_H_STATUS
:
137 case CS35L34_VPBR_ATTEN_STATUS
:
138 case CS35L34_OTP_TRIM_STATUS
:
145 static bool cs35l34_readable_register(struct device
*dev
, unsigned int reg
)
148 case CS35L34_DEVID_AB
:
149 case CS35L34_DEVID_CD
:
150 case CS35L34_DEVID_E
:
153 case CS35L34_PWRCTL1
:
154 case CS35L34_PWRCTL2
:
155 case CS35L34_PWRCTL3
:
156 case CS35L34_ADSP_CLK_CTL
:
157 case CS35L34_MCLK_CTL
:
158 case CS35L34_AMP_INP_DRV_CTL
:
159 case CS35L34_AMP_DIG_VOL_CTL
:
160 case CS35L34_AMP_DIG_VOL
:
161 case CS35L34_AMP_ANLG_GAIN_CTL
:
162 case CS35L34_PROTECT_CTL
:
163 case CS35L34_AMP_KEEP_ALIVE_CTL
:
164 case CS35L34_BST_CVTR_V_CTL
:
165 case CS35L34_BST_PEAK_I
:
166 case CS35L34_BST_RAMP_CTL
:
167 case CS35L34_BST_CONV_COEF_1
:
168 case CS35L34_BST_CONV_COEF_2
:
169 case CS35L34_BST_CONV_SLOPE_COMP
:
170 case CS35L34_BST_CONV_SW_FREQ
:
171 case CS35L34_CLASS_H_CTL
:
172 case CS35L34_CLASS_H_HEADRM_CTL
:
173 case CS35L34_CLASS_H_RELEASE_RATE
:
174 case CS35L34_CLASS_H_FET_DRIVE_CTL
:
175 case CS35L34_CLASS_H_STATUS
:
176 case CS35L34_VPBR_CTL
:
177 case CS35L34_VPBR_VOL_CTL
:
178 case CS35L34_VPBR_TIMING_CTL
:
179 case CS35L34_PRED_MAX_ATTEN_SPK_LOAD
:
180 case CS35L34_PRED_BROWNOUT_THRESH
:
181 case CS35L34_PRED_BROWNOUT_VOL_CTL
:
182 case CS35L34_PRED_BROWNOUT_RATE_CTL
:
183 case CS35L34_PRED_WAIT_CTL
:
184 case CS35L34_PRED_ZVP_INIT_IMP_CTL
:
185 case CS35L34_PRED_MAN_SAFE_VPI_CTL
:
186 case CS35L34_VPBR_ATTEN_STATUS
:
187 case CS35L34_PRED_BRWNOUT_ATT_STATUS
:
188 case CS35L34_SPKR_MON_CTL
:
189 case CS35L34_ADSP_I2S_CTL
:
190 case CS35L34_ADSP_TDM_CTL
:
191 case CS35L34_TDM_TX_CTL_1_VMON
:
192 case CS35L34_TDM_TX_CTL_2_IMON
:
193 case CS35L34_TDM_TX_CTL_3_VPMON
:
194 case CS35L34_TDM_TX_CTL_4_VBSTMON
:
195 case CS35L34_TDM_TX_CTL_5_FLAG1
:
196 case CS35L34_TDM_TX_CTL_6_FLAG2
:
197 case CS35L34_TDM_TX_SLOT_EN_1
:
198 case CS35L34_TDM_TX_SLOT_EN_2
:
199 case CS35L34_TDM_TX_SLOT_EN_3
:
200 case CS35L34_TDM_TX_SLOT_EN_4
:
201 case CS35L34_TDM_RX_CTL_1_AUDIN
:
202 case CS35L34_TDM_RX_CTL_3_ALIVE
:
203 case CS35L34_MULT_DEV_SYNCH1
:
204 case CS35L34_MULT_DEV_SYNCH2
:
205 case CS35L34_PROT_RELEASE_CTL
:
206 case CS35L34_DIAG_MODE_REG_LOCK
:
207 case CS35L34_DIAG_MODE_CTL_1
:
208 case CS35L34_DIAG_MODE_CTL_2
:
209 case CS35L34_INT_MASK_1
:
210 case CS35L34_INT_MASK_2
:
211 case CS35L34_INT_MASK_3
:
212 case CS35L34_INT_MASK_4
:
213 case CS35L34_INT_STATUS_1
:
214 case CS35L34_INT_STATUS_2
:
215 case CS35L34_INT_STATUS_3
:
216 case CS35L34_INT_STATUS_4
:
217 case CS35L34_OTP_TRIM_STATUS
:
224 static bool cs35l34_precious_register(struct device
*dev
, unsigned int reg
)
227 case CS35L34_INT_STATUS_1
:
228 case CS35L34_INT_STATUS_2
:
229 case CS35L34_INT_STATUS_3
:
230 case CS35L34_INT_STATUS_4
:
237 static int cs35l34_sdin_event(struct snd_soc_dapm_widget
*w
,
238 struct snd_kcontrol
*kcontrol
, int event
)
240 struct snd_soc_codec
*codec
= snd_soc_dapm_to_codec(w
->dapm
);
241 struct cs35l34_private
*priv
= snd_soc_codec_get_drvdata(codec
);
245 case SND_SOC_DAPM_PRE_PMU
:
247 regmap_update_bits(priv
->regmap
, CS35L34_PWRCTL3
,
248 CS35L34_PDN_TDM
, 0x00);
250 ret
= regmap_update_bits(priv
->regmap
, CS35L34_PWRCTL1
,
253 dev_err(codec
->dev
, "Cannot set Power bits %d\n", ret
);
256 usleep_range(5000, 5100);
258 case SND_SOC_DAPM_POST_PMD
:
259 if (priv
->tdm_mode
) {
260 regmap_update_bits(priv
->regmap
, CS35L34_PWRCTL3
,
261 CS35L34_PDN_TDM
, CS35L34_PDN_TDM
);
263 ret
= regmap_update_bits(priv
->regmap
, CS35L34_PWRCTL1
,
264 CS35L34_PDN_ALL
, CS35L34_PDN_ALL
);
267 pr_err("Invalid event = 0x%x\n", event
);
272 static int cs35l34_set_tdm_slot(struct snd_soc_dai
*dai
, unsigned int tx_mask
,
273 unsigned int rx_mask
, int slots
, int slot_width
)
275 struct snd_soc_codec
*codec
= dai
->codec
;
276 struct cs35l34_private
*priv
= snd_soc_codec_get_drvdata(codec
);
277 unsigned int reg
, bit_pos
;
283 priv
->tdm_mode
= true;
284 /* scan rx_mask for aud slot */
285 slot
= ffs(rx_mask
) - 1;
287 snd_soc_update_bits(codec
, CS35L34_TDM_RX_CTL_1_AUDIN
,
288 CS35L34_X_LOC
, slot
);
290 /* scan tx_mask: vmon(2 slots); imon (2 slots); vpmon (1 slot)
293 slot
= ffs(tx_mask
) - 1;
296 /* disable vpmon/vbstmon: enable later if set in tx_mask */
297 snd_soc_update_bits(codec
, CS35L34_TDM_TX_CTL_3_VPMON
,
298 CS35L34_X_STATE
| CS35L34_X_LOC
,
299 CS35L34_X_STATE
| CS35L34_X_LOC
);
300 snd_soc_update_bits(codec
, CS35L34_TDM_TX_CTL_4_VBSTMON
,
301 CS35L34_X_STATE
| CS35L34_X_LOC
,
302 CS35L34_X_STATE
| CS35L34_X_LOC
);
304 /* disconnect {vp,vbst}_mon routes: eanble later if set in tx_mask*/
306 /* configure VMON_TX_LOC */
308 snd_soc_update_bits(codec
, CS35L34_TDM_TX_CTL_1_VMON
,
309 CS35L34_X_STATE
| CS35L34_X_LOC
, slot
);
311 /* configure IMON_TX_LOC */
313 snd_soc_update_bits(codec
, CS35L34_TDM_TX_CTL_2_IMON
,
314 CS35L34_X_STATE
| CS35L34_X_LOC
, slot
);
316 /* configure VPMON_TX_LOC */
318 snd_soc_update_bits(codec
, CS35L34_TDM_TX_CTL_3_VPMON
,
319 CS35L34_X_STATE
| CS35L34_X_LOC
, slot
);
321 /* configure VBSTMON_TX_LOC */
323 snd_soc_update_bits(codec
,
324 CS35L34_TDM_TX_CTL_4_VBSTMON
,
325 CS35L34_X_STATE
| CS35L34_X_LOC
, slot
);
328 /* Enable the relevant tx slot */
329 reg
= CS35L34_TDM_TX_SLOT_EN_4
- (slot
/8);
330 bit_pos
= slot
- ((slot
/ 8) * (8));
331 snd_soc_update_bits(codec
, reg
,
332 1 << bit_pos
, 1 << bit_pos
);
334 tx_mask
&= ~(1 << slot
);
335 slot
= ffs(tx_mask
) - 1;
342 static int cs35l34_main_amp_event(struct snd_soc_dapm_widget
*w
,
343 struct snd_kcontrol
*kcontrol
, int event
)
345 struct snd_soc_codec
*codec
= snd_soc_dapm_to_codec(w
->dapm
);
346 struct cs35l34_private
*priv
= snd_soc_codec_get_drvdata(codec
);
349 case SND_SOC_DAPM_POST_PMU
:
350 regmap_update_bits(priv
->regmap
, CS35L34_BST_CVTR_V_CTL
,
351 CS35L34_BST_CVTL_MASK
, priv
->pdata
.boost_vtge
);
352 usleep_range(5000, 5100);
353 regmap_update_bits(priv
->regmap
, CS35L34_PROTECT_CTL
,
356 case SND_SOC_DAPM_POST_PMD
:
357 regmap_update_bits(priv
->regmap
, CS35L34_BST_CVTR_V_CTL
,
358 CS35L34_BST_CVTL_MASK
, 0);
359 regmap_update_bits(priv
->regmap
, CS35L34_PROTECT_CTL
,
360 CS35L34_MUTE
, CS35L34_MUTE
);
361 usleep_range(5000, 5100);
364 pr_err("Invalid event = 0x%x\n", event
);
369 static DECLARE_TLV_DB_SCALE(dig_vol_tlv
, -10200, 50, 0);
371 static DECLARE_TLV_DB_SCALE(amp_gain_tlv
, 300, 100, 0);
374 static const struct snd_kcontrol_new cs35l34_snd_controls
[] = {
375 SOC_SINGLE_SX_TLV("Digital Volume", CS35L34_AMP_DIG_VOL
,
376 0, 0x34, 0xE4, dig_vol_tlv
),
377 SOC_SINGLE_TLV("Amp Gain Volume", CS35L34_AMP_ANLG_GAIN_CTL
,
378 0, 0xF, 0, amp_gain_tlv
),
382 static int cs35l34_mclk_event(struct snd_soc_dapm_widget
*w
,
383 struct snd_kcontrol
*kcontrol
, int event
)
385 struct snd_soc_codec
*codec
= snd_soc_dapm_to_codec(w
->dapm
);
386 struct cs35l34_private
*priv
= snd_soc_codec_get_drvdata(codec
);
391 case SND_SOC_DAPM_PRE_PMD
:
392 ret
= regmap_read(priv
->regmap
, CS35L34_AMP_DIG_VOL_CTL
,
395 pr_err("%s regmap read failure %d\n", __func__
, ret
);
398 if (reg
& CS35L34_AMP_DIGSFT
)
401 usleep_range(2000, 2100);
403 for (i
= 0; i
< PDN_DONE_ATTEMPTS
; i
++) {
404 ret
= regmap_read(priv
->regmap
, CS35L34_INT_STATUS_2
,
407 pr_err("%s regmap read failure %d\n",
411 if (reg
& CS35L34_PDN_DONE
)
414 usleep_range(5000, 5100);
416 if (i
== PDN_DONE_ATTEMPTS
)
417 pr_err("%s Device did not power down properly\n",
421 pr_err("Invalid event = 0x%x\n", event
);
427 static const struct snd_soc_dapm_widget cs35l34_dapm_widgets
[] = {
428 SND_SOC_DAPM_AIF_IN_E("SDIN", NULL
, 0, CS35L34_PWRCTL3
,
429 1, 1, cs35l34_sdin_event
,
430 SND_SOC_DAPM_PRE_PMU
|
431 SND_SOC_DAPM_POST_PMD
),
432 SND_SOC_DAPM_AIF_OUT("SDOUT", NULL
, 0, CS35L34_PWRCTL3
, 2, 1),
434 SND_SOC_DAPM_SUPPLY("EXTCLK", CS35L34_PWRCTL3
, 7, 1,
435 cs35l34_mclk_event
, SND_SOC_DAPM_PRE_PMD
),
437 SND_SOC_DAPM_OUTPUT("SPK"),
439 SND_SOC_DAPM_INPUT("VP"),
440 SND_SOC_DAPM_INPUT("VPST"),
441 SND_SOC_DAPM_INPUT("ISENSE"),
442 SND_SOC_DAPM_INPUT("VSENSE"),
444 SND_SOC_DAPM_ADC("VMON ADC", NULL
, CS35L34_PWRCTL2
, 7, 1),
445 SND_SOC_DAPM_ADC("IMON ADC", NULL
, CS35L34_PWRCTL2
, 6, 1),
446 SND_SOC_DAPM_ADC("VPMON ADC", NULL
, CS35L34_PWRCTL3
, 3, 1),
447 SND_SOC_DAPM_ADC("VBSTMON ADC", NULL
, CS35L34_PWRCTL3
, 4, 1),
448 SND_SOC_DAPM_ADC("CLASS H", NULL
, CS35L34_PWRCTL2
, 5, 1),
449 SND_SOC_DAPM_ADC("BOOST", NULL
, CS35L34_PWRCTL2
, 2, 1),
451 SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L34_PWRCTL2
, 0, 1, NULL
, 0,
452 cs35l34_main_amp_event
, SND_SOC_DAPM_POST_PMU
|
453 SND_SOC_DAPM_POST_PMD
),
456 static const struct snd_soc_dapm_route cs35l34_audio_map
[] = {
457 {"SDIN", NULL
, "AMP Playback"},
458 {"BOOST", NULL
, "SDIN"},
459 {"CLASS H", NULL
, "BOOST"},
460 {"Main AMP", NULL
, "CLASS H"},
461 {"SPK", NULL
, "Main AMP"},
463 {"VPMON ADC", NULL
, "CLASS H"},
464 {"VBSTMON ADC", NULL
, "CLASS H"},
465 {"SPK", NULL
, "VPMON ADC"},
466 {"SPK", NULL
, "VBSTMON ADC"},
468 {"IMON ADC", NULL
, "ISENSE"},
469 {"VMON ADC", NULL
, "VSENSE"},
470 {"SDOUT", NULL
, "IMON ADC"},
471 {"SDOUT", NULL
, "VMON ADC"},
472 {"AMP Capture", NULL
, "SDOUT"},
474 {"SDIN", NULL
, "EXTCLK"},
475 {"SDOUT", NULL
, "EXTCLK"},
478 struct cs35l34_mclk_div
{
484 static struct cs35l34_mclk_div cs35l34_mclk_coeffs
[] = {
486 /* MCLK, Sample Rate, adsp_rate */
488 {5644800, 11025, 0x1},
489 {5644800, 22050, 0x4},
490 {5644800, 44100, 0x7},
492 {6000000, 8000, 0x0},
493 {6000000, 11025, 0x1},
494 {6000000, 12000, 0x2},
495 {6000000, 16000, 0x3},
496 {6000000, 22050, 0x4},
497 {6000000, 24000, 0x5},
498 {6000000, 32000, 0x6},
499 {6000000, 44100, 0x7},
500 {6000000, 48000, 0x8},
502 {6144000, 8000, 0x0},
503 {6144000, 11025, 0x1},
504 {6144000, 12000, 0x2},
505 {6144000, 16000, 0x3},
506 {6144000, 22050, 0x4},
507 {6144000, 24000, 0x5},
508 {6144000, 32000, 0x6},
509 {6144000, 44100, 0x7},
510 {6144000, 48000, 0x8},
513 static int cs35l34_get_mclk_coeff(int mclk
, int srate
)
517 for (i
= 0; i
< ARRAY_SIZE(cs35l34_mclk_coeffs
); i
++) {
518 if (cs35l34_mclk_coeffs
[i
].mclk
== mclk
&&
519 cs35l34_mclk_coeffs
[i
].srate
== srate
)
525 static int cs35l34_set_dai_fmt(struct snd_soc_dai
*codec_dai
, unsigned int fmt
)
527 struct snd_soc_codec
*codec
= codec_dai
->codec
;
528 struct cs35l34_private
*priv
= snd_soc_codec_get_drvdata(codec
);
530 switch (fmt
& SND_SOC_DAIFMT_MASTER_MASK
) {
531 case SND_SOC_DAIFMT_CBM_CFM
:
532 regmap_update_bits(priv
->regmap
, CS35L34_ADSP_CLK_CTL
,
535 case SND_SOC_DAIFMT_CBS_CFS
:
536 regmap_update_bits(priv
->regmap
, CS35L34_ADSP_CLK_CTL
,
545 static int cs35l34_pcm_hw_params(struct snd_pcm_substream
*substream
,
546 struct snd_pcm_hw_params
*params
,
547 struct snd_soc_dai
*dai
)
549 struct snd_soc_codec
*codec
= dai
->codec
;
550 struct cs35l34_private
*priv
= snd_soc_codec_get_drvdata(codec
);
551 int srate
= params_rate(params
);
554 int coeff
= cs35l34_get_mclk_coeff(priv
->mclk_int
, srate
);
557 dev_err(codec
->dev
, "ERROR: Invalid mclk %d and/or srate %d\n",
558 priv
->mclk_int
, srate
);
562 ret
= regmap_update_bits(priv
->regmap
, CS35L34_ADSP_CLK_CTL
,
563 CS35L34_ADSP_RATE
, cs35l34_mclk_coeffs
[coeff
].adsp_rate
);
565 dev_err(codec
->dev
, "Failed to set clock state %d\n", ret
);
570 static unsigned int cs35l34_src_rates
[] = {
571 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
575 static struct snd_pcm_hw_constraint_list cs35l34_constraints
= {
576 .count
= ARRAY_SIZE(cs35l34_src_rates
),
577 .list
= cs35l34_src_rates
,
580 static int cs35l34_pcm_startup(struct snd_pcm_substream
*substream
,
581 struct snd_soc_dai
*dai
)
584 snd_pcm_hw_constraint_list(substream
->runtime
, 0,
585 SNDRV_PCM_HW_PARAM_RATE
, &cs35l34_constraints
);
590 static int cs35l34_set_tristate(struct snd_soc_dai
*dai
, int tristate
)
593 struct snd_soc_codec
*codec
= dai
->codec
;
596 snd_soc_update_bits(codec
, CS35L34_PWRCTL3
,
597 CS35L34_PDN_SDOUT
, CS35L34_PDN_SDOUT
);
599 snd_soc_update_bits(codec
, CS35L34_PWRCTL3
,
600 CS35L34_PDN_SDOUT
, 0);
604 static int cs35l34_dai_set_sysclk(struct snd_soc_dai
*dai
,
605 int clk_id
, unsigned int freq
, int dir
)
607 struct snd_soc_codec
*codec
= dai
->codec
;
608 struct cs35l34_private
*cs35l34
= snd_soc_codec_get_drvdata(codec
);
612 case CS35L34_MCLK_5644
:
613 value
= CS35L34_MCLK_RATE_5P6448
;
614 cs35l34
->mclk_int
= freq
;
617 value
= CS35L34_MCLK_RATE_6P0000
;
618 cs35l34
->mclk_int
= freq
;
620 case CS35L34_MCLK_6144
:
621 value
= CS35L34_MCLK_RATE_6P1440
;
622 cs35l34
->mclk_int
= freq
;
624 case CS35L34_MCLK_11289
:
625 value
= CS35L34_MCLK_DIV
| CS35L34_MCLK_RATE_5P6448
;
626 cs35l34
->mclk_int
= freq
/ 2;
628 case CS35L34_MCLK_12
:
629 value
= CS35L34_MCLK_DIV
| CS35L34_MCLK_RATE_6P0000
;
630 cs35l34
->mclk_int
= freq
/ 2;
632 case CS35L34_MCLK_12288
:
633 value
= CS35L34_MCLK_DIV
| CS35L34_MCLK_RATE_6P1440
;
634 cs35l34
->mclk_int
= freq
/ 2;
637 dev_err(codec
->dev
, "ERROR: Invalid Frequency %d\n", freq
);
638 cs35l34
->mclk_int
= 0;
641 regmap_update_bits(cs35l34
->regmap
, CS35L34_MCLK_CTL
,
642 CS35L34_MCLK_DIV
| CS35L34_MCLK_RATE_MASK
, value
);
646 static const struct snd_soc_dai_ops cs35l34_ops
= {
647 .startup
= cs35l34_pcm_startup
,
648 .set_tristate
= cs35l34_set_tristate
,
649 .set_fmt
= cs35l34_set_dai_fmt
,
650 .hw_params
= cs35l34_pcm_hw_params
,
651 .set_sysclk
= cs35l34_dai_set_sysclk
,
652 .set_tdm_slot
= cs35l34_set_tdm_slot
,
655 static struct snd_soc_dai_driver cs35l34_dai
= {
659 .stream_name
= "AMP Playback",
662 .rates
= CS35L34_RATES
,
663 .formats
= CS35L34_FORMATS
,
666 .stream_name
= "AMP Capture",
669 .rates
= CS35L34_RATES
,
670 .formats
= CS35L34_FORMATS
,
673 .symmetric_rates
= 1,
676 static int cs35l34_boost_inductor(struct cs35l34_private
*cs35l34
,
677 unsigned int inductor
)
679 struct snd_soc_codec
*codec
= cs35l34
->codec
;
682 case 1000: /* 1 uH */
683 regmap_write(cs35l34
->regmap
, CS35L34_BST_CONV_COEF_1
, 0x24);
684 regmap_write(cs35l34
->regmap
, CS35L34_BST_CONV_COEF_2
, 0x24);
685 regmap_write(cs35l34
->regmap
, CS35L34_BST_CONV_SLOPE_COMP
,
687 regmap_write(cs35l34
->regmap
, CS35L34_BST_CONV_SW_FREQ
, 0);
689 case 1200: /* 1.2 uH */
690 regmap_write(cs35l34
->regmap
, CS35L34_BST_CONV_COEF_1
, 0x20);
691 regmap_write(cs35l34
->regmap
, CS35L34_BST_CONV_COEF_2
, 0x20);
692 regmap_write(cs35l34
->regmap
, CS35L34_BST_CONV_SLOPE_COMP
,
694 regmap_write(cs35l34
->regmap
, CS35L34_BST_CONV_SW_FREQ
, 1);
696 case 1500: /* 1.5uH */
697 regmap_write(cs35l34
->regmap
, CS35L34_BST_CONV_COEF_1
, 0x20);
698 regmap_write(cs35l34
->regmap
, CS35L34_BST_CONV_COEF_2
, 0x20);
699 regmap_write(cs35l34
->regmap
, CS35L34_BST_CONV_SLOPE_COMP
,
701 regmap_write(cs35l34
->regmap
, CS35L34_BST_CONV_SW_FREQ
, 2);
703 case 2200: /* 2.2uH */
704 regmap_write(cs35l34
->regmap
, CS35L34_BST_CONV_COEF_1
, 0x19);
705 regmap_write(cs35l34
->regmap
, CS35L34_BST_CONV_COEF_2
, 0x25);
706 regmap_write(cs35l34
->regmap
, CS35L34_BST_CONV_SLOPE_COMP
,
708 regmap_write(cs35l34
->regmap
, CS35L34_BST_CONV_SW_FREQ
, 3);
711 dev_err(codec
->dev
, "%s Invalid Inductor Value %d uH\n",
718 static int cs35l34_probe(struct snd_soc_codec
*codec
)
721 struct cs35l34_private
*cs35l34
= snd_soc_codec_get_drvdata(codec
);
723 pm_runtime_get_sync(codec
->dev
);
725 /* Set over temperature warning attenuation to 6 dB */
726 regmap_update_bits(cs35l34
->regmap
, CS35L34_PROTECT_CTL
,
727 CS35L34_OTW_ATTN_MASK
, 0x8);
729 /* Set Power control registers 2 and 3 to have everything
730 * powered down at initialization
732 regmap_write(cs35l34
->regmap
, CS35L34_PWRCTL2
, 0xFD);
733 regmap_write(cs35l34
->regmap
, CS35L34_PWRCTL3
, 0x1F);
735 /* Set mute bit at startup */
736 regmap_update_bits(cs35l34
->regmap
, CS35L34_PROTECT_CTL
,
737 CS35L34_MUTE
, CS35L34_MUTE
);
739 /* Set Platform Data */
740 if (cs35l34
->pdata
.boost_peak
)
741 regmap_update_bits(cs35l34
->regmap
, CS35L34_BST_PEAK_I
,
742 CS35L34_BST_PEAK_MASK
,
743 cs35l34
->pdata
.boost_peak
);
745 if (cs35l34
->pdata
.gain_zc_disable
)
746 regmap_update_bits(cs35l34
->regmap
, CS35L34_PROTECT_CTL
,
747 CS35L34_GAIN_ZC_MASK
, 0);
749 regmap_update_bits(cs35l34
->regmap
, CS35L34_PROTECT_CTL
,
750 CS35L34_GAIN_ZC_MASK
, CS35L34_GAIN_ZC_MASK
);
752 if (cs35l34
->pdata
.aif_half_drv
)
753 regmap_update_bits(cs35l34
->regmap
, CS35L34_ADSP_CLK_CTL
,
754 CS35L34_ADSP_DRIVE
, 0);
756 if (cs35l34
->pdata
.digsft_disable
)
757 regmap_update_bits(cs35l34
->regmap
, CS35L34_AMP_DIG_VOL_CTL
,
758 CS35L34_AMP_DIGSFT
, 0);
760 if (cs35l34
->pdata
.amp_inv
)
761 regmap_update_bits(cs35l34
->regmap
, CS35L34_AMP_DIG_VOL_CTL
,
762 CS35L34_INV
, CS35L34_INV
);
764 if (cs35l34
->pdata
.boost_ind
)
765 ret
= cs35l34_boost_inductor(cs35l34
, cs35l34
->pdata
.boost_ind
);
767 if (cs35l34
->pdata
.i2s_sdinloc
)
768 regmap_update_bits(cs35l34
->regmap
, CS35L34_ADSP_I2S_CTL
,
769 CS35L34_I2S_LOC_MASK
,
770 cs35l34
->pdata
.i2s_sdinloc
<< CS35L34_I2S_LOC_SHIFT
);
772 if (cs35l34
->pdata
.tdm_rising_edge
)
773 regmap_update_bits(cs35l34
->regmap
, CS35L34_ADSP_TDM_CTL
,
776 pm_runtime_put_sync(codec
->dev
);
782 static struct snd_soc_codec_driver soc_codec_dev_cs35l34
= {
783 .probe
= cs35l34_probe
,
785 .component_driver
= {
786 .dapm_widgets
= cs35l34_dapm_widgets
,
787 .num_dapm_widgets
= ARRAY_SIZE(cs35l34_dapm_widgets
),
788 .dapm_routes
= cs35l34_audio_map
,
789 .num_dapm_routes
= ARRAY_SIZE(cs35l34_audio_map
),
790 .controls
= cs35l34_snd_controls
,
791 .num_controls
= ARRAY_SIZE(cs35l34_snd_controls
),
795 static struct regmap_config cs35l34_regmap
= {
799 .max_register
= CS35L34_MAX_REGISTER
,
800 .reg_defaults
= cs35l34_reg
,
801 .num_reg_defaults
= ARRAY_SIZE(cs35l34_reg
),
802 .volatile_reg
= cs35l34_volatile_register
,
803 .readable_reg
= cs35l34_readable_register
,
804 .precious_reg
= cs35l34_precious_register
,
805 .cache_type
= REGCACHE_RBTREE
,
808 static int cs35l34_handle_of_data(struct i2c_client
*i2c_client
,
809 struct cs35l34_platform_data
*pdata
)
811 struct device_node
*np
= i2c_client
->dev
.of_node
;
814 if (of_property_read_u32(np
, "cirrus,boost-vtge-millivolt",
816 /* Boost Voltage has a maximum of 8V */
817 if (val
> 8000 || (val
< 3300 && val
> 0)) {
818 dev_err(&i2c_client
->dev
,
819 "Invalid Boost Voltage %d mV\n", val
);
823 pdata
->boost_vtge
= 0; /* Use VP */
825 pdata
->boost_vtge
= ((val
- 3300)/100) + 1;
827 dev_warn(&i2c_client
->dev
,
828 "Boost Voltage not specified. Using VP\n");
831 if (of_property_read_u32(np
, "cirrus,boost-ind-nanohenry", &val
) >= 0) {
832 pdata
->boost_ind
= val
;
834 dev_err(&i2c_client
->dev
, "Inductor not specified.\n");
838 if (of_property_read_u32(np
, "cirrus,boost-peak-milliamp", &val
) >= 0) {
839 if (val
> 3840 || val
< 1200) {
840 dev_err(&i2c_client
->dev
,
841 "Invalid Boost Peak Current %d mA\n", val
);
844 pdata
->boost_peak
= ((val
- 1200)/80) + 1;
847 pdata
->aif_half_drv
= of_property_read_bool(np
,
848 "cirrus,aif-half-drv");
849 pdata
->digsft_disable
= of_property_read_bool(np
,
850 "cirrus,digsft-disable");
852 pdata
->gain_zc_disable
= of_property_read_bool(np
,
853 "cirrus,gain-zc-disable");
854 pdata
->amp_inv
= of_property_read_bool(np
, "cirrus,amp-inv");
856 if (of_property_read_u32(np
, "cirrus,i2s-sdinloc", &val
) >= 0)
857 pdata
->i2s_sdinloc
= val
;
858 if (of_property_read_u32(np
, "cirrus,tdm-rising-edge", &val
) >= 0)
859 pdata
->tdm_rising_edge
= val
;
864 static irqreturn_t
cs35l34_irq_thread(int irq
, void *data
)
866 struct cs35l34_private
*cs35l34
= data
;
867 struct snd_soc_codec
*codec
= cs35l34
->codec
;
868 unsigned int sticky1
, sticky2
, sticky3
, sticky4
;
869 unsigned int mask1
, mask2
, mask3
, mask4
, current1
;
872 /* ack the irq by reading all status registers */
873 regmap_read(cs35l34
->regmap
, CS35L34_INT_STATUS_4
, &sticky4
);
874 regmap_read(cs35l34
->regmap
, CS35L34_INT_STATUS_3
, &sticky3
);
875 regmap_read(cs35l34
->regmap
, CS35L34_INT_STATUS_2
, &sticky2
);
876 regmap_read(cs35l34
->regmap
, CS35L34_INT_STATUS_1
, &sticky1
);
878 regmap_read(cs35l34
->regmap
, CS35L34_INT_MASK_4
, &mask4
);
879 regmap_read(cs35l34
->regmap
, CS35L34_INT_MASK_3
, &mask3
);
880 regmap_read(cs35l34
->regmap
, CS35L34_INT_MASK_2
, &mask2
);
881 regmap_read(cs35l34
->regmap
, CS35L34_INT_MASK_1
, &mask1
);
883 if (!(sticky1
& ~mask1
) && !(sticky2
& ~mask2
) && !(sticky3
& ~mask3
)
884 && !(sticky4
& ~mask4
))
887 regmap_read(cs35l34
->regmap
, CS35L34_INT_STATUS_1
, ¤t1
);
889 if (sticky1
& CS35L34_CAL_ERR
) {
890 dev_err(codec
->dev
, "Cal error\n");
892 /* error is no longer asserted; safe to reset */
893 if (!(current1
& CS35L34_CAL_ERR
)) {
894 dev_dbg(codec
->dev
, "Cal error release\n");
895 regmap_update_bits(cs35l34
->regmap
,
896 CS35L34_PROT_RELEASE_CTL
,
897 CS35L34_CAL_ERR_RLS
, 0);
898 regmap_update_bits(cs35l34
->regmap
,
899 CS35L34_PROT_RELEASE_CTL
,
901 CS35L34_CAL_ERR_RLS
);
902 regmap_update_bits(cs35l34
->regmap
,
903 CS35L34_PROT_RELEASE_CTL
,
904 CS35L34_CAL_ERR_RLS
, 0);
905 /* note: amp will re-calibrate on next resume */
909 if (sticky1
& CS35L34_ALIVE_ERR
)
910 dev_err(codec
->dev
, "Alive error\n");
912 if (sticky1
& CS35L34_AMP_SHORT
) {
913 dev_crit(codec
->dev
, "Amp short error\n");
915 /* error is no longer asserted; safe to reset */
916 if (!(current1
& CS35L34_AMP_SHORT
)) {
918 "Amp short error release\n");
919 regmap_update_bits(cs35l34
->regmap
,
920 CS35L34_PROT_RELEASE_CTL
,
921 CS35L34_SHORT_RLS
, 0);
922 regmap_update_bits(cs35l34
->regmap
,
923 CS35L34_PROT_RELEASE_CTL
,
926 regmap_update_bits(cs35l34
->regmap
,
927 CS35L34_PROT_RELEASE_CTL
,
928 CS35L34_SHORT_RLS
, 0);
932 if (sticky1
& CS35L34_OTW
) {
933 dev_crit(codec
->dev
, "Over temperature warning\n");
935 /* error is no longer asserted; safe to reset */
936 if (!(current1
& CS35L34_OTW
)) {
938 "Over temperature warning release\n");
939 regmap_update_bits(cs35l34
->regmap
,
940 CS35L34_PROT_RELEASE_CTL
,
942 regmap_update_bits(cs35l34
->regmap
,
943 CS35L34_PROT_RELEASE_CTL
,
946 regmap_update_bits(cs35l34
->regmap
,
947 CS35L34_PROT_RELEASE_CTL
,
952 if (sticky1
& CS35L34_OTE
) {
953 dev_crit(codec
->dev
, "Over temperature error\n");
955 /* error is no longer asserted; safe to reset */
956 if (!(current1
& CS35L34_OTE
)) {
958 "Over temperature error release\n");
959 regmap_update_bits(cs35l34
->regmap
,
960 CS35L34_PROT_RELEASE_CTL
,
962 regmap_update_bits(cs35l34
->regmap
,
963 CS35L34_PROT_RELEASE_CTL
,
966 regmap_update_bits(cs35l34
->regmap
,
967 CS35L34_PROT_RELEASE_CTL
,
972 if (sticky3
& CS35L34_BST_HIGH
) {
973 dev_crit(codec
->dev
, "VBST too high error; powering off!\n");
974 regmap_update_bits(cs35l34
->regmap
, CS35L34_PWRCTL2
,
975 CS35L34_PDN_AMP
, CS35L34_PDN_AMP
);
976 regmap_update_bits(cs35l34
->regmap
, CS35L34_PWRCTL1
,
977 CS35L34_PDN_ALL
, CS35L34_PDN_ALL
);
980 if (sticky3
& CS35L34_LBST_SHORT
) {
981 dev_crit(codec
->dev
, "LBST short error; powering off!\n");
982 regmap_update_bits(cs35l34
->regmap
, CS35L34_PWRCTL2
,
983 CS35L34_PDN_AMP
, CS35L34_PDN_AMP
);
984 regmap_update_bits(cs35l34
->regmap
, CS35L34_PWRCTL1
,
985 CS35L34_PDN_ALL
, CS35L34_PDN_ALL
);
991 static const char * const cs35l34_core_supplies
[] = {
996 static int cs35l34_i2c_probe(struct i2c_client
*i2c_client
,
997 const struct i2c_device_id
*id
)
999 struct cs35l34_private
*cs35l34
;
1000 struct cs35l34_platform_data
*pdata
=
1001 dev_get_platdata(&i2c_client
->dev
);
1004 unsigned int devid
= 0;
1007 cs35l34
= devm_kzalloc(&i2c_client
->dev
,
1008 sizeof(struct cs35l34_private
),
1011 dev_err(&i2c_client
->dev
, "could not allocate codec\n");
1015 i2c_set_clientdata(i2c_client
, cs35l34
);
1016 cs35l34
->regmap
= devm_regmap_init_i2c(i2c_client
, &cs35l34_regmap
);
1017 if (IS_ERR(cs35l34
->regmap
)) {
1018 ret
= PTR_ERR(cs35l34
->regmap
);
1019 dev_err(&i2c_client
->dev
, "regmap_init() failed: %d\n", ret
);
1023 cs35l34
->num_core_supplies
= ARRAY_SIZE(cs35l34_core_supplies
);
1024 for (i
= 0; i
< ARRAY_SIZE(cs35l34_core_supplies
); i
++)
1025 cs35l34
->core_supplies
[i
].supply
= cs35l34_core_supplies
[i
];
1027 ret
= devm_regulator_bulk_get(&i2c_client
->dev
,
1028 cs35l34
->num_core_supplies
,
1029 cs35l34
->core_supplies
);
1031 dev_err(&i2c_client
->dev
,
1032 "Failed to request core supplies %d\n", ret
);
1036 ret
= regulator_bulk_enable(cs35l34
->num_core_supplies
,
1037 cs35l34
->core_supplies
);
1039 dev_err(&i2c_client
->dev
,
1040 "Failed to enable core supplies: %d\n", ret
);
1045 cs35l34
->pdata
= *pdata
;
1047 pdata
= devm_kzalloc(&i2c_client
->dev
,
1048 sizeof(struct cs35l34_platform_data
),
1051 dev_err(&i2c_client
->dev
,
1052 "could not allocate pdata\n");
1055 if (i2c_client
->dev
.of_node
) {
1056 ret
= cs35l34_handle_of_data(i2c_client
, pdata
);
1061 cs35l34
->pdata
= *pdata
;
1064 ret
= devm_request_threaded_irq(&i2c_client
->dev
, i2c_client
->irq
, NULL
,
1065 cs35l34_irq_thread
, IRQF_ONESHOT
| IRQF_TRIGGER_LOW
,
1066 "cs35l34", cs35l34
);
1068 dev_err(&i2c_client
->dev
, "Failed to request IRQ: %d\n", ret
);
1070 cs35l34
->reset_gpio
= devm_gpiod_get_optional(&i2c_client
->dev
,
1071 "reset-gpios", GPIOD_OUT_LOW
);
1072 if (IS_ERR(cs35l34
->reset_gpio
))
1073 return PTR_ERR(cs35l34
->reset_gpio
);
1075 gpiod_set_value_cansleep(cs35l34
->reset_gpio
, 1);
1077 msleep(CS35L34_START_DELAY
);
1079 ret
= regmap_read(cs35l34
->regmap
, CS35L34_DEVID_AB
, ®
);
1081 devid
= (reg
& 0xFF) << 12;
1082 ret
= regmap_read(cs35l34
->regmap
, CS35L34_DEVID_CD
, ®
);
1083 devid
|= (reg
& 0xFF) << 4;
1084 ret
= regmap_read(cs35l34
->regmap
, CS35L34_DEVID_E
, ®
);
1085 devid
|= (reg
& 0xF0) >> 4;
1087 if (devid
!= CS35L34_CHIP_ID
) {
1088 dev_err(&i2c_client
->dev
,
1089 "CS35l34 Device ID (%X). Expected ID %X\n",
1090 devid
, CS35L34_CHIP_ID
);
1095 ret
= regmap_read(cs35l34
->regmap
, CS35L34_REV_ID
, ®
);
1097 dev_err(&i2c_client
->dev
, "Get Revision ID failed\n");
1101 dev_info(&i2c_client
->dev
,
1102 "Cirrus Logic CS35l34 (%x), Revision: %02X\n", devid
,
1105 /* Unmask critical interrupts */
1106 regmap_update_bits(cs35l34
->regmap
, CS35L34_INT_MASK_1
,
1107 CS35L34_M_CAL_ERR
| CS35L34_M_ALIVE_ERR
|
1108 CS35L34_M_AMP_SHORT
| CS35L34_M_OTW
|
1110 regmap_update_bits(cs35l34
->regmap
, CS35L34_INT_MASK_3
,
1111 CS35L34_M_BST_HIGH
| CS35L34_M_LBST_SHORT
, 0);
1113 pm_runtime_set_autosuspend_delay(&i2c_client
->dev
, 100);
1114 pm_runtime_use_autosuspend(&i2c_client
->dev
);
1115 pm_runtime_set_active(&i2c_client
->dev
);
1116 pm_runtime_enable(&i2c_client
->dev
);
1118 ret
= snd_soc_register_codec(&i2c_client
->dev
,
1119 &soc_codec_dev_cs35l34
, &cs35l34_dai
, 1);
1121 dev_err(&i2c_client
->dev
,
1122 "%s: Register codec failed\n", __func__
);
1129 regulator_bulk_disable(cs35l34
->num_core_supplies
,
1130 cs35l34
->core_supplies
);
1135 static int cs35l34_i2c_remove(struct i2c_client
*client
)
1137 struct cs35l34_private
*cs35l34
= i2c_get_clientdata(client
);
1139 snd_soc_unregister_codec(&client
->dev
);
1141 if (cs35l34
->reset_gpio
)
1142 gpiod_set_value_cansleep(cs35l34
->reset_gpio
, 0);
1144 pm_runtime_disable(&client
->dev
);
1145 regulator_bulk_disable(cs35l34
->num_core_supplies
,
1146 cs35l34
->core_supplies
);
1151 static int __maybe_unused
cs35l34_runtime_resume(struct device
*dev
)
1153 struct cs35l34_private
*cs35l34
= dev_get_drvdata(dev
);
1156 ret
= regulator_bulk_enable(cs35l34
->num_core_supplies
,
1157 cs35l34
->core_supplies
);
1160 dev_err(dev
, "Failed to enable core supplies: %d\n",
1165 regcache_cache_only(cs35l34
->regmap
, false);
1167 gpiod_set_value_cansleep(cs35l34
->reset_gpio
, 1);
1168 msleep(CS35L34_START_DELAY
);
1170 ret
= regcache_sync(cs35l34
->regmap
);
1172 dev_err(dev
, "Failed to restore register cache\n");
1177 regcache_cache_only(cs35l34
->regmap
, true);
1178 regulator_bulk_disable(cs35l34
->num_core_supplies
,
1179 cs35l34
->core_supplies
);
1184 static int __maybe_unused
cs35l34_runtime_suspend(struct device
*dev
)
1186 struct cs35l34_private
*cs35l34
= dev_get_drvdata(dev
);
1188 regcache_cache_only(cs35l34
->regmap
, true);
1189 regcache_mark_dirty(cs35l34
->regmap
);
1191 gpiod_set_value_cansleep(cs35l34
->reset_gpio
, 0);
1193 regulator_bulk_disable(cs35l34
->num_core_supplies
,
1194 cs35l34
->core_supplies
);
1199 static const struct dev_pm_ops cs35l34_pm_ops
= {
1200 SET_RUNTIME_PM_OPS(cs35l34_runtime_suspend
,
1201 cs35l34_runtime_resume
,
1205 static const struct of_device_id cs35l34_of_match
[] = {
1206 {.compatible
= "cirrus,cs35l34"},
1209 MODULE_DEVICE_TABLE(of
, cs35l34_of_match
);
1211 static const struct i2c_device_id cs35l34_id
[] = {
1215 MODULE_DEVICE_TABLE(i2c
, cs35l34_id
);
1217 static struct i2c_driver cs35l34_i2c_driver
= {
1220 .pm
= &cs35l34_pm_ops
,
1221 .of_match_table
= cs35l34_of_match
,
1224 .id_table
= cs35l34_id
,
1225 .probe
= cs35l34_i2c_probe
,
1226 .remove
= cs35l34_i2c_remove
,
1230 static int __init
cs35l34_modinit(void)
1234 ret
= i2c_add_driver(&cs35l34_i2c_driver
);
1236 pr_err("Failed to register CS35l34 I2C driver: %d\n", ret
);
1241 module_init(cs35l34_modinit
);
1243 static void __exit
cs35l34_exit(void)
1245 i2c_del_driver(&cs35l34_i2c_driver
);
1247 module_exit(cs35l34_exit
);
1249 MODULE_DESCRIPTION("ASoC CS35l34 driver");
1250 MODULE_AUTHOR("Paul Handrigan, Cirrus Logic Inc, <Paul.Handrigan@cirrus.com>");
1251 MODULE_LICENSE("GPL");