1 // SPDX-License-Identifier: GPL-2.0-only
3 * cs42l84.c -- CS42L84 ALSA SoC audio driver
5 * Copyright (C) The Asahi Linux Contributors
7 * Based on sound/soc/codecs/cs42l42{.c,.h}
8 * Copyright 2016 Cirrus Logic, Inc.
11 #include <linux/bitfield.h>
12 #include <linux/bits.h>
13 #include <linux/module.h>
14 #include <linux/moduleparam.h>
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/delay.h>
18 #include <linux/i2c.h>
19 #include <linux/gpio.h>
20 #include <linux/regmap.h>
21 #include <linux/slab.h>
22 #include <linux/acpi.h>
23 #include <linux/platform_device.h>
24 #include <linux/property.h>
25 #include <linux/regulator/consumer.h>
26 #include <linux/gpio/consumer.h>
27 #include <linux/of_device.h>
28 #include <sound/core.h>
29 #include <sound/jack.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 <sound/initval.h>
35 #include <sound/tlv.h>
38 #include "cirrus_legacy.h"
40 struct cs42l84_private
{
41 struct regmap
*regmap
;
43 struct gpio_desc
*reset_gpio
;
44 struct snd_soc_jack
*jack
;
45 struct mutex irq_lock
;
56 static bool cs42l84_volatile_register(struct device
*dev
, unsigned int reg
)
59 case CS42L84_DEVID
... CS42L84_DEVID
+5:
60 case CS42L84_TSRS_PLUG_INT_STATUS
:
61 case CS42L84_PLL_LOCK_STATUS
:
62 case CS42L84_TSRS_PLUG_STATUS
:
63 case CS42L84_HS_DET_STATUS2
:
70 static const struct regmap_config cs42l84_regmap
= {
74 .volatile_reg
= cs42l84_volatile_register
,
76 .max_register
= 0x73fe,
78 .cache_type
= REGCACHE_MAPLE
,
80 .use_single_read
= true,
81 .use_single_write
= true,
84 static int cs42l84_put_dac_vol(struct snd_kcontrol
*kctl
,
85 struct snd_ctl_elem_value
*val
)
87 struct snd_soc_component
*component
= snd_soc_kcontrol_component(kctl
);
88 struct soc_mixer_control
*mc
= (struct soc_mixer_control
*) kctl
->private_value
;
90 int ret
, ret2
, updated
= 0;
92 vola
= val
->value
.integer
.value
[0] + mc
->min
;
93 volb
= val
->value
.integer
.value
[1] + mc
->min
;
95 if (vola
< mc
->min
|| vola
> mc
->max
|| volb
< mc
->min
|| volb
> mc
->max
)
98 ret
= snd_soc_component_update_bits(component
, CS42L84_FRZ_CTL
,
99 CS42L84_FRZ_CTL_ENGAGE
,
100 CS42L84_FRZ_CTL_ENGAGE
);
105 ret
= snd_soc_component_update_bits(component
, CS42L84_DAC_CHA_VOL_LSB
,
111 ret
= snd_soc_component_update_bits(component
, CS42L84_DAC_CHA_VOL_MSB
,
112 0xff, (vola
>> 8) & 0x01);
117 ret
= snd_soc_component_update_bits(component
, CS42L84_DAC_CHB_VOL_LSB
,
123 ret
= snd_soc_component_update_bits(component
, CS42L84_DAC_CHB_VOL_MSB
,
124 0xff, (volb
>> 8) & 0x01);
130 ret2
= snd_soc_component_update_bits(component
, CS42L84_FRZ_CTL
,
131 CS42L84_FRZ_CTL_ENGAGE
, 0);
132 if (ret2
< 0 && ret
>= 0)
138 static int cs42l84_get_dac_vol(struct snd_kcontrol
*kctl
,
139 struct snd_ctl_elem_value
*val
)
141 struct snd_soc_component
*component
= snd_soc_kcontrol_component(kctl
);
142 struct soc_mixer_control
*mc
= (struct soc_mixer_control
*) kctl
->private_value
;
146 ret
= snd_soc_component_read(component
, CS42L84_DAC_CHA_VOL_LSB
);
151 ret
= snd_soc_component_read(component
, CS42L84_DAC_CHA_VOL_MSB
);
154 vola
|= (ret
& 1) << 8;
156 ret
= snd_soc_component_read(component
, CS42L84_DAC_CHB_VOL_LSB
);
161 ret
= snd_soc_component_read(component
, CS42L84_DAC_CHB_VOL_MSB
);
164 volb
|= (ret
& 1) << 8;
167 vola
|= ~((int)(BIT(8) - 1));
169 volb
|= ~((int)(BIT(8) - 1));
171 val
->value
.integer
.value
[0] = vola
- mc
->min
;
172 val
->value
.integer
.value
[1] = volb
- mc
->min
;
177 static const DECLARE_TLV_DB_SCALE(cs42l84_dac_tlv
, -12800, 50, true);
178 static const DECLARE_TLV_DB_SCALE(cs42l84_adc_tlv
, -1200, 50, false);
179 static const DECLARE_TLV_DB_SCALE(cs42l84_pre_tlv
, 0, 1000, false);
181 static const struct snd_kcontrol_new cs42l84_snd_controls
[] = {
182 SOC_DOUBLE_R_S_EXT_TLV("DAC Playback Volume", CS42L84_DAC_CHA_VOL_LSB
,
183 CS42L84_DAC_CHB_VOL_LSB
, 0, -256, 24, 8, 0,
184 cs42l84_get_dac_vol
, cs42l84_put_dac_vol
, cs42l84_dac_tlv
),
185 SOC_SINGLE_TLV("ADC Preamp Capture Volume", CS42L84_ADC_CTL1
,
186 CS42L84_ADC_CTL1_PREAMP_GAIN_SHIFT
, 2, 0, cs42l84_pre_tlv
),
187 SOC_SINGLE_TLV("ADC PGA Capture Volume", CS42L84_ADC_CTL1
,
188 CS42L84_ADC_CTL1_PGA_GAIN_SHIFT
, 24, 0, cs42l84_adc_tlv
),
189 SOC_SINGLE("ADC WNF Switch", CS42L84_ADC_CTL4
,
190 CS42L84_ADC_CTL4_WNF_EN_SHIFT
, 1, 0),
191 SOC_SINGLE("WNF Corner Frequency", CS42L84_ADC_CTL4
,
192 CS42L84_ADC_CTL4_WNF_CF_SHIFT
, 3, 0),
193 SOC_SINGLE("ADC HPF Switch", CS42L84_ADC_CTL4
,
194 CS42L84_ADC_CTL4_HPF_EN_SHIFT
, 1, 0),
195 SOC_SINGLE("HPF Corner Frequency", CS42L84_ADC_CTL4
,
196 CS42L84_ADC_CTL4_HPF_CF_SHIFT
, 3, 0),
199 static const char * const cs42l84_mux_text
[] = {
200 "Blank", "ADC", "ASP RX CH1", "ASP RX CH2",
203 static const unsigned int cs42l84_mux_values
[] = {
204 0b0000, 0b0111, 0b1101, 0b1110,
207 static SOC_VALUE_ENUM_SINGLE_DECL(cs42l84_daca_mux_enum
,
208 CS42L84_BUS_DAC_SRC
, CS42L84_BUS_DAC_SRC_DACA_SHIFT
,
209 0b1111, cs42l84_mux_text
, cs42l84_mux_values
);
211 static SOC_VALUE_ENUM_SINGLE_DECL(cs42l84_dacb_mux_enum
,
212 CS42L84_BUS_DAC_SRC
, CS42L84_BUS_DAC_SRC_DACB_SHIFT
,
213 0b1111, cs42l84_mux_text
, cs42l84_mux_values
);
215 static SOC_VALUE_ENUM_SINGLE_DECL(cs42l84_sdout1_mux_enum
,
216 CS42L84_BUS_ASP_TX_SRC
, CS42L84_BUS_ASP_TX_SRC_CH1_SHIFT
,
217 0b1111, cs42l84_mux_text
, cs42l84_mux_values
);
219 static const struct snd_kcontrol_new cs42l84_daca_mux_ctrl
=
220 SOC_DAPM_ENUM("DACA Select", cs42l84_daca_mux_enum
);
222 static const struct snd_kcontrol_new cs42l84_dacb_mux_ctrl
=
223 SOC_DAPM_ENUM("DACB Select", cs42l84_dacb_mux_enum
);
225 static const struct snd_kcontrol_new cs42l84_sdout1_mux_ctrl
=
226 SOC_DAPM_ENUM("SDOUT1 Select", cs42l84_sdout1_mux_enum
);
228 static const struct snd_soc_dapm_widget cs42l84_dapm_widgets
[] = {
230 SND_SOC_DAPM_OUTPUT("HP"),
231 SND_SOC_DAPM_DAC("DAC", NULL
, CS42L84_MSM_BLOCK_EN2
, CS42L84_MSM_BLOCK_EN2_DAC_SHIFT
, 0),
232 SND_SOC_DAPM_MUX("DACA Select", SND_SOC_NOPM
, 0, 0, &cs42l84_daca_mux_ctrl
),
233 SND_SOC_DAPM_MUX("DACB Select", SND_SOC_NOPM
, 0, 0, &cs42l84_dacb_mux_ctrl
),
234 SND_SOC_DAPM_AIF_IN("SDIN1", NULL
, 0, CS42L84_ASP_RX_EN
, CS42L84_ASP_RX_EN_CH1_SHIFT
, 0),
235 SND_SOC_DAPM_AIF_IN("SDIN2", NULL
, 1, CS42L84_ASP_RX_EN
, CS42L84_ASP_RX_EN_CH2_SHIFT
, 0),
238 SND_SOC_DAPM_INPUT("HS"),
239 SND_SOC_DAPM_ADC("ADC", NULL
, CS42L84_MSM_BLOCK_EN2
, CS42L84_MSM_BLOCK_EN2_ADC_SHIFT
, 0),
240 SND_SOC_DAPM_MUX("SDOUT1 Select", SND_SOC_NOPM
, 0, 0, &cs42l84_sdout1_mux_ctrl
),
241 SND_SOC_DAPM_AIF_OUT("SDOUT1", NULL
, 0, CS42L84_ASP_TX_EN
, CS42L84_ASP_TX_EN_CH1_SHIFT
, 0),
243 /* Playback/Capture Requirements */
244 SND_SOC_DAPM_SUPPLY("BUS", CS42L84_MSM_BLOCK_EN2
, CS42L84_MSM_BLOCK_EN2_BUS_SHIFT
, 0, NULL
, 0),
245 SND_SOC_DAPM_SUPPLY("ASP", CS42L84_MSM_BLOCK_EN2
, CS42L84_MSM_BLOCK_EN2_ASP_SHIFT
, 0, NULL
, 0),
246 SND_SOC_DAPM_SUPPLY("BCLK", CS42L84_ASP_CTL
, CS42L84_ASP_CTL_BCLK_EN_SHIFT
, 0, NULL
, 0),
249 static const struct snd_soc_dapm_route cs42l84_audio_map
[] = {
252 {"DAC", NULL
, "DACA Select"},
253 {"DAC", NULL
, "DACB Select"},
254 {"DACA Select", "ASP RX CH1", "SDIN1"},
255 {"DACA Select", "ASP RX CH2", "SDIN2"},
256 {"DACB Select", "ASP RX CH1", "SDIN1"},
257 {"DACB Select", "ASP RX CH2", "SDIN2"},
258 {"SDIN1", NULL
, "Playback"},
259 {"SDIN2", NULL
, "Playback"},
262 {"SDOUT1 Select", "ADC", "ADC"},
263 {"SDOUT1", NULL
, "SDOUT1 Select"},
264 {"Capture", NULL
, "SDOUT1"},
266 /* Playback Requirements */
267 {"DAC", NULL
, "BUS"},
268 {"SDIN1", NULL
, "ASP"},
269 {"SDIN2", NULL
, "ASP"},
270 {"SDIN1", NULL
, "BCLK"},
271 {"SDIN2", NULL
, "BCLK"},
273 /* Capture Requirements */
274 {"SDOUT1", NULL
, "BUS"},
275 {"SDOUT1", NULL
, "ASP"},
276 {"SDOUT1", NULL
, "BCLK"},
279 static int cs42l84_set_jack(struct snd_soc_component
*component
, struct snd_soc_jack
*jk
, void *d
)
281 struct cs42l84_private
*cs42l84
= snd_soc_component_get_drvdata(component
);
283 /* Prevent race with interrupt handler */
284 mutex_lock(&cs42l84
->irq_lock
);
286 snd_soc_jack_report(jk
, cs42l84
->hs_type
, SND_JACK_HEADSET
);
287 mutex_unlock(&cs42l84
->irq_lock
);
292 static int cs42l84_component_probe(struct snd_soc_component
*component
)
294 snd_soc_component_update_bits(component
, CS42L84_ASP_CTL
,
295 CS42L84_ASP_CTL_TDM_MODE
, 0);
296 snd_soc_component_update_bits(component
, CS42L84_HP_VOL_CTL
,
297 CS42L84_HP_VOL_CTL_SOFT
| CS42L84_HP_VOL_CTL_ZERO_CROSS
,
298 CS42L84_HP_VOL_CTL_ZERO_CROSS
);
301 snd_soc_component_update_bits(component
, CS42L84_ASP_RX_CH1_CTL1
,
302 CS42L84_ASP_RX_CHx_CTL1_EDGE
|
303 CS42L84_ASP_RX_CHx_CTL1_SLOT_START_LSB
, 0);
304 snd_soc_component_update_bits(component
, CS42L84_ASP_RX_CH1_CTL2
,
305 CS42L84_ASP_RX_CHx_CTL2_SLOT_START_MSB
, 0);
306 snd_soc_component_update_bits(component
, CS42L84_ASP_RX_CH2_CTL1
,
307 CS42L84_ASP_RX_CHx_CTL1_EDGE
|
308 CS42L84_ASP_RX_CHx_CTL1_SLOT_START_LSB
,
309 CS42L84_ASP_RX_CHx_CTL1_EDGE
);
310 snd_soc_component_update_bits(component
, CS42L84_ASP_RX_CH2_CTL2
,
311 CS42L84_ASP_RX_CHx_CTL2_SLOT_START_MSB
, 0);
312 snd_soc_component_update_bits(component
, CS42L84_ASP_TX_CH1_CTL1
,
313 CS42L84_ASP_RX_CHx_CTL1_EDGE
| \
314 CS42L84_ASP_RX_CHx_CTL1_SLOT_START_LSB
, 0);
315 snd_soc_component_update_bits(component
, CS42L84_ASP_TX_CH1_CTL2
,
316 CS42L84_ASP_RX_CHx_CTL2_SLOT_START_MSB
, 0);
317 snd_soc_component_update_bits(component
, CS42L84_ASP_TX_CH2_CTL1
,
318 CS42L84_ASP_RX_CHx_CTL1_EDGE
| \
319 CS42L84_ASP_RX_CHx_CTL1_SLOT_START_LSB
,
320 CS42L84_ASP_RX_CHx_CTL1_EDGE
);
321 snd_soc_component_update_bits(component
, CS42L84_ASP_TX_CH2_CTL2
,
322 CS42L84_ASP_RX_CHx_CTL2_SLOT_START_MSB
, 0);
323 /* Routing defaults */
324 snd_soc_component_write(component
, CS42L84_BUS_DAC_SRC
,
325 0b1101 << CS42L84_BUS_DAC_SRC_DACA_SHIFT
|
326 0b1110 << CS42L84_BUS_DAC_SRC_DACB_SHIFT
);
327 snd_soc_component_write(component
, CS42L84_BUS_ASP_TX_SRC
,
328 0b0111 << CS42L84_BUS_ASP_TX_SRC_CH1_SHIFT
);
333 static const struct snd_soc_component_driver soc_component_dev_cs42l84
= {
334 .set_jack
= cs42l84_set_jack
,
335 .probe
= cs42l84_component_probe
,
336 .controls
= cs42l84_snd_controls
,
337 .num_controls
= ARRAY_SIZE(cs42l84_snd_controls
),
338 .dapm_widgets
= cs42l84_dapm_widgets
,
339 .num_dapm_widgets
= ARRAY_SIZE(cs42l84_dapm_widgets
),
340 .dapm_routes
= cs42l84_audio_map
,
341 .num_dapm_routes
= ARRAY_SIZE(cs42l84_audio_map
),
345 struct cs42l84_pll_params
{
357 * Common PLL Settings for given BCLK
359 static const struct cs42l84_pll_params pll_ratio_table
[] = {
360 { 3072000, 1, 0, 0x40, 0x000000, 0x03, 0x10, 12288000},
361 { 6144000, 1, 1, 0x40, 0x000000, 0x03, 0x10, 12288000},
362 { 12288000, 0, 0, 0, 0, 0, 0, 12288000},
363 { 24576000, 1, 3, 0x40, 0x000000, 0x03, 0x10, 12288000},
366 static int cs42l84_pll_config(struct snd_soc_component
*component
)
368 struct cs42l84_private
*cs42l84
= snd_soc_component_get_drvdata(component
);
375 /* Don't reconfigure if there is an audio stream running */
376 if (cs42l84
->stream_use
) {
377 if (pll_ratio_table
[cs42l84
->pll_config
].bclk
== clk
)
383 for (i
= 0; i
< ARRAY_SIZE(pll_ratio_table
); i
++) {
384 if (pll_ratio_table
[i
].bclk
== clk
) {
385 cs42l84
->pll_config
= i
;
390 if (i
== ARRAY_SIZE(pll_ratio_table
))
393 /* Set up the LRCLK */
394 fsync
= clk
/ cs42l84
->srate
;
395 if (((fsync
* cs42l84
->srate
) != clk
)
396 || ((fsync
% 2) != 0)) {
397 dev_err(component
->dev
,
398 "Unsupported bclk %d/sample rate %d\n",
399 clk
, cs42l84
->srate
);
403 /* Set the LRCLK period */
404 snd_soc_component_update_bits(component
, CS42L84_ASP_FSYNC_CTL2
,
405 CS42L84_ASP_FSYNC_CTL2_BCLK_PERIOD_LO
,
406 FIELD_PREP(CS42L84_ASP_FSYNC_CTL2_BCLK_PERIOD_LO
, fsync
& 0x7f));
407 snd_soc_component_update_bits(component
, CS42L84_ASP_FSYNC_CTL3
,
408 CS42L84_ASP_FSYNC_CTL3_BCLK_PERIOD_HI
,
409 FIELD_PREP(CS42L84_ASP_FSYNC_CTL3_BCLK_PERIOD_HI
, fsync
>> 7));
411 /* Save what the MCLK will be */
412 switch (pll_ratio_table
[i
].mclk_int
) {
414 cs42l84
->pll_mclk_f
= CS42L84_CCM_CTL1_MCLK_F_12MHZ
;
417 cs42l84
->pll_mclk_f
= CS42L84_CCM_CTL1_MCLK_F_12_288KHZ
;
420 cs42l84
->pll_mclk_f
= CS42L84_CCM_CTL1_MCLK_F_24MHZ
;
423 cs42l84
->pll_mclk_f
= CS42L84_CCM_CTL1_MCLK_F_24_576KHZ
;
427 snd_soc_component_update_bits(component
, CS42L84_PLL_CTL1
, CS42L84_PLL_CTL1_EN
, 0);
429 if (pll_ratio_table
[i
].mclk_src_sel
) {
431 snd_soc_component_update_bits(component
,
432 CS42L84_CCM_CTL3
, CS42L84_CCM_CTL3_REFCLK_DIV
,
433 FIELD_PREP(CS42L84_CCM_CTL3_REFCLK_DIV
, pll_ratio_table
[i
].bclk_prediv
));
434 snd_soc_component_write(component
,
436 pll_ratio_table
[i
].pll_div_int
);
437 snd_soc_component_write(component
,
438 CS42L84_PLL_DIV_FRAC0
,
439 pll_ratio_table
[i
].pll_div_frac
);
440 snd_soc_component_write(component
,
441 CS42L84_PLL_DIV_FRAC1
,
442 pll_ratio_table
[i
].pll_div_frac
>> 8);
443 snd_soc_component_write(component
,
444 CS42L84_PLL_DIV_FRAC2
,
445 pll_ratio_table
[i
].pll_div_frac
>> 16);
446 snd_soc_component_update_bits(component
,
447 CS42L84_PLL_CTL1
, CS42L84_PLL_CTL1_MODE
,
448 FIELD_PREP(CS42L84_PLL_CTL1_MODE
, pll_ratio_table
[i
].pll_mode
));
449 snd_soc_component_write(component
,
451 pll_ratio_table
[i
].pll_divout
);
457 static int cs42l84_set_dai_fmt(struct snd_soc_dai
*codec_dai
, unsigned int fmt
)
459 switch (fmt
& SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK
) {
460 case SND_SOC_DAIFMT_BC_FC
:
466 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
467 case SND_SOC_DAIFMT_I2S
:
473 /* Bitclock/frame inversion */
474 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
475 case SND_SOC_DAIFMT_IB_IF
:
484 static int cs42l84_pcm_hw_params(struct snd_pcm_substream
*substream
,
485 struct snd_pcm_hw_params
*params
,
486 struct snd_soc_dai
*dai
)
488 struct snd_soc_component
*component
= dai
->component
;
489 struct cs42l84_private
*cs42l84
= snd_soc_component_get_drvdata(component
);
493 cs42l84
->srate
= params_rate(params
);
495 ret
= cs42l84_pll_config(component
);
499 switch (params_rate(params
)) {
501 ccm_samp_rate
= CS42L84_CCM_SAMP_RATE_RATE_44K1HZ
;
504 ccm_samp_rate
= CS42L84_CCM_SAMP_RATE_RATE_48KHZ
;
507 ccm_samp_rate
= CS42L84_CCM_SAMP_RATE_RATE_88K2HZ
;
510 ccm_samp_rate
= CS42L84_CCM_SAMP_RATE_RATE_96KHZ
;
513 ccm_samp_rate
= CS42L84_CCM_SAMP_RATE_RATE_176K4HZ
;
516 ccm_samp_rate
= CS42L84_CCM_SAMP_RATE_RATE_192KHZ
;
522 snd_soc_component_write(component
, CS42L84_CCM_SAMP_RATE
, ccm_samp_rate
);
524 switch (substream
->stream
) {
525 case SNDRV_PCM_STREAM_PLAYBACK
:
526 snd_soc_component_write(component
, CS42L84_ASP_RX_CH1_WIDTH
,
527 params_width(params
) - 1);
528 snd_soc_component_write(component
, CS42L84_ASP_RX_CH2_WIDTH
,
529 params_width(params
) - 1);
532 case SNDRV_PCM_STREAM_CAPTURE
:
533 snd_soc_component_write(component
, CS42L84_ASP_TX_CH1_WIDTH
,
534 params_width(params
) - 1);
535 snd_soc_component_write(component
, CS42L84_ASP_TX_CH2_WIDTH
,
536 params_width(params
) - 1);
543 static int cs42l84_set_sysclk(struct snd_soc_dai
*dai
,
544 int clk_id
, unsigned int freq
, int dir
)
546 struct snd_soc_component
*component
= dai
->component
;
547 struct cs42l84_private
*cs42l84
= snd_soc_component_get_drvdata(component
);
555 for (i
= 0; i
< ARRAY_SIZE(pll_ratio_table
); i
++) {
556 if (pll_ratio_table
[i
].bclk
== freq
) {
557 cs42l84
->bclk
= freq
;
562 dev_err(component
->dev
, "BCLK %u not supported\n", freq
);
567 static int cs42l84_mute_stream(struct snd_soc_dai
*dai
, int mute
, int stream
)
569 struct snd_soc_component
*component
= dai
->component
;
570 struct cs42l84_private
*cs42l84
= snd_soc_component_get_drvdata(component
);
575 /* Mute the headphone */
576 if (stream
== SNDRV_PCM_STREAM_PLAYBACK
)
577 snd_soc_component_update_bits(component
, CS42L84_DAC_CTL1
,
578 CS42L84_DAC_CTL1_UNMUTE
, 0);
579 cs42l84
->stream_use
&= ~(1 << stream
);
580 if (!cs42l84
->stream_use
) {
581 /* Must disconnect PLL before stopping it */
582 snd_soc_component_write(component
, CS42L84_CCM_CTL1
,
583 CS42L84_CCM_CTL1_RCO
);
585 usleep_range(150, 300);
587 snd_soc_component_update_bits(component
, CS42L84_PLL_CTL1
,
588 CS42L84_PLL_CTL1_EN
, 0);
590 snd_soc_component_update_bits(component
, CS42L84_CCM_CTL4
,
591 CS42L84_CCM_CTL4_REFCLK_EN
, 0);
594 if (!cs42l84
->stream_use
) {
595 /* SCLK must be running before codec unmute.
597 * Note carried over from CS42L42:
599 * PLL must not be started with ADC and HP both off
600 * otherwise the FILT+ supply will not charge properly.
601 * DAPM widgets power-up before stream unmute so at least
602 * one of the "DAC" or "ADC" widgets will already have
606 snd_soc_component_update_bits(component
, CS42L84_CCM_CTL4
,
607 CS42L84_CCM_CTL4_REFCLK_EN
,
608 CS42L84_CCM_CTL4_REFCLK_EN
);
610 if (pll_ratio_table
[cs42l84
->pll_config
].mclk_src_sel
) {
611 snd_soc_component_update_bits(component
, CS42L84_PLL_CTL1
,
613 CS42L84_PLL_CTL1_EN
);
614 /* TODO: should we be doing something with divout here? */
616 ret
= regmap_read_poll_timeout(cs42l84
->regmap
,
617 CS42L84_PLL_LOCK_STATUS
,
619 (regval
& CS42L84_PLL_LOCK_STATUS_LOCKED
),
620 CS42L84_PLL_LOCK_POLL_US
,
621 CS42L84_PLL_LOCK_TIMEOUT_US
);
623 dev_warn(component
->dev
, "PLL failed to lock: %d\n", ret
);
625 if (regval
& CS42L84_PLL_LOCK_STATUS_ERROR
)
626 dev_warn(component
->dev
, "PLL lock error\n");
628 /* PLL must be running to drive glitchless switch logic */
629 snd_soc_component_update_bits(component
,
631 CS42L84_CCM_CTL1_MCLK_SRC
| CS42L84_CCM_CTL1_MCLK_FREQ
,
632 FIELD_PREP(CS42L84_CCM_CTL1_MCLK_SRC
, CS42L84_CCM_CTL1_MCLK_SRC_PLL
)
633 | FIELD_PREP(CS42L84_CCM_CTL1_MCLK_FREQ
, cs42l84
->pll_mclk_f
));
634 usleep_range(CS42L84_CLOCK_SWITCH_DELAY_US
, CS42L84_CLOCK_SWITCH_DELAY_US
*2);
636 snd_soc_component_update_bits(component
,
638 CS42L84_CCM_CTL1_MCLK_SRC
| CS42L84_CCM_CTL1_MCLK_FREQ
,
639 FIELD_PREP(CS42L84_CCM_CTL1_MCLK_SRC
, CS42L84_CCM_CTL1_MCLK_SRC_BCLK
)
640 | FIELD_PREP(CS42L84_CCM_CTL1_MCLK_FREQ
, cs42l84
->pll_mclk_f
));
641 usleep_range(CS42L84_CLOCK_SWITCH_DELAY_US
, CS42L84_CLOCK_SWITCH_DELAY_US
*2);
644 cs42l84
->stream_use
|= 1 << stream
;
646 if (stream
== SNDRV_PCM_STREAM_PLAYBACK
)
647 /* Un-mute the headphone */
648 snd_soc_component_update_bits(component
, CS42L84_DAC_CTL1
,
649 CS42L84_DAC_CTL1_UNMUTE
,
650 CS42L84_DAC_CTL1_UNMUTE
);
656 static const struct snd_soc_dai_ops cs42l84_ops
= {
657 .hw_params
= cs42l84_pcm_hw_params
,
658 .set_fmt
= cs42l84_set_dai_fmt
,
659 .set_sysclk
= cs42l84_set_sysclk
,
660 .mute_stream
= cs42l84_mute_stream
,
663 #define CS42L84_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
664 SNDRV_PCM_FMTBIT_S24_LE |\
665 SNDRV_PCM_FMTBIT_S32_LE)
667 static struct snd_soc_dai_driver cs42l84_dai
= {
670 .stream_name
= "Playback",
673 .rates
= SNDRV_PCM_RATE_48000
| SNDRV_PCM_RATE_96000
,
674 .formats
= CS42L84_FORMATS
,
677 .stream_name
= "Capture",
680 .rates
= SNDRV_PCM_RATE_48000
| SNDRV_PCM_RATE_96000
,
681 .formats
= CS42L84_FORMATS
,
684 .symmetric_sample_bits
= 1,
688 struct cs42l84_irq_params
{
694 static const struct cs42l84_irq_params irq_params_table
[] = {
695 {CS42L84_TSRS_PLUG_INT_STATUS
, CS42L84_TSRS_PLUG_INT_MASK
,
696 CS42L84_TSRS_PLUG_VAL_MASK
}
699 static void cs42l84_detect_hs(struct cs42l84_private
*cs42l84
)
703 /* Power up HSBIAS */
704 regmap_update_bits(cs42l84
->regmap
,
705 CS42L84_MISC_DET_CTL
,
706 CS42L84_MISC_DET_CTL_HSBIAS_CTL
| CS42L84_MISC_DET_CTL_DETECT_MODE
,
707 FIELD_PREP(CS42L84_MISC_DET_CTL_HSBIAS_CTL
, 3) | /* 2.7 V */
708 FIELD_PREP(CS42L84_MISC_DET_CTL_DETECT_MODE
, 0));
710 /* Power up level detection circuitry */
711 regmap_update_bits(cs42l84
->regmap
,
712 CS42L84_MISC_DET_CTL
,
713 CS42L84_MISC_DET_CTL_PDN_MIC_LVL_DET
, 0);
718 /* Connect HSBIAS in CTIA wiring */
719 /* TODO: Should likely be subject of detection */
720 regmap_write(cs42l84
->regmap
,
721 CS42L84_HS_SWITCH_CTL
,
722 CS42L84_HS_SWITCH_CTL_REF_HS3
| \
723 CS42L84_HS_SWITCH_CTL_HSB_FILT_HS3
| \
724 CS42L84_HS_SWITCH_CTL_GNDHS_HS3
| \
725 CS42L84_HS_SWITCH_CTL_HSB_HS4
);
726 regmap_update_bits(cs42l84
->regmap
,
728 CS42L84_HS_DET_CTL2_SET
,
729 FIELD_PREP(CS42L84_HS_DET_CTL2_SET
, 0));
731 regmap_update_bits(cs42l84
->regmap
,
732 CS42L84_MISC_DET_CTL
,
733 CS42L84_MISC_DET_CTL_DETECT_MODE
,
734 FIELD_PREP(CS42L84_MISC_DET_CTL_DETECT_MODE
, 3));
739 regmap_read(cs42l84
->regmap
, CS42L84_HS_DET_STATUS2
, ®
);
740 regmap_update_bits(cs42l84
->regmap
,
741 CS42L84_MISC_DET_CTL
,
742 CS42L84_MISC_DET_CTL_PDN_MIC_LVL_DET
,
743 CS42L84_MISC_DET_CTL_PDN_MIC_LVL_DET
);
745 switch (reg
& 0b11) {
746 case 0b11: /* shorted */
747 case 0b00: /* open */
748 /* Power down HSBIAS */
749 regmap_update_bits(cs42l84
->regmap
,
750 CS42L84_MISC_DET_CTL
,
751 CS42L84_MISC_DET_CTL_HSBIAS_CTL
,
752 FIELD_PREP(CS42L84_MISC_DET_CTL_HSBIAS_CTL
, 1)); /* 0.0 V */
756 switch (reg
& 0b11) {
757 case 0b10: /* load */
758 dev_dbg(cs42l84
->dev
, "Detected mic\n");
759 cs42l84
->hs_type
= SND_JACK_HEADSET
;
760 snd_soc_jack_report(cs42l84
->jack
, SND_JACK_HEADSET
,
764 case 0b00: /* open */
765 dev_dbg(cs42l84
->dev
, "Detected open circuit on HS4\n");
767 case 0b11: /* shorted */
769 snd_soc_jack_report(cs42l84
->jack
, SND_JACK_HEADPHONE
,
771 cs42l84
->hs_type
= SND_JACK_HEADPHONE
;
772 dev_dbg(cs42l84
->dev
, "Detected bare headphone (no mic)\n");
777 static void cs42l84_revert_hs(struct cs42l84_private
*cs42l84
)
779 /* Power down HSBIAS */
780 regmap_update_bits(cs42l84
->regmap
,
781 CS42L84_MISC_DET_CTL
,
782 CS42L84_MISC_DET_CTL_HSBIAS_CTL
| CS42L84_MISC_DET_CTL_DETECT_MODE
,
783 FIELD_PREP(CS42L84_MISC_DET_CTL_HSBIAS_CTL
, 1) | /* 0.0 V */
784 FIELD_PREP(CS42L84_MISC_DET_CTL_DETECT_MODE
, 0));
786 /* Disconnect HSBIAS */
787 regmap_write(cs42l84
->regmap
,
788 CS42L84_HS_SWITCH_CTL
,
789 CS42L84_HS_SWITCH_CTL_REF_HS3
| \
790 CS42L84_HS_SWITCH_CTL_REF_HS4
| \
791 CS42L84_HS_SWITCH_CTL_HSB_FILT_HS3
| \
792 CS42L84_HS_SWITCH_CTL_HSB_FILT_HS4
| \
793 CS42L84_HS_SWITCH_CTL_GNDHS_HS3
| \
794 CS42L84_HS_SWITCH_CTL_GNDHS_HS4
);
795 regmap_update_bits(cs42l84
->regmap
,
797 CS42L84_HS_DET_CTL2_SET
,
798 FIELD_PREP(CS42L84_HS_DET_CTL2_SET
, 2));
801 static void cs42l84_set_interrupt_masks(struct cs42l84_private
*cs42l84
,
804 regmap_update_bits(cs42l84
->regmap
, CS42L84_TSRS_PLUG_INT_MASK
,
805 CS42L84_RS_PLUG
| CS42L84_RS_UNPLUG
|
806 CS42L84_TS_PLUG
| CS42L84_TS_UNPLUG
,
810 static irqreturn_t
cs42l84_irq_thread(int irq
, void *data
)
812 struct cs42l84_private
*cs42l84
= (struct cs42l84_private
*)data
;
813 unsigned int stickies
[1];
814 unsigned int masks
[1];
816 u8 current_tip_state
;
817 u8 current_ring_state
;
820 mutex_lock(&cs42l84
->irq_lock
);
821 /* Read sticky registers to clear interrupt */
822 for (i
= 0; i
< ARRAY_SIZE(stickies
); i
++) {
823 regmap_read(cs42l84
->regmap
, irq_params_table
[i
].status_addr
,
825 regmap_read(cs42l84
->regmap
, irq_params_table
[i
].mask_addr
,
827 stickies
[i
] = stickies
[i
] & (~masks
[i
]) &
828 irq_params_table
[i
].mask
;
831 /* When handling plug sene IRQs, we only care about EITHER tip OR ring.
832 * Ring is useless on remove, and is only useful on insert for
833 * detecting if the plug state has changed AFTER we have handled the
834 * tip sense IRQ, e.g. if the plug was not fully seated within the tip
835 * sense debounce time.
838 if ((~masks
[0]) & irq_params_table
[0].mask
) {
839 regmap_read(cs42l84
->regmap
, CS42L84_TSRS_PLUG_STATUS
, ®
);
841 current_tip_state
= (((char) reg
) &
842 (CS42L84_TS_PLUG
| CS42L84_TS_UNPLUG
)) >>
843 CS42L84_TS_PLUG_SHIFT
;
845 if (current_tip_state
!= cs42l84
->tip_state
) {
846 cs42l84
->tip_state
= current_tip_state
;
847 switch (current_tip_state
) {
849 dev_dbg(cs42l84
->dev
, "Plug event\n");
851 cs42l84_detect_hs(cs42l84
);
854 * Check the tip sense status again, and possibly invalidate
855 * the detection result
857 * Thanks to debounce, this should reliably indicate if the tip
858 * was disconnected at any point during the detection procedure.
860 regmap_read(cs42l84
->regmap
, CS42L84_TSRS_PLUG_STATUS
, ®
);
861 current_tip_state
= (((char) reg
) &
862 (CS42L84_TS_PLUG
| CS42L84_TS_UNPLUG
)) >>
863 CS42L84_TS_PLUG_SHIFT
;
864 if (current_tip_state
!= CS42L84_PLUG
) {
865 dev_dbg(cs42l84
->dev
, "Wobbly connection, detection invalidated\n");
866 cs42l84
->tip_state
= CS42L84_UNPLUG
;
867 cs42l84_revert_hs(cs42l84
);
870 /* Unmask ring sense interrupts */
871 cs42l84_set_interrupt_masks(cs42l84
, 0);
874 cs42l84
->ring_state
= CS42L84_UNPLUG
;
875 dev_dbg(cs42l84
->dev
, "Unplug event\n");
877 cs42l84_revert_hs(cs42l84
);
878 cs42l84
->hs_type
= 0;
879 snd_soc_jack_report(cs42l84
->jack
, 0,
882 /* Mask ring sense interrupts */
883 cs42l84_set_interrupt_masks(cs42l84
,
884 CS42L84_RS_PLUG
| CS42L84_RS_UNPLUG
);
887 cs42l84
->ring_state
= CS42L84_TRANS
;
891 mutex_unlock(&cs42l84
->irq_lock
);
896 /* Tip state didn't change, we must've got a ring sense IRQ */
897 current_ring_state
= (((char) reg
) &
898 (CS42L84_RS_PLUG
| CS42L84_RS_UNPLUG
)) >>
899 CS42L84_RS_PLUG_SHIFT
;
901 if (current_ring_state
!= cs42l84
->ring_state
) {
902 cs42l84
->ring_state
= current_ring_state
;
903 if (current_ring_state
== CS42L84_PLUG
)
904 cs42l84_detect_hs(cs42l84
);
908 mutex_unlock(&cs42l84
->irq_lock
);
913 static void cs42l84_setup_plug_detect(struct cs42l84_private
*cs42l84
)
917 /* Set up plug detection */
918 regmap_update_bits(cs42l84
->regmap
, CS42L84_MIC_DET_CTL4
,
919 CS42L84_MIC_DET_CTL4_LATCH_TO_VP
,
920 CS42L84_MIC_DET_CTL4_LATCH_TO_VP
);
921 regmap_update_bits(cs42l84
->regmap
, CS42L84_TIP_SENSE_CTL2
,
922 CS42L84_TIP_SENSE_CTL2_MODE
,
923 FIELD_PREP(CS42L84_TIP_SENSE_CTL2_MODE
, CS42L84_TIP_SENSE_CTL2_MODE_SHORT_DET
));
924 regmap_update_bits(cs42l84
->regmap
, CS42L84_RING_SENSE_CTL
,
925 CS42L84_RING_SENSE_CTL_INV
| CS42L84_RING_SENSE_CTL_UNK1
|
926 CS42L84_RING_SENSE_CTL_RISETIME
| CS42L84_RING_SENSE_CTL_FALLTIME
,
927 CS42L84_RING_SENSE_CTL_INV
| CS42L84_RING_SENSE_CTL_UNK1
|
928 FIELD_PREP(CS42L84_RING_SENSE_CTL_RISETIME
, CS42L84_DEBOUNCE_TIME_125MS
) |
929 FIELD_PREP(CS42L84_RING_SENSE_CTL_FALLTIME
, CS42L84_DEBOUNCE_TIME_125MS
));
930 regmap_update_bits(cs42l84
->regmap
, CS42L84_TIP_SENSE_CTL
,
931 CS42L84_TIP_SENSE_CTL_INV
|
932 CS42L84_TIP_SENSE_CTL_RISETIME
| CS42L84_TIP_SENSE_CTL_FALLTIME
,
933 CS42L84_TIP_SENSE_CTL_INV
|
934 FIELD_PREP(CS42L84_TIP_SENSE_CTL_RISETIME
, CS42L84_DEBOUNCE_TIME_500MS
) |
935 FIELD_PREP(CS42L84_TIP_SENSE_CTL_FALLTIME
, CS42L84_DEBOUNCE_TIME_125MS
));
936 regmap_update_bits(cs42l84
->regmap
, CS42L84_MSM_BLOCK_EN3
,
937 CS42L84_MSM_BLOCK_EN3_TR_SENSE
,
938 CS42L84_MSM_BLOCK_EN3_TR_SENSE
);
940 /* Save the initial status of the tip sense */
941 regmap_read(cs42l84
->regmap
, CS42L84_TSRS_PLUG_STATUS
, ®
);
942 cs42l84
->tip_state
= (((char) reg
) &
943 (CS42L84_TS_PLUG
| CS42L84_TS_UNPLUG
)) >>
944 CS42L84_TS_PLUG_SHIFT
;
946 /* Set mic-detection threshold */
947 regmap_update_bits(cs42l84
->regmap
,
948 CS42L84_MIC_DET_CTL1
, CS42L84_MIC_DET_CTL1_HS_DET_LEVEL
,
949 FIELD_PREP(CS42L84_MIC_DET_CTL1_HS_DET_LEVEL
, 0x2c)); /* ~1.9 V */
951 /* Disconnect HSBIAS (initially) */
952 regmap_write(cs42l84
->regmap
,
953 CS42L84_HS_SWITCH_CTL
,
954 CS42L84_HS_SWITCH_CTL_REF_HS3
| \
955 CS42L84_HS_SWITCH_CTL_REF_HS4
| \
956 CS42L84_HS_SWITCH_CTL_HSB_FILT_HS3
| \
957 CS42L84_HS_SWITCH_CTL_HSB_FILT_HS4
| \
958 CS42L84_HS_SWITCH_CTL_GNDHS_HS3
| \
959 CS42L84_HS_SWITCH_CTL_GNDHS_HS4
);
960 regmap_update_bits(cs42l84
->regmap
,
962 CS42L84_HS_DET_CTL2_SET
| CS42L84_HS_DET_CTL2_CTL
,
963 FIELD_PREP(CS42L84_HS_DET_CTL2_SET
, 2) |
964 FIELD_PREP(CS42L84_HS_DET_CTL2_CTL
, 0));
965 regmap_update_bits(cs42l84
->regmap
,
966 CS42L84_HS_CLAMP_DISABLE
, 1, 1);
970 static int cs42l84_i2c_probe(struct i2c_client
*i2c_client
)
972 struct cs42l84_private
*cs42l84
;
976 cs42l84
= devm_kzalloc(&i2c_client
->dev
, sizeof(struct cs42l84_private
),
981 cs42l84
->dev
= &i2c_client
->dev
;
982 i2c_set_clientdata(i2c_client
, cs42l84
);
983 mutex_init(&cs42l84
->irq_lock
);
985 cs42l84
->regmap
= devm_regmap_init_i2c(i2c_client
, &cs42l84_regmap
);
986 if (IS_ERR(cs42l84
->regmap
)) {
987 ret
= PTR_ERR(cs42l84
->regmap
);
988 dev_err(&i2c_client
->dev
, "regmap_init() failed: %d\n", ret
);
992 /* Reset the Device */
993 cs42l84
->reset_gpio
= devm_gpiod_get_optional(&i2c_client
->dev
,
994 "reset", GPIOD_OUT_LOW
);
995 if (IS_ERR(cs42l84
->reset_gpio
)) {
996 ret
= PTR_ERR(cs42l84
->reset_gpio
);
997 goto err_disable_noreset
;
1000 if (cs42l84
->reset_gpio
) {
1001 dev_dbg(&i2c_client
->dev
, "Found reset GPIO\n");
1002 gpiod_set_value_cansleep(cs42l84
->reset_gpio
, 1);
1004 usleep_range(CS42L84_BOOT_TIME_US
, CS42L84_BOOT_TIME_US
* 2);
1006 /* Request IRQ if one was specified */
1007 if (i2c_client
->irq
) {
1008 ret
= request_threaded_irq(i2c_client
->irq
,
1009 NULL
, cs42l84_irq_thread
,
1011 "cs42l84", cs42l84
);
1012 if (ret
== -EPROBE_DEFER
) {
1013 goto err_disable_noirq
;
1014 } else if (ret
!= 0) {
1015 dev_err(&i2c_client
->dev
,
1016 "Failed to request IRQ: %d\n", ret
);
1017 goto err_disable_noirq
;
1021 /* initialize codec */
1022 devid
= cirrus_read_device_id(cs42l84
->regmap
, CS42L84_DEVID
);
1025 dev_err(&i2c_client
->dev
, "Failed to read device ID: %d\n", ret
);
1029 if (devid
!= CS42L84_CHIP_ID
) {
1030 dev_err(&i2c_client
->dev
,
1031 "CS42L84 Device ID (%X). Expected %X\n",
1032 devid
, CS42L84_CHIP_ID
);
1037 ret
= regmap_read(cs42l84
->regmap
, CS42L84_REVID
, ®
);
1039 dev_err(&i2c_client
->dev
, "Get Revision ID failed\n");
1043 dev_info(&i2c_client
->dev
,
1044 "Cirrus Logic CS42L84, Revision: %02X\n", reg
& 0xFF);
1046 /* Setup plug detection */
1047 cs42l84_setup_plug_detect(cs42l84
);
1049 /* Mask ring sense interrupts */
1050 cs42l84_set_interrupt_masks(cs42l84
, CS42L84_RS_PLUG
| CS42L84_RS_UNPLUG
);
1052 /* Register codec for machine driver */
1053 ret
= devm_snd_soc_register_component(&i2c_client
->dev
,
1054 &soc_component_dev_cs42l84
, &cs42l84_dai
, 1);
1064 if (i2c_client
->irq
)
1065 free_irq(i2c_client
->irq
, cs42l84
);
1068 gpiod_set_value_cansleep(cs42l84
->reset_gpio
, 0);
1069 err_disable_noreset
:
1073 static void cs42l84_i2c_remove(struct i2c_client
*i2c_client
)
1075 struct cs42l84_private
*cs42l84
= i2c_get_clientdata(i2c_client
);
1077 if (i2c_client
->irq
)
1078 free_irq(i2c_client
->irq
, cs42l84
);
1080 gpiod_set_value_cansleep(cs42l84
->reset_gpio
, 0);
1083 static const struct of_device_id cs42l84_of_match
[] = {
1084 { .compatible
= "cirrus,cs42l84", },
1087 MODULE_DEVICE_TABLE(of
, cs42l84_of_match
);
1089 static const struct i2c_device_id cs42l84_id
[] = {
1093 MODULE_DEVICE_TABLE(i2c
, cs42l84_id
);
1095 static struct i2c_driver cs42l84_i2c_driver
= {
1098 .of_match_table
= cs42l84_of_match
,
1100 .id_table
= cs42l84_id
,
1101 .probe
= cs42l84_i2c_probe
,
1102 .remove
= cs42l84_i2c_remove
,
1105 module_i2c_driver(cs42l84_i2c_driver
);
1107 MODULE_DESCRIPTION("ASoC CS42L84 driver");
1108 MODULE_AUTHOR("Martin PoviĊĦer <povik+lin@cutebit.org>");
1109 MODULE_AUTHOR("Hector Martin <marcan@marcan.st>");
1110 MODULE_AUTHOR("James Calligeros <jcalligeros99@gmail.com>");
1111 MODULE_LICENSE("GPL");