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/regmap.h>
19 #include <sound/pcm.h>
20 #include <sound/pcm_params.h>
21 #include <sound/soc.h>
22 #include <sound/soc-dapm.h>
23 #include <sound/tlv.h>
26 /* In slave mode at single speed, the codec is documented as accepting 5
27 * MCLK/LRCK ratios, but we also add ratio 400, which is commonly used on
28 * Intel Cherry Trail platforms (19.2MHz MCLK, 48kHz LRCK).
30 #define NR_SUPPORTED_MCLK_LRCK_RATIOS 6
31 static const unsigned int supported_mclk_lrck_ratios[] = {
32 256, 384, 400, 512, 768, 1024
37 unsigned int allowed_rates[NR_SUPPORTED_MCLK_LRCK_RATIOS];
38 struct snd_pcm_hw_constraint_list sysclk_constraints;
44 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(dac_vol_tlv, -9600, 50, 1);
45 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_vol_tlv, -9600, 50, 1);
46 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_max_gain_tlv, -650, 150, 0);
47 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_min_gain_tlv, -1200, 150, 0);
48 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_target_tlv, -1650, 150, 0);
49 static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(hpmixer_gain_tlv,
50 0, 4, TLV_DB_SCALE_ITEM(-1200, 150, 0),
51 8, 11, TLV_DB_SCALE_ITEM(-450, 150, 0),
54 static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(adc_pga_gain_tlv,
55 0, 0, TLV_DB_SCALE_ITEM(-350, 0, 0),
56 1, 1, TLV_DB_SCALE_ITEM(0, 0, 0),
57 2, 2, TLV_DB_SCALE_ITEM(250, 0, 0),
58 3, 3, TLV_DB_SCALE_ITEM(450, 0, 0),
59 4, 7, TLV_DB_SCALE_ITEM(700, 300, 0),
60 8, 10, TLV_DB_SCALE_ITEM(1800, 300, 0),
63 static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(hpout_vol_tlv,
64 0, 0, TLV_DB_SCALE_ITEM(-4800, 0, 0),
65 1, 3, TLV_DB_SCALE_ITEM(-2400, 1200, 0),
68 static const char * const ng_type_txt[] =
69 { "Constant PGA Gain", "Mute ADC Output" };
70 static const struct soc_enum ng_type =
71 SOC_ENUM_SINGLE(ES8316_ADC_ALC_NG, 6, 2, ng_type_txt);
73 static const char * const adcpol_txt[] = { "Normal", "Invert" };
74 static const struct soc_enum adcpol =
75 SOC_ENUM_SINGLE(ES8316_ADC_MUTE, 1, 2, adcpol_txt);
76 static const char *const dacpol_txt[] =
77 { "Normal", "R Invert", "L Invert", "L + R Invert" };
78 static const struct soc_enum dacpol =
79 SOC_ENUM_SINGLE(ES8316_DAC_SET1, 0, 4, dacpol_txt);
81 static const struct snd_kcontrol_new es8316_snd_controls[] = {
82 SOC_DOUBLE_TLV("Headphone Playback Volume", ES8316_CPHP_ICAL_VOL,
83 4, 0, 3, 1, hpout_vol_tlv),
84 SOC_DOUBLE_TLV("Headphone Mixer Volume", ES8316_HPMIX_VOL,
85 0, 4, 11, 0, hpmixer_gain_tlv),
87 SOC_ENUM("Playback Polarity", dacpol),
88 SOC_DOUBLE_R_TLV("DAC Playback Volume", ES8316_DAC_VOLL,
89 ES8316_DAC_VOLR, 0, 0xc0, 1, dac_vol_tlv),
90 SOC_SINGLE("DAC Soft Ramp Switch", ES8316_DAC_SET1, 4, 1, 1),
91 SOC_SINGLE("DAC Soft Ramp Rate", ES8316_DAC_SET1, 2, 4, 0),
92 SOC_SINGLE("DAC Notch Filter Switch", ES8316_DAC_SET2, 6, 1, 0),
93 SOC_SINGLE("DAC Double Fs Switch", ES8316_DAC_SET2, 7, 1, 0),
94 SOC_SINGLE("DAC Stereo Enhancement", ES8316_DAC_SET3, 0, 7, 0),
96 SOC_ENUM("Capture Polarity", adcpol),
97 SOC_SINGLE("Mic Boost Switch", ES8316_ADC_D2SEPGA, 0, 1, 0),
98 SOC_SINGLE_TLV("ADC Capture Volume", ES8316_ADC_VOLUME,
99 0, 0xc0, 1, adc_vol_tlv),
100 SOC_SINGLE_TLV("ADC PGA Gain Volume", ES8316_ADC_PGAGAIN,
101 4, 10, 0, adc_pga_gain_tlv),
102 SOC_SINGLE("ADC Soft Ramp Switch", ES8316_ADC_MUTE, 4, 1, 0),
103 SOC_SINGLE("ADC Double Fs Switch", ES8316_ADC_DMIC, 4, 1, 0),
105 SOC_SINGLE("ALC Capture Switch", ES8316_ADC_ALC1, 6, 1, 0),
106 SOC_SINGLE_TLV("ALC Capture Max Volume", ES8316_ADC_ALC1, 0, 28, 0,
108 SOC_SINGLE_TLV("ALC Capture Min Volume", ES8316_ADC_ALC2, 0, 28, 0,
110 SOC_SINGLE_TLV("ALC Capture Target Volume", ES8316_ADC_ALC3, 4, 10, 0,
112 SOC_SINGLE("ALC Capture Hold Time", ES8316_ADC_ALC3, 0, 10, 0),
113 SOC_SINGLE("ALC Capture Decay Time", ES8316_ADC_ALC4, 4, 10, 0),
114 SOC_SINGLE("ALC Capture Attack Time", ES8316_ADC_ALC4, 0, 10, 0),
115 SOC_SINGLE("ALC Capture Noise Gate Switch", ES8316_ADC_ALC_NG,
117 SOC_SINGLE("ALC Capture Noise Gate Threshold", ES8316_ADC_ALC_NG,
119 SOC_ENUM("ALC Capture Noise Gate Type", ng_type),
122 /* Analog Input Mux */
123 static const char * const es8316_analog_in_txt[] = {
126 "lin1-rin1 with 20db Boost",
127 "lin2-rin2 with 20db Boost"
129 static const unsigned int es8316_analog_in_values[] = { 0, 1, 2, 3 };
130 static const struct soc_enum es8316_analog_input_enum =
131 SOC_VALUE_ENUM_SINGLE(ES8316_ADC_PDN_LINSEL, 4, 3,
132 ARRAY_SIZE(es8316_analog_in_txt),
133 es8316_analog_in_txt,
134 es8316_analog_in_values);
135 static const struct snd_kcontrol_new es8316_analog_in_mux_controls =
136 SOC_DAPM_ENUM("Route", es8316_analog_input_enum);
138 static const char * const es8316_dmic_txt[] = {
140 "dmic data at high level",
141 "dmic data at low level",
143 static const unsigned int es8316_dmic_values[] = { 0, 1, 2 };
144 static const struct soc_enum es8316_dmic_src_enum =
145 SOC_VALUE_ENUM_SINGLE(ES8316_ADC_DMIC, 0, 3,
146 ARRAY_SIZE(es8316_dmic_txt),
149 static const struct snd_kcontrol_new es8316_dmic_src_controls =
150 SOC_DAPM_ENUM("Route", es8316_dmic_src_enum);
153 static const char * const es8316_hpmux_texts[] = {
156 "lin-rin with Boost",
157 "lin-rin with Boost and PGA"
160 static const unsigned int es8316_hpmux_values[] = { 0, 1, 2, 3 };
162 static SOC_ENUM_SINGLE_DECL(es8316_left_hpmux_enum, ES8316_HPMIX_SEL,
163 4, es8316_hpmux_texts);
165 static const struct snd_kcontrol_new es8316_left_hpmux_controls =
166 SOC_DAPM_ENUM("Route", es8316_left_hpmux_enum);
168 static SOC_ENUM_SINGLE_DECL(es8316_right_hpmux_enum, ES8316_HPMIX_SEL,
169 0, es8316_hpmux_texts);
171 static const struct snd_kcontrol_new es8316_right_hpmux_controls =
172 SOC_DAPM_ENUM("Route", es8316_right_hpmux_enum);
174 /* headphone Output Mixer */
175 static const struct snd_kcontrol_new es8316_out_left_mix[] = {
176 SOC_DAPM_SINGLE("LLIN Switch", ES8316_HPMIX_SWITCH, 6, 1, 0),
177 SOC_DAPM_SINGLE("Left DAC Switch", ES8316_HPMIX_SWITCH, 7, 1, 0),
179 static const struct snd_kcontrol_new es8316_out_right_mix[] = {
180 SOC_DAPM_SINGLE("RLIN Switch", ES8316_HPMIX_SWITCH, 2, 1, 0),
181 SOC_DAPM_SINGLE("Right DAC Switch", ES8316_HPMIX_SWITCH, 3, 1, 0),
184 /* DAC data source mux */
185 static const char * const es8316_dacsrc_texts[] = {
186 "LDATA TO LDAC, RDATA TO RDAC",
187 "LDATA TO LDAC, LDATA TO RDAC",
188 "RDATA TO LDAC, RDATA TO RDAC",
189 "RDATA TO LDAC, LDATA TO RDAC",
192 static const unsigned int es8316_dacsrc_values[] = { 0, 1, 2, 3 };
194 static SOC_ENUM_SINGLE_DECL(es8316_dacsrc_mux_enum, ES8316_DAC_SET1,
195 6, es8316_dacsrc_texts);
197 static const struct snd_kcontrol_new es8316_dacsrc_mux_controls =
198 SOC_DAPM_ENUM("Route", es8316_dacsrc_mux_enum);
200 static const struct snd_soc_dapm_widget es8316_dapm_widgets[] = {
201 SND_SOC_DAPM_SUPPLY("Bias", ES8316_SYS_PDN, 3, 1, NULL, 0),
202 SND_SOC_DAPM_SUPPLY("Analog power", ES8316_SYS_PDN, 4, 1, NULL, 0),
203 SND_SOC_DAPM_SUPPLY("Mic Bias", ES8316_SYS_PDN, 5, 1, NULL, 0),
205 SND_SOC_DAPM_INPUT("DMIC"),
206 SND_SOC_DAPM_INPUT("MIC1"),
207 SND_SOC_DAPM_INPUT("MIC2"),
210 SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0,
211 &es8316_analog_in_mux_controls),
213 SND_SOC_DAPM_SUPPLY("ADC Vref", ES8316_SYS_PDN, 1, 1, NULL, 0),
214 SND_SOC_DAPM_SUPPLY("ADC bias", ES8316_SYS_PDN, 2, 1, NULL, 0),
215 SND_SOC_DAPM_SUPPLY("ADC Clock", ES8316_CLKMGR_CLKSW, 3, 0, NULL, 0),
216 SND_SOC_DAPM_PGA("Line input PGA", ES8316_ADC_PDN_LINSEL,
218 SND_SOC_DAPM_ADC("Mono ADC", NULL, ES8316_ADC_PDN_LINSEL, 6, 1),
219 SND_SOC_DAPM_MUX("Digital Mic Mux", SND_SOC_NOPM, 0, 0,
220 &es8316_dmic_src_controls),
222 /* Digital Interface */
223 SND_SOC_DAPM_AIF_OUT("I2S OUT", "I2S1 Capture", 1,
224 ES8316_SERDATA_ADC, 6, 1),
225 SND_SOC_DAPM_AIF_IN("I2S IN", "I2S1 Playback", 0,
228 SND_SOC_DAPM_MUX("DAC Source Mux", SND_SOC_NOPM, 0, 0,
229 &es8316_dacsrc_mux_controls),
231 SND_SOC_DAPM_SUPPLY("DAC Vref", ES8316_SYS_PDN, 0, 1, NULL, 0),
232 SND_SOC_DAPM_SUPPLY("DAC Clock", ES8316_CLKMGR_CLKSW, 2, 0, NULL, 0),
233 SND_SOC_DAPM_DAC("Right DAC", NULL, ES8316_DAC_PDN, 0, 1),
234 SND_SOC_DAPM_DAC("Left DAC", NULL, ES8316_DAC_PDN, 4, 1),
236 /* Headphone Output Side */
237 SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0,
238 &es8316_left_hpmux_controls),
239 SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0,
240 &es8316_right_hpmux_controls),
241 SND_SOC_DAPM_MIXER("Left Headphone Mixer", ES8316_HPMIX_PDN,
242 5, 1, &es8316_out_left_mix[0],
243 ARRAY_SIZE(es8316_out_left_mix)),
244 SND_SOC_DAPM_MIXER("Right Headphone Mixer", ES8316_HPMIX_PDN,
245 1, 1, &es8316_out_right_mix[0],
246 ARRAY_SIZE(es8316_out_right_mix)),
247 SND_SOC_DAPM_PGA("Left Headphone Mixer Out", ES8316_HPMIX_PDN,
249 SND_SOC_DAPM_PGA("Right Headphone Mixer Out", ES8316_HPMIX_PDN,
252 SND_SOC_DAPM_OUT_DRV("Left Headphone Charge Pump", ES8316_CPHP_OUTEN,
254 SND_SOC_DAPM_OUT_DRV("Right Headphone Charge Pump", ES8316_CPHP_OUTEN,
256 SND_SOC_DAPM_SUPPLY("Headphone Charge Pump", ES8316_CPHP_PDN2,
258 SND_SOC_DAPM_SUPPLY("Headphone Charge Pump Clock", ES8316_CLKMGR_CLKSW,
261 SND_SOC_DAPM_OUT_DRV("Left Headphone Driver", ES8316_CPHP_OUTEN,
263 SND_SOC_DAPM_OUT_DRV("Right Headphone Driver", ES8316_CPHP_OUTEN,
265 SND_SOC_DAPM_SUPPLY("Headphone Out", ES8316_CPHP_PDN1, 2, 1, NULL, 0),
267 /* pdn_Lical and pdn_Rical bits are documented as Reserved, but must
268 * be explicitly unset in order to enable HP output
270 SND_SOC_DAPM_SUPPLY("Left Headphone ical", ES8316_CPHP_ICAL_VOL,
272 SND_SOC_DAPM_SUPPLY("Right Headphone ical", ES8316_CPHP_ICAL_VOL,
275 SND_SOC_DAPM_OUTPUT("HPOL"),
276 SND_SOC_DAPM_OUTPUT("HPOR"),
279 static const struct snd_soc_dapm_route es8316_dapm_routes[] = {
281 {"MIC1", NULL, "Mic Bias"},
282 {"MIC2", NULL, "Mic Bias"},
283 {"MIC1", NULL, "Bias"},
284 {"MIC2", NULL, "Bias"},
285 {"MIC1", NULL, "Analog power"},
286 {"MIC2", NULL, "Analog power"},
288 {"Differential Mux", "lin1-rin1", "MIC1"},
289 {"Differential Mux", "lin2-rin2", "MIC2"},
290 {"Line input PGA", NULL, "Differential Mux"},
292 {"Mono ADC", NULL, "ADC Clock"},
293 {"Mono ADC", NULL, "ADC Vref"},
294 {"Mono ADC", NULL, "ADC bias"},
295 {"Mono ADC", NULL, "Line input PGA"},
297 /* It's not clear why, but to avoid recording only silence,
298 * the DAC clock must be running for the ADC to work.
300 {"Mono ADC", NULL, "DAC Clock"},
302 {"Digital Mic Mux", "dmic disable", "Mono ADC"},
304 {"I2S OUT", NULL, "Digital Mic Mux"},
307 {"DAC Source Mux", "LDATA TO LDAC, RDATA TO RDAC", "I2S IN"},
309 {"Left DAC", NULL, "DAC Clock"},
310 {"Right DAC", NULL, "DAC Clock"},
312 {"Left DAC", NULL, "DAC Vref"},
313 {"Right DAC", NULL, "DAC Vref"},
315 {"Left DAC", NULL, "DAC Source Mux"},
316 {"Right DAC", NULL, "DAC Source Mux"},
318 {"Left Headphone Mux", "lin-rin with Boost and PGA", "Line input PGA"},
319 {"Right Headphone Mux", "lin-rin with Boost and PGA", "Line input PGA"},
321 {"Left Headphone Mixer", "LLIN Switch", "Left Headphone Mux"},
322 {"Left Headphone Mixer", "Left DAC Switch", "Left DAC"},
324 {"Right Headphone Mixer", "RLIN Switch", "Right Headphone Mux"},
325 {"Right Headphone Mixer", "Right DAC Switch", "Right DAC"},
327 {"Left Headphone Mixer Out", NULL, "Left Headphone Mixer"},
328 {"Right Headphone Mixer Out", NULL, "Right Headphone Mixer"},
330 {"Left Headphone Charge Pump", NULL, "Left Headphone Mixer Out"},
331 {"Right Headphone Charge Pump", NULL, "Right Headphone Mixer Out"},
333 {"Left Headphone Charge Pump", NULL, "Headphone Charge Pump"},
334 {"Right Headphone Charge Pump", NULL, "Headphone Charge Pump"},
336 {"Left Headphone Charge Pump", NULL, "Headphone Charge Pump Clock"},
337 {"Right Headphone Charge Pump", NULL, "Headphone Charge Pump Clock"},
339 {"Left Headphone Driver", NULL, "Left Headphone Charge Pump"},
340 {"Right Headphone Driver", NULL, "Right Headphone Charge Pump"},
342 {"HPOL", NULL, "Left Headphone Driver"},
343 {"HPOR", NULL, "Right Headphone Driver"},
345 {"HPOL", NULL, "Left Headphone ical"},
346 {"HPOR", NULL, "Right Headphone ical"},
348 {"Headphone Out", NULL, "Bias"},
349 {"Headphone Out", NULL, "Analog power"},
350 {"HPOL", NULL, "Headphone Out"},
351 {"HPOR", NULL, "Headphone Out"},
354 static int es8316_set_dai_sysclk(struct snd_soc_dai *codec_dai,
355 int clk_id, unsigned int freq, int dir)
357 struct snd_soc_component *component = codec_dai->component;
358 struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
362 es8316->sysclk = freq;
367 /* Limit supported sample rates to ones that can be autodetected
368 * by the codec running in slave mode.
370 for (i = 0; i < NR_SUPPORTED_MCLK_LRCK_RATIOS; i++) {
371 const unsigned int ratio = supported_mclk_lrck_ratios[i];
373 if (freq % ratio == 0)
374 es8316->allowed_rates[count++] = freq / ratio;
377 es8316->sysclk_constraints.list = es8316->allowed_rates;
378 es8316->sysclk_constraints.count = count;
383 static int es8316_set_dai_fmt(struct snd_soc_dai *codec_dai,
386 struct snd_soc_component *component = codec_dai->component;
392 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
393 dev_err(component->dev, "Codec driver only supports slave mode\n");
397 if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_I2S) {
398 dev_err(component->dev, "Codec driver only supports I2S format\n");
402 /* Clock inversion */
403 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
404 case SND_SOC_DAIFMT_NB_NF:
406 case SND_SOC_DAIFMT_IB_IF:
407 serdata1 |= ES8316_SERDATA1_BCLK_INV;
408 serdata2 |= ES8316_SERDATA2_ADCLRP;
410 case SND_SOC_DAIFMT_IB_NF:
411 serdata1 |= ES8316_SERDATA1_BCLK_INV;
413 case SND_SOC_DAIFMT_NB_IF:
414 serdata2 |= ES8316_SERDATA2_ADCLRP;
420 mask = ES8316_SERDATA1_MASTER | ES8316_SERDATA1_BCLK_INV;
421 snd_soc_component_update_bits(component, ES8316_SERDATA1, mask, serdata1);
423 mask = ES8316_SERDATA2_FMT_MASK | ES8316_SERDATA2_ADCLRP;
424 snd_soc_component_update_bits(component, ES8316_SERDATA_ADC, mask, serdata2);
425 snd_soc_component_update_bits(component, ES8316_SERDATA_DAC, mask, serdata2);
427 /* Enable BCLK and MCLK inputs in slave mode */
428 clksw = ES8316_CLKMGR_CLKSW_MCLK_ON | ES8316_CLKMGR_CLKSW_BCLK_ON;
429 snd_soc_component_update_bits(component, ES8316_CLKMGR_CLKSW, clksw, clksw);
434 static int es8316_pcm_startup(struct snd_pcm_substream *substream,
435 struct snd_soc_dai *dai)
437 struct snd_soc_component *component = dai->component;
438 struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
440 if (es8316->sysclk == 0) {
441 dev_err(component->dev, "No sysclk provided\n");
445 /* The set of sample rates that can be supported depends on the
446 * MCLK supplied to the CODEC.
448 snd_pcm_hw_constraint_list(substream->runtime, 0,
449 SNDRV_PCM_HW_PARAM_RATE,
450 &es8316->sysclk_constraints);
455 static int es8316_pcm_hw_params(struct snd_pcm_substream *substream,
456 struct snd_pcm_hw_params *params,
457 struct snd_soc_dai *dai)
459 struct snd_soc_component *component = dai->component;
460 struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
463 if (!es8316->sysclk) {
464 dev_err(component->dev, "No MCLK configured\n");
468 switch (params_format(params)) {
469 case SNDRV_PCM_FORMAT_S16_LE:
470 wordlen = ES8316_SERDATA2_LEN_16;
472 case SNDRV_PCM_FORMAT_S20_3LE:
473 wordlen = ES8316_SERDATA2_LEN_20;
475 case SNDRV_PCM_FORMAT_S24_LE:
476 wordlen = ES8316_SERDATA2_LEN_24;
478 case SNDRV_PCM_FORMAT_S32_LE:
479 wordlen = ES8316_SERDATA2_LEN_32;
485 snd_soc_component_update_bits(component, ES8316_SERDATA_DAC,
486 ES8316_SERDATA2_LEN_MASK, wordlen);
487 snd_soc_component_update_bits(component, ES8316_SERDATA_ADC,
488 ES8316_SERDATA2_LEN_MASK, wordlen);
492 static int es8316_mute(struct snd_soc_dai *dai, int mute)
494 snd_soc_component_update_bits(dai->component, ES8316_DAC_SET1, 0x20,
499 #define ES8316_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
500 SNDRV_PCM_FMTBIT_S24_LE)
502 static const struct snd_soc_dai_ops es8316_ops = {
503 .startup = es8316_pcm_startup,
504 .hw_params = es8316_pcm_hw_params,
505 .set_fmt = es8316_set_dai_fmt,
506 .set_sysclk = es8316_set_dai_sysclk,
507 .digital_mute = es8316_mute,
510 static struct snd_soc_dai_driver es8316_dai = {
511 .name = "ES8316 HiFi",
513 .stream_name = "Playback",
516 .rates = SNDRV_PCM_RATE_8000_48000,
517 .formats = ES8316_FORMATS,
520 .stream_name = "Capture",
523 .rates = SNDRV_PCM_RATE_8000_48000,
524 .formats = ES8316_FORMATS,
527 .symmetric_rates = 1,
530 static int es8316_probe(struct snd_soc_component *component)
532 /* Reset codec and enable current state machine */
533 snd_soc_component_write(component, ES8316_RESET, 0x3f);
534 usleep_range(5000, 5500);
535 snd_soc_component_write(component, ES8316_RESET, ES8316_RESET_CSM_ON);
539 * Documentation is unclear, but this value from the vendor driver is
540 * needed otherwise audio output is silent.
542 snd_soc_component_write(component, ES8316_SYS_VMIDSEL, 0xff);
545 * Documentation for this register is unclear and incomplete,
546 * but here is a vendor-provided value that improves volume
547 * and quality for Intel CHT platforms.
549 snd_soc_component_write(component, ES8316_CLKMGR_ADCOSR, 0x32);
554 static const struct snd_soc_component_driver soc_component_dev_es8316 = {
555 .probe = es8316_probe,
556 .controls = es8316_snd_controls,
557 .num_controls = ARRAY_SIZE(es8316_snd_controls),
558 .dapm_widgets = es8316_dapm_widgets,
559 .num_dapm_widgets = ARRAY_SIZE(es8316_dapm_widgets),
560 .dapm_routes = es8316_dapm_routes,
561 .num_dapm_routes = ARRAY_SIZE(es8316_dapm_routes),
562 .use_pmdown_time = 1,
564 .non_legacy_dai_naming = 1,
567 static const struct regmap_config es8316_regmap = {
570 .max_register = 0x53,
571 .cache_type = REGCACHE_RBTREE,
574 static int es8316_i2c_probe(struct i2c_client *i2c_client,
575 const struct i2c_device_id *id)
577 struct es8316_priv *es8316;
578 struct regmap *regmap;
580 es8316 = devm_kzalloc(&i2c_client->dev, sizeof(struct es8316_priv),
585 i2c_set_clientdata(i2c_client, es8316);
587 regmap = devm_regmap_init_i2c(i2c_client, &es8316_regmap);
589 return PTR_ERR(regmap);
591 return devm_snd_soc_register_component(&i2c_client->dev,
592 &soc_component_dev_es8316,
596 static const struct i2c_device_id es8316_i2c_id[] = {
600 MODULE_DEVICE_TABLE(i2c, es8316_i2c_id);
602 static const struct of_device_id es8316_of_match[] = {
603 { .compatible = "everest,es8316", },
606 MODULE_DEVICE_TABLE(of, es8316_of_match);
608 static const struct acpi_device_id es8316_acpi_match[] = {
612 MODULE_DEVICE_TABLE(acpi, es8316_acpi_match);
614 static struct i2c_driver es8316_i2c_driver = {
617 .acpi_match_table = ACPI_PTR(es8316_acpi_match),
618 .of_match_table = of_match_ptr(es8316_of_match),
620 .probe = es8316_i2c_probe,
621 .id_table = es8316_i2c_id,
623 module_i2c_driver(es8316_i2c_driver);
625 MODULE_DESCRIPTION("Everest Semi ES8316 ALSA SoC Codec Driver");
626 MODULE_AUTHOR("David Yang <yangxiaohua@everest-semi.com>");
627 MODULE_LICENSE("GPL v2");