~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/codecs/es8316.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * es8316.c -- es8316 ALSA SoC audio driver
  4  * Copyright Everest Semiconductor Co.,Ltd
  5  *
  6  * Authors: David Yang <yangxiaohua@everest-semi.com>,
  7  *          Daniel Drake <drake@endlessm.com>
  8  */
  9 
 10 #include <linux/module.h>
 11 #include <linux/acpi.h>
 12 #include <linux/clk.h>
 13 #include <linux/delay.h>
 14 #include <linux/i2c.h>
 15 #include <linux/mod_devicetable.h>
 16 #include <linux/mutex.h>
 17 #include <linux/regmap.h>
 18 #include <sound/pcm.h>
 19 #include <sound/pcm_params.h>
 20 #include <sound/soc.h>
 21 #include <sound/soc-dapm.h>
 22 #include <sound/tlv.h>
 23 #include <sound/jack.h>
 24 #include "es8316.h"
 25 
 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).
 29  */
 30 static const unsigned int supported_mclk_lrck_ratios[] = {
 31         256, 384, 400, 500, 512, 768, 1024
 32 };
 33 
 34 struct es8316_priv {
 35         struct mutex lock;
 36         struct clk *mclk;
 37         struct regmap *regmap;
 38         struct snd_soc_component *component;
 39         struct snd_soc_jack *jack;
 40         int irq;
 41         unsigned int sysclk;
 42         unsigned int allowed_rates[ARRAY_SIZE(supported_mclk_lrck_ratios)];
 43         struct snd_pcm_hw_constraint_list sysclk_constraints;
 44         bool jd_inverted;
 45 };
 46 
 47 /*
 48  * ES8316 controls
 49  */
 50 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(dac_vol_tlv, -9600, 50, 1);
 51 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_vol_tlv, -9600, 50, 1);
 52 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_max_gain_tlv, -650, 150, 0);
 53 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_min_gain_tlv, -1200, 150, 0);
 54 
 55 static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(alc_target_tlv,
 56         0, 10, TLV_DB_SCALE_ITEM(-1650, 150, 0),
 57         11, 11, TLV_DB_SCALE_ITEM(-150, 0, 0),
 58 );
 59 
 60 static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(hpmixer_gain_tlv,
 61         0, 4, TLV_DB_SCALE_ITEM(-1200, 150, 0),
 62         8, 11, TLV_DB_SCALE_ITEM(-450, 150, 0),
 63 );
 64 
 65 static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(adc_pga_gain_tlv,
 66         0, 0, TLV_DB_SCALE_ITEM(-350, 0, 0),
 67         1, 1, TLV_DB_SCALE_ITEM(0, 0, 0),
 68         2, 2, TLV_DB_SCALE_ITEM(250, 0, 0),
 69         3, 3, TLV_DB_SCALE_ITEM(450, 0, 0),
 70         4, 7, TLV_DB_SCALE_ITEM(700, 300, 0),
 71         8, 10, TLV_DB_SCALE_ITEM(1800, 300, 0),
 72 );
 73 
 74 static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(hpout_vol_tlv,
 75         0, 0, TLV_DB_SCALE_ITEM(-4800, 0, 0),
 76         1, 3, TLV_DB_SCALE_ITEM(-2400, 1200, 0),
 77 );
 78 
 79 static const char * const ng_type_txt[] =
 80         { "Constant PGA Gain", "Mute ADC Output" };
 81 static const struct soc_enum ng_type =
 82         SOC_ENUM_SINGLE(ES8316_ADC_ALC_NG, 6, 2, ng_type_txt);
 83 
 84 static const char * const adcpol_txt[] = { "Normal", "Invert" };
 85 static const struct soc_enum adcpol =
 86         SOC_ENUM_SINGLE(ES8316_ADC_MUTE, 1, 2, adcpol_txt);
 87 static const char *const dacpol_txt[] =
 88         { "Normal", "R Invert", "L Invert", "L + R Invert" };
 89 static const struct soc_enum dacpol =
 90         SOC_ENUM_SINGLE(ES8316_DAC_SET1, 0, 4, dacpol_txt);
 91 
 92 static const struct snd_kcontrol_new es8316_snd_controls[] = {
 93         SOC_DOUBLE_TLV("Headphone Playback Volume", ES8316_CPHP_ICAL_VOL,
 94                        4, 0, 3, 1, hpout_vol_tlv),
 95         SOC_DOUBLE_TLV("Headphone Mixer Volume", ES8316_HPMIX_VOL,
 96                        4, 0, 11, 0, hpmixer_gain_tlv),
 97 
 98         SOC_ENUM("Playback Polarity", dacpol),
 99         SOC_DOUBLE_R_TLV("DAC Playback Volume", ES8316_DAC_VOLL,
100                          ES8316_DAC_VOLR, 0, 0xc0, 1, dac_vol_tlv),
101         SOC_SINGLE("DAC Soft Ramp Switch", ES8316_DAC_SET1, 4, 1, 1),
102         SOC_SINGLE("DAC Soft Ramp Rate", ES8316_DAC_SET1, 2, 4, 0),
103         SOC_SINGLE("DAC Notch Filter Switch", ES8316_DAC_SET2, 6, 1, 0),
104         SOC_SINGLE("DAC Double Fs Switch", ES8316_DAC_SET2, 7, 1, 0),
105         SOC_SINGLE("DAC Stereo Enhancement", ES8316_DAC_SET3, 0, 7, 0),
106         SOC_SINGLE("DAC Mono Mix Switch", ES8316_DAC_SET3, 3, 1, 0),
107 
108         SOC_ENUM("Capture Polarity", adcpol),
109         SOC_SINGLE("Mic Boost Switch", ES8316_ADC_D2SEPGA, 0, 1, 0),
110         SOC_SINGLE_TLV("ADC Capture Volume", ES8316_ADC_VOLUME,
111                        0, 0xc0, 1, adc_vol_tlv),
112         SOC_SINGLE_TLV("ADC PGA Gain Volume", ES8316_ADC_PGAGAIN,
113                        4, 10, 0, adc_pga_gain_tlv),
114         SOC_SINGLE("ADC Soft Ramp Switch", ES8316_ADC_MUTE, 4, 1, 0),
115         SOC_SINGLE("ADC Double Fs Switch", ES8316_ADC_DMIC, 4, 1, 0),
116 
117         SOC_SINGLE("ALC Capture Switch", ES8316_ADC_ALC1, 6, 1, 0),
118         SOC_SINGLE_TLV("ALC Capture Max Volume", ES8316_ADC_ALC1, 0, 28, 0,
119                        alc_max_gain_tlv),
120         SOC_SINGLE_TLV("ALC Capture Min Volume", ES8316_ADC_ALC2, 0, 28, 0,
121                        alc_min_gain_tlv),
122         SOC_SINGLE_TLV("ALC Capture Target Volume", ES8316_ADC_ALC3, 4, 11, 0,
123                        alc_target_tlv),
124         SOC_SINGLE("ALC Capture Hold Time", ES8316_ADC_ALC3, 0, 10, 0),
125         SOC_SINGLE("ALC Capture Decay Time", ES8316_ADC_ALC4, 4, 10, 0),
126         SOC_SINGLE("ALC Capture Attack Time", ES8316_ADC_ALC4, 0, 10, 0),
127         SOC_SINGLE("ALC Capture Noise Gate Switch", ES8316_ADC_ALC_NG,
128                    5, 1, 0),
129         SOC_SINGLE("ALC Capture Noise Gate Threshold", ES8316_ADC_ALC_NG,
130                    0, 31, 0),
131         SOC_ENUM("ALC Capture Noise Gate Type", ng_type),
132 };
133 
134 /* Analog Input Mux */
135 static const char * const es8316_analog_in_txt[] = {
136                 "lin1-rin1",
137                 "lin2-rin2",
138                 "lin1-rin1 with 20db Boost",
139                 "lin2-rin2 with 20db Boost"
140 };
141 static const unsigned int es8316_analog_in_values[] = { 0, 1, 2, 3 };
142 static const struct soc_enum es8316_analog_input_enum =
143         SOC_VALUE_ENUM_SINGLE(ES8316_ADC_PDN_LINSEL, 4, 3,
144                               ARRAY_SIZE(es8316_analog_in_txt),
145                               es8316_analog_in_txt,
146                               es8316_analog_in_values);
147 static const struct snd_kcontrol_new es8316_analog_in_mux_controls =
148         SOC_DAPM_ENUM("Route", es8316_analog_input_enum);
149 
150 static const char * const es8316_dmic_txt[] = {
151                 "dmic disable",
152                 "dmic data at high level",
153                 "dmic data at low level",
154 };
155 static const unsigned int es8316_dmic_values[] = { 0, 2, 3 };
156 static const struct soc_enum es8316_dmic_src_enum =
157         SOC_VALUE_ENUM_SINGLE(ES8316_ADC_DMIC, 0, 3,
158                               ARRAY_SIZE(es8316_dmic_txt),
159                               es8316_dmic_txt,
160                               es8316_dmic_values);
161 static const struct snd_kcontrol_new es8316_dmic_src_controls =
162         SOC_DAPM_ENUM("Route", es8316_dmic_src_enum);
163 
164 /* hp mixer mux */
165 static const char * const es8316_hpmux_texts[] = {
166         "lin1-rin1",
167         "lin2-rin2",
168         "lin-rin with Boost",
169         "lin-rin with Boost and PGA"
170 };
171 
172 static SOC_ENUM_SINGLE_DECL(es8316_left_hpmux_enum, ES8316_HPMIX_SEL,
173         4, es8316_hpmux_texts);
174 
175 static const struct snd_kcontrol_new es8316_left_hpmux_controls =
176         SOC_DAPM_ENUM("Route", es8316_left_hpmux_enum);
177 
178 static SOC_ENUM_SINGLE_DECL(es8316_right_hpmux_enum, ES8316_HPMIX_SEL,
179         0, es8316_hpmux_texts);
180 
181 static const struct snd_kcontrol_new es8316_right_hpmux_controls =
182         SOC_DAPM_ENUM("Route", es8316_right_hpmux_enum);
183 
184 /* headphone Output Mixer */
185 static const struct snd_kcontrol_new es8316_out_left_mix[] = {
186         SOC_DAPM_SINGLE("LLIN Switch", ES8316_HPMIX_SWITCH, 6, 1, 0),
187         SOC_DAPM_SINGLE("Left DAC Switch", ES8316_HPMIX_SWITCH, 7, 1, 0),
188 };
189 static const struct snd_kcontrol_new es8316_out_right_mix[] = {
190         SOC_DAPM_SINGLE("RLIN Switch", ES8316_HPMIX_SWITCH, 2, 1, 0),
191         SOC_DAPM_SINGLE("Right DAC Switch", ES8316_HPMIX_SWITCH, 3, 1, 0),
192 };
193 
194 /* DAC data source mux */
195 static const char * const es8316_dacsrc_texts[] = {
196         "LDATA TO LDAC, RDATA TO RDAC",
197         "LDATA TO LDAC, LDATA TO RDAC",
198         "RDATA TO LDAC, RDATA TO RDAC",
199         "RDATA TO LDAC, LDATA TO RDAC",
200 };
201 
202 static SOC_ENUM_SINGLE_DECL(es8316_dacsrc_mux_enum, ES8316_DAC_SET1,
203         6, es8316_dacsrc_texts);
204 
205 static const struct snd_kcontrol_new es8316_dacsrc_mux_controls =
206         SOC_DAPM_ENUM("Route", es8316_dacsrc_mux_enum);
207 
208 static const struct snd_soc_dapm_widget es8316_dapm_widgets[] = {
209         SND_SOC_DAPM_SUPPLY("Bias", ES8316_SYS_PDN, 3, 1, NULL, 0),
210         SND_SOC_DAPM_SUPPLY("Analog power", ES8316_SYS_PDN, 4, 1, NULL, 0),
211         SND_SOC_DAPM_SUPPLY("Mic Bias", ES8316_SYS_PDN, 5, 1, NULL, 0),
212 
213         SND_SOC_DAPM_INPUT("DMIC"),
214         SND_SOC_DAPM_INPUT("MIC1"),
215         SND_SOC_DAPM_INPUT("MIC2"),
216 
217         /* Input Mux */
218         SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0,
219                          &es8316_analog_in_mux_controls),
220 
221         SND_SOC_DAPM_SUPPLY("ADC Vref", ES8316_SYS_PDN, 1, 1, NULL, 0),
222         SND_SOC_DAPM_SUPPLY("ADC bias", ES8316_SYS_PDN, 2, 1, NULL, 0),
223         SND_SOC_DAPM_SUPPLY("ADC Clock", ES8316_CLKMGR_CLKSW, 3, 0, NULL, 0),
224         SND_SOC_DAPM_PGA("Line input PGA", ES8316_ADC_PDN_LINSEL,
225                          7, 1, NULL, 0),
226         SND_SOC_DAPM_ADC("Mono ADC", NULL, ES8316_ADC_PDN_LINSEL, 6, 1),
227         SND_SOC_DAPM_MUX("Digital Mic Mux", SND_SOC_NOPM, 0, 0,
228                          &es8316_dmic_src_controls),
229 
230         /* Digital Interface */
231         SND_SOC_DAPM_AIF_OUT("I2S OUT", "I2S1 Capture",  1,
232                              ES8316_SERDATA_ADC, 6, 1),
233         SND_SOC_DAPM_AIF_IN("I2S IN", "I2S1 Playback", 0,
234                             SND_SOC_NOPM, 0, 0),
235 
236         SND_SOC_DAPM_MUX("DAC Source Mux", SND_SOC_NOPM, 0, 0,
237                          &es8316_dacsrc_mux_controls),
238 
239         SND_SOC_DAPM_SUPPLY("DAC Vref", ES8316_SYS_PDN, 0, 1, NULL, 0),
240         SND_SOC_DAPM_SUPPLY("DAC Clock", ES8316_CLKMGR_CLKSW, 2, 0, NULL, 0),
241         SND_SOC_DAPM_DAC("Right DAC", NULL, ES8316_DAC_PDN, 0, 1),
242         SND_SOC_DAPM_DAC("Left DAC", NULL, ES8316_DAC_PDN, 4, 1),
243 
244         /* Headphone Output Side */
245         SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0,
246                          &es8316_left_hpmux_controls),
247         SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0,
248                          &es8316_right_hpmux_controls),
249         SND_SOC_DAPM_MIXER("Left Headphone Mixer", ES8316_HPMIX_PDN,
250                            5, 1, &es8316_out_left_mix[0],
251                            ARRAY_SIZE(es8316_out_left_mix)),
252         SND_SOC_DAPM_MIXER("Right Headphone Mixer", ES8316_HPMIX_PDN,
253                            1, 1, &es8316_out_right_mix[0],
254                            ARRAY_SIZE(es8316_out_right_mix)),
255         SND_SOC_DAPM_PGA("Left Headphone Mixer Out", ES8316_HPMIX_PDN,
256                          4, 1, NULL, 0),
257         SND_SOC_DAPM_PGA("Right Headphone Mixer Out", ES8316_HPMIX_PDN,
258                          0, 1, NULL, 0),
259 
260         SND_SOC_DAPM_OUT_DRV("Left Headphone Charge Pump", ES8316_CPHP_OUTEN,
261                              6, 0, NULL, 0),
262         SND_SOC_DAPM_OUT_DRV("Right Headphone Charge Pump", ES8316_CPHP_OUTEN,
263                              2, 0, NULL, 0),
264         SND_SOC_DAPM_SUPPLY("Headphone Charge Pump", ES8316_CPHP_PDN2,
265                             5, 1, NULL, 0),
266         SND_SOC_DAPM_SUPPLY("Headphone Charge Pump Clock", ES8316_CLKMGR_CLKSW,
267                             4, 0, NULL, 0),
268 
269         SND_SOC_DAPM_OUT_DRV("Left Headphone Driver", ES8316_CPHP_OUTEN,
270                              5, 0, NULL, 0),
271         SND_SOC_DAPM_OUT_DRV("Right Headphone Driver", ES8316_CPHP_OUTEN,
272                              1, 0, NULL, 0),
273         SND_SOC_DAPM_SUPPLY("Headphone Out", ES8316_CPHP_PDN1, 2, 1, NULL, 0),
274 
275         /* pdn_Lical and pdn_Rical bits are documented as Reserved, but must
276          * be explicitly unset in order to enable HP output
277          */
278         SND_SOC_DAPM_SUPPLY("Left Headphone ical", ES8316_CPHP_ICAL_VOL,
279                             7, 1, NULL, 0),
280         SND_SOC_DAPM_SUPPLY("Right Headphone ical", ES8316_CPHP_ICAL_VOL,
281                             3, 1, NULL, 0),
282 
283         SND_SOC_DAPM_OUTPUT("HPOL"),
284         SND_SOC_DAPM_OUTPUT("HPOR"),
285 };
286 
287 static const struct snd_soc_dapm_route es8316_dapm_routes[] = {
288         /* Recording */
289         {"MIC1", NULL, "Mic Bias"},
290         {"MIC2", NULL, "Mic Bias"},
291         {"MIC1", NULL, "Bias"},
292         {"MIC2", NULL, "Bias"},
293         {"MIC1", NULL, "Analog power"},
294         {"MIC2", NULL, "Analog power"},
295 
296         {"Differential Mux", "lin1-rin1", "MIC1"},
297         {"Differential Mux", "lin2-rin2", "MIC2"},
298         {"Line input PGA", NULL, "Differential Mux"},
299 
300         {"Mono ADC", NULL, "ADC Clock"},
301         {"Mono ADC", NULL, "ADC Vref"},
302         {"Mono ADC", NULL, "ADC bias"},
303         {"Mono ADC", NULL, "Line input PGA"},
304 
305         /* It's not clear why, but to avoid recording only silence,
306          * the DAC clock must be running for the ADC to work.
307          */
308         {"Mono ADC", NULL, "DAC Clock"},
309 
310         {"Digital Mic Mux", "dmic disable", "Mono ADC"},
311 
312         {"I2S OUT", NULL, "Digital Mic Mux"},
313 
314         /* Playback */
315         {"DAC Source Mux", "LDATA TO LDAC, RDATA TO RDAC", "I2S IN"},
316 
317         {"Left DAC", NULL, "DAC Clock"},
318         {"Right DAC", NULL, "DAC Clock"},
319 
320         {"Left DAC", NULL, "DAC Vref"},
321         {"Right DAC", NULL, "DAC Vref"},
322 
323         {"Left DAC", NULL, "DAC Source Mux"},
324         {"Right DAC", NULL, "DAC Source Mux"},
325 
326         {"Left Headphone Mux", "lin-rin with Boost and PGA", "Line input PGA"},
327         {"Right Headphone Mux", "lin-rin with Boost and PGA", "Line input PGA"},
328 
329         {"Left Headphone Mixer", "LLIN Switch", "Left Headphone Mux"},
330         {"Left Headphone Mixer", "Left DAC Switch", "Left DAC"},
331 
332         {"Right Headphone Mixer", "RLIN Switch", "Right Headphone Mux"},
333         {"Right Headphone Mixer", "Right DAC Switch", "Right DAC"},
334 
335         {"Left Headphone Mixer Out", NULL, "Left Headphone Mixer"},
336         {"Right Headphone Mixer Out", NULL, "Right Headphone Mixer"},
337 
338         {"Left Headphone Charge Pump", NULL, "Left Headphone Mixer Out"},
339         {"Right Headphone Charge Pump", NULL, "Right Headphone Mixer Out"},
340 
341         {"Left Headphone Charge Pump", NULL, "Headphone Charge Pump"},
342         {"Right Headphone Charge Pump", NULL, "Headphone Charge Pump"},
343 
344         {"Left Headphone Charge Pump", NULL, "Headphone Charge Pump Clock"},
345         {"Right Headphone Charge Pump", NULL, "Headphone Charge Pump Clock"},
346 
347         {"Left Headphone Driver", NULL, "Left Headphone Charge Pump"},
348         {"Right Headphone Driver", NULL, "Right Headphone Charge Pump"},
349 
350         {"HPOL", NULL, "Left Headphone Driver"},
351         {"HPOR", NULL, "Right Headphone Driver"},
352 
353         {"HPOL", NULL, "Left Headphone ical"},
354         {"HPOR", NULL, "Right Headphone ical"},
355 
356         {"Headphone Out", NULL, "Bias"},
357         {"Headphone Out", NULL, "Analog power"},
358         {"HPOL", NULL, "Headphone Out"},
359         {"HPOR", NULL, "Headphone Out"},
360 };
361 
362 static int es8316_set_dai_sysclk(struct snd_soc_dai *codec_dai,
363                                  int clk_id, unsigned int freq, int dir)
364 {
365         struct snd_soc_component *component = codec_dai->component;
366         struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
367         int i, ret;
368         int count = 0;
369 
370         es8316->sysclk = freq;
371         es8316->sysclk_constraints.list = NULL;
372         es8316->sysclk_constraints.count = 0;
373 
374         if (freq == 0)
375                 return 0;
376 
377         ret = clk_set_rate(es8316->mclk, freq);
378         if (ret)
379                 return ret;
380 
381         /* Limit supported sample rates to ones that can be autodetected
382          * by the codec running in slave mode.
383          */
384         for (i = 0; i < ARRAY_SIZE(supported_mclk_lrck_ratios); i++) {
385                 const unsigned int ratio = supported_mclk_lrck_ratios[i];
386 
387                 if (freq % ratio == 0)
388                         es8316->allowed_rates[count++] = freq / ratio;
389         }
390 
391         if (count) {
392                 es8316->sysclk_constraints.list = es8316->allowed_rates;
393                 es8316->sysclk_constraints.count = count;
394         }
395 
396         return 0;
397 }
398 
399 static int es8316_set_dai_fmt(struct snd_soc_dai *codec_dai,
400                               unsigned int fmt)
401 {
402         struct snd_soc_component *component = codec_dai->component;
403         u8 serdata1 = 0;
404         u8 serdata2 = 0;
405         u8 clksw;
406         u8 mask;
407 
408         if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBP_CFP)
409                 serdata1 |= ES8316_SERDATA1_MASTER;
410 
411         if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_I2S) {
412                 dev_err(component->dev, "Codec driver only supports I2S format\n");
413                 return -EINVAL;
414         }
415 
416         /* Clock inversion */
417         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
418         case SND_SOC_DAIFMT_NB_NF:
419                 break;
420         case SND_SOC_DAIFMT_IB_IF:
421                 serdata1 |= ES8316_SERDATA1_BCLK_INV;
422                 serdata2 |= ES8316_SERDATA2_ADCLRP;
423                 break;
424         case SND_SOC_DAIFMT_IB_NF:
425                 serdata1 |= ES8316_SERDATA1_BCLK_INV;
426                 break;
427         case SND_SOC_DAIFMT_NB_IF:
428                 serdata2 |= ES8316_SERDATA2_ADCLRP;
429                 break;
430         default:
431                 return -EINVAL;
432         }
433 
434         mask = ES8316_SERDATA1_MASTER | ES8316_SERDATA1_BCLK_INV;
435         snd_soc_component_update_bits(component, ES8316_SERDATA1, mask, serdata1);
436 
437         mask = ES8316_SERDATA2_FMT_MASK | ES8316_SERDATA2_ADCLRP;
438         snd_soc_component_update_bits(component, ES8316_SERDATA_ADC, mask, serdata2);
439         snd_soc_component_update_bits(component, ES8316_SERDATA_DAC, mask, serdata2);
440 
441         /* Enable BCLK and MCLK inputs in slave mode */
442         clksw = ES8316_CLKMGR_CLKSW_MCLK_ON | ES8316_CLKMGR_CLKSW_BCLK_ON;
443         snd_soc_component_update_bits(component, ES8316_CLKMGR_CLKSW, clksw, clksw);
444 
445         return 0;
446 }
447 
448 static int es8316_pcm_startup(struct snd_pcm_substream *substream,
449                               struct snd_soc_dai *dai)
450 {
451         struct snd_soc_component *component = dai->component;
452         struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
453 
454         if (es8316->sysclk_constraints.list)
455                 snd_pcm_hw_constraint_list(substream->runtime, 0,
456                                            SNDRV_PCM_HW_PARAM_RATE,
457                                            &es8316->sysclk_constraints);
458 
459         return 0;
460 }
461 
462 static int es8316_pcm_hw_params(struct snd_pcm_substream *substream,
463                                 struct snd_pcm_hw_params *params,
464                                 struct snd_soc_dai *dai)
465 {
466         struct snd_soc_component *component = dai->component;
467         struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
468         u8 wordlen = 0;
469         u8 bclk_divider;
470         u16 lrck_divider;
471         int i;
472         unsigned int clk = es8316->sysclk / 2;
473         bool clk_valid = false;
474 
475         /* We will start with halved sysclk and see if we can use it
476          * for proper clocking. This is to minimise the risk of running
477          * the CODEC with a too high frequency. We have an SKU where
478          * the sysclk frequency is 48Mhz and this causes the sound to be
479          * sped up. If we can run with a halved sysclk, we will use it,
480          * if we can't use it, then full sysclk will be used.
481          */
482         do {
483                 /* Validate supported sample rates that are autodetected from MCLK */
484                 for (i = 0; i < ARRAY_SIZE(supported_mclk_lrck_ratios); i++) {
485                         const unsigned int ratio = supported_mclk_lrck_ratios[i];
486 
487                         if (clk % ratio != 0)
488                                 continue;
489                         if (clk / ratio == params_rate(params))
490                                 break;
491                 }
492                 if (i == ARRAY_SIZE(supported_mclk_lrck_ratios)) {
493                         if (clk == es8316->sysclk)
494                                 return -EINVAL;
495                         clk = es8316->sysclk;
496                 } else {
497                         clk_valid = true;
498                 }
499         } while (!clk_valid);
500 
501         if (clk != es8316->sysclk) {
502                 snd_soc_component_update_bits(component, ES8316_CLKMGR_CLKSW,
503                                               ES8316_CLKMGR_CLKSW_MCLK_DIV,
504                                               ES8316_CLKMGR_CLKSW_MCLK_DIV);
505         }
506 
507         lrck_divider = clk / params_rate(params);
508         bclk_divider = lrck_divider / 4;
509         switch (params_format(params)) {
510         case SNDRV_PCM_FORMAT_S16_LE:
511                 wordlen = ES8316_SERDATA2_LEN_16;
512                 bclk_divider /= 16;
513                 break;
514         case SNDRV_PCM_FORMAT_S20_3LE:
515                 wordlen = ES8316_SERDATA2_LEN_20;
516                 bclk_divider /= 20;
517                 break;
518         case SNDRV_PCM_FORMAT_S24_LE:
519         case SNDRV_PCM_FORMAT_S24_3LE:
520                 wordlen = ES8316_SERDATA2_LEN_24;
521                 bclk_divider /= 24;
522                 break;
523         case SNDRV_PCM_FORMAT_S32_LE:
524                 wordlen = ES8316_SERDATA2_LEN_32;
525                 bclk_divider /= 32;
526                 break;
527         default:
528                 return -EINVAL;
529         }
530 
531         snd_soc_component_update_bits(component, ES8316_SERDATA_DAC,
532                             ES8316_SERDATA2_LEN_MASK, wordlen);
533         snd_soc_component_update_bits(component, ES8316_SERDATA_ADC,
534                             ES8316_SERDATA2_LEN_MASK, wordlen);
535         snd_soc_component_update_bits(component, ES8316_SERDATA1, 0x1f, bclk_divider);
536         snd_soc_component_update_bits(component, ES8316_CLKMGR_ADCDIV1, 0x0f, lrck_divider >> 8);
537         snd_soc_component_update_bits(component, ES8316_CLKMGR_ADCDIV2, 0xff, lrck_divider & 0xff);
538         snd_soc_component_update_bits(component, ES8316_CLKMGR_DACDIV1, 0x0f, lrck_divider >> 8);
539         snd_soc_component_update_bits(component, ES8316_CLKMGR_DACDIV2, 0xff, lrck_divider & 0xff);
540         return 0;
541 }
542 
543 static int es8316_mute(struct snd_soc_dai *dai, int mute, int direction)
544 {
545         snd_soc_component_update_bits(dai->component, ES8316_DAC_SET1, 0x20,
546                             mute ? 0x20 : 0);
547         return 0;
548 }
549 
550 #define ES8316_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
551                         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
552 
553 static const struct snd_soc_dai_ops es8316_ops = {
554         .startup = es8316_pcm_startup,
555         .hw_params = es8316_pcm_hw_params,
556         .set_fmt = es8316_set_dai_fmt,
557         .set_sysclk = es8316_set_dai_sysclk,
558         .mute_stream = es8316_mute,
559         .no_capture_mute = 1,
560 };
561 
562 static struct snd_soc_dai_driver es8316_dai = {
563         .name = "ES8316 HiFi",
564         .playback = {
565                 .stream_name = "Playback",
566                 .channels_min = 1,
567                 .channels_max = 2,
568                 .rates = SNDRV_PCM_RATE_8000_48000,
569                 .formats = ES8316_FORMATS,
570         },
571         .capture = {
572                 .stream_name = "Capture",
573                 .channels_min = 1,
574                 .channels_max = 2,
575                 .rates = SNDRV_PCM_RATE_8000_48000,
576                 .formats = ES8316_FORMATS,
577         },
578         .ops = &es8316_ops,
579         .symmetric_rate = 1,
580 };
581 
582 static void es8316_enable_micbias_for_mic_gnd_short_detect(
583         struct snd_soc_component *component)
584 {
585         struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
586 
587         snd_soc_dapm_mutex_lock(dapm);
588         snd_soc_dapm_force_enable_pin_unlocked(dapm, "Bias");
589         snd_soc_dapm_force_enable_pin_unlocked(dapm, "Analog power");
590         snd_soc_dapm_force_enable_pin_unlocked(dapm, "Mic Bias");
591         snd_soc_dapm_sync_unlocked(dapm);
592         snd_soc_dapm_mutex_unlock(dapm);
593 
594         msleep(20);
595 }
596 
597 static void es8316_disable_micbias_for_mic_gnd_short_detect(
598         struct snd_soc_component *component)
599 {
600         struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
601 
602         snd_soc_dapm_mutex_lock(dapm);
603         snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Bias");
604         snd_soc_dapm_disable_pin_unlocked(dapm, "Analog power");
605         snd_soc_dapm_disable_pin_unlocked(dapm, "Bias");
606         snd_soc_dapm_sync_unlocked(dapm);
607         snd_soc_dapm_mutex_unlock(dapm);
608 }
609 
610 static irqreturn_t es8316_irq(int irq, void *data)
611 {
612         struct es8316_priv *es8316 = data;
613         struct snd_soc_component *comp = es8316->component;
614         unsigned int flags;
615 
616         mutex_lock(&es8316->lock);
617 
618         regmap_read(es8316->regmap, ES8316_GPIO_FLAG, &flags);
619         if (flags == 0x00)
620                 goto out; /* Powered-down / reset */
621 
622         /* Catch spurious IRQ before set_jack is called */
623         if (!es8316->jack)
624                 goto out;
625 
626         if (es8316->jd_inverted)
627                 flags ^= ES8316_GPIO_FLAG_HP_NOT_INSERTED;
628 
629         dev_dbg(comp->dev, "gpio flags %#04x\n", flags);
630         if (flags & ES8316_GPIO_FLAG_HP_NOT_INSERTED) {
631                 /* Jack removed, or spurious IRQ? */
632                 if (es8316->jack->status & SND_JACK_MICROPHONE)
633                         es8316_disable_micbias_for_mic_gnd_short_detect(comp);
634 
635                 if (es8316->jack->status & SND_JACK_HEADPHONE) {
636                         snd_soc_jack_report(es8316->jack, 0,
637                                             SND_JACK_HEADSET | SND_JACK_BTN_0);
638                         dev_dbg(comp->dev, "jack unplugged\n");
639                 }
640         } else if (!(es8316->jack->status & SND_JACK_HEADPHONE)) {
641                 /* Jack inserted, determine type */
642                 es8316_enable_micbias_for_mic_gnd_short_detect(comp);
643                 regmap_read(es8316->regmap, ES8316_GPIO_FLAG, &flags);
644                 if (es8316->jd_inverted)
645                         flags ^= ES8316_GPIO_FLAG_HP_NOT_INSERTED;
646                 dev_dbg(comp->dev, "gpio flags %#04x\n", flags);
647                 if (flags & ES8316_GPIO_FLAG_HP_NOT_INSERTED) {
648                         /* Jack unplugged underneath us */
649                         es8316_disable_micbias_for_mic_gnd_short_detect(comp);
650                 } else if (flags & ES8316_GPIO_FLAG_GM_NOT_SHORTED) {
651                         /* Open, headset */
652                         snd_soc_jack_report(es8316->jack,
653                                             SND_JACK_HEADSET,
654                                             SND_JACK_HEADSET);
655                         /* Keep mic-gnd-short detection on for button press */
656                 } else {
657                         /* Shorted, headphones */
658                         snd_soc_jack_report(es8316->jack,
659                                             SND_JACK_HEADPHONE,
660                                             SND_JACK_HEADSET);
661                         /* No longer need mic-gnd-short detection */
662                         es8316_disable_micbias_for_mic_gnd_short_detect(comp);
663                 }
664         } else if (es8316->jack->status & SND_JACK_MICROPHONE) {
665                 /* Interrupt while jack inserted, report button state */
666                 if (flags & ES8316_GPIO_FLAG_GM_NOT_SHORTED) {
667                         /* Open, button release */
668                         snd_soc_jack_report(es8316->jack, 0, SND_JACK_BTN_0);
669                 } else {
670                         /* Short, button press */
671                         snd_soc_jack_report(es8316->jack,
672                                             SND_JACK_BTN_0,
673                                             SND_JACK_BTN_0);
674                 }
675         }
676 
677 out:
678         mutex_unlock(&es8316->lock);
679         return IRQ_HANDLED;
680 }
681 
682 static void es8316_enable_jack_detect(struct snd_soc_component *component,
683                                       struct snd_soc_jack *jack)
684 {
685         struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
686 
687         /*
688          * Init es8316->jd_inverted here and not in the probe, as we cannot
689          * guarantee that the bytchr-es8316 driver, which might set this
690          * property, will probe before us.
691          */
692         es8316->jd_inverted = device_property_read_bool(component->dev,
693                                                         "everest,jack-detect-inverted");
694 
695         mutex_lock(&es8316->lock);
696 
697         es8316->jack = jack;
698 
699         if (es8316->jack->status & SND_JACK_MICROPHONE)
700                 es8316_enable_micbias_for_mic_gnd_short_detect(component);
701 
702         snd_soc_component_update_bits(component, ES8316_GPIO_DEBOUNCE,
703                                       ES8316_GPIO_ENABLE_INTERRUPT,
704                                       ES8316_GPIO_ENABLE_INTERRUPT);
705 
706         mutex_unlock(&es8316->lock);
707 
708         /* Enable irq and sync initial jack state */
709         enable_irq(es8316->irq);
710         es8316_irq(es8316->irq, es8316);
711 }
712 
713 static void es8316_disable_jack_detect(struct snd_soc_component *component)
714 {
715         struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
716 
717         if (!es8316->jack)
718                 return; /* Already disabled (or never enabled) */
719 
720         disable_irq(es8316->irq);
721 
722         mutex_lock(&es8316->lock);
723 
724         snd_soc_component_update_bits(component, ES8316_GPIO_DEBOUNCE,
725                                       ES8316_GPIO_ENABLE_INTERRUPT, 0);
726 
727         if (es8316->jack->status & SND_JACK_MICROPHONE) {
728                 es8316_disable_micbias_for_mic_gnd_short_detect(component);
729                 snd_soc_jack_report(es8316->jack, 0, SND_JACK_BTN_0);
730         }
731 
732         es8316->jack = NULL;
733 
734         mutex_unlock(&es8316->lock);
735 }
736 
737 static int es8316_set_jack(struct snd_soc_component *component,
738                            struct snd_soc_jack *jack, void *data)
739 {
740         if (jack)
741                 es8316_enable_jack_detect(component, jack);
742         else
743                 es8316_disable_jack_detect(component);
744 
745         return 0;
746 }
747 
748 static int es8316_probe(struct snd_soc_component *component)
749 {
750         struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
751         int ret;
752 
753         es8316->component = component;
754 
755         es8316->mclk = devm_clk_get_optional(component->dev, "mclk");
756         if (IS_ERR(es8316->mclk)) {
757                 dev_err(component->dev, "unable to get mclk\n");
758                 return PTR_ERR(es8316->mclk);
759         }
760         if (!es8316->mclk)
761                 dev_warn(component->dev, "assuming static mclk\n");
762 
763         ret = clk_prepare_enable(es8316->mclk);
764         if (ret) {
765                 dev_err(component->dev, "unable to enable mclk\n");
766                 return ret;
767         }
768 
769         /* Reset codec and enable current state machine */
770         snd_soc_component_write(component, ES8316_RESET, 0x3f);
771         usleep_range(5000, 5500);
772         snd_soc_component_write(component, ES8316_RESET, ES8316_RESET_CSM_ON);
773         msleep(30);
774 
775         /*
776          * Documentation is unclear, but this value from the vendor driver is
777          * needed otherwise audio output is silent.
778          */
779         snd_soc_component_write(component, ES8316_SYS_VMIDSEL, 0xff);
780 
781         /*
782          * Documentation for this register is unclear and incomplete,
783          * but here is a vendor-provided value that improves volume
784          * and quality for Intel CHT platforms.
785          */
786         snd_soc_component_write(component, ES8316_CLKMGR_ADCOSR, 0x32);
787 
788         return 0;
789 }
790 
791 static void es8316_remove(struct snd_soc_component *component)
792 {
793         struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
794 
795         clk_disable_unprepare(es8316->mclk);
796 }
797 
798 static int es8316_resume(struct snd_soc_component *component)
799 {
800         struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
801 
802         regcache_cache_only(es8316->regmap, false);
803         regcache_sync(es8316->regmap);
804 
805         return 0;
806 }
807 
808 static int es8316_suspend(struct snd_soc_component *component)
809 {
810         struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
811 
812         regcache_cache_only(es8316->regmap, true);
813         regcache_mark_dirty(es8316->regmap);
814 
815         return 0;
816 }
817 
818 static const struct snd_soc_component_driver soc_component_dev_es8316 = {
819         .probe                  = es8316_probe,
820         .remove                 = es8316_remove,
821         .resume                 = es8316_resume,
822         .suspend                = es8316_suspend,
823         .set_jack               = es8316_set_jack,
824         .controls               = es8316_snd_controls,
825         .num_controls           = ARRAY_SIZE(es8316_snd_controls),
826         .dapm_widgets           = es8316_dapm_widgets,
827         .num_dapm_widgets       = ARRAY_SIZE(es8316_dapm_widgets),
828         .dapm_routes            = es8316_dapm_routes,
829         .num_dapm_routes        = ARRAY_SIZE(es8316_dapm_routes),
830         .use_pmdown_time        = 1,
831         .endianness             = 1,
832 };
833 
834 static bool es8316_volatile_reg(struct device *dev, unsigned int reg)
835 {
836         switch (reg) {
837         case ES8316_GPIO_FLAG:
838                 return true;
839         default:
840                 return false;
841         }
842 }
843 
844 static const struct regmap_config es8316_regmap = {
845         .reg_bits = 8,
846         .val_bits = 8,
847         .use_single_read = true,
848         .use_single_write = true,
849         .max_register = 0x53,
850         .volatile_reg = es8316_volatile_reg,
851         .cache_type = REGCACHE_MAPLE,
852 };
853 
854 static int es8316_i2c_probe(struct i2c_client *i2c_client)
855 {
856         struct device *dev = &i2c_client->dev;
857         struct es8316_priv *es8316;
858         int ret;
859 
860         es8316 = devm_kzalloc(&i2c_client->dev, sizeof(struct es8316_priv),
861                               GFP_KERNEL);
862         if (es8316 == NULL)
863                 return -ENOMEM;
864 
865         i2c_set_clientdata(i2c_client, es8316);
866 
867         es8316->regmap = devm_regmap_init_i2c(i2c_client, &es8316_regmap);
868         if (IS_ERR(es8316->regmap))
869                 return PTR_ERR(es8316->regmap);
870 
871         es8316->irq = i2c_client->irq;
872         mutex_init(&es8316->lock);
873 
874         if (es8316->irq > 0) {
875                 ret = devm_request_threaded_irq(dev, es8316->irq, NULL, es8316_irq,
876                                                 IRQF_TRIGGER_HIGH | IRQF_ONESHOT | IRQF_NO_AUTOEN,
877                                                 "es8316", es8316);
878                 if (ret) {
879                         dev_warn(dev, "Failed to get IRQ %d: %d\n", es8316->irq, ret);
880                         es8316->irq = -ENXIO;
881                 }
882         }
883 
884         return devm_snd_soc_register_component(&i2c_client->dev,
885                                       &soc_component_dev_es8316,
886                                       &es8316_dai, 1);
887 }
888 
889 static const struct i2c_device_id es8316_i2c_id[] = {
890         {"es8316" },
891         {}
892 };
893 MODULE_DEVICE_TABLE(i2c, es8316_i2c_id);
894 
895 #ifdef CONFIG_OF
896 static const struct of_device_id es8316_of_match[] = {
897         { .compatible = "everest,es8316", },
898         {},
899 };
900 MODULE_DEVICE_TABLE(of, es8316_of_match);
901 #endif
902 
903 #ifdef CONFIG_ACPI
904 static const struct acpi_device_id es8316_acpi_match[] = {
905         {"ESSX8316", 0},
906         {"ESSX8336", 0},
907         {},
908 };
909 MODULE_DEVICE_TABLE(acpi, es8316_acpi_match);
910 #endif
911 
912 static struct i2c_driver es8316_i2c_driver = {
913         .driver = {
914                 .name                   = "es8316",
915                 .acpi_match_table       = ACPI_PTR(es8316_acpi_match),
916                 .of_match_table         = of_match_ptr(es8316_of_match),
917         },
918         .probe          = es8316_i2c_probe,
919         .id_table       = es8316_i2c_id,
920 };
921 module_i2c_driver(es8316_i2c_driver);
922 
923 MODULE_DESCRIPTION("Everest Semi ES8316 ALSA SoC Codec Driver");
924 MODULE_AUTHOR("David Yang <yangxiaohua@everest-semi.com>");
925 MODULE_LICENSE("GPL v2");
926 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php