2 * da7219.c - DA7219 ALSA SoC Codec Driver
4 * Copyright (c) 2015 Dialog Semiconductor
6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
14 #include <linux/acpi.h>
15 #include <linux/clk.h>
16 #include <linux/clkdev.h>
17 #include <linux/clk-provider.h>
18 #include <linux/i2c.h>
19 #include <linux/of_device.h>
20 #include <linux/property.h>
21 #include <linux/regmap.h>
22 #include <linux/slab.h>
24 #include <linux/module.h>
25 #include <linux/delay.h>
26 #include <linux/regulator/consumer.h>
27 #include <sound/pcm.h>
28 #include <sound/pcm_params.h>
29 #include <sound/soc.h>
30 #include <sound/soc-dapm.h>
31 #include <sound/initval.h>
32 #include <sound/tlv.h>
33 #include <asm/div64.h>
35 #include <sound/da7219.h>
37 #include "da7219-aad.h"
45 static const DECLARE_TLV_DB_SCALE(da7219_mic_gain_tlv
, -600, 600, 0);
46 static const DECLARE_TLV_DB_SCALE(da7219_mixin_gain_tlv
, -450, 150, 0);
47 static const DECLARE_TLV_DB_SCALE(da7219_adc_dig_gain_tlv
, -8325, 75, 0);
48 static const DECLARE_TLV_DB_SCALE(da7219_alc_threshold_tlv
, -9450, 150, 0);
49 static const DECLARE_TLV_DB_SCALE(da7219_alc_gain_tlv
, 0, 600, 0);
50 static const DECLARE_TLV_DB_SCALE(da7219_alc_ana_gain_tlv
, 0, 600, 0);
51 static const DECLARE_TLV_DB_SCALE(da7219_sidetone_gain_tlv
, -4200, 300, 0);
52 static const DECLARE_TLV_DB_SCALE(da7219_tonegen_gain_tlv
, -4500, 300, 0);
55 static const DECLARE_TLV_DB_SCALE(da7219_dac_eq_band_tlv
, -1050, 150, 0);
57 static const DECLARE_TLV_DB_RANGE(da7219_dac_dig_gain_tlv
,
58 0x0, 0x07, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE
, 0, 1),
59 /* -77.25dB to 12dB */
60 0x08, 0x7f, TLV_DB_SCALE_ITEM(-7725, 75, 0)
63 static const DECLARE_TLV_DB_SCALE(da7219_dac_ng_threshold_tlv
, -10200, 600, 0);
64 static const DECLARE_TLV_DB_SCALE(da7219_hp_gain_tlv
, -5700, 100, 0);
67 static const char * const da7219_alc_attack_rate_txt
[] = {
68 "7.33/fs", "14.66/fs", "29.32/fs", "58.64/fs", "117.3/fs", "234.6/fs",
69 "469.1/fs", "938.2/fs", "1876/fs", "3753/fs", "7506/fs", "15012/fs",
73 static const struct soc_enum da7219_alc_attack_rate
=
74 SOC_ENUM_SINGLE(DA7219_ALC_CTRL2
, DA7219_ALC_ATTACK_SHIFT
,
75 DA7219_ALC_ATTACK_MAX
, da7219_alc_attack_rate_txt
);
77 static const char * const da7219_alc_release_rate_txt
[] = {
78 "28.66/fs", "57.33/fs", "114.6/fs", "229.3/fs", "458.6/fs", "917.1/fs",
79 "1834/fs", "3668/fs", "7337/fs", "14674/fs", "29348/fs"
82 static const struct soc_enum da7219_alc_release_rate
=
83 SOC_ENUM_SINGLE(DA7219_ALC_CTRL2
, DA7219_ALC_RELEASE_SHIFT
,
84 DA7219_ALC_RELEASE_MAX
, da7219_alc_release_rate_txt
);
86 static const char * const da7219_alc_hold_time_txt
[] = {
87 "62/fs", "124/fs", "248/fs", "496/fs", "992/fs", "1984/fs", "3968/fs",
88 "7936/fs", "15872/fs", "31744/fs", "63488/fs", "126976/fs",
89 "253952/fs", "507904/fs", "1015808/fs", "2031616/fs"
92 static const struct soc_enum da7219_alc_hold_time
=
93 SOC_ENUM_SINGLE(DA7219_ALC_CTRL3
, DA7219_ALC_HOLD_SHIFT
,
94 DA7219_ALC_HOLD_MAX
, da7219_alc_hold_time_txt
);
96 static const char * const da7219_alc_env_rate_txt
[] = {
97 "1/4", "1/16", "1/256", "1/65536"
100 static const struct soc_enum da7219_alc_env_attack_rate
=
101 SOC_ENUM_SINGLE(DA7219_ALC_CTRL3
, DA7219_ALC_INTEG_ATTACK_SHIFT
,
102 DA7219_ALC_INTEG_MAX
, da7219_alc_env_rate_txt
);
104 static const struct soc_enum da7219_alc_env_release_rate
=
105 SOC_ENUM_SINGLE(DA7219_ALC_CTRL3
, DA7219_ALC_INTEG_RELEASE_SHIFT
,
106 DA7219_ALC_INTEG_MAX
, da7219_alc_env_rate_txt
);
108 static const char * const da7219_alc_anticlip_step_txt
[] = {
109 "0.034dB/fs", "0.068dB/fs", "0.136dB/fs", "0.272dB/fs"
112 static const struct soc_enum da7219_alc_anticlip_step
=
113 SOC_ENUM_SINGLE(DA7219_ALC_ANTICLIP_CTRL
,
114 DA7219_ALC_ANTICLIP_STEP_SHIFT
,
115 DA7219_ALC_ANTICLIP_STEP_MAX
,
116 da7219_alc_anticlip_step_txt
);
118 /* Input/Output Enums */
119 static const char * const da7219_gain_ramp_rate_txt
[] = {
120 "Nominal Rate * 8", "Nominal Rate", "Nominal Rate / 8",
124 static const struct soc_enum da7219_gain_ramp_rate
=
125 SOC_ENUM_SINGLE(DA7219_GAIN_RAMP_CTRL
, DA7219_GAIN_RAMP_RATE_SHIFT
,
126 DA7219_GAIN_RAMP_RATE_MAX
, da7219_gain_ramp_rate_txt
);
128 static const char * const da7219_hpf_mode_txt
[] = {
129 "Disabled", "Audio", "Voice"
132 static const unsigned int da7219_hpf_mode_val
[] = {
133 DA7219_HPF_DISABLED
, DA7219_HPF_AUDIO_EN
, DA7219_HPF_VOICE_EN
,
136 static const struct soc_enum da7219_adc_hpf_mode
=
137 SOC_VALUE_ENUM_SINGLE(DA7219_ADC_FILTERS1
, DA7219_HPF_MODE_SHIFT
,
138 DA7219_HPF_MODE_MASK
, DA7219_HPF_MODE_MAX
,
139 da7219_hpf_mode_txt
, da7219_hpf_mode_val
);
141 static const struct soc_enum da7219_dac_hpf_mode
=
142 SOC_VALUE_ENUM_SINGLE(DA7219_DAC_FILTERS1
, DA7219_HPF_MODE_SHIFT
,
143 DA7219_HPF_MODE_MASK
, DA7219_HPF_MODE_MAX
,
144 da7219_hpf_mode_txt
, da7219_hpf_mode_val
);
146 static const char * const da7219_audio_hpf_corner_txt
[] = {
147 "2Hz", "4Hz", "8Hz", "16Hz"
150 static const struct soc_enum da7219_adc_audio_hpf_corner
=
151 SOC_ENUM_SINGLE(DA7219_ADC_FILTERS1
,
152 DA7219_ADC_AUDIO_HPF_CORNER_SHIFT
,
153 DA7219_AUDIO_HPF_CORNER_MAX
,
154 da7219_audio_hpf_corner_txt
);
156 static const struct soc_enum da7219_dac_audio_hpf_corner
=
157 SOC_ENUM_SINGLE(DA7219_DAC_FILTERS1
,
158 DA7219_DAC_AUDIO_HPF_CORNER_SHIFT
,
159 DA7219_AUDIO_HPF_CORNER_MAX
,
160 da7219_audio_hpf_corner_txt
);
162 static const char * const da7219_voice_hpf_corner_txt
[] = {
163 "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
166 static const struct soc_enum da7219_adc_voice_hpf_corner
=
167 SOC_ENUM_SINGLE(DA7219_ADC_FILTERS1
,
168 DA7219_ADC_VOICE_HPF_CORNER_SHIFT
,
169 DA7219_VOICE_HPF_CORNER_MAX
,
170 da7219_voice_hpf_corner_txt
);
172 static const struct soc_enum da7219_dac_voice_hpf_corner
=
173 SOC_ENUM_SINGLE(DA7219_DAC_FILTERS1
,
174 DA7219_DAC_VOICE_HPF_CORNER_SHIFT
,
175 DA7219_VOICE_HPF_CORNER_MAX
,
176 da7219_voice_hpf_corner_txt
);
178 static const char * const da7219_tonegen_dtmf_key_txt
[] = {
179 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D",
183 static const struct soc_enum da7219_tonegen_dtmf_key
=
184 SOC_ENUM_SINGLE(DA7219_TONE_GEN_CFG1
, DA7219_DTMF_REG_SHIFT
,
185 DA7219_DTMF_REG_MAX
, da7219_tonegen_dtmf_key_txt
);
187 static const char * const da7219_tonegen_swg_sel_txt
[] = {
188 "Sum", "SWG1", "SWG2", "SWG1_1-Cos"
191 static const struct soc_enum da7219_tonegen_swg_sel
=
192 SOC_ENUM_SINGLE(DA7219_TONE_GEN_CFG2
, DA7219_SWG_SEL_SHIFT
,
193 DA7219_SWG_SEL_MAX
, da7219_tonegen_swg_sel_txt
);
196 static const char * const da7219_dac_softmute_rate_txt
[] = {
197 "1 Sample", "2 Samples", "4 Samples", "8 Samples", "16 Samples",
198 "32 Samples", "64 Samples"
201 static const struct soc_enum da7219_dac_softmute_rate
=
202 SOC_ENUM_SINGLE(DA7219_DAC_FILTERS5
, DA7219_DAC_SOFTMUTE_RATE_SHIFT
,
203 DA7219_DAC_SOFTMUTE_RATE_MAX
,
204 da7219_dac_softmute_rate_txt
);
206 static const char * const da7219_dac_ng_setup_time_txt
[] = {
207 "256 Samples", "512 Samples", "1024 Samples", "2048 Samples"
210 static const struct soc_enum da7219_dac_ng_setup_time
=
211 SOC_ENUM_SINGLE(DA7219_DAC_NG_SETUP_TIME
,
212 DA7219_DAC_NG_SETUP_TIME_SHIFT
,
213 DA7219_DAC_NG_SETUP_TIME_MAX
,
214 da7219_dac_ng_setup_time_txt
);
216 static const char * const da7219_dac_ng_rampup_txt
[] = {
217 "0.22ms/dB", "0.0138ms/dB"
220 static const struct soc_enum da7219_dac_ng_rampup_rate
=
221 SOC_ENUM_SINGLE(DA7219_DAC_NG_SETUP_TIME
,
222 DA7219_DAC_NG_RAMPUP_RATE_SHIFT
,
223 DA7219_DAC_NG_RAMP_RATE_MAX
,
224 da7219_dac_ng_rampup_txt
);
226 static const char * const da7219_dac_ng_rampdown_txt
[] = {
227 "0.88ms/dB", "14.08ms/dB"
230 static const struct soc_enum da7219_dac_ng_rampdown_rate
=
231 SOC_ENUM_SINGLE(DA7219_DAC_NG_SETUP_TIME
,
232 DA7219_DAC_NG_RAMPDN_RATE_SHIFT
,
233 DA7219_DAC_NG_RAMP_RATE_MAX
,
234 da7219_dac_ng_rampdown_txt
);
237 static const char * const da7219_cp_track_mode_txt
[] = {
238 "Largest Volume", "DAC Volume", "Signal Magnitude"
241 static const unsigned int da7219_cp_track_mode_val
[] = {
242 DA7219_CP_MCHANGE_LARGEST_VOL
, DA7219_CP_MCHANGE_DAC_VOL
,
243 DA7219_CP_MCHANGE_SIG_MAG
246 static const struct soc_enum da7219_cp_track_mode
=
247 SOC_VALUE_ENUM_SINGLE(DA7219_CP_CTRL
, DA7219_CP_MCHANGE_SHIFT
,
248 DA7219_CP_MCHANGE_REL_MASK
, DA7219_CP_MCHANGE_MAX
,
249 da7219_cp_track_mode_txt
,
250 da7219_cp_track_mode_val
);
257 /* Locked Kcontrol calls */
258 static int da7219_volsw_locked_get(struct snd_kcontrol
*kcontrol
,
259 struct snd_ctl_elem_value
*ucontrol
)
261 struct snd_soc_component
*component
= snd_soc_kcontrol_component(kcontrol
);
262 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
265 mutex_lock(&da7219
->ctrl_lock
);
266 ret
= snd_soc_get_volsw(kcontrol
, ucontrol
);
267 mutex_unlock(&da7219
->ctrl_lock
);
272 static int da7219_volsw_locked_put(struct snd_kcontrol
*kcontrol
,
273 struct snd_ctl_elem_value
*ucontrol
)
275 struct snd_soc_component
*component
= snd_soc_kcontrol_component(kcontrol
);
276 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
279 mutex_lock(&da7219
->ctrl_lock
);
280 ret
= snd_soc_put_volsw(kcontrol
, ucontrol
);
281 mutex_unlock(&da7219
->ctrl_lock
);
286 static int da7219_enum_locked_get(struct snd_kcontrol
*kcontrol
,
287 struct snd_ctl_elem_value
*ucontrol
)
289 struct snd_soc_component
*component
= snd_soc_kcontrol_component(kcontrol
);
290 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
293 mutex_lock(&da7219
->ctrl_lock
);
294 ret
= snd_soc_get_enum_double(kcontrol
, ucontrol
);
295 mutex_unlock(&da7219
->ctrl_lock
);
300 static int da7219_enum_locked_put(struct snd_kcontrol
*kcontrol
,
301 struct snd_ctl_elem_value
*ucontrol
)
303 struct snd_soc_component
*component
= snd_soc_kcontrol_component(kcontrol
);
304 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
307 mutex_lock(&da7219
->ctrl_lock
);
308 ret
= snd_soc_put_enum_double(kcontrol
, ucontrol
);
309 mutex_unlock(&da7219
->ctrl_lock
);
315 static void da7219_alc_calib(struct snd_soc_component
*component
)
317 u8 mic_ctrl
, mixin_ctrl
, adc_ctrl
, calib_ctrl
;
319 /* Save current state of mic control register */
320 mic_ctrl
= snd_soc_component_read32(component
, DA7219_MIC_1_CTRL
);
322 /* Save current state of input mixer control register */
323 mixin_ctrl
= snd_soc_component_read32(component
, DA7219_MIXIN_L_CTRL
);
325 /* Save current state of input ADC control register */
326 adc_ctrl
= snd_soc_component_read32(component
, DA7219_ADC_L_CTRL
);
328 /* Enable then Mute MIC PGAs */
329 snd_soc_component_update_bits(component
, DA7219_MIC_1_CTRL
, DA7219_MIC_1_AMP_EN_MASK
,
330 DA7219_MIC_1_AMP_EN_MASK
);
331 snd_soc_component_update_bits(component
, DA7219_MIC_1_CTRL
,
332 DA7219_MIC_1_AMP_MUTE_EN_MASK
,
333 DA7219_MIC_1_AMP_MUTE_EN_MASK
);
335 /* Enable input mixers unmuted */
336 snd_soc_component_update_bits(component
, DA7219_MIXIN_L_CTRL
,
337 DA7219_MIXIN_L_AMP_EN_MASK
|
338 DA7219_MIXIN_L_AMP_MUTE_EN_MASK
,
339 DA7219_MIXIN_L_AMP_EN_MASK
);
341 /* Enable input filters unmuted */
342 snd_soc_component_update_bits(component
, DA7219_ADC_L_CTRL
,
343 DA7219_ADC_L_MUTE_EN_MASK
| DA7219_ADC_L_EN_MASK
,
344 DA7219_ADC_L_EN_MASK
);
346 /* Perform auto calibration */
347 snd_soc_component_update_bits(component
, DA7219_ALC_CTRL1
,
348 DA7219_ALC_AUTO_CALIB_EN_MASK
,
349 DA7219_ALC_AUTO_CALIB_EN_MASK
);
351 calib_ctrl
= snd_soc_component_read32(component
, DA7219_ALC_CTRL1
);
352 } while (calib_ctrl
& DA7219_ALC_AUTO_CALIB_EN_MASK
);
354 /* If auto calibration fails, disable DC offset, hybrid ALC */
355 if (calib_ctrl
& DA7219_ALC_CALIB_OVERFLOW_MASK
) {
356 dev_warn(component
->dev
,
357 "ALC auto calibration failed with overflow\n");
358 snd_soc_component_update_bits(component
, DA7219_ALC_CTRL1
,
359 DA7219_ALC_OFFSET_EN_MASK
|
360 DA7219_ALC_SYNC_MODE_MASK
, 0);
362 /* Enable DC offset cancellation, hybrid mode */
363 snd_soc_component_update_bits(component
, DA7219_ALC_CTRL1
,
364 DA7219_ALC_OFFSET_EN_MASK
|
365 DA7219_ALC_SYNC_MODE_MASK
,
366 DA7219_ALC_OFFSET_EN_MASK
|
367 DA7219_ALC_SYNC_MODE_MASK
);
370 /* Restore input filter control register to original state */
371 snd_soc_component_write(component
, DA7219_ADC_L_CTRL
, adc_ctrl
);
373 /* Restore input mixer control registers to original state */
374 snd_soc_component_write(component
, DA7219_MIXIN_L_CTRL
, mixin_ctrl
);
376 /* Restore MIC control registers to original states */
377 snd_soc_component_write(component
, DA7219_MIC_1_CTRL
, mic_ctrl
);
380 static int da7219_mixin_gain_put(struct snd_kcontrol
*kcontrol
,
381 struct snd_ctl_elem_value
*ucontrol
)
383 struct snd_soc_component
*component
= snd_soc_kcontrol_component(kcontrol
);
384 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
387 ret
= snd_soc_put_volsw(kcontrol
, ucontrol
);
390 * If ALC in operation and value of control has been updated,
391 * make sure calibrated offsets are updated.
393 if ((ret
== 1) && (da7219
->alc_en
))
394 da7219_alc_calib(component
);
399 static int da7219_alc_sw_put(struct snd_kcontrol
*kcontrol
,
400 struct snd_ctl_elem_value
*ucontrol
)
402 struct snd_soc_component
*component
= snd_soc_kcontrol_component(kcontrol
);
403 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
406 /* Force ALC offset calibration if enabling ALC */
407 if ((ucontrol
->value
.integer
.value
[0]) && (!da7219
->alc_en
)) {
408 da7219_alc_calib(component
);
409 da7219
->alc_en
= true;
411 da7219
->alc_en
= false;
414 return snd_soc_put_volsw(kcontrol
, ucontrol
);
418 static int da7219_tonegen_freq_get(struct snd_kcontrol
*kcontrol
,
419 struct snd_ctl_elem_value
*ucontrol
)
421 struct snd_soc_component
*component
= snd_soc_kcontrol_component(kcontrol
);
422 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
423 struct soc_mixer_control
*mixer_ctrl
=
424 (struct soc_mixer_control
*) kcontrol
->private_value
;
425 unsigned int reg
= mixer_ctrl
->reg
;
429 mutex_lock(&da7219
->ctrl_lock
);
430 ret
= regmap_raw_read(da7219
->regmap
, reg
, &val
, sizeof(val
));
431 mutex_unlock(&da7219
->ctrl_lock
);
437 * Frequency value spans two 8-bit registers, lower then upper byte.
438 * Therefore we need to convert to host endianness here.
440 ucontrol
->value
.integer
.value
[0] = le16_to_cpu(val
);
445 static int da7219_tonegen_freq_put(struct snd_kcontrol
*kcontrol
,
446 struct snd_ctl_elem_value
*ucontrol
)
448 struct snd_soc_component
*component
= snd_soc_kcontrol_component(kcontrol
);
449 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
450 struct soc_mixer_control
*mixer_ctrl
=
451 (struct soc_mixer_control
*) kcontrol
->private_value
;
452 unsigned int reg
= mixer_ctrl
->reg
;
457 * Frequency value spans two 8-bit registers, lower then upper byte.
458 * Therefore we need to convert to little endian here to align with
461 val
= cpu_to_le16(ucontrol
->value
.integer
.value
[0]);
463 mutex_lock(&da7219
->ctrl_lock
);
464 ret
= regmap_raw_write(da7219
->regmap
, reg
, &val
, sizeof(val
));
465 mutex_unlock(&da7219
->ctrl_lock
);
475 static const struct snd_kcontrol_new da7219_snd_controls
[] = {
477 SOC_SINGLE_TLV("Mic Volume", DA7219_MIC_1_GAIN
,
478 DA7219_MIC_1_AMP_GAIN_SHIFT
, DA7219_MIC_1_AMP_GAIN_MAX
,
479 DA7219_NO_INVERT
, da7219_mic_gain_tlv
),
480 SOC_SINGLE("Mic Switch", DA7219_MIC_1_CTRL
,
481 DA7219_MIC_1_AMP_MUTE_EN_SHIFT
, DA7219_SWITCH_EN_MAX
,
485 SOC_SINGLE_EXT_TLV("Mixin Volume", DA7219_MIXIN_L_GAIN
,
486 DA7219_MIXIN_L_AMP_GAIN_SHIFT
,
487 DA7219_MIXIN_L_AMP_GAIN_MAX
, DA7219_NO_INVERT
,
488 snd_soc_get_volsw
, da7219_mixin_gain_put
,
489 da7219_mixin_gain_tlv
),
490 SOC_SINGLE("Mixin Switch", DA7219_MIXIN_L_CTRL
,
491 DA7219_MIXIN_L_AMP_MUTE_EN_SHIFT
, DA7219_SWITCH_EN_MAX
,
493 SOC_SINGLE("Mixin Gain Ramp Switch", DA7219_MIXIN_L_CTRL
,
494 DA7219_MIXIN_L_AMP_RAMP_EN_SHIFT
, DA7219_SWITCH_EN_MAX
,
496 SOC_SINGLE("Mixin ZC Gain Switch", DA7219_MIXIN_L_CTRL
,
497 DA7219_MIXIN_L_AMP_ZC_EN_SHIFT
, DA7219_SWITCH_EN_MAX
,
501 SOC_SINGLE_TLV("Capture Digital Volume", DA7219_ADC_L_GAIN
,
502 DA7219_ADC_L_DIGITAL_GAIN_SHIFT
,
503 DA7219_ADC_L_DIGITAL_GAIN_MAX
, DA7219_NO_INVERT
,
504 da7219_adc_dig_gain_tlv
),
505 SOC_SINGLE("Capture Digital Switch", DA7219_ADC_L_CTRL
,
506 DA7219_ADC_L_MUTE_EN_SHIFT
, DA7219_SWITCH_EN_MAX
,
508 SOC_SINGLE("Capture Digital Gain Ramp Switch", DA7219_ADC_L_CTRL
,
509 DA7219_ADC_L_RAMP_EN_SHIFT
, DA7219_SWITCH_EN_MAX
,
513 SOC_ENUM("ALC Attack Rate", da7219_alc_attack_rate
),
514 SOC_ENUM("ALC Release Rate", da7219_alc_release_rate
),
515 SOC_ENUM("ALC Hold Time", da7219_alc_hold_time
),
516 SOC_ENUM("ALC Envelope Attack Rate", da7219_alc_env_attack_rate
),
517 SOC_ENUM("ALC Envelope Release Rate", da7219_alc_env_release_rate
),
518 SOC_SINGLE_TLV("ALC Noise Threshold", DA7219_ALC_NOISE
,
519 DA7219_ALC_NOISE_SHIFT
, DA7219_ALC_THRESHOLD_MAX
,
520 DA7219_INVERT
, da7219_alc_threshold_tlv
),
521 SOC_SINGLE_TLV("ALC Min Threshold", DA7219_ALC_TARGET_MIN
,
522 DA7219_ALC_THRESHOLD_MIN_SHIFT
, DA7219_ALC_THRESHOLD_MAX
,
523 DA7219_INVERT
, da7219_alc_threshold_tlv
),
524 SOC_SINGLE_TLV("ALC Max Threshold", DA7219_ALC_TARGET_MAX
,
525 DA7219_ALC_THRESHOLD_MAX_SHIFT
, DA7219_ALC_THRESHOLD_MAX
,
526 DA7219_INVERT
, da7219_alc_threshold_tlv
),
527 SOC_SINGLE_TLV("ALC Max Attenuation", DA7219_ALC_GAIN_LIMITS
,
528 DA7219_ALC_ATTEN_MAX_SHIFT
, DA7219_ALC_ATTEN_GAIN_MAX
,
529 DA7219_NO_INVERT
, da7219_alc_gain_tlv
),
530 SOC_SINGLE_TLV("ALC Max Volume", DA7219_ALC_GAIN_LIMITS
,
531 DA7219_ALC_GAIN_MAX_SHIFT
, DA7219_ALC_ATTEN_GAIN_MAX
,
532 DA7219_NO_INVERT
, da7219_alc_gain_tlv
),
533 SOC_SINGLE_RANGE_TLV("ALC Min Analog Volume", DA7219_ALC_ANA_GAIN_LIMITS
,
534 DA7219_ALC_ANA_GAIN_MIN_SHIFT
,
535 DA7219_ALC_ANA_GAIN_MIN
, DA7219_ALC_ANA_GAIN_MAX
,
536 DA7219_NO_INVERT
, da7219_alc_ana_gain_tlv
),
537 SOC_SINGLE_RANGE_TLV("ALC Max Analog Volume", DA7219_ALC_ANA_GAIN_LIMITS
,
538 DA7219_ALC_ANA_GAIN_MAX_SHIFT
,
539 DA7219_ALC_ANA_GAIN_MIN
, DA7219_ALC_ANA_GAIN_MAX
,
540 DA7219_NO_INVERT
, da7219_alc_ana_gain_tlv
),
541 SOC_ENUM("ALC Anticlip Step", da7219_alc_anticlip_step
),
542 SOC_SINGLE("ALC Anticlip Switch", DA7219_ALC_ANTICLIP_CTRL
,
543 DA7219_ALC_ANTIPCLIP_EN_SHIFT
, DA7219_SWITCH_EN_MAX
,
545 SOC_SINGLE_EXT("ALC Switch", DA7219_ALC_CTRL1
, DA7219_ALC_EN_SHIFT
,
546 DA7219_SWITCH_EN_MAX
, DA7219_NO_INVERT
,
547 snd_soc_get_volsw
, da7219_alc_sw_put
),
549 /* Input High-Pass Filters */
550 SOC_ENUM("ADC HPF Mode", da7219_adc_hpf_mode
),
551 SOC_ENUM("ADC HPF Corner Audio", da7219_adc_audio_hpf_corner
),
552 SOC_ENUM("ADC HPF Corner Voice", da7219_adc_voice_hpf_corner
),
554 /* Sidetone Filter */
555 SOC_SINGLE_TLV("Sidetone Volume", DA7219_SIDETONE_GAIN
,
556 DA7219_SIDETONE_GAIN_SHIFT
, DA7219_SIDETONE_GAIN_MAX
,
557 DA7219_NO_INVERT
, da7219_sidetone_gain_tlv
),
558 SOC_SINGLE("Sidetone Switch", DA7219_SIDETONE_CTRL
,
559 DA7219_SIDETONE_MUTE_EN_SHIFT
, DA7219_SWITCH_EN_MAX
,
563 SOC_SINGLE_EXT_TLV("ToneGen Volume", DA7219_TONE_GEN_CFG2
,
564 DA7219_TONE_GEN_GAIN_SHIFT
, DA7219_TONE_GEN_GAIN_MAX
,
565 DA7219_NO_INVERT
, da7219_volsw_locked_get
,
566 da7219_volsw_locked_put
, da7219_tonegen_gain_tlv
),
567 SOC_ENUM_EXT("ToneGen DTMF Key", da7219_tonegen_dtmf_key
,
568 da7219_enum_locked_get
, da7219_enum_locked_put
),
569 SOC_SINGLE_EXT("ToneGen DTMF Switch", DA7219_TONE_GEN_CFG1
,
570 DA7219_DTMF_EN_SHIFT
, DA7219_SWITCH_EN_MAX
,
571 DA7219_NO_INVERT
, da7219_volsw_locked_get
,
572 da7219_volsw_locked_put
),
573 SOC_ENUM_EXT("ToneGen Sinewave Gen Type", da7219_tonegen_swg_sel
,
574 da7219_enum_locked_get
, da7219_enum_locked_put
),
575 SOC_SINGLE_EXT("ToneGen Sinewave1 Freq", DA7219_TONE_GEN_FREQ1_L
,
576 DA7219_FREQ1_L_SHIFT
, DA7219_FREQ_MAX
, DA7219_NO_INVERT
,
577 da7219_tonegen_freq_get
, da7219_tonegen_freq_put
),
578 SOC_SINGLE_EXT("ToneGen Sinewave2 Freq", DA7219_TONE_GEN_FREQ2_L
,
579 DA7219_FREQ2_L_SHIFT
, DA7219_FREQ_MAX
, DA7219_NO_INVERT
,
580 da7219_tonegen_freq_get
, da7219_tonegen_freq_put
),
581 SOC_SINGLE_EXT("ToneGen On Time", DA7219_TONE_GEN_ON_PER
,
582 DA7219_BEEP_ON_PER_SHIFT
, DA7219_BEEP_ON_OFF_MAX
,
583 DA7219_NO_INVERT
, da7219_volsw_locked_get
,
584 da7219_volsw_locked_put
),
585 SOC_SINGLE("ToneGen Off Time", DA7219_TONE_GEN_OFF_PER
,
586 DA7219_BEEP_OFF_PER_SHIFT
, DA7219_BEEP_ON_OFF_MAX
,
590 SOC_ENUM("Gain Ramp Rate", da7219_gain_ramp_rate
),
592 /* DAC High-Pass Filter */
593 SOC_ENUM_EXT("DAC HPF Mode", da7219_dac_hpf_mode
,
594 da7219_enum_locked_get
, da7219_enum_locked_put
),
595 SOC_ENUM("DAC HPF Corner Audio", da7219_dac_audio_hpf_corner
),
596 SOC_ENUM("DAC HPF Corner Voice", da7219_dac_voice_hpf_corner
),
598 /* DAC 5-Band Equaliser */
599 SOC_SINGLE_TLV("DAC EQ Band1 Volume", DA7219_DAC_FILTERS2
,
600 DA7219_DAC_EQ_BAND1_SHIFT
, DA7219_DAC_EQ_BAND_MAX
,
601 DA7219_NO_INVERT
, da7219_dac_eq_band_tlv
),
602 SOC_SINGLE_TLV("DAC EQ Band2 Volume", DA7219_DAC_FILTERS2
,
603 DA7219_DAC_EQ_BAND2_SHIFT
, DA7219_DAC_EQ_BAND_MAX
,
604 DA7219_NO_INVERT
, da7219_dac_eq_band_tlv
),
605 SOC_SINGLE_TLV("DAC EQ Band3 Volume", DA7219_DAC_FILTERS3
,
606 DA7219_DAC_EQ_BAND3_SHIFT
, DA7219_DAC_EQ_BAND_MAX
,
607 DA7219_NO_INVERT
, da7219_dac_eq_band_tlv
),
608 SOC_SINGLE_TLV("DAC EQ Band4 Volume", DA7219_DAC_FILTERS3
,
609 DA7219_DAC_EQ_BAND4_SHIFT
, DA7219_DAC_EQ_BAND_MAX
,
610 DA7219_NO_INVERT
, da7219_dac_eq_band_tlv
),
611 SOC_SINGLE_TLV("DAC EQ Band5 Volume", DA7219_DAC_FILTERS4
,
612 DA7219_DAC_EQ_BAND5_SHIFT
, DA7219_DAC_EQ_BAND_MAX
,
613 DA7219_NO_INVERT
, da7219_dac_eq_band_tlv
),
614 SOC_SINGLE_EXT("DAC EQ Switch", DA7219_DAC_FILTERS4
,
615 DA7219_DAC_EQ_EN_SHIFT
, DA7219_SWITCH_EN_MAX
,
616 DA7219_NO_INVERT
, da7219_volsw_locked_get
,
617 da7219_volsw_locked_put
),
620 SOC_ENUM("DAC Soft Mute Rate", da7219_dac_softmute_rate
),
621 SOC_SINGLE_EXT("DAC Soft Mute Switch", DA7219_DAC_FILTERS5
,
622 DA7219_DAC_SOFTMUTE_EN_SHIFT
, DA7219_SWITCH_EN_MAX
,
623 DA7219_NO_INVERT
, da7219_volsw_locked_get
,
624 da7219_volsw_locked_put
),
627 SOC_ENUM("DAC NG Setup Time", da7219_dac_ng_setup_time
),
628 SOC_ENUM("DAC NG Rampup Rate", da7219_dac_ng_rampup_rate
),
629 SOC_ENUM("DAC NG Rampdown Rate", da7219_dac_ng_rampdown_rate
),
630 SOC_SINGLE_TLV("DAC NG Off Threshold", DA7219_DAC_NG_OFF_THRESH
,
631 DA7219_DAC_NG_OFF_THRESHOLD_SHIFT
,
632 DA7219_DAC_NG_THRESHOLD_MAX
, DA7219_NO_INVERT
,
633 da7219_dac_ng_threshold_tlv
),
634 SOC_SINGLE_TLV("DAC NG On Threshold", DA7219_DAC_NG_ON_THRESH
,
635 DA7219_DAC_NG_ON_THRESHOLD_SHIFT
,
636 DA7219_DAC_NG_THRESHOLD_MAX
, DA7219_NO_INVERT
,
637 da7219_dac_ng_threshold_tlv
),
638 SOC_SINGLE("DAC NG Switch", DA7219_DAC_NG_CTRL
, DA7219_DAC_NG_EN_SHIFT
,
639 DA7219_SWITCH_EN_MAX
, DA7219_NO_INVERT
),
642 SOC_DOUBLE_R_EXT_TLV("Playback Digital Volume", DA7219_DAC_L_GAIN
,
643 DA7219_DAC_R_GAIN
, DA7219_DAC_L_DIGITAL_GAIN_SHIFT
,
644 DA7219_DAC_DIGITAL_GAIN_MAX
, DA7219_NO_INVERT
,
645 da7219_volsw_locked_get
, da7219_volsw_locked_put
,
646 da7219_dac_dig_gain_tlv
),
647 SOC_DOUBLE_R_EXT("Playback Digital Switch", DA7219_DAC_L_CTRL
,
648 DA7219_DAC_R_CTRL
, DA7219_DAC_L_MUTE_EN_SHIFT
,
649 DA7219_SWITCH_EN_MAX
, DA7219_INVERT
,
650 da7219_volsw_locked_get
, da7219_volsw_locked_put
),
651 SOC_DOUBLE_R("Playback Digital Gain Ramp Switch", DA7219_DAC_L_CTRL
,
652 DA7219_DAC_R_CTRL
, DA7219_DAC_L_RAMP_EN_SHIFT
,
653 DA7219_SWITCH_EN_MAX
, DA7219_NO_INVERT
),
656 SOC_ENUM("Charge Pump Track Mode", da7219_cp_track_mode
),
657 SOC_SINGLE("Charge Pump Threshold", DA7219_CP_VOL_THRESHOLD1
,
658 DA7219_CP_THRESH_VDD2_SHIFT
, DA7219_CP_THRESH_VDD2_MAX
,
662 SOC_DOUBLE_R_EXT_TLV("Headphone Volume", DA7219_HP_L_GAIN
,
663 DA7219_HP_R_GAIN
, DA7219_HP_L_AMP_GAIN_SHIFT
,
664 DA7219_HP_AMP_GAIN_MAX
, DA7219_NO_INVERT
,
665 da7219_volsw_locked_get
, da7219_volsw_locked_put
,
667 SOC_DOUBLE_R_EXT("Headphone Switch", DA7219_HP_L_CTRL
, DA7219_HP_R_CTRL
,
668 DA7219_HP_L_AMP_MUTE_EN_SHIFT
, DA7219_SWITCH_EN_MAX
,
669 DA7219_INVERT
, da7219_volsw_locked_get
,
670 da7219_volsw_locked_put
),
671 SOC_DOUBLE_R("Headphone Gain Ramp Switch", DA7219_HP_L_CTRL
,
672 DA7219_HP_R_CTRL
, DA7219_HP_L_AMP_RAMP_EN_SHIFT
,
673 DA7219_SWITCH_EN_MAX
, DA7219_NO_INVERT
),
674 SOC_DOUBLE_R("Headphone ZC Gain Switch", DA7219_HP_L_CTRL
,
675 DA7219_HP_R_CTRL
, DA7219_HP_L_AMP_ZC_EN_SHIFT
,
676 DA7219_SWITCH_EN_MAX
, DA7219_NO_INVERT
),
684 static const char * const da7219_out_sel_txt
[] = {
685 "ADC", "Tone Generator", "DAIL", "DAIR"
688 static const struct soc_enum da7219_out_dail_sel
=
689 SOC_ENUM_SINGLE(DA7219_DIG_ROUTING_DAI
,
690 DA7219_DAI_L_SRC_SHIFT
,
694 static const struct snd_kcontrol_new da7219_out_dail_sel_mux
=
695 SOC_DAPM_ENUM("Out DAIL Mux", da7219_out_dail_sel
);
697 static const struct soc_enum da7219_out_dair_sel
=
698 SOC_ENUM_SINGLE(DA7219_DIG_ROUTING_DAI
,
699 DA7219_DAI_R_SRC_SHIFT
,
703 static const struct snd_kcontrol_new da7219_out_dair_sel_mux
=
704 SOC_DAPM_ENUM("Out DAIR Mux", da7219_out_dair_sel
);
706 static const struct soc_enum da7219_out_dacl_sel
=
707 SOC_ENUM_SINGLE(DA7219_DIG_ROUTING_DAC
,
708 DA7219_DAC_L_SRC_SHIFT
,
712 static const struct snd_kcontrol_new da7219_out_dacl_sel_mux
=
713 SOC_DAPM_ENUM("Out DACL Mux", da7219_out_dacl_sel
);
715 static const struct soc_enum da7219_out_dacr_sel
=
716 SOC_ENUM_SINGLE(DA7219_DIG_ROUTING_DAC
,
717 DA7219_DAC_R_SRC_SHIFT
,
721 static const struct snd_kcontrol_new da7219_out_dacr_sel_mux
=
722 SOC_DAPM_ENUM("Out DACR Mux", da7219_out_dacr_sel
);
726 * DAPM Mixer Controls
729 static const struct snd_kcontrol_new da7219_mixin_controls
[] = {
730 SOC_DAPM_SINGLE("Mic Switch", DA7219_MIXIN_L_SELECT
,
731 DA7219_MIXIN_L_MIX_SELECT_SHIFT
,
732 DA7219_SWITCH_EN_MAX
, DA7219_NO_INVERT
),
735 static const struct snd_kcontrol_new da7219_mixout_l_controls
[] = {
736 SOC_DAPM_SINGLE("DACL Switch", DA7219_MIXOUT_L_SELECT
,
737 DA7219_MIXOUT_L_MIX_SELECT_SHIFT
,
738 DA7219_SWITCH_EN_MAX
, DA7219_NO_INVERT
),
741 static const struct snd_kcontrol_new da7219_mixout_r_controls
[] = {
742 SOC_DAPM_SINGLE("DACR Switch", DA7219_MIXOUT_R_SELECT
,
743 DA7219_MIXOUT_R_MIX_SELECT_SHIFT
,
744 DA7219_SWITCH_EN_MAX
, DA7219_NO_INVERT
),
747 #define DA7219_DMIX_ST_CTRLS(reg) \
748 SOC_DAPM_SINGLE("Out FilterL Switch", reg, \
749 DA7219_DMIX_ST_SRC_OUTFILT1L_SHIFT, \
750 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT), \
751 SOC_DAPM_SINGLE("Out FilterR Switch", reg, \
752 DA7219_DMIX_ST_SRC_OUTFILT1R_SHIFT, \
753 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT), \
754 SOC_DAPM_SINGLE("Sidetone Switch", reg, \
755 DA7219_DMIX_ST_SRC_SIDETONE_SHIFT, \
756 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT) \
758 static const struct snd_kcontrol_new da7219_st_out_filtl_mix_controls[] = {
759 DA7219_DMIX_ST_CTRLS(DA7219_DROUTING_ST_OUTFILT_1L
),
762 static const struct snd_kcontrol_new da7219_st_out_filtr_mix_controls
[] = {
763 DA7219_DMIX_ST_CTRLS(DA7219_DROUTING_ST_OUTFILT_1R
),
771 static int da7219_mic_pga_event(struct snd_soc_dapm_widget
*w
,
772 struct snd_kcontrol
*kcontrol
, int event
)
774 struct snd_soc_component
*component
= snd_soc_dapm_to_component(w
->dapm
);
775 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
778 case SND_SOC_DAPM_POST_PMU
:
779 if (da7219
->micbias_on_event
) {
781 * Delay only for first capture after bias enabled to
782 * avoid possible DC offset related noise.
784 da7219
->micbias_on_event
= false;
785 msleep(da7219
->mic_pga_delay
);
795 static int da7219_dai_event(struct snd_soc_dapm_widget
*w
,
796 struct snd_kcontrol
*kcontrol
, int event
)
798 struct snd_soc_component
*component
= snd_soc_dapm_to_component(w
->dapm
);
799 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
800 struct clk
*bclk
= da7219
->dai_clks
[DA7219_DAI_BCLK_IDX
];
801 u8 pll_ctrl
, pll_status
;
803 bool srm_lock
= false;
806 case SND_SOC_DAPM_PRE_PMU
:
807 if (da7219
->master
) {
808 /* Enable DAI clks for master mode */
810 ret
= clk_prepare_enable(bclk
);
812 dev_err(component
->dev
,
813 "Failed to enable DAI clks\n");
817 snd_soc_component_update_bits(component
,
819 DA7219_DAI_CLK_EN_MASK
,
820 DA7219_DAI_CLK_EN_MASK
);
824 /* PC synchronised to DAI */
825 snd_soc_component_update_bits(component
, DA7219_PC_COUNT
,
826 DA7219_PC_FREERUN_MASK
, 0);
828 /* Slave mode, if SRM not enabled no need for status checks */
829 pll_ctrl
= snd_soc_component_read32(component
, DA7219_PLL_CTRL
);
830 if ((pll_ctrl
& DA7219_PLL_MODE_MASK
) != DA7219_PLL_MODE_SRM
)
833 /* Check SRM has locked */
835 pll_status
= snd_soc_component_read32(component
, DA7219_PLL_SRM_STS
);
836 if (pll_status
& DA7219_PLL_SRM_STS_SRM_LOCK
) {
842 } while ((i
< DA7219_SRM_CHECK_RETRIES
) && (!srm_lock
));
845 dev_warn(component
->dev
, "SRM failed to lock\n");
848 case SND_SOC_DAPM_POST_PMD
:
849 /* PC free-running */
850 snd_soc_component_update_bits(component
, DA7219_PC_COUNT
,
851 DA7219_PC_FREERUN_MASK
,
852 DA7219_PC_FREERUN_MASK
);
854 /* Disable DAI clks if in master mode */
855 if (da7219
->master
) {
857 clk_disable_unprepare(bclk
);
859 snd_soc_component_update_bits(component
,
861 DA7219_DAI_CLK_EN_MASK
,
871 static int da7219_settling_event(struct snd_soc_dapm_widget
*w
,
872 struct snd_kcontrol
*kcontrol
, int event
)
875 case SND_SOC_DAPM_POST_PMU
:
876 case SND_SOC_DAPM_POST_PMD
:
877 msleep(DA7219_SETTLING_DELAY
);
886 static int da7219_mixout_event(struct snd_soc_dapm_widget
*w
,
887 struct snd_kcontrol
*kcontrol
, int event
)
889 struct snd_soc_component
*component
= snd_soc_dapm_to_component(w
->dapm
);
890 u8 hp_ctrl
, min_gain_mask
;
893 case DA7219_MIXOUT_L_CTRL
:
894 hp_ctrl
= DA7219_HP_L_CTRL
;
895 min_gain_mask
= DA7219_HP_L_AMP_MIN_GAIN_EN_MASK
;
897 case DA7219_MIXOUT_R_CTRL
:
898 hp_ctrl
= DA7219_HP_R_CTRL
;
899 min_gain_mask
= DA7219_HP_R_AMP_MIN_GAIN_EN_MASK
;
906 case SND_SOC_DAPM_PRE_PMD
:
907 /* Enable minimum gain on HP to avoid pops */
908 snd_soc_component_update_bits(component
, hp_ctrl
, min_gain_mask
,
911 msleep(DA7219_MIN_GAIN_DELAY
);
914 case SND_SOC_DAPM_POST_PMU
:
915 /* Remove minimum gain on HP */
916 snd_soc_component_update_bits(component
, hp_ctrl
, min_gain_mask
, 0);
924 static int da7219_gain_ramp_event(struct snd_soc_dapm_widget
*w
,
925 struct snd_kcontrol
*kcontrol
, int event
)
927 struct snd_soc_component
*component
= snd_soc_dapm_to_component(w
->dapm
);
928 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
931 case SND_SOC_DAPM_PRE_PMU
:
932 case SND_SOC_DAPM_PRE_PMD
:
933 /* Ensure nominal gain ramping for DAPM sequence */
934 da7219
->gain_ramp_ctrl
=
935 snd_soc_component_read32(component
, DA7219_GAIN_RAMP_CTRL
);
936 snd_soc_component_write(component
, DA7219_GAIN_RAMP_CTRL
,
937 DA7219_GAIN_RAMP_RATE_NOMINAL
);
939 case SND_SOC_DAPM_POST_PMU
:
940 case SND_SOC_DAPM_POST_PMD
:
941 /* Restore previous gain ramp settings */
942 snd_soc_component_write(component
, DA7219_GAIN_RAMP_CTRL
,
943 da7219
->gain_ramp_ctrl
);
955 static const struct snd_soc_dapm_widget da7219_dapm_widgets
[] = {
957 SND_SOC_DAPM_SUPPLY("Mic Bias", DA7219_MICBIAS_CTRL
,
958 DA7219_MICBIAS1_EN_SHIFT
, DA7219_NO_INVERT
,
962 SND_SOC_DAPM_INPUT("MIC"),
965 SND_SOC_DAPM_PGA_E("Mic PGA", DA7219_MIC_1_CTRL
,
966 DA7219_MIC_1_AMP_EN_SHIFT
, DA7219_NO_INVERT
,
967 NULL
, 0, da7219_mic_pga_event
, SND_SOC_DAPM_POST_PMU
),
968 SND_SOC_DAPM_PGA_E("Mixin PGA", DA7219_MIXIN_L_CTRL
,
969 DA7219_MIXIN_L_AMP_EN_SHIFT
, DA7219_NO_INVERT
,
970 NULL
, 0, da7219_settling_event
, SND_SOC_DAPM_POST_PMU
),
973 SND_SOC_DAPM_ADC("ADC", NULL
, DA7219_ADC_L_CTRL
, DA7219_ADC_L_EN_SHIFT
,
977 SND_SOC_DAPM_SIGGEN("TONE"),
978 SND_SOC_DAPM_PGA("Tone Generator", DA7219_TONE_GEN_CFG1
,
979 DA7219_START_STOPN_SHIFT
, DA7219_NO_INVERT
, NULL
, 0),
982 SND_SOC_DAPM_ADC("Sidetone Filter", NULL
, DA7219_SIDETONE_CTRL
,
983 DA7219_SIDETONE_EN_SHIFT
, DA7219_NO_INVERT
),
985 /* Input Mixer Supply */
986 SND_SOC_DAPM_SUPPLY("Mixer In Supply", DA7219_MIXIN_L_CTRL
,
987 DA7219_MIXIN_L_MIX_EN_SHIFT
, DA7219_NO_INVERT
,
991 SND_SOC_DAPM_MIXER("Mixer In", SND_SOC_NOPM
, 0, 0,
992 da7219_mixin_controls
,
993 ARRAY_SIZE(da7219_mixin_controls
)),
996 SND_SOC_DAPM_MUX("Out DAIL Mux", SND_SOC_NOPM
, 0, 0,
997 &da7219_out_dail_sel_mux
),
998 SND_SOC_DAPM_MUX("Out DAIR Mux", SND_SOC_NOPM
, 0, 0,
999 &da7219_out_dair_sel_mux
),
1002 SND_SOC_DAPM_SUPPLY("DAI", DA7219_DAI_CTRL
, DA7219_DAI_EN_SHIFT
,
1003 DA7219_NO_INVERT
, da7219_dai_event
,
1004 SND_SOC_DAPM_PRE_PMU
| SND_SOC_DAPM_POST_PMD
),
1007 SND_SOC_DAPM_AIF_OUT("DAIOUT", "Capture", 0, DA7219_DAI_TDM_CTRL
,
1008 DA7219_DAI_OE_SHIFT
, DA7219_NO_INVERT
),
1009 SND_SOC_DAPM_AIF_IN("DAIIN", "Playback", 0, SND_SOC_NOPM
, 0, 0),
1012 SND_SOC_DAPM_MUX("Out DACL Mux", SND_SOC_NOPM
, 0, 0,
1013 &da7219_out_dacl_sel_mux
),
1014 SND_SOC_DAPM_MUX("Out DACR Mux", SND_SOC_NOPM
, 0, 0,
1015 &da7219_out_dacr_sel_mux
),
1018 SND_SOC_DAPM_MIXER("Mixer Out FilterL", SND_SOC_NOPM
, 0, 0,
1019 da7219_mixout_l_controls
,
1020 ARRAY_SIZE(da7219_mixout_l_controls
)),
1021 SND_SOC_DAPM_MIXER("Mixer Out FilterR", SND_SOC_NOPM
, 0, 0,
1022 da7219_mixout_r_controls
,
1023 ARRAY_SIZE(da7219_mixout_r_controls
)),
1025 /* Sidetone Mixers */
1026 SND_SOC_DAPM_MIXER("ST Mixer Out FilterL", SND_SOC_NOPM
, 0, 0,
1027 da7219_st_out_filtl_mix_controls
,
1028 ARRAY_SIZE(da7219_st_out_filtl_mix_controls
)),
1029 SND_SOC_DAPM_MIXER("ST Mixer Out FilterR", SND_SOC_NOPM
, 0,
1030 0, da7219_st_out_filtr_mix_controls
,
1031 ARRAY_SIZE(da7219_st_out_filtr_mix_controls
)),
1034 SND_SOC_DAPM_DAC_E("DACL", NULL
, DA7219_DAC_L_CTRL
,
1035 DA7219_DAC_L_EN_SHIFT
, DA7219_NO_INVERT
,
1036 da7219_settling_event
,
1037 SND_SOC_DAPM_POST_PMU
| SND_SOC_DAPM_POST_PMD
),
1038 SND_SOC_DAPM_DAC_E("DACR", NULL
, DA7219_DAC_R_CTRL
,
1039 DA7219_DAC_R_EN_SHIFT
, DA7219_NO_INVERT
,
1040 da7219_settling_event
,
1041 SND_SOC_DAPM_POST_PMU
| SND_SOC_DAPM_POST_PMD
),
1044 SND_SOC_DAPM_PGA_E("Mixout Left PGA", DA7219_MIXOUT_L_CTRL
,
1045 DA7219_MIXOUT_L_AMP_EN_SHIFT
, DA7219_NO_INVERT
,
1046 NULL
, 0, da7219_mixout_event
,
1047 SND_SOC_DAPM_POST_PMU
| SND_SOC_DAPM_PRE_PMD
),
1048 SND_SOC_DAPM_PGA_E("Mixout Right PGA", DA7219_MIXOUT_R_CTRL
,
1049 DA7219_MIXOUT_R_AMP_EN_SHIFT
, DA7219_NO_INVERT
,
1050 NULL
, 0, da7219_mixout_event
,
1051 SND_SOC_DAPM_POST_PMU
| SND_SOC_DAPM_PRE_PMD
),
1052 SND_SOC_DAPM_SUPPLY_S("Headphone Left PGA", 1, DA7219_HP_L_CTRL
,
1053 DA7219_HP_L_AMP_EN_SHIFT
, DA7219_NO_INVERT
,
1054 da7219_settling_event
,
1055 SND_SOC_DAPM_POST_PMU
| SND_SOC_DAPM_POST_PMD
),
1056 SND_SOC_DAPM_SUPPLY_S("Headphone Right PGA", 1, DA7219_HP_R_CTRL
,
1057 DA7219_HP_R_AMP_EN_SHIFT
, DA7219_NO_INVERT
,
1058 da7219_settling_event
,
1059 SND_SOC_DAPM_POST_PMU
| SND_SOC_DAPM_POST_PMD
),
1061 /* Output Supplies */
1062 SND_SOC_DAPM_SUPPLY_S("Charge Pump", 0, DA7219_CP_CTRL
,
1063 DA7219_CP_EN_SHIFT
, DA7219_NO_INVERT
,
1064 da7219_settling_event
,
1065 SND_SOC_DAPM_POST_PMU
),
1068 SND_SOC_DAPM_OUTPUT("HPL"),
1069 SND_SOC_DAPM_OUTPUT("HPR"),
1071 /* Pre/Post Power */
1072 SND_SOC_DAPM_PRE("Pre Power Gain Ramp", da7219_gain_ramp_event
),
1073 SND_SOC_DAPM_POST("Post Power Gain Ramp", da7219_gain_ramp_event
),
1081 #define DA7219_OUT_DAI_MUX_ROUTES(name) \
1082 {name, "ADC", "Mixer In"}, \
1083 {name, "Tone Generator", "Tone Generator"}, \
1084 {name, "DAIL", "DAIOUT"}, \
1085 {name, "DAIR", "DAIOUT"}
1087 #define DA7219_OUT_DAC_MUX_ROUTES(name) \
1088 {name, "ADC", "Mixer In"}, \
1089 {name, "Tone Generator", "Tone Generator"}, \
1090 {name, "DAIL", "DAIIN"}, \
1091 {name, "DAIR", "DAIIN"}
1097 #define DA7219_DMIX_ST_ROUTES(name) \
1098 {name, "Out FilterL Switch", "Mixer Out FilterL"}, \
1099 {name, "Out FilterR Switch", "Mixer Out FilterR"}, \
1100 {name, "Sidetone Switch", "Sidetone Filter"}
1104 * DAPM audio route definition
1107 static const struct snd_soc_dapm_route da7219_audio_map
[] = {
1109 {"MIC", NULL
, "Mic Bias"},
1110 {"Mic PGA", NULL
, "MIC"},
1111 {"Mixin PGA", NULL
, "Mic PGA"},
1112 {"ADC", NULL
, "Mixin PGA"},
1114 {"Mixer In", NULL
, "Mixer In Supply"},
1115 {"Mixer In", "Mic Switch", "ADC"},
1117 {"Sidetone Filter", NULL
, "Mixer In"},
1119 {"Tone Generator", NULL
, "TONE"},
1121 DA7219_OUT_DAI_MUX_ROUTES("Out DAIL Mux"),
1122 DA7219_OUT_DAI_MUX_ROUTES("Out DAIR Mux"),
1124 {"DAIOUT", NULL
, "Out DAIL Mux"},
1125 {"DAIOUT", NULL
, "Out DAIR Mux"},
1126 {"DAIOUT", NULL
, "DAI"},
1129 {"DAIIN", NULL
, "DAI"},
1131 DA7219_OUT_DAC_MUX_ROUTES("Out DACL Mux"),
1132 DA7219_OUT_DAC_MUX_ROUTES("Out DACR Mux"),
1134 {"Mixer Out FilterL", "DACL Switch", "Out DACL Mux"},
1135 {"Mixer Out FilterR", "DACR Switch", "Out DACR Mux"},
1137 DA7219_DMIX_ST_ROUTES("ST Mixer Out FilterL"),
1138 DA7219_DMIX_ST_ROUTES("ST Mixer Out FilterR"),
1140 {"DACL", NULL
, "ST Mixer Out FilterL"},
1141 {"DACR", NULL
, "ST Mixer Out FilterR"},
1143 {"Mixout Left PGA", NULL
, "DACL"},
1144 {"Mixout Right PGA", NULL
, "DACR"},
1146 {"HPL", NULL
, "Mixout Left PGA"},
1147 {"HPR", NULL
, "Mixout Right PGA"},
1149 {"HPL", NULL
, "Headphone Left PGA"},
1150 {"HPR", NULL
, "Headphone Right PGA"},
1152 {"HPL", NULL
, "Charge Pump"},
1153 {"HPR", NULL
, "Charge Pump"},
1161 static int da7219_set_dai_sysclk(struct snd_soc_dai
*codec_dai
,
1162 int clk_id
, unsigned int freq
, int dir
)
1164 struct snd_soc_component
*component
= codec_dai
->component
;
1165 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
1168 if ((da7219
->clk_src
== clk_id
) && (da7219
->mclk_rate
== freq
))
1171 if ((freq
< 2000000) || (freq
> 54000000)) {
1172 dev_err(codec_dai
->dev
, "Unsupported MCLK value %d\n",
1177 mutex_lock(&da7219
->pll_lock
);
1180 case DA7219_CLKSRC_MCLK_SQR
:
1181 snd_soc_component_update_bits(component
, DA7219_PLL_CTRL
,
1182 DA7219_PLL_MCLK_SQR_EN_MASK
,
1183 DA7219_PLL_MCLK_SQR_EN_MASK
);
1185 case DA7219_CLKSRC_MCLK
:
1186 snd_soc_component_update_bits(component
, DA7219_PLL_CTRL
,
1187 DA7219_PLL_MCLK_SQR_EN_MASK
, 0);
1190 dev_err(codec_dai
->dev
, "Unknown clock source %d\n", clk_id
);
1191 mutex_unlock(&da7219
->pll_lock
);
1195 da7219
->clk_src
= clk_id
;
1198 freq
= clk_round_rate(da7219
->mclk
, freq
);
1199 ret
= clk_set_rate(da7219
->mclk
, freq
);
1201 dev_err(codec_dai
->dev
, "Failed to set clock rate %d\n",
1203 mutex_unlock(&da7219
->pll_lock
);
1208 da7219
->mclk_rate
= freq
;
1210 mutex_unlock(&da7219
->pll_lock
);
1215 int da7219_set_pll(struct snd_soc_component
*component
, int source
, unsigned int fout
)
1217 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
1219 u8 pll_ctrl
, indiv_bits
, indiv
;
1220 u8 pll_frac_top
, pll_frac_bot
, pll_integer
;
1224 /* Verify 2MHz - 54MHz MCLK provided, and set input divider */
1225 if (da7219
->mclk_rate
< 2000000) {
1226 dev_err(component
->dev
, "PLL input clock %d below valid range\n",
1229 } else if (da7219
->mclk_rate
<= 4500000) {
1230 indiv_bits
= DA7219_PLL_INDIV_2_TO_4_5_MHZ
;
1231 indiv
= DA7219_PLL_INDIV_2_TO_4_5_MHZ_VAL
;
1232 } else if (da7219
->mclk_rate
<= 9000000) {
1233 indiv_bits
= DA7219_PLL_INDIV_4_5_TO_9_MHZ
;
1234 indiv
= DA7219_PLL_INDIV_4_5_TO_9_MHZ_VAL
;
1235 } else if (da7219
->mclk_rate
<= 18000000) {
1236 indiv_bits
= DA7219_PLL_INDIV_9_TO_18_MHZ
;
1237 indiv
= DA7219_PLL_INDIV_9_TO_18_MHZ_VAL
;
1238 } else if (da7219
->mclk_rate
<= 36000000) {
1239 indiv_bits
= DA7219_PLL_INDIV_18_TO_36_MHZ
;
1240 indiv
= DA7219_PLL_INDIV_18_TO_36_MHZ_VAL
;
1241 } else if (da7219
->mclk_rate
<= 54000000) {
1242 indiv_bits
= DA7219_PLL_INDIV_36_TO_54_MHZ
;
1243 indiv
= DA7219_PLL_INDIV_36_TO_54_MHZ_VAL
;
1245 dev_err(component
->dev
, "PLL input clock %d above valid range\n",
1249 freq_ref
= (da7219
->mclk_rate
/ indiv
);
1250 pll_ctrl
= indiv_bits
;
1254 case DA7219_SYSCLK_MCLK
:
1255 pll_ctrl
|= DA7219_PLL_MODE_BYPASS
;
1256 snd_soc_component_update_bits(component
, DA7219_PLL_CTRL
,
1257 DA7219_PLL_INDIV_MASK
|
1258 DA7219_PLL_MODE_MASK
, pll_ctrl
);
1260 case DA7219_SYSCLK_PLL
:
1261 pll_ctrl
|= DA7219_PLL_MODE_NORMAL
;
1263 case DA7219_SYSCLK_PLL_SRM
:
1264 pll_ctrl
|= DA7219_PLL_MODE_SRM
;
1267 dev_err(component
->dev
, "Invalid PLL config\n");
1271 /* Calculate dividers for PLL */
1272 pll_integer
= fout
/ freq_ref
;
1273 frac_div
= (u64
)(fout
% freq_ref
) * 8192ULL;
1274 do_div(frac_div
, freq_ref
);
1275 pll_frac_top
= (frac_div
>> DA7219_BYTE_SHIFT
) & DA7219_BYTE_MASK
;
1276 pll_frac_bot
= (frac_div
) & DA7219_BYTE_MASK
;
1278 /* Write PLL config & dividers */
1279 snd_soc_component_write(component
, DA7219_PLL_FRAC_TOP
, pll_frac_top
);
1280 snd_soc_component_write(component
, DA7219_PLL_FRAC_BOT
, pll_frac_bot
);
1281 snd_soc_component_write(component
, DA7219_PLL_INTEGER
, pll_integer
);
1282 snd_soc_component_update_bits(component
, DA7219_PLL_CTRL
,
1283 DA7219_PLL_INDIV_MASK
| DA7219_PLL_MODE_MASK
,
1289 static int da7219_set_dai_pll(struct snd_soc_dai
*codec_dai
, int pll_id
,
1290 int source
, unsigned int fref
, unsigned int fout
)
1292 struct snd_soc_component
*component
= codec_dai
->component
;
1293 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
1296 mutex_lock(&da7219
->pll_lock
);
1297 ret
= da7219_set_pll(component
, source
, fout
);
1298 mutex_unlock(&da7219
->pll_lock
);
1303 static int da7219_set_dai_fmt(struct snd_soc_dai
*codec_dai
, unsigned int fmt
)
1305 struct snd_soc_component
*component
= codec_dai
->component
;
1306 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
1307 u8 dai_clk_mode
= 0, dai_ctrl
= 0;
1309 switch (fmt
& SND_SOC_DAIFMT_MASTER_MASK
) {
1310 case SND_SOC_DAIFMT_CBM_CFM
:
1311 da7219
->master
= true;
1313 case SND_SOC_DAIFMT_CBS_CFS
:
1314 da7219
->master
= false;
1320 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
1321 case SND_SOC_DAIFMT_I2S
:
1322 case SND_SOC_DAIFMT_LEFT_J
:
1323 case SND_SOC_DAIFMT_RIGHT_J
:
1324 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
1325 case SND_SOC_DAIFMT_NB_NF
:
1327 case SND_SOC_DAIFMT_NB_IF
:
1328 dai_clk_mode
|= DA7219_DAI_WCLK_POL_INV
;
1330 case SND_SOC_DAIFMT_IB_NF
:
1331 dai_clk_mode
|= DA7219_DAI_CLK_POL_INV
;
1333 case SND_SOC_DAIFMT_IB_IF
:
1334 dai_clk_mode
|= DA7219_DAI_WCLK_POL_INV
|
1335 DA7219_DAI_CLK_POL_INV
;
1341 case SND_SOC_DAIFMT_DSP_B
:
1342 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
1343 case SND_SOC_DAIFMT_NB_NF
:
1344 dai_clk_mode
|= DA7219_DAI_CLK_POL_INV
;
1346 case SND_SOC_DAIFMT_NB_IF
:
1347 dai_clk_mode
|= DA7219_DAI_WCLK_POL_INV
|
1348 DA7219_DAI_CLK_POL_INV
;
1350 case SND_SOC_DAIFMT_IB_NF
:
1352 case SND_SOC_DAIFMT_IB_IF
:
1353 dai_clk_mode
|= DA7219_DAI_WCLK_POL_INV
;
1363 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
1364 case SND_SOC_DAIFMT_I2S
:
1365 dai_ctrl
|= DA7219_DAI_FORMAT_I2S
;
1367 case SND_SOC_DAIFMT_LEFT_J
:
1368 dai_ctrl
|= DA7219_DAI_FORMAT_LEFT_J
;
1370 case SND_SOC_DAIFMT_RIGHT_J
:
1371 dai_ctrl
|= DA7219_DAI_FORMAT_RIGHT_J
;
1373 case SND_SOC_DAIFMT_DSP_B
:
1374 dai_ctrl
|= DA7219_DAI_FORMAT_DSP
;
1380 snd_soc_component_update_bits(component
, DA7219_DAI_CLK_MODE
,
1381 DA7219_DAI_CLK_POL_MASK
| DA7219_DAI_WCLK_POL_MASK
,
1383 snd_soc_component_update_bits(component
, DA7219_DAI_CTRL
, DA7219_DAI_FORMAT_MASK
,
1389 static int da7219_set_bclks_per_wclk(struct snd_soc_component
*component
,
1390 unsigned long factor
)
1396 bclks_per_wclk
= DA7219_DAI_BCLKS_PER_WCLK_32
;
1399 bclks_per_wclk
= DA7219_DAI_BCLKS_PER_WCLK_64
;
1402 bclks_per_wclk
= DA7219_DAI_BCLKS_PER_WCLK_128
;
1405 bclks_per_wclk
= DA7219_DAI_BCLKS_PER_WCLK_256
;
1411 snd_soc_component_update_bits(component
, DA7219_DAI_CLK_MODE
,
1412 DA7219_DAI_BCLKS_PER_WCLK_MASK
,
1418 static int da7219_set_dai_tdm_slot(struct snd_soc_dai
*dai
,
1419 unsigned int tx_mask
, unsigned int rx_mask
,
1420 int slots
, int slot_width
)
1422 struct snd_soc_component
*component
= dai
->component
;
1423 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
1424 struct clk
*wclk
= da7219
->dai_clks
[DA7219_DAI_WCLK_IDX
];
1425 struct clk
*bclk
= da7219
->dai_clks
[DA7219_DAI_BCLK_IDX
];
1426 unsigned int ch_mask
;
1427 unsigned long sr
, bclk_rate
;
1434 /* No channels enabled so disable TDM */
1436 snd_soc_component_update_bits(component
, DA7219_DAI_TDM_CTRL
,
1437 DA7219_DAI_TDM_CH_EN_MASK
|
1438 DA7219_DAI_TDM_MODE_EN_MASK
, 0);
1439 da7219
->tdm_en
= false;
1443 /* Check we have valid slots */
1444 slot_offset
= ffs(tx_mask
) - 1;
1445 ch_mask
= (tx_mask
>> slot_offset
);
1446 if (fls(ch_mask
) > DA7219_DAI_TDM_MAX_SLOTS
) {
1447 dev_err(component
->dev
,
1448 "Invalid number of slots, max = %d\n",
1449 DA7219_DAI_TDM_MAX_SLOTS
);
1454 * Ensure we have a valid offset into the frame, based on slot width
1455 * and slot offset of first slot we're interested in.
1457 offset
= slot_offset
* slot_width
;
1458 if (offset
> DA7219_DAI_OFFSET_MAX
) {
1459 dev_err(component
->dev
, "Invalid frame offset %d\n", offset
);
1464 * If we're master, calculate & validate frame size based on slot info
1465 * provided as we have a limited set of rates available.
1467 if (da7219
->master
) {
1468 frame_size
= slots
* slot_width
;
1471 sr
= clk_get_rate(wclk
);
1472 bclk_rate
= sr
* frame_size
;
1473 ret
= clk_set_rate(bclk
, bclk_rate
);
1475 dev_err(component
->dev
,
1476 "Failed to set TDM BCLK rate %lu: %d\n",
1481 ret
= da7219_set_bclks_per_wclk(component
, frame_size
);
1483 dev_err(component
->dev
,
1484 "Failed to set TDM BCLKs per WCLK %d: %d\n",
1491 dai_offset
= cpu_to_le16(offset
);
1492 regmap_bulk_write(da7219
->regmap
, DA7219_DAI_OFFSET_LOWER
,
1493 &dai_offset
, sizeof(dai_offset
));
1495 snd_soc_component_update_bits(component
, DA7219_DAI_TDM_CTRL
,
1496 DA7219_DAI_TDM_CH_EN_MASK
|
1497 DA7219_DAI_TDM_MODE_EN_MASK
,
1498 (ch_mask
<< DA7219_DAI_TDM_CH_EN_SHIFT
) |
1499 DA7219_DAI_TDM_MODE_EN_MASK
);
1501 da7219
->tdm_en
= true;
1506 static int da7219_set_sr(struct snd_soc_component
*component
,
1513 fs
= DA7219_SR_8000
;
1516 fs
= DA7219_SR_11025
;
1519 fs
= DA7219_SR_12000
;
1522 fs
= DA7219_SR_16000
;
1525 fs
= DA7219_SR_22050
;
1528 fs
= DA7219_SR_24000
;
1531 fs
= DA7219_SR_32000
;
1534 fs
= DA7219_SR_44100
;
1537 fs
= DA7219_SR_48000
;
1540 fs
= DA7219_SR_88200
;
1543 fs
= DA7219_SR_96000
;
1549 snd_soc_component_write(component
, DA7219_SR
, fs
);
1554 static int da7219_hw_params(struct snd_pcm_substream
*substream
,
1555 struct snd_pcm_hw_params
*params
,
1556 struct snd_soc_dai
*dai
)
1558 struct snd_soc_component
*component
= dai
->component
;
1559 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
1560 struct clk
*wclk
= da7219
->dai_clks
[DA7219_DAI_WCLK_IDX
];
1561 struct clk
*bclk
= da7219
->dai_clks
[DA7219_DAI_BCLK_IDX
];
1563 unsigned int channels
;
1564 unsigned long sr
, bclk_rate
;
1565 int word_len
= params_width(params
);
1566 int frame_size
, ret
;
1570 dai_ctrl
|= DA7219_DAI_WORD_LENGTH_S16_LE
;
1573 dai_ctrl
|= DA7219_DAI_WORD_LENGTH_S20_LE
;
1576 dai_ctrl
|= DA7219_DAI_WORD_LENGTH_S24_LE
;
1579 dai_ctrl
|= DA7219_DAI_WORD_LENGTH_S32_LE
;
1585 channels
= params_channels(params
);
1586 if ((channels
< 1) || (channels
> DA7219_DAI_CH_NUM_MAX
)) {
1587 dev_err(component
->dev
,
1588 "Invalid number of channels, only 1 to %d supported\n",
1589 DA7219_DAI_CH_NUM_MAX
);
1592 dai_ctrl
|= channels
<< DA7219_DAI_CH_NUM_SHIFT
;
1594 sr
= params_rate(params
);
1595 if (da7219
->master
&& wclk
) {
1596 ret
= clk_set_rate(wclk
, sr
);
1598 dev_err(component
->dev
,
1599 "Failed to set WCLK SR %lu: %d\n", sr
, ret
);
1603 ret
= da7219_set_sr(component
, sr
);
1605 dev_err(component
->dev
,
1606 "Failed to set SR %lu: %d\n", sr
, ret
);
1612 * If we're master, then we have a limited set of BCLK rates we
1613 * support. For slave mode this isn't the case and the codec can detect
1614 * the BCLK rate automatically.
1616 if (da7219
->master
&& !da7219
->tdm_en
) {
1617 if ((word_len
* DA7219_DAI_CH_NUM_MAX
) <= 32)
1623 bclk_rate
= frame_size
* sr
;
1625 * Rounding the rate here avoids failure trying to set a
1626 * new rate on an already enabled bclk. In that
1627 * instance this will just set the same rate as is
1628 * currently in use, and so should continue without
1629 * problem, as long as the BCLK rate is suitable for the
1630 * desired frame size.
1632 bclk_rate
= clk_round_rate(bclk
, bclk_rate
);
1633 if ((bclk_rate
/ sr
) < frame_size
) {
1634 dev_err(component
->dev
,
1635 "BCLK rate mismatch against frame size");
1639 ret
= clk_set_rate(bclk
, bclk_rate
);
1641 dev_err(component
->dev
,
1642 "Failed to set BCLK rate %lu: %d\n",
1647 ret
= da7219_set_bclks_per_wclk(component
, frame_size
);
1649 dev_err(component
->dev
,
1650 "Failed to set BCLKs per WCLK %d: %d\n",
1657 snd_soc_component_update_bits(component
, DA7219_DAI_CTRL
,
1658 DA7219_DAI_WORD_LENGTH_MASK
|
1659 DA7219_DAI_CH_NUM_MASK
,
1665 static const struct snd_soc_dai_ops da7219_dai_ops
= {
1666 .hw_params
= da7219_hw_params
,
1667 .set_sysclk
= da7219_set_dai_sysclk
,
1668 .set_pll
= da7219_set_dai_pll
,
1669 .set_fmt
= da7219_set_dai_fmt
,
1670 .set_tdm_slot
= da7219_set_dai_tdm_slot
,
1673 #define DA7219_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1674 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1676 #define DA7219_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
1677 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
1678 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
1679 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
1680 SNDRV_PCM_RATE_96000)
1682 static struct snd_soc_dai_driver da7219_dai
= {
1683 .name
= "da7219-hifi",
1685 .stream_name
= "Playback",
1687 .channels_max
= DA7219_DAI_CH_NUM_MAX
,
1688 .rates
= DA7219_RATES
,
1689 .formats
= DA7219_FORMATS
,
1692 .stream_name
= "Capture",
1694 .channels_max
= DA7219_DAI_CH_NUM_MAX
,
1695 .rates
= DA7219_RATES
,
1696 .formats
= DA7219_FORMATS
,
1698 .ops
= &da7219_dai_ops
,
1699 .symmetric_rates
= 1,
1700 .symmetric_channels
= 1,
1701 .symmetric_samplebits
= 1,
1709 static const struct of_device_id da7219_of_match
[] = {
1710 { .compatible
= "dlg,da7219", },
1713 MODULE_DEVICE_TABLE(of
, da7219_of_match
);
1715 static const struct acpi_device_id da7219_acpi_match
[] = {
1716 { .id
= "DLGS7219", },
1719 MODULE_DEVICE_TABLE(acpi
, da7219_acpi_match
);
1721 static enum da7219_micbias_voltage
1722 da7219_fw_micbias_lvl(struct device
*dev
, u32 val
)
1726 return DA7219_MICBIAS_1_6V
;
1728 return DA7219_MICBIAS_1_8V
;
1730 return DA7219_MICBIAS_2_0V
;
1732 return DA7219_MICBIAS_2_2V
;
1734 return DA7219_MICBIAS_2_4V
;
1736 return DA7219_MICBIAS_2_6V
;
1738 dev_warn(dev
, "Invalid micbias level");
1739 return DA7219_MICBIAS_2_2V
;
1743 static enum da7219_mic_amp_in_sel
1744 da7219_fw_mic_amp_in_sel(struct device
*dev
, const char *str
)
1746 if (!strcmp(str
, "diff")) {
1747 return DA7219_MIC_AMP_IN_SEL_DIFF
;
1748 } else if (!strcmp(str
, "se_p")) {
1749 return DA7219_MIC_AMP_IN_SEL_SE_P
;
1750 } else if (!strcmp(str
, "se_n")) {
1751 return DA7219_MIC_AMP_IN_SEL_SE_N
;
1753 dev_warn(dev
, "Invalid mic input type selection");
1754 return DA7219_MIC_AMP_IN_SEL_DIFF
;
1758 static struct da7219_pdata
*da7219_fw_to_pdata(struct snd_soc_component
*component
)
1760 struct device
*dev
= component
->dev
;
1761 struct da7219_pdata
*pdata
;
1765 pdata
= devm_kzalloc(dev
, sizeof(*pdata
), GFP_KERNEL
);
1769 pdata
->wakeup_source
= device_property_read_bool(dev
, "wakeup-source");
1771 pdata
->dai_clk_names
[DA7219_DAI_WCLK_IDX
] = "da7219-dai-wclk";
1772 pdata
->dai_clk_names
[DA7219_DAI_BCLK_IDX
] = "da7219-dai-bclk";
1773 if (device_property_read_string_array(dev
, "clock-output-names",
1774 pdata
->dai_clk_names
,
1775 DA7219_DAI_NUM_CLKS
) < 0)
1776 dev_warn(dev
, "Using default DAI clk names: %s, %s\n",
1777 pdata
->dai_clk_names
[DA7219_DAI_WCLK_IDX
],
1778 pdata
->dai_clk_names
[DA7219_DAI_BCLK_IDX
]);
1780 if (device_property_read_u32(dev
, "dlg,micbias-lvl", &of_val32
) >= 0)
1781 pdata
->micbias_lvl
= da7219_fw_micbias_lvl(dev
, of_val32
);
1783 pdata
->micbias_lvl
= DA7219_MICBIAS_2_2V
;
1785 if (!device_property_read_string(dev
, "dlg,mic-amp-in-sel", &of_str
))
1786 pdata
->mic_amp_in_sel
= da7219_fw_mic_amp_in_sel(dev
, of_str
);
1788 pdata
->mic_amp_in_sel
= DA7219_MIC_AMP_IN_SEL_DIFF
;
1795 * Codec driver functions
1798 static int da7219_set_bias_level(struct snd_soc_component
*component
,
1799 enum snd_soc_bias_level level
)
1801 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
1805 case SND_SOC_BIAS_ON
:
1807 case SND_SOC_BIAS_PREPARE
:
1808 /* Enable MCLK for transition to ON state */
1809 if (snd_soc_component_get_bias_level(component
) == SND_SOC_BIAS_STANDBY
) {
1811 ret
= clk_prepare_enable(da7219
->mclk
);
1813 dev_err(component
->dev
,
1814 "Failed to enable mclk\n");
1821 case SND_SOC_BIAS_STANDBY
:
1822 if (snd_soc_component_get_bias_level(component
) == SND_SOC_BIAS_OFF
)
1824 snd_soc_component_update_bits(component
, DA7219_REFERENCES
,
1825 DA7219_BIAS_EN_MASK
,
1826 DA7219_BIAS_EN_MASK
);
1828 if (snd_soc_component_get_bias_level(component
) == SND_SOC_BIAS_PREPARE
) {
1831 clk_disable_unprepare(da7219
->mclk
);
1834 case SND_SOC_BIAS_OFF
:
1835 /* Only disable master bias if we're not a wake-up source */
1836 if (!da7219
->wakeup_source
)
1837 snd_soc_component_update_bits(component
, DA7219_REFERENCES
,
1838 DA7219_BIAS_EN_MASK
, 0);
1846 static const char *da7219_supply_names
[DA7219_NUM_SUPPLIES
] = {
1847 [DA7219_SUPPLY_VDD
] = "VDD",
1848 [DA7219_SUPPLY_VDDMIC
] = "VDDMIC",
1849 [DA7219_SUPPLY_VDDIO
] = "VDDIO",
1852 static int da7219_handle_supplies(struct snd_soc_component
*component
)
1854 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
1855 struct regulator
*vddio
;
1856 u8 io_voltage_lvl
= DA7219_IO_VOLTAGE_LEVEL_2_5V_3_6V
;
1859 /* Get required supplies */
1860 for (i
= 0; i
< DA7219_NUM_SUPPLIES
; ++i
)
1861 da7219
->supplies
[i
].supply
= da7219_supply_names
[i
];
1863 ret
= devm_regulator_bulk_get(component
->dev
, DA7219_NUM_SUPPLIES
,
1866 dev_err(component
->dev
, "Failed to get supplies");
1870 /* Determine VDDIO voltage provided */
1871 vddio
= da7219
->supplies
[DA7219_SUPPLY_VDDIO
].consumer
;
1872 ret
= regulator_get_voltage(vddio
);
1874 dev_warn(component
->dev
, "Invalid VDDIO voltage\n");
1875 else if (ret
< 2800000)
1876 io_voltage_lvl
= DA7219_IO_VOLTAGE_LEVEL_1_2V_2_8V
;
1878 /* Enable main supplies */
1879 ret
= regulator_bulk_enable(DA7219_NUM_SUPPLIES
, da7219
->supplies
);
1881 dev_err(component
->dev
, "Failed to enable supplies");
1885 /* Ensure device in active mode */
1886 snd_soc_component_write(component
, DA7219_SYSTEM_ACTIVE
, DA7219_SYSTEM_ACTIVE_MASK
);
1888 /* Update IO voltage level range */
1889 snd_soc_component_write(component
, DA7219_IO_CTRL
, io_voltage_lvl
);
1894 #ifdef CONFIG_COMMON_CLK
1895 static int da7219_wclk_prepare(struct clk_hw
*hw
)
1897 struct da7219_priv
*da7219
=
1898 container_of(hw
, struct da7219_priv
,
1899 dai_clks_hw
[DA7219_DAI_WCLK_IDX
]);
1900 struct snd_soc_component
*component
= da7219
->component
;
1902 if (!da7219
->master
)
1905 snd_soc_component_update_bits(component
, DA7219_DAI_CLK_MODE
,
1906 DA7219_DAI_CLK_EN_MASK
,
1907 DA7219_DAI_CLK_EN_MASK
);
1912 static void da7219_wclk_unprepare(struct clk_hw
*hw
)
1914 struct da7219_priv
*da7219
=
1915 container_of(hw
, struct da7219_priv
,
1916 dai_clks_hw
[DA7219_DAI_WCLK_IDX
]);
1917 struct snd_soc_component
*component
= da7219
->component
;
1919 if (!da7219
->master
)
1922 snd_soc_component_update_bits(component
, DA7219_DAI_CLK_MODE
,
1923 DA7219_DAI_CLK_EN_MASK
, 0);
1926 static int da7219_wclk_is_prepared(struct clk_hw
*hw
)
1928 struct da7219_priv
*da7219
=
1929 container_of(hw
, struct da7219_priv
,
1930 dai_clks_hw
[DA7219_DAI_WCLK_IDX
]);
1931 struct snd_soc_component
*component
= da7219
->component
;
1934 if (!da7219
->master
)
1937 clk_reg
= snd_soc_component_read32(component
, DA7219_DAI_CLK_MODE
);
1939 return !!(clk_reg
& DA7219_DAI_CLK_EN_MASK
);
1942 static unsigned long da7219_wclk_recalc_rate(struct clk_hw
*hw
,
1943 unsigned long parent_rate
)
1945 struct da7219_priv
*da7219
=
1946 container_of(hw
, struct da7219_priv
,
1947 dai_clks_hw
[DA7219_DAI_WCLK_IDX
]);
1948 struct snd_soc_component
*component
= da7219
->component
;
1949 u8 fs
= snd_soc_component_read32(component
, DA7219_SR
);
1951 switch (fs
& DA7219_SR_MASK
) {
1952 case DA7219_SR_8000
:
1954 case DA7219_SR_11025
:
1956 case DA7219_SR_12000
:
1958 case DA7219_SR_16000
:
1960 case DA7219_SR_22050
:
1962 case DA7219_SR_24000
:
1964 case DA7219_SR_32000
:
1966 case DA7219_SR_44100
:
1968 case DA7219_SR_48000
:
1970 case DA7219_SR_88200
:
1972 case DA7219_SR_96000
:
1979 static long da7219_wclk_round_rate(struct clk_hw
*hw
, unsigned long rate
,
1980 unsigned long *parent_rate
)
1982 struct da7219_priv
*da7219
=
1983 container_of(hw
, struct da7219_priv
,
1984 dai_clks_hw
[DA7219_DAI_WCLK_IDX
]);
1986 if (!da7219
->master
)
1991 else if (rate
< 12000)
1993 else if (rate
< 16000)
1995 else if (rate
< 22050)
1997 else if (rate
< 24000)
1999 else if (rate
< 32000)
2001 else if (rate
< 44100)
2003 else if (rate
< 48000)
2005 else if (rate
< 88200)
2007 else if (rate
< 96000)
2013 static int da7219_wclk_set_rate(struct clk_hw
*hw
, unsigned long rate
,
2014 unsigned long parent_rate
)
2016 struct da7219_priv
*da7219
=
2017 container_of(hw
, struct da7219_priv
,
2018 dai_clks_hw
[DA7219_DAI_WCLK_IDX
]);
2019 struct snd_soc_component
*component
= da7219
->component
;
2021 if (!da7219
->master
)
2024 return da7219_set_sr(component
, rate
);
2027 static unsigned long da7219_bclk_recalc_rate(struct clk_hw
*hw
,
2028 unsigned long parent_rate
)
2030 struct da7219_priv
*da7219
=
2031 container_of(hw
, struct da7219_priv
,
2032 dai_clks_hw
[DA7219_DAI_BCLK_IDX
]);
2033 struct snd_soc_component
*component
= da7219
->component
;
2034 u8 bclks_per_wclk
= snd_soc_component_read32(component
,
2035 DA7219_DAI_CLK_MODE
);
2037 switch (bclks_per_wclk
& DA7219_DAI_BCLKS_PER_WCLK_MASK
) {
2038 case DA7219_DAI_BCLKS_PER_WCLK_32
:
2039 return parent_rate
* 32;
2040 case DA7219_DAI_BCLKS_PER_WCLK_64
:
2041 return parent_rate
* 64;
2042 case DA7219_DAI_BCLKS_PER_WCLK_128
:
2043 return parent_rate
* 128;
2044 case DA7219_DAI_BCLKS_PER_WCLK_256
:
2045 return parent_rate
* 256;
2051 static unsigned long da7219_bclk_get_factor(unsigned long rate
,
2052 unsigned long parent_rate
)
2054 unsigned long factor
;
2056 factor
= rate
/ parent_rate
;
2059 else if (factor
< 128)
2061 else if (factor
< 256)
2067 static long da7219_bclk_round_rate(struct clk_hw
*hw
, unsigned long rate
,
2068 unsigned long *parent_rate
)
2070 struct da7219_priv
*da7219
=
2071 container_of(hw
, struct da7219_priv
,
2072 dai_clks_hw
[DA7219_DAI_BCLK_IDX
]);
2073 unsigned long factor
;
2075 if (!*parent_rate
|| !da7219
->master
)
2079 * We don't allow changing the parent rate as some BCLK rates can be
2080 * derived from multiple parent WCLK rates (BCLK rates are set as a
2081 * multiplier of WCLK in HW). We just do some rounding down based on the
2082 * parent WCLK rate set and find the appropriate multiplier of BCLK to
2083 * get the rounded down BCLK value.
2085 factor
= da7219_bclk_get_factor(rate
, *parent_rate
);
2087 return *parent_rate
* factor
;
2090 static int da7219_bclk_set_rate(struct clk_hw
*hw
, unsigned long rate
,
2091 unsigned long parent_rate
)
2093 struct da7219_priv
*da7219
=
2094 container_of(hw
, struct da7219_priv
,
2095 dai_clks_hw
[DA7219_DAI_BCLK_IDX
]);
2096 struct snd_soc_component
*component
= da7219
->component
;
2097 unsigned long factor
;
2099 if (!da7219
->master
)
2102 factor
= da7219_bclk_get_factor(rate
, parent_rate
);
2104 return da7219_set_bclks_per_wclk(component
, factor
);
2107 static const struct clk_ops da7219_dai_clk_ops
[DA7219_DAI_NUM_CLKS
] = {
2108 [DA7219_DAI_WCLK_IDX
] = {
2109 .prepare
= da7219_wclk_prepare
,
2110 .unprepare
= da7219_wclk_unprepare
,
2111 .is_prepared
= da7219_wclk_is_prepared
,
2112 .recalc_rate
= da7219_wclk_recalc_rate
,
2113 .round_rate
= da7219_wclk_round_rate
,
2114 .set_rate
= da7219_wclk_set_rate
,
2116 [DA7219_DAI_BCLK_IDX
] = {
2117 .recalc_rate
= da7219_bclk_recalc_rate
,
2118 .round_rate
= da7219_bclk_round_rate
,
2119 .set_rate
= da7219_bclk_set_rate
,
2123 static int da7219_register_dai_clks(struct snd_soc_component
*component
)
2125 struct device
*dev
= component
->dev
;
2126 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
2127 struct da7219_pdata
*pdata
= da7219
->pdata
;
2128 const char *parent_name
;
2131 for (i
= 0; i
< DA7219_DAI_NUM_CLKS
; ++i
) {
2132 struct clk_init_data init
= {};
2133 struct clk
*dai_clk
;
2134 struct clk_lookup
*dai_clk_lookup
;
2135 struct clk_hw
*dai_clk_hw
= &da7219
->dai_clks_hw
[i
];
2138 case DA7219_DAI_WCLK_IDX
:
2140 * If we can, make MCLK the parent of WCLK to ensure
2141 * it's enabled as required.
2144 parent_name
= __clk_get_name(da7219
->mclk
);
2145 init
.parent_names
= &parent_name
;
2146 init
.num_parents
= 1;
2148 init
.parent_names
= NULL
;
2149 init
.num_parents
= 0;
2152 case DA7219_DAI_BCLK_IDX
:
2153 /* Make WCLK the parent of BCLK */
2154 parent_name
= __clk_get_name(da7219
->dai_clks
[DA7219_DAI_WCLK_IDX
]);
2155 init
.parent_names
= &parent_name
;
2156 init
.num_parents
= 1;
2159 dev_err(dev
, "Invalid clock index\n");
2164 init
.name
= pdata
->dai_clk_names
[i
];
2165 init
.ops
= &da7219_dai_clk_ops
[i
];
2166 init
.flags
= CLK_GET_RATE_NOCACHE
| CLK_SET_RATE_GATE
;
2167 dai_clk_hw
->init
= &init
;
2169 dai_clk
= devm_clk_register(dev
, dai_clk_hw
);
2170 if (IS_ERR(dai_clk
)) {
2171 dev_warn(dev
, "Failed to register %s: %ld\n",
2172 init
.name
, PTR_ERR(dai_clk
));
2173 ret
= PTR_ERR(dai_clk
);
2176 da7219
->dai_clks
[i
] = dai_clk
;
2178 /* If we're using DT, then register as provider accordingly */
2180 devm_of_clk_add_hw_provider(dev
, of_clk_hw_simple_get
,
2183 dai_clk_lookup
= clkdev_create(dai_clk
, init
.name
,
2184 "%s", dev_name(dev
));
2185 if (!dai_clk_lookup
) {
2189 da7219
->dai_clks_lookup
[i
] = dai_clk_lookup
;
2198 if (da7219
->dai_clks_lookup
[i
])
2199 clkdev_drop(da7219
->dai_clks_lookup
[i
]);
2205 static inline int da7219_register_dai_clks(struct snd_soc_component
*component
)
2209 #endif /* CONFIG_COMMON_CLK */
2211 static void da7219_handle_pdata(struct snd_soc_component
*component
)
2213 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
2214 struct da7219_pdata
*pdata
= da7219
->pdata
;
2219 da7219
->wakeup_source
= pdata
->wakeup_source
;
2221 /* Mic Bias voltages */
2222 switch (pdata
->micbias_lvl
) {
2223 case DA7219_MICBIAS_1_6V
:
2224 case DA7219_MICBIAS_1_8V
:
2225 case DA7219_MICBIAS_2_0V
:
2226 case DA7219_MICBIAS_2_2V
:
2227 case DA7219_MICBIAS_2_4V
:
2228 case DA7219_MICBIAS_2_6V
:
2229 micbias_lvl
|= (pdata
->micbias_lvl
<<
2230 DA7219_MICBIAS1_LEVEL_SHIFT
);
2234 snd_soc_component_write(component
, DA7219_MICBIAS_CTRL
, micbias_lvl
);
2237 * Calculate delay required to compensate for DC offset in
2238 * Mic PGA, based on Mic Bias voltage.
2240 da7219
->mic_pga_delay
= DA7219_MIC_PGA_BASE_DELAY
+
2241 (pdata
->micbias_lvl
*
2242 DA7219_MIC_PGA_OFFSET_DELAY
);
2245 switch (pdata
->mic_amp_in_sel
) {
2246 case DA7219_MIC_AMP_IN_SEL_DIFF
:
2247 case DA7219_MIC_AMP_IN_SEL_SE_P
:
2248 case DA7219_MIC_AMP_IN_SEL_SE_N
:
2249 snd_soc_component_write(component
, DA7219_MIC_1_SELECT
,
2250 pdata
->mic_amp_in_sel
);
2256 static struct reg_sequence da7219_rev_aa_patch
[] = {
2257 { DA7219_REFERENCES
, 0x08 },
2260 static int da7219_probe(struct snd_soc_component
*component
)
2262 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
2266 da7219
->component
= component
;
2267 mutex_init(&da7219
->ctrl_lock
);
2268 mutex_init(&da7219
->pll_lock
);
2270 /* Regulator configuration */
2271 ret
= da7219_handle_supplies(component
);
2275 ret
= regmap_read(da7219
->regmap
, DA7219_CHIP_REVISION
, &rev
);
2277 dev_err(component
->dev
, "Failed to read chip revision: %d\n", ret
);
2278 goto err_disable_reg
;
2281 switch (rev
& DA7219_CHIP_MINOR_MASK
) {
2283 ret
= regmap_register_patch(da7219
->regmap
, da7219_rev_aa_patch
,
2284 ARRAY_SIZE(da7219_rev_aa_patch
));
2286 dev_err(component
->dev
, "Failed to register AA patch: %d\n",
2288 goto err_disable_reg
;
2295 /* Handle DT/ACPI/Platform data */
2296 da7219
->pdata
= dev_get_platdata(component
->dev
);
2298 da7219
->pdata
= da7219_fw_to_pdata(component
);
2300 da7219_handle_pdata(component
);
2302 /* Check if MCLK provided */
2303 da7219
->mclk
= devm_clk_get(component
->dev
, "mclk");
2304 if (IS_ERR(da7219
->mclk
)) {
2305 if (PTR_ERR(da7219
->mclk
) != -ENOENT
) {
2306 ret
= PTR_ERR(da7219
->mclk
);
2307 goto err_disable_reg
;
2309 da7219
->mclk
= NULL
;
2313 /* Register CCF DAI clock control */
2314 ret
= da7219_register_dai_clks(component
);
2318 /* Default PC counter to free-running */
2319 snd_soc_component_update_bits(component
, DA7219_PC_COUNT
, DA7219_PC_FREERUN_MASK
,
2320 DA7219_PC_FREERUN_MASK
);
2322 /* Default gain ramping */
2323 snd_soc_component_update_bits(component
, DA7219_MIXIN_L_CTRL
,
2324 DA7219_MIXIN_L_AMP_RAMP_EN_MASK
,
2325 DA7219_MIXIN_L_AMP_RAMP_EN_MASK
);
2326 snd_soc_component_update_bits(component
, DA7219_ADC_L_CTRL
, DA7219_ADC_L_RAMP_EN_MASK
,
2327 DA7219_ADC_L_RAMP_EN_MASK
);
2328 snd_soc_component_update_bits(component
, DA7219_DAC_L_CTRL
, DA7219_DAC_L_RAMP_EN_MASK
,
2329 DA7219_DAC_L_RAMP_EN_MASK
);
2330 snd_soc_component_update_bits(component
, DA7219_DAC_R_CTRL
, DA7219_DAC_R_RAMP_EN_MASK
,
2331 DA7219_DAC_R_RAMP_EN_MASK
);
2332 snd_soc_component_update_bits(component
, DA7219_HP_L_CTRL
,
2333 DA7219_HP_L_AMP_RAMP_EN_MASK
,
2334 DA7219_HP_L_AMP_RAMP_EN_MASK
);
2335 snd_soc_component_update_bits(component
, DA7219_HP_R_CTRL
,
2336 DA7219_HP_R_AMP_RAMP_EN_MASK
,
2337 DA7219_HP_R_AMP_RAMP_EN_MASK
);
2339 /* Default minimum gain on HP to avoid pops during DAPM sequencing */
2340 snd_soc_component_update_bits(component
, DA7219_HP_L_CTRL
,
2341 DA7219_HP_L_AMP_MIN_GAIN_EN_MASK
,
2342 DA7219_HP_L_AMP_MIN_GAIN_EN_MASK
);
2343 snd_soc_component_update_bits(component
, DA7219_HP_R_CTRL
,
2344 DA7219_HP_R_AMP_MIN_GAIN_EN_MASK
,
2345 DA7219_HP_R_AMP_MIN_GAIN_EN_MASK
);
2347 /* Default infinite tone gen, start/stop by Kcontrol */
2348 snd_soc_component_write(component
, DA7219_TONE_GEN_CYCLES
, DA7219_BEEP_CYCLES_MASK
);
2350 /* Initialise AAD block */
2351 ret
= da7219_aad_init(component
);
2353 goto err_disable_reg
;
2358 regulator_bulk_disable(DA7219_NUM_SUPPLIES
, da7219
->supplies
);
2363 static void da7219_remove(struct snd_soc_component
*component
)
2365 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
2368 da7219_aad_exit(component
);
2370 #ifdef CONFIG_COMMON_CLK
2371 for (i
= DA7219_DAI_NUM_CLKS
- 1; i
>= 0; --i
) {
2372 if (da7219
->dai_clks_lookup
[i
])
2373 clkdev_drop(da7219
->dai_clks_lookup
[i
]);
2378 regulator_bulk_disable(DA7219_NUM_SUPPLIES
, da7219
->supplies
);
2382 static int da7219_suspend(struct snd_soc_component
*component
)
2384 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
2386 /* Suspend AAD if we're not a wake-up source */
2387 if (!da7219
->wakeup_source
)
2388 da7219_aad_suspend(component
);
2390 snd_soc_component_force_bias_level(component
, SND_SOC_BIAS_OFF
);
2395 static int da7219_resume(struct snd_soc_component
*component
)
2397 struct da7219_priv
*da7219
= snd_soc_component_get_drvdata(component
);
2399 snd_soc_component_force_bias_level(component
, SND_SOC_BIAS_STANDBY
);
2401 /* Resume AAD if previously suspended */
2402 if (!da7219
->wakeup_source
)
2403 da7219_aad_resume(component
);
2408 #define da7219_suspend NULL
2409 #define da7219_resume NULL
2412 static const struct snd_soc_component_driver soc_component_dev_da7219
= {
2413 .probe
= da7219_probe
,
2414 .remove
= da7219_remove
,
2415 .suspend
= da7219_suspend
,
2416 .resume
= da7219_resume
,
2417 .set_bias_level
= da7219_set_bias_level
,
2418 .controls
= da7219_snd_controls
,
2419 .num_controls
= ARRAY_SIZE(da7219_snd_controls
),
2420 .dapm_widgets
= da7219_dapm_widgets
,
2421 .num_dapm_widgets
= ARRAY_SIZE(da7219_dapm_widgets
),
2422 .dapm_routes
= da7219_audio_map
,
2423 .num_dapm_routes
= ARRAY_SIZE(da7219_audio_map
),
2425 .use_pmdown_time
= 1,
2427 .non_legacy_dai_naming
= 1,
2435 static struct reg_default da7219_reg_defaults
[] = {
2436 { DA7219_MIC_1_SELECT
, 0x00 },
2437 { DA7219_CIF_TIMEOUT_CTRL
, 0x01 },
2438 { DA7219_SR_24_48
, 0x00 },
2439 { DA7219_SR
, 0x0A },
2440 { DA7219_CIF_I2C_ADDR_CFG
, 0x02 },
2441 { DA7219_PLL_CTRL
, 0x10 },
2442 { DA7219_PLL_FRAC_TOP
, 0x00 },
2443 { DA7219_PLL_FRAC_BOT
, 0x00 },
2444 { DA7219_PLL_INTEGER
, 0x20 },
2445 { DA7219_DIG_ROUTING_DAI
, 0x10 },
2446 { DA7219_DAI_CLK_MODE
, 0x01 },
2447 { DA7219_DAI_CTRL
, 0x28 },
2448 { DA7219_DAI_TDM_CTRL
, 0x40 },
2449 { DA7219_DIG_ROUTING_DAC
, 0x32 },
2450 { DA7219_DAI_OFFSET_LOWER
, 0x00 },
2451 { DA7219_DAI_OFFSET_UPPER
, 0x00 },
2452 { DA7219_REFERENCES
, 0x08 },
2453 { DA7219_MIXIN_L_SELECT
, 0x00 },
2454 { DA7219_MIXIN_L_GAIN
, 0x03 },
2455 { DA7219_ADC_L_GAIN
, 0x6F },
2456 { DA7219_ADC_FILTERS1
, 0x80 },
2457 { DA7219_MIC_1_GAIN
, 0x01 },
2458 { DA7219_SIDETONE_CTRL
, 0x40 },
2459 { DA7219_SIDETONE_GAIN
, 0x0E },
2460 { DA7219_DROUTING_ST_OUTFILT_1L
, 0x01 },
2461 { DA7219_DROUTING_ST_OUTFILT_1R
, 0x02 },
2462 { DA7219_DAC_FILTERS5
, 0x00 },
2463 { DA7219_DAC_FILTERS2
, 0x88 },
2464 { DA7219_DAC_FILTERS3
, 0x88 },
2465 { DA7219_DAC_FILTERS4
, 0x08 },
2466 { DA7219_DAC_FILTERS1
, 0x80 },
2467 { DA7219_DAC_L_GAIN
, 0x6F },
2468 { DA7219_DAC_R_GAIN
, 0x6F },
2469 { DA7219_CP_CTRL
, 0x20 },
2470 { DA7219_HP_L_GAIN
, 0x39 },
2471 { DA7219_HP_R_GAIN
, 0x39 },
2472 { DA7219_MIXOUT_L_SELECT
, 0x00 },
2473 { DA7219_MIXOUT_R_SELECT
, 0x00 },
2474 { DA7219_MICBIAS_CTRL
, 0x03 },
2475 { DA7219_MIC_1_CTRL
, 0x40 },
2476 { DA7219_MIXIN_L_CTRL
, 0x40 },
2477 { DA7219_ADC_L_CTRL
, 0x40 },
2478 { DA7219_DAC_L_CTRL
, 0x40 },
2479 { DA7219_DAC_R_CTRL
, 0x40 },
2480 { DA7219_HP_L_CTRL
, 0x40 },
2481 { DA7219_HP_R_CTRL
, 0x40 },
2482 { DA7219_MIXOUT_L_CTRL
, 0x10 },
2483 { DA7219_MIXOUT_R_CTRL
, 0x10 },
2484 { DA7219_CHIP_ID1
, 0x23 },
2485 { DA7219_CHIP_ID2
, 0x93 },
2486 { DA7219_IO_CTRL
, 0x00 },
2487 { DA7219_GAIN_RAMP_CTRL
, 0x00 },
2488 { DA7219_PC_COUNT
, 0x02 },
2489 { DA7219_CP_VOL_THRESHOLD1
, 0x0E },
2490 { DA7219_DIG_CTRL
, 0x00 },
2491 { DA7219_ALC_CTRL2
, 0x00 },
2492 { DA7219_ALC_CTRL3
, 0x00 },
2493 { DA7219_ALC_NOISE
, 0x3F },
2494 { DA7219_ALC_TARGET_MIN
, 0x3F },
2495 { DA7219_ALC_TARGET_MAX
, 0x00 },
2496 { DA7219_ALC_GAIN_LIMITS
, 0xFF },
2497 { DA7219_ALC_ANA_GAIN_LIMITS
, 0x71 },
2498 { DA7219_ALC_ANTICLIP_CTRL
, 0x00 },
2499 { DA7219_ALC_ANTICLIP_LEVEL
, 0x00 },
2500 { DA7219_DAC_NG_SETUP_TIME
, 0x00 },
2501 { DA7219_DAC_NG_OFF_THRESH
, 0x00 },
2502 { DA7219_DAC_NG_ON_THRESH
, 0x00 },
2503 { DA7219_DAC_NG_CTRL
, 0x00 },
2504 { DA7219_TONE_GEN_CFG1
, 0x00 },
2505 { DA7219_TONE_GEN_CFG2
, 0x00 },
2506 { DA7219_TONE_GEN_CYCLES
, 0x00 },
2507 { DA7219_TONE_GEN_FREQ1_L
, 0x55 },
2508 { DA7219_TONE_GEN_FREQ1_U
, 0x15 },
2509 { DA7219_TONE_GEN_FREQ2_L
, 0x00 },
2510 { DA7219_TONE_GEN_FREQ2_U
, 0x40 },
2511 { DA7219_TONE_GEN_ON_PER
, 0x02 },
2512 { DA7219_TONE_GEN_OFF_PER
, 0x01 },
2513 { DA7219_ACCDET_IRQ_MASK_A
, 0x00 },
2514 { DA7219_ACCDET_IRQ_MASK_B
, 0x00 },
2515 { DA7219_ACCDET_CONFIG_1
, 0xD6 },
2516 { DA7219_ACCDET_CONFIG_2
, 0x34 },
2517 { DA7219_ACCDET_CONFIG_3
, 0x0A },
2518 { DA7219_ACCDET_CONFIG_4
, 0x16 },
2519 { DA7219_ACCDET_CONFIG_5
, 0x21 },
2520 { DA7219_ACCDET_CONFIG_6
, 0x3E },
2521 { DA7219_ACCDET_CONFIG_7
, 0x01 },
2522 { DA7219_SYSTEM_ACTIVE
, 0x00 },
2525 static bool da7219_volatile_register(struct device
*dev
, unsigned int reg
)
2528 case DA7219_MIC_1_GAIN_STATUS
:
2529 case DA7219_MIXIN_L_GAIN_STATUS
:
2530 case DA7219_ADC_L_GAIN_STATUS
:
2531 case DA7219_DAC_L_GAIN_STATUS
:
2532 case DA7219_DAC_R_GAIN_STATUS
:
2533 case DA7219_HP_L_GAIN_STATUS
:
2534 case DA7219_HP_R_GAIN_STATUS
:
2535 case DA7219_CIF_CTRL
:
2536 case DA7219_PLL_SRM_STS
:
2537 case DA7219_ALC_CTRL1
:
2538 case DA7219_SYSTEM_MODES_INPUT
:
2539 case DA7219_SYSTEM_MODES_OUTPUT
:
2540 case DA7219_ALC_OFFSET_AUTO_M_L
:
2541 case DA7219_ALC_OFFSET_AUTO_U_L
:
2542 case DA7219_TONE_GEN_CFG1
:
2543 case DA7219_ACCDET_STATUS_A
:
2544 case DA7219_ACCDET_STATUS_B
:
2545 case DA7219_ACCDET_IRQ_EVENT_A
:
2546 case DA7219_ACCDET_IRQ_EVENT_B
:
2547 case DA7219_ACCDET_CONFIG_8
:
2548 case DA7219_SYSTEM_STATUS
:
2555 static const struct regmap_config da7219_regmap_config
= {
2559 .max_register
= DA7219_SYSTEM_ACTIVE
,
2560 .reg_defaults
= da7219_reg_defaults
,
2561 .num_reg_defaults
= ARRAY_SIZE(da7219_reg_defaults
),
2562 .volatile_reg
= da7219_volatile_register
,
2563 .cache_type
= REGCACHE_RBTREE
,
2571 static int da7219_i2c_probe(struct i2c_client
*i2c
,
2572 const struct i2c_device_id
*id
)
2574 struct da7219_priv
*da7219
;
2575 unsigned int system_active
, system_status
;
2578 da7219
= devm_kzalloc(&i2c
->dev
, sizeof(struct da7219_priv
),
2583 i2c_set_clientdata(i2c
, da7219
);
2585 da7219
->regmap
= devm_regmap_init_i2c(i2c
, &da7219_regmap_config
);
2586 if (IS_ERR(da7219
->regmap
)) {
2587 ret
= PTR_ERR(da7219
->regmap
);
2588 dev_err(&i2c
->dev
, "regmap_init() failed: %d\n", ret
);
2592 regcache_cache_bypass(da7219
->regmap
, true);
2594 /* Disable audio paths if still active from previous start */
2595 regmap_read(da7219
->regmap
, DA7219_SYSTEM_ACTIVE
, &system_active
);
2596 if (system_active
) {
2597 regmap_write(da7219
->regmap
, DA7219_GAIN_RAMP_CTRL
,
2598 DA7219_GAIN_RAMP_RATE_NOMINAL
);
2599 regmap_write(da7219
->regmap
, DA7219_SYSTEM_MODES_INPUT
, 0x00);
2600 regmap_write(da7219
->regmap
, DA7219_SYSTEM_MODES_OUTPUT
, 0x01);
2602 for (i
= 0; i
< DA7219_SYS_STAT_CHECK_RETRIES
; ++i
) {
2603 regmap_read(da7219
->regmap
, DA7219_SYSTEM_STATUS
,
2608 msleep(DA7219_SYS_STAT_CHECK_DELAY
);
2612 /* Soft reset component */
2613 regmap_write_bits(da7219
->regmap
, DA7219_ACCDET_CONFIG_1
,
2614 DA7219_ACCDET_EN_MASK
, 0);
2615 regmap_write_bits(da7219
->regmap
, DA7219_CIF_CTRL
,
2616 DA7219_CIF_REG_SOFT_RESET_MASK
,
2617 DA7219_CIF_REG_SOFT_RESET_MASK
);
2618 regmap_write_bits(da7219
->regmap
, DA7219_SYSTEM_ACTIVE
,
2619 DA7219_SYSTEM_ACTIVE_MASK
, 0);
2621 regcache_cache_bypass(da7219
->regmap
, false);
2623 ret
= devm_snd_soc_register_component(&i2c
->dev
,
2624 &soc_component_dev_da7219
,
2627 dev_err(&i2c
->dev
, "Failed to register da7219 component: %d\n",
2633 static int da7219_i2c_remove(struct i2c_client
*client
)
2638 static const struct i2c_device_id da7219_i2c_id
[] = {
2642 MODULE_DEVICE_TABLE(i2c
, da7219_i2c_id
);
2644 static struct i2c_driver da7219_i2c_driver
= {
2647 .of_match_table
= of_match_ptr(da7219_of_match
),
2648 .acpi_match_table
= ACPI_PTR(da7219_acpi_match
),
2650 .probe
= da7219_i2c_probe
,
2651 .remove
= da7219_i2c_remove
,
2652 .id_table
= da7219_i2c_id
,
2655 module_i2c_driver(da7219_i2c_driver
);
2657 MODULE_DESCRIPTION("ASoC DA7219 Codec Driver");
2658 MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");
2659 MODULE_LICENSE("GPL");