2 * es8316.c -- es8316 ALSA SoC audio driver
3 * Copyright Everest Semiconductor Co.,Ltd
5 * Authors: David Yang <yangxiaohua@everest-semi.com>,
6 * Daniel Drake <drake@endlessm.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/module.h>
14 #include <linux/acpi.h>
15 #include <linux/delay.h>
16 #include <linux/i2c.h>
17 #include <linux/mod_devicetable.h>
18 #include <linux/mutex.h>
19 #include <linux/regmap.h>
20 #include <sound/pcm.h>
21 #include <sound/pcm_params.h>
22 #include <sound/soc.h>
23 #include <sound/soc-dapm.h>
24 #include <sound/tlv.h>
25 #include <sound/jack.h>
28 /* In slave mode at single speed, the codec is documented as accepting 5
29 * MCLK/LRCK ratios, but we also add ratio 400, which is commonly used on
30 * Intel Cherry Trail platforms (19.2MHz MCLK, 48kHz LRCK).
32 #define NR_SUPPORTED_MCLK_LRCK_RATIOS 6
33 static const unsigned int supported_mclk_lrck_ratios
[] = {
34 256, 384, 400, 512, 768, 1024
39 struct regmap
*regmap
;
40 struct snd_soc_component
*component
;
41 struct snd_soc_jack
*jack
;
44 unsigned int allowed_rates
[NR_SUPPORTED_MCLK_LRCK_RATIOS
];
45 struct snd_pcm_hw_constraint_list sysclk_constraints
;
51 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(dac_vol_tlv
, -9600, 50, 1);
52 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_vol_tlv
, -9600, 50, 1);
53 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_max_gain_tlv
, -650, 150, 0);
54 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_min_gain_tlv
, -1200, 150, 0);
55 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_target_tlv
, -1650, 150, 0);
56 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(hpmixer_gain_tlv
, -1200, 150, 0);
58 static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(adc_pga_gain_tlv
,
59 0, 0, TLV_DB_SCALE_ITEM(-350, 0, 0),
60 1, 1, TLV_DB_SCALE_ITEM(0, 0, 0),
61 2, 2, TLV_DB_SCALE_ITEM(250, 0, 0),
62 3, 3, TLV_DB_SCALE_ITEM(450, 0, 0),
63 4, 4, TLV_DB_SCALE_ITEM(700, 0, 0),
64 5, 5, TLV_DB_SCALE_ITEM(1000, 0, 0),
65 6, 6, TLV_DB_SCALE_ITEM(1300, 0, 0),
66 7, 7, TLV_DB_SCALE_ITEM(1600, 0, 0),
67 8, 8, TLV_DB_SCALE_ITEM(1800, 0, 0),
68 9, 9, TLV_DB_SCALE_ITEM(2100, 0, 0),
69 10, 10, TLV_DB_SCALE_ITEM(2400, 0, 0),
72 static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(hpout_vol_tlv
,
73 0, 0, TLV_DB_SCALE_ITEM(-4800, 0, 0),
74 1, 3, TLV_DB_SCALE_ITEM(-2400, 1200, 0),
77 static const char * const ng_type_txt
[] =
78 { "Constant PGA Gain", "Mute ADC Output" };
79 static const struct soc_enum ng_type
=
80 SOC_ENUM_SINGLE(ES8316_ADC_ALC_NG
, 6, 2, ng_type_txt
);
82 static const char * const adcpol_txt
[] = { "Normal", "Invert" };
83 static const struct soc_enum adcpol
=
84 SOC_ENUM_SINGLE(ES8316_ADC_MUTE
, 1, 2, adcpol_txt
);
85 static const char *const dacpol_txt
[] =
86 { "Normal", "R Invert", "L Invert", "L + R Invert" };
87 static const struct soc_enum dacpol
=
88 SOC_ENUM_SINGLE(ES8316_DAC_SET1
, 0, 4, dacpol_txt
);
90 static const struct snd_kcontrol_new es8316_snd_controls
[] = {
91 SOC_DOUBLE_TLV("Headphone Playback Volume", ES8316_CPHP_ICAL_VOL
,
92 4, 0, 3, 1, hpout_vol_tlv
),
93 SOC_DOUBLE_TLV("Headphone Mixer Volume", ES8316_HPMIX_VOL
,
94 0, 4, 7, 0, hpmixer_gain_tlv
),
96 SOC_ENUM("Playback Polarity", dacpol
),
97 SOC_DOUBLE_R_TLV("DAC Playback Volume", ES8316_DAC_VOLL
,
98 ES8316_DAC_VOLR
, 0, 0xc0, 1, dac_vol_tlv
),
99 SOC_SINGLE("DAC Soft Ramp Switch", ES8316_DAC_SET1
, 4, 1, 1),
100 SOC_SINGLE("DAC Soft Ramp Rate", ES8316_DAC_SET1
, 2, 4, 0),
101 SOC_SINGLE("DAC Notch Filter Switch", ES8316_DAC_SET2
, 6, 1, 0),
102 SOC_SINGLE("DAC Double Fs Switch", ES8316_DAC_SET2
, 7, 1, 0),
103 SOC_SINGLE("DAC Stereo Enhancement", ES8316_DAC_SET3
, 0, 7, 0),
105 SOC_ENUM("Capture Polarity", adcpol
),
106 SOC_SINGLE("Mic Boost Switch", ES8316_ADC_D2SEPGA
, 0, 1, 0),
107 SOC_SINGLE_TLV("ADC Capture Volume", ES8316_ADC_VOLUME
,
108 0, 0xc0, 1, adc_vol_tlv
),
109 SOC_SINGLE_TLV("ADC PGA Gain Volume", ES8316_ADC_PGAGAIN
,
110 4, 10, 0, adc_pga_gain_tlv
),
111 SOC_SINGLE("ADC Soft Ramp Switch", ES8316_ADC_MUTE
, 4, 1, 0),
112 SOC_SINGLE("ADC Double Fs Switch", ES8316_ADC_DMIC
, 4, 1, 0),
114 SOC_SINGLE("ALC Capture Switch", ES8316_ADC_ALC1
, 6, 1, 0),
115 SOC_SINGLE_TLV("ALC Capture Max Volume", ES8316_ADC_ALC1
, 0, 28, 0,
117 SOC_SINGLE_TLV("ALC Capture Min Volume", ES8316_ADC_ALC2
, 0, 28, 0,
119 SOC_SINGLE_TLV("ALC Capture Target Volume", ES8316_ADC_ALC3
, 4, 10, 0,
121 SOC_SINGLE("ALC Capture Hold Time", ES8316_ADC_ALC3
, 0, 10, 0),
122 SOC_SINGLE("ALC Capture Decay Time", ES8316_ADC_ALC4
, 4, 10, 0),
123 SOC_SINGLE("ALC Capture Attack Time", ES8316_ADC_ALC4
, 0, 10, 0),
124 SOC_SINGLE("ALC Capture Noise Gate Switch", ES8316_ADC_ALC_NG
,
126 SOC_SINGLE("ALC Capture Noise Gate Threshold", ES8316_ADC_ALC_NG
,
128 SOC_ENUM("ALC Capture Noise Gate Type", ng_type
),
131 /* Analog Input Mux */
132 static const char * const es8316_analog_in_txt
[] = {
135 "lin1-rin1 with 20db Boost",
136 "lin2-rin2 with 20db Boost"
138 static const unsigned int es8316_analog_in_values
[] = { 0, 1, 2, 3 };
139 static const struct soc_enum es8316_analog_input_enum
=
140 SOC_VALUE_ENUM_SINGLE(ES8316_ADC_PDN_LINSEL
, 4, 3,
141 ARRAY_SIZE(es8316_analog_in_txt
),
142 es8316_analog_in_txt
,
143 es8316_analog_in_values
);
144 static const struct snd_kcontrol_new es8316_analog_in_mux_controls
=
145 SOC_DAPM_ENUM("Route", es8316_analog_input_enum
);
147 static const char * const es8316_dmic_txt
[] = {
149 "dmic data at high level",
150 "dmic data at low level",
152 static const unsigned int es8316_dmic_values
[] = { 0, 1, 2 };
153 static const struct soc_enum es8316_dmic_src_enum
=
154 SOC_VALUE_ENUM_SINGLE(ES8316_ADC_DMIC
, 0, 3,
155 ARRAY_SIZE(es8316_dmic_txt
),
158 static const struct snd_kcontrol_new es8316_dmic_src_controls
=
159 SOC_DAPM_ENUM("Route", es8316_dmic_src_enum
);
162 static const char * const es8316_hpmux_texts
[] = {
165 "lin-rin with Boost",
166 "lin-rin with Boost and PGA"
169 static const unsigned int es8316_hpmux_values
[] = { 0, 1, 2, 3 };
171 static SOC_ENUM_SINGLE_DECL(es8316_left_hpmux_enum
, ES8316_HPMIX_SEL
,
172 4, es8316_hpmux_texts
);
174 static const struct snd_kcontrol_new es8316_left_hpmux_controls
=
175 SOC_DAPM_ENUM("Route", es8316_left_hpmux_enum
);
177 static SOC_ENUM_SINGLE_DECL(es8316_right_hpmux_enum
, ES8316_HPMIX_SEL
,
178 0, es8316_hpmux_texts
);
180 static const struct snd_kcontrol_new es8316_right_hpmux_controls
=
181 SOC_DAPM_ENUM("Route", es8316_right_hpmux_enum
);
183 /* headphone Output Mixer */
184 static const struct snd_kcontrol_new es8316_out_left_mix
[] = {
185 SOC_DAPM_SINGLE("LLIN Switch", ES8316_HPMIX_SWITCH
, 6, 1, 0),
186 SOC_DAPM_SINGLE("Left DAC Switch", ES8316_HPMIX_SWITCH
, 7, 1, 0),
188 static const struct snd_kcontrol_new es8316_out_right_mix
[] = {
189 SOC_DAPM_SINGLE("RLIN Switch", ES8316_HPMIX_SWITCH
, 2, 1, 0),
190 SOC_DAPM_SINGLE("Right DAC Switch", ES8316_HPMIX_SWITCH
, 3, 1, 0),
193 /* DAC data source mux */
194 static const char * const es8316_dacsrc_texts
[] = {
195 "LDATA TO LDAC, RDATA TO RDAC",
196 "LDATA TO LDAC, LDATA TO RDAC",
197 "RDATA TO LDAC, RDATA TO RDAC",
198 "RDATA TO LDAC, LDATA TO RDAC",
201 static const unsigned int es8316_dacsrc_values
[] = { 0, 1, 2, 3 };
203 static SOC_ENUM_SINGLE_DECL(es8316_dacsrc_mux_enum
, ES8316_DAC_SET1
,
204 6, es8316_dacsrc_texts
);
206 static const struct snd_kcontrol_new es8316_dacsrc_mux_controls
=
207 SOC_DAPM_ENUM("Route", es8316_dacsrc_mux_enum
);
209 static const struct snd_soc_dapm_widget es8316_dapm_widgets
[] = {
210 SND_SOC_DAPM_SUPPLY("Bias", ES8316_SYS_PDN
, 3, 1, NULL
, 0),
211 SND_SOC_DAPM_SUPPLY("Analog power", ES8316_SYS_PDN
, 4, 1, NULL
, 0),
212 SND_SOC_DAPM_SUPPLY("Mic Bias", ES8316_SYS_PDN
, 5, 1, NULL
, 0),
214 SND_SOC_DAPM_INPUT("DMIC"),
215 SND_SOC_DAPM_INPUT("MIC1"),
216 SND_SOC_DAPM_INPUT("MIC2"),
219 SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM
, 0, 0,
220 &es8316_analog_in_mux_controls
),
222 SND_SOC_DAPM_SUPPLY("ADC Vref", ES8316_SYS_PDN
, 1, 1, NULL
, 0),
223 SND_SOC_DAPM_SUPPLY("ADC bias", ES8316_SYS_PDN
, 2, 1, NULL
, 0),
224 SND_SOC_DAPM_SUPPLY("ADC Clock", ES8316_CLKMGR_CLKSW
, 3, 0, NULL
, 0),
225 SND_SOC_DAPM_PGA("Line input PGA", ES8316_ADC_PDN_LINSEL
,
227 SND_SOC_DAPM_ADC("Mono ADC", NULL
, ES8316_ADC_PDN_LINSEL
, 6, 1),
228 SND_SOC_DAPM_MUX("Digital Mic Mux", SND_SOC_NOPM
, 0, 0,
229 &es8316_dmic_src_controls
),
231 /* Digital Interface */
232 SND_SOC_DAPM_AIF_OUT("I2S OUT", "I2S1 Capture", 1,
233 ES8316_SERDATA_ADC
, 6, 1),
234 SND_SOC_DAPM_AIF_IN("I2S IN", "I2S1 Playback", 0,
237 SND_SOC_DAPM_MUX("DAC Source Mux", SND_SOC_NOPM
, 0, 0,
238 &es8316_dacsrc_mux_controls
),
240 SND_SOC_DAPM_SUPPLY("DAC Vref", ES8316_SYS_PDN
, 0, 1, NULL
, 0),
241 SND_SOC_DAPM_SUPPLY("DAC Clock", ES8316_CLKMGR_CLKSW
, 2, 0, NULL
, 0),
242 SND_SOC_DAPM_DAC("Right DAC", NULL
, ES8316_DAC_PDN
, 0, 1),
243 SND_SOC_DAPM_DAC("Left DAC", NULL
, ES8316_DAC_PDN
, 4, 1),
245 /* Headphone Output Side */
246 SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM
, 0, 0,
247 &es8316_left_hpmux_controls
),
248 SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM
, 0, 0,
249 &es8316_right_hpmux_controls
),
250 SND_SOC_DAPM_MIXER("Left Headphone Mixer", ES8316_HPMIX_PDN
,
251 5, 1, &es8316_out_left_mix
[0],
252 ARRAY_SIZE(es8316_out_left_mix
)),
253 SND_SOC_DAPM_MIXER("Right Headphone Mixer", ES8316_HPMIX_PDN
,
254 1, 1, &es8316_out_right_mix
[0],
255 ARRAY_SIZE(es8316_out_right_mix
)),
256 SND_SOC_DAPM_PGA("Left Headphone Mixer Out", ES8316_HPMIX_PDN
,
258 SND_SOC_DAPM_PGA("Right Headphone Mixer Out", ES8316_HPMIX_PDN
,
261 SND_SOC_DAPM_OUT_DRV("Left Headphone Charge Pump", ES8316_CPHP_OUTEN
,
263 SND_SOC_DAPM_OUT_DRV("Right Headphone Charge Pump", ES8316_CPHP_OUTEN
,
265 SND_SOC_DAPM_SUPPLY("Headphone Charge Pump", ES8316_CPHP_PDN2
,
267 SND_SOC_DAPM_SUPPLY("Headphone Charge Pump Clock", ES8316_CLKMGR_CLKSW
,
270 SND_SOC_DAPM_OUT_DRV("Left Headphone Driver", ES8316_CPHP_OUTEN
,
272 SND_SOC_DAPM_OUT_DRV("Right Headphone Driver", ES8316_CPHP_OUTEN
,
274 SND_SOC_DAPM_SUPPLY("Headphone Out", ES8316_CPHP_PDN1
, 2, 1, NULL
, 0),
276 /* pdn_Lical and pdn_Rical bits are documented as Reserved, but must
277 * be explicitly unset in order to enable HP output
279 SND_SOC_DAPM_SUPPLY("Left Headphone ical", ES8316_CPHP_ICAL_VOL
,
281 SND_SOC_DAPM_SUPPLY("Right Headphone ical", ES8316_CPHP_ICAL_VOL
,
284 SND_SOC_DAPM_OUTPUT("HPOL"),
285 SND_SOC_DAPM_OUTPUT("HPOR"),
288 static const struct snd_soc_dapm_route es8316_dapm_routes
[] = {
290 {"MIC1", NULL
, "Mic Bias"},
291 {"MIC2", NULL
, "Mic Bias"},
292 {"MIC1", NULL
, "Bias"},
293 {"MIC2", NULL
, "Bias"},
294 {"MIC1", NULL
, "Analog power"},
295 {"MIC2", NULL
, "Analog power"},
297 {"Differential Mux", "lin1-rin1", "MIC1"},
298 {"Differential Mux", "lin2-rin2", "MIC2"},
299 {"Line input PGA", NULL
, "Differential Mux"},
301 {"Mono ADC", NULL
, "ADC Clock"},
302 {"Mono ADC", NULL
, "ADC Vref"},
303 {"Mono ADC", NULL
, "ADC bias"},
304 {"Mono ADC", NULL
, "Line input PGA"},
306 /* It's not clear why, but to avoid recording only silence,
307 * the DAC clock must be running for the ADC to work.
309 {"Mono ADC", NULL
, "DAC Clock"},
311 {"Digital Mic Mux", "dmic disable", "Mono ADC"},
313 {"I2S OUT", NULL
, "Digital Mic Mux"},
316 {"DAC Source Mux", "LDATA TO LDAC, RDATA TO RDAC", "I2S IN"},
318 {"Left DAC", NULL
, "DAC Clock"},
319 {"Right DAC", NULL
, "DAC Clock"},
321 {"Left DAC", NULL
, "DAC Vref"},
322 {"Right DAC", NULL
, "DAC Vref"},
324 {"Left DAC", NULL
, "DAC Source Mux"},
325 {"Right DAC", NULL
, "DAC Source Mux"},
327 {"Left Headphone Mux", "lin-rin with Boost and PGA", "Line input PGA"},
328 {"Right Headphone Mux", "lin-rin with Boost and PGA", "Line input PGA"},
330 {"Left Headphone Mixer", "LLIN Switch", "Left Headphone Mux"},
331 {"Left Headphone Mixer", "Left DAC Switch", "Left DAC"},
333 {"Right Headphone Mixer", "RLIN Switch", "Right Headphone Mux"},
334 {"Right Headphone Mixer", "Right DAC Switch", "Right DAC"},
336 {"Left Headphone Mixer Out", NULL
, "Left Headphone Mixer"},
337 {"Right Headphone Mixer Out", NULL
, "Right Headphone Mixer"},
339 {"Left Headphone Charge Pump", NULL
, "Left Headphone Mixer Out"},
340 {"Right Headphone Charge Pump", NULL
, "Right Headphone Mixer Out"},
342 {"Left Headphone Charge Pump", NULL
, "Headphone Charge Pump"},
343 {"Right Headphone Charge Pump", NULL
, "Headphone Charge Pump"},
345 {"Left Headphone Charge Pump", NULL
, "Headphone Charge Pump Clock"},
346 {"Right Headphone Charge Pump", NULL
, "Headphone Charge Pump Clock"},
348 {"Left Headphone Driver", NULL
, "Left Headphone Charge Pump"},
349 {"Right Headphone Driver", NULL
, "Right Headphone Charge Pump"},
351 {"HPOL", NULL
, "Left Headphone Driver"},
352 {"HPOR", NULL
, "Right Headphone Driver"},
354 {"HPOL", NULL
, "Left Headphone ical"},
355 {"HPOR", NULL
, "Right Headphone ical"},
357 {"Headphone Out", NULL
, "Bias"},
358 {"Headphone Out", NULL
, "Analog power"},
359 {"HPOL", NULL
, "Headphone Out"},
360 {"HPOR", NULL
, "Headphone Out"},
363 static int es8316_set_dai_sysclk(struct snd_soc_dai
*codec_dai
,
364 int clk_id
, unsigned int freq
, int dir
)
366 struct snd_soc_component
*component
= codec_dai
->component
;
367 struct es8316_priv
*es8316
= snd_soc_component_get_drvdata(component
);
371 es8316
->sysclk
= freq
;
376 /* Limit supported sample rates to ones that can be autodetected
377 * by the codec running in slave mode.
379 for (i
= 0; i
< NR_SUPPORTED_MCLK_LRCK_RATIOS
; i
++) {
380 const unsigned int ratio
= supported_mclk_lrck_ratios
[i
];
382 if (freq
% ratio
== 0)
383 es8316
->allowed_rates
[count
++] = freq
/ ratio
;
386 es8316
->sysclk_constraints
.list
= es8316
->allowed_rates
;
387 es8316
->sysclk_constraints
.count
= count
;
392 static int es8316_set_dai_fmt(struct snd_soc_dai
*codec_dai
,
395 struct snd_soc_component
*component
= codec_dai
->component
;
401 if ((fmt
& SND_SOC_DAIFMT_MASTER_MASK
) != SND_SOC_DAIFMT_CBS_CFS
) {
402 dev_err(component
->dev
, "Codec driver only supports slave mode\n");
406 if ((fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) != SND_SOC_DAIFMT_I2S
) {
407 dev_err(component
->dev
, "Codec driver only supports I2S format\n");
411 /* Clock inversion */
412 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
413 case SND_SOC_DAIFMT_NB_NF
:
415 case SND_SOC_DAIFMT_IB_IF
:
416 serdata1
|= ES8316_SERDATA1_BCLK_INV
;
417 serdata2
|= ES8316_SERDATA2_ADCLRP
;
419 case SND_SOC_DAIFMT_IB_NF
:
420 serdata1
|= ES8316_SERDATA1_BCLK_INV
;
422 case SND_SOC_DAIFMT_NB_IF
:
423 serdata2
|= ES8316_SERDATA2_ADCLRP
;
429 mask
= ES8316_SERDATA1_MASTER
| ES8316_SERDATA1_BCLK_INV
;
430 snd_soc_component_update_bits(component
, ES8316_SERDATA1
, mask
, serdata1
);
432 mask
= ES8316_SERDATA2_FMT_MASK
| ES8316_SERDATA2_ADCLRP
;
433 snd_soc_component_update_bits(component
, ES8316_SERDATA_ADC
, mask
, serdata2
);
434 snd_soc_component_update_bits(component
, ES8316_SERDATA_DAC
, mask
, serdata2
);
436 /* Enable BCLK and MCLK inputs in slave mode */
437 clksw
= ES8316_CLKMGR_CLKSW_MCLK_ON
| ES8316_CLKMGR_CLKSW_BCLK_ON
;
438 snd_soc_component_update_bits(component
, ES8316_CLKMGR_CLKSW
, clksw
, clksw
);
443 static int es8316_pcm_startup(struct snd_pcm_substream
*substream
,
444 struct snd_soc_dai
*dai
)
446 struct snd_soc_component
*component
= dai
->component
;
447 struct es8316_priv
*es8316
= snd_soc_component_get_drvdata(component
);
449 if (es8316
->sysclk
== 0) {
450 dev_err(component
->dev
, "No sysclk provided\n");
454 /* The set of sample rates that can be supported depends on the
455 * MCLK supplied to the CODEC.
457 snd_pcm_hw_constraint_list(substream
->runtime
, 0,
458 SNDRV_PCM_HW_PARAM_RATE
,
459 &es8316
->sysclk_constraints
);
464 static int es8316_pcm_hw_params(struct snd_pcm_substream
*substream
,
465 struct snd_pcm_hw_params
*params
,
466 struct snd_soc_dai
*dai
)
468 struct snd_soc_component
*component
= dai
->component
;
469 struct es8316_priv
*es8316
= snd_soc_component_get_drvdata(component
);
472 if (!es8316
->sysclk
) {
473 dev_err(component
->dev
, "No MCLK configured\n");
477 switch (params_format(params
)) {
478 case SNDRV_PCM_FORMAT_S16_LE
:
479 wordlen
= ES8316_SERDATA2_LEN_16
;
481 case SNDRV_PCM_FORMAT_S20_3LE
:
482 wordlen
= ES8316_SERDATA2_LEN_20
;
484 case SNDRV_PCM_FORMAT_S24_LE
:
485 wordlen
= ES8316_SERDATA2_LEN_24
;
487 case SNDRV_PCM_FORMAT_S32_LE
:
488 wordlen
= ES8316_SERDATA2_LEN_32
;
494 snd_soc_component_update_bits(component
, ES8316_SERDATA_DAC
,
495 ES8316_SERDATA2_LEN_MASK
, wordlen
);
496 snd_soc_component_update_bits(component
, ES8316_SERDATA_ADC
,
497 ES8316_SERDATA2_LEN_MASK
, wordlen
);
501 static int es8316_mute(struct snd_soc_dai
*dai
, int mute
)
503 snd_soc_component_update_bits(dai
->component
, ES8316_DAC_SET1
, 0x20,
508 #define ES8316_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
509 SNDRV_PCM_FMTBIT_S24_LE)
511 static const struct snd_soc_dai_ops es8316_ops
= {
512 .startup
= es8316_pcm_startup
,
513 .hw_params
= es8316_pcm_hw_params
,
514 .set_fmt
= es8316_set_dai_fmt
,
515 .set_sysclk
= es8316_set_dai_sysclk
,
516 .digital_mute
= es8316_mute
,
519 static struct snd_soc_dai_driver es8316_dai
= {
520 .name
= "ES8316 HiFi",
522 .stream_name
= "Playback",
525 .rates
= SNDRV_PCM_RATE_8000_48000
,
526 .formats
= ES8316_FORMATS
,
529 .stream_name
= "Capture",
532 .rates
= SNDRV_PCM_RATE_8000_48000
,
533 .formats
= ES8316_FORMATS
,
536 .symmetric_rates
= 1,
539 static void es8316_enable_micbias_for_mic_gnd_short_detect(
540 struct snd_soc_component
*component
)
542 struct snd_soc_dapm_context
*dapm
= snd_soc_component_get_dapm(component
);
544 snd_soc_dapm_mutex_lock(dapm
);
545 snd_soc_dapm_force_enable_pin_unlocked(dapm
, "Bias");
546 snd_soc_dapm_force_enable_pin_unlocked(dapm
, "Analog power");
547 snd_soc_dapm_force_enable_pin_unlocked(dapm
, "Mic Bias");
548 snd_soc_dapm_sync_unlocked(dapm
);
549 snd_soc_dapm_mutex_unlock(dapm
);
554 static void es8316_disable_micbias_for_mic_gnd_short_detect(
555 struct snd_soc_component
*component
)
557 struct snd_soc_dapm_context
*dapm
= snd_soc_component_get_dapm(component
);
559 snd_soc_dapm_mutex_lock(dapm
);
560 snd_soc_dapm_disable_pin_unlocked(dapm
, "Mic Bias");
561 snd_soc_dapm_disable_pin_unlocked(dapm
, "Analog power");
562 snd_soc_dapm_disable_pin_unlocked(dapm
, "Bias");
563 snd_soc_dapm_sync_unlocked(dapm
);
564 snd_soc_dapm_mutex_unlock(dapm
);
567 static irqreturn_t
es8316_irq(int irq
, void *data
)
569 struct es8316_priv
*es8316
= data
;
570 struct snd_soc_component
*comp
= es8316
->component
;
573 mutex_lock(&es8316
->lock
);
575 regmap_read(es8316
->regmap
, ES8316_GPIO_FLAG
, &flags
);
577 goto out
; /* Powered-down / reset */
579 /* Catch spurious IRQ before set_jack is called */
583 dev_dbg(comp
->dev
, "gpio flags %#04x\n", flags
);
584 if (flags
& ES8316_GPIO_FLAG_HP_NOT_INSERTED
) {
585 /* Jack removed, or spurious IRQ? */
586 if (es8316
->jack
->status
& SND_JACK_MICROPHONE
)
587 es8316_disable_micbias_for_mic_gnd_short_detect(comp
);
589 if (es8316
->jack
->status
& SND_JACK_HEADPHONE
) {
590 snd_soc_jack_report(es8316
->jack
, 0,
591 SND_JACK_HEADSET
| SND_JACK_BTN_0
);
592 dev_dbg(comp
->dev
, "jack unplugged\n");
594 } else if (!(es8316
->jack
->status
& SND_JACK_HEADPHONE
)) {
595 /* Jack inserted, determine type */
596 es8316_enable_micbias_for_mic_gnd_short_detect(comp
);
597 regmap_read(es8316
->regmap
, ES8316_GPIO_FLAG
, &flags
);
598 dev_dbg(comp
->dev
, "gpio flags %#04x\n", flags
);
599 if (flags
& ES8316_GPIO_FLAG_HP_NOT_INSERTED
) {
600 /* Jack unplugged underneath us */
601 es8316_disable_micbias_for_mic_gnd_short_detect(comp
);
602 } else if (flags
& ES8316_GPIO_FLAG_GM_NOT_SHORTED
) {
604 snd_soc_jack_report(es8316
->jack
,
607 /* Keep mic-gnd-short detection on for button press */
609 /* Shorted, headphones */
610 snd_soc_jack_report(es8316
->jack
,
613 /* No longer need mic-gnd-short detection */
614 es8316_disable_micbias_for_mic_gnd_short_detect(comp
);
616 } else if (es8316
->jack
->status
& SND_JACK_MICROPHONE
) {
617 /* Interrupt while jack inserted, report button state */
618 if (flags
& ES8316_GPIO_FLAG_GM_NOT_SHORTED
) {
619 /* Open, button release */
620 snd_soc_jack_report(es8316
->jack
, 0, SND_JACK_BTN_0
);
622 /* Short, button press */
623 snd_soc_jack_report(es8316
->jack
,
630 mutex_unlock(&es8316
->lock
);
634 static void es8316_enable_jack_detect(struct snd_soc_component
*component
,
635 struct snd_soc_jack
*jack
)
637 struct es8316_priv
*es8316
= snd_soc_component_get_drvdata(component
);
639 mutex_lock(&es8316
->lock
);
643 if (es8316
->jack
->status
& SND_JACK_MICROPHONE
)
644 es8316_enable_micbias_for_mic_gnd_short_detect(component
);
646 snd_soc_component_update_bits(component
, ES8316_GPIO_DEBOUNCE
,
647 ES8316_GPIO_ENABLE_INTERRUPT
,
648 ES8316_GPIO_ENABLE_INTERRUPT
);
650 mutex_unlock(&es8316
->lock
);
652 /* Enable irq and sync initial jack state */
653 enable_irq(es8316
->irq
);
654 es8316_irq(es8316
->irq
, es8316
);
657 static void es8316_disable_jack_detect(struct snd_soc_component
*component
)
659 struct es8316_priv
*es8316
= snd_soc_component_get_drvdata(component
);
661 disable_irq(es8316
->irq
);
663 mutex_lock(&es8316
->lock
);
665 snd_soc_component_update_bits(component
, ES8316_GPIO_DEBOUNCE
,
666 ES8316_GPIO_ENABLE_INTERRUPT
, 0);
668 if (es8316
->jack
->status
& SND_JACK_MICROPHONE
) {
669 es8316_disable_micbias_for_mic_gnd_short_detect(component
);
670 snd_soc_jack_report(es8316
->jack
, 0, SND_JACK_BTN_0
);
675 mutex_unlock(&es8316
->lock
);
678 static int es8316_set_jack(struct snd_soc_component
*component
,
679 struct snd_soc_jack
*jack
, void *data
)
682 es8316_enable_jack_detect(component
, jack
);
684 es8316_disable_jack_detect(component
);
689 static int es8316_probe(struct snd_soc_component
*component
)
691 struct es8316_priv
*es8316
= snd_soc_component_get_drvdata(component
);
693 es8316
->component
= component
;
695 /* Reset codec and enable current state machine */
696 snd_soc_component_write(component
, ES8316_RESET
, 0x3f);
697 usleep_range(5000, 5500);
698 snd_soc_component_write(component
, ES8316_RESET
, ES8316_RESET_CSM_ON
);
702 * Documentation is unclear, but this value from the vendor driver is
703 * needed otherwise audio output is silent.
705 snd_soc_component_write(component
, ES8316_SYS_VMIDSEL
, 0xff);
708 * Documentation for this register is unclear and incomplete,
709 * but here is a vendor-provided value that improves volume
710 * and quality for Intel CHT platforms.
712 snd_soc_component_write(component
, ES8316_CLKMGR_ADCOSR
, 0x32);
717 static const struct snd_soc_component_driver soc_component_dev_es8316
= {
718 .probe
= es8316_probe
,
719 .set_jack
= es8316_set_jack
,
720 .controls
= es8316_snd_controls
,
721 .num_controls
= ARRAY_SIZE(es8316_snd_controls
),
722 .dapm_widgets
= es8316_dapm_widgets
,
723 .num_dapm_widgets
= ARRAY_SIZE(es8316_dapm_widgets
),
724 .dapm_routes
= es8316_dapm_routes
,
725 .num_dapm_routes
= ARRAY_SIZE(es8316_dapm_routes
),
726 .use_pmdown_time
= 1,
728 .non_legacy_dai_naming
= 1,
731 static const struct regmap_range es8316_volatile_ranges
[] = {
732 regmap_reg_range(ES8316_GPIO_FLAG
, ES8316_GPIO_FLAG
),
735 static const struct regmap_access_table es8316_volatile_table
= {
736 .yes_ranges
= es8316_volatile_ranges
,
737 .n_yes_ranges
= ARRAY_SIZE(es8316_volatile_ranges
),
740 static const struct regmap_config es8316_regmap
= {
743 .max_register
= 0x53,
744 .volatile_table
= &es8316_volatile_table
,
745 .cache_type
= REGCACHE_RBTREE
,
748 static int es8316_i2c_probe(struct i2c_client
*i2c_client
,
749 const struct i2c_device_id
*id
)
751 struct device
*dev
= &i2c_client
->dev
;
752 struct es8316_priv
*es8316
;
755 es8316
= devm_kzalloc(&i2c_client
->dev
, sizeof(struct es8316_priv
),
760 i2c_set_clientdata(i2c_client
, es8316
);
762 es8316
->regmap
= devm_regmap_init_i2c(i2c_client
, &es8316_regmap
);
763 if (IS_ERR(es8316
->regmap
))
764 return PTR_ERR(es8316
->regmap
);
766 es8316
->irq
= i2c_client
->irq
;
767 mutex_init(&es8316
->lock
);
769 ret
= devm_request_threaded_irq(dev
, es8316
->irq
, NULL
, es8316_irq
,
770 IRQF_TRIGGER_HIGH
| IRQF_ONESHOT
,
773 /* Gets re-enabled by es8316_set_jack() */
774 disable_irq(es8316
->irq
);
776 dev_warn(dev
, "Failed to get IRQ %d: %d\n", es8316
->irq
, ret
);
777 es8316
->irq
= -ENXIO
;
780 return devm_snd_soc_register_component(&i2c_client
->dev
,
781 &soc_component_dev_es8316
,
785 static const struct i2c_device_id es8316_i2c_id
[] = {
789 MODULE_DEVICE_TABLE(i2c
, es8316_i2c_id
);
791 static const struct of_device_id es8316_of_match
[] = {
792 { .compatible
= "everest,es8316", },
795 MODULE_DEVICE_TABLE(of
, es8316_of_match
);
797 static const struct acpi_device_id es8316_acpi_match
[] = {
801 MODULE_DEVICE_TABLE(acpi
, es8316_acpi_match
);
803 static struct i2c_driver es8316_i2c_driver
= {
806 .acpi_match_table
= ACPI_PTR(es8316_acpi_match
),
807 .of_match_table
= of_match_ptr(es8316_of_match
),
809 .probe
= es8316_i2c_probe
,
810 .id_table
= es8316_i2c_id
,
812 module_i2c_driver(es8316_i2c_driver
);
814 MODULE_DESCRIPTION("Everest Semi ES8316 ALSA SoC Codec Driver");
815 MODULE_AUTHOR("David Yang <yangxiaohua@everest-semi.com>");
816 MODULE_LICENSE("GPL v2");