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

TOMOYO Linux Cross Reference
Linux/sound/soc/codecs/es8311.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  * es8311.c -- es8311 ALSA SoC audio driver
  4  *
  5  * Copyright (C) 2024 Matteo Martelli <matteomartelli3@gmail.com>
  6  *
  7  * Author: Matteo Martelli <matteomartelli3@gmail.com>
  8  */
  9 
 10 #include "linux/array_size.h"
 11 #include "sound/pcm.h"
 12 #include <linux/clk.h>
 13 #include <linux/i2c.h>
 14 #include <linux/module.h>
 15 #include <linux/regmap.h>
 16 #include <sound/core.h>
 17 #include <sound/pcm_params.h>
 18 #include <sound/soc.h>
 19 #include <sound/tlv.h>
 20 #include "es8311.h"
 21 
 22 #define ES8311_NUM_RATES 10
 23 #define ES8311_RATES (SNDRV_PCM_RATE_8000_96000)
 24 #define ES8311_FORMATS                                         \
 25         (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE |  \
 26          SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_3LE | \
 27          SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 28 
 29 struct es8311_priv {
 30         struct regmap *regmap;
 31         struct clk *mclk;
 32         unsigned long mclk_freq;
 33         bool provider;
 34         unsigned int rates[ES8311_NUM_RATES];
 35         struct snd_pcm_hw_constraint_list constraints;
 36 };
 37 
 38 static const DECLARE_TLV_DB_SCALE(es8311_adc_vol_tlv, -9550, 50, 0);
 39 static const DECLARE_TLV_DB_SCALE(es8311_pga_gain_tlv, 0, 300, 0);
 40 static const DECLARE_TLV_DB_SCALE(es8311_adc_scale_tlv, 0, 600, 0);
 41 
 42 #define ES8311_DB_LRCK_STEPS \
 43         "0.25db/4LRCK", \
 44         "0.25db/8LRCK", \
 45         "0.25db/16LRCK", \
 46         "0.25db/32LRCK", \
 47         "0.25db/64LRCK", \
 48         "0.25db/128LRCK", \
 49         "0.25db/256LRCK", \
 50         "0.25db/512LRCK", \
 51         "0.25db/1024LRCK", \
 52         "0.25db/2048LRCK", \
 53         "0.25db/4096LRCK", \
 54         "0.25db/8192LRCK", \
 55         "0.25db/16384LRCK", \
 56         "0.25db/32768LRCK", \
 57         "0.25db/65536LRCK",
 58 
 59 static const char *const es8311_level_winsize_txt[] = {
 60         "0.25db/2LRCK",
 61         ES8311_DB_LRCK_STEPS
 62 };
 63 
 64 static SOC_ENUM_SINGLE_DECL(
 65         es8311_alc_winsize, ES8311_ADC4,
 66         ES8311_ADC4_ALC_WINSIZE_SHIFT, es8311_level_winsize_txt);
 67 static const DECLARE_TLV_DB_RANGE(es8311_level_tlv,
 68         0, 1, TLV_DB_SCALE_ITEM(-3010, 600, 0),
 69         2, 3, TLV_DB_SCALE_ITEM(-2060, 250, 0),
 70         4, 5, TLV_DB_SCALE_ITEM(-1610, 160, 0),
 71         6, 7, TLV_DB_SCALE_ITEM(-1320, 120, 0),
 72         8, 9, TLV_DB_SCALE_ITEM(-1100, 90, 0),
 73         10, 11, TLV_DB_SCALE_ITEM(-930, 80, 0),
 74         12, 15, TLV_DB_SCALE_ITEM(-780, 60, 0),
 75 );
 76 
 77 static const char *const es8311_ramprate_txt[] = {
 78         "Disabled",
 79         ES8311_DB_LRCK_STEPS
 80 };
 81 static SOC_ENUM_SINGLE_DECL(
 82         es8311_adc_ramprate, ES8311_ADC1,
 83         ES8311_ADC1_RAMPRATE_SHIFT, es8311_ramprate_txt);
 84 
 85 static const char *const es8311_automute_winsize_txt[] = {
 86         "2048 samples",
 87         "4096 samples",
 88         "6144 samples",
 89         "8192 samples",
 90         "10240 samples",
 91         "12288 samples",
 92         "14336 samples",
 93         "16384 samples",
 94         "18432 samples",
 95         "20480 samples",
 96         "22528 samples",
 97         "24576 samples",
 98         "26624 samples",
 99         "28672 samples",
100         "30720 samples",
101         "32768 samples",
102 };
103 static SOC_ENUM_SINGLE_DECL(
104         es8311_automute_winsize, ES8311_ADC6,
105         ES8311_ADC6_AUTOMUTE_WS_SHIFT, es8311_automute_winsize_txt);
106 static const DECLARE_TLV_DB_RANGE(es8311_automute_ng_tlv,
107         0, 7, TLV_DB_SCALE_ITEM(-9600, 600, 0),
108         8, 15, TLV_DB_SCALE_ITEM(-5100, 300, 0),
109 );
110 static const DECLARE_TLV_DB_SCALE(es8311_automute_vol_tlv, -2800, 400, 0);
111 
112 static const DECLARE_TLV_DB_SCALE(es8311_dac_vol_tlv, -9550, 50, 0);
113 static SOC_ENUM_SINGLE_DECL(
114         es8311_drc_winsize, ES8311_DAC4,
115         ES8311_DAC4_DRC_WINSIZE_SHIFT, es8311_level_winsize_txt);
116 static SOC_ENUM_SINGLE_DECL(
117         es8311_dac_ramprate, ES8311_DAC6,
118         ES8311_DAC6_RAMPRATE_SHIFT, es8311_ramprate_txt);
119 
120 static const char *const es8311_out_mode_txt[] = {
121         "Lineout",
122         "Headphones"
123 };
124 static SOC_ENUM_SINGLE_DECL(
125         es8311_out_mode, ES8311_SYS9,
126         ES8311_SYS9_HPSW_SHIFT, es8311_out_mode_txt);
127 
128 static const struct snd_kcontrol_new es8311_snd_controls[] = {
129         /* Capture path */
130         SOC_SINGLE_TLV("PGA Capture Volume", ES8311_SYS10,
131                        ES8311_SYS10_PGAGAIN_SHIFT, ES8311_SYS10_PGAGAIN_MAX, 0,
132                        es8311_pga_gain_tlv),
133         SOC_SINGLE("ADC Polarity Invert Capture Switch", ES8311_ADC2,
134                    ES8311_ADC2_INV_SHIFT, 1, 0),
135         SOC_SINGLE_TLV("ADC Scale Capture Volume", ES8311_ADC2,
136                        ES8311_ADC2_SCALE_SHIFT, ES8311_ADC2_SCALE_MAX, 0,
137                        es8311_adc_scale_tlv),
138         SOC_SINGLE_TLV("ADC Capture Volume", ES8311_ADC3,
139                        ES8311_ADC3_VOLUME_SHIFT, ES8311_ADC3_VOLUME_MAX, 0,
140                        es8311_adc_vol_tlv),
141         SOC_ENUM("ADC Capture Ramp Rate", es8311_adc_ramprate),
142         SOC_SINGLE("ADC Automute Capture Switch", ES8311_ADC4,
143                    ES8311_ADC4_AUTOMUTE_EN_SHIFT, 1, 0),
144         SOC_ENUM("ADC Automute Capture Winsize", es8311_automute_winsize),
145         SOC_SINGLE_TLV("ADC Automute Noise Gate Capture Volume", ES8311_ADC6,
146                        ES8311_ADC6_AUTOMUTE_NG_SHIFT,
147                        ES8311_ADC6_AUTOMUTE_NG_MAX, 0, es8311_automute_ng_tlv),
148         SOC_SINGLE_TLV("ADC Automute Capture Volume", ES8311_ADC7,
149                        ES8311_ADC7_AUTOMUTE_VOL_SHIFT,
150                        ES8311_ADC7_AUTOMUTE_VOL_MAX, 0,
151                        es8311_automute_vol_tlv),
152         SOC_SINGLE("ADC HPF Capture Switch", ES8311_ADC8, ES8311_ADC8_HPF_SHIFT,
153                    1, 0),
154         SOC_SINGLE("ADC EQ Capture Switch", ES8311_ADC8,
155                    ES8311_ADC8_EQBYPASS_SHIFT, 1, 1),
156         SOC_SINGLE("ALC Capture Switch", ES8311_ADC4, ES8311_ADC4_ALC_EN_SHIFT,
157                    1, 0),
158         SOC_SINGLE_TLV("ALC Capture Max Volume", ES8311_ADC5,
159                        ES8311_ADC5_ALC_MAXLEVEL_SHIFT,
160                        ES8311_ADC5_ALC_MAXLEVEL_MAX, 0, es8311_level_tlv),
161         SOC_SINGLE_TLV("ALC Capture Min Volume", ES8311_ADC5,
162                        ES8311_ADC5_ALC_MINLEVEL_SHIFT,
163                        ES8311_ADC5_ALC_MINLEVEL_MAX, 0, es8311_level_tlv),
164         SOC_ENUM("ALC Capture Winsize", es8311_alc_winsize),
165 
166         /* Playback path */
167         SOC_SINGLE_TLV("DAC Playback Volume", ES8311_DAC2, 0,
168                        ES8311_DAC2_VOLUME_MAX, 0, es8311_dac_vol_tlv),
169         SOC_SINGLE("DRC Playback Switch", ES8311_DAC4, ES8311_DAC4_DRC_EN_SHIFT,
170                    1, 0),
171         SOC_SINGLE_TLV("DRC Playback Max Volume", ES8311_DAC5,
172                        ES8311_DAC5_DRC_MAXLEVEL_SHIFT,
173                        ES8311_DAC5_DRC_MAXLEVEL_MAX, 0, es8311_level_tlv),
174         SOC_SINGLE_TLV("DRC Playback Min Volume", ES8311_DAC5,
175                        ES8311_DAC5_DRC_MINLEVEL_SHIFT,
176                        ES8311_DAC5_DRC_MINLEVEL_MAX, 0, es8311_level_tlv),
177         SOC_ENUM("DRC Playback Winsize", es8311_drc_winsize),
178         SOC_ENUM("DAC Playback Ramp Rate", es8311_dac_ramprate),
179         SOC_SINGLE("DAC EQ Playback Switch", ES8311_DAC6,
180                    ES8311_DAC6_EQBYPASS_SHIFT, 1, 1),
181 
182         SOC_ENUM("Output Mode", es8311_out_mode),
183 };
184 
185 static const char *const es8311_diff_src_txt[] = {
186         "Disabled",
187         "MIC1P-MIC1N",
188 };
189 static SOC_ENUM_SINGLE_DECL(
190         es8311_diff_src_enum, ES8311_SYS10,
191         ES8311_SYS10_LINESEL_SHIFT, es8311_diff_src_txt);
192 static const struct snd_kcontrol_new es8311_diff_src_mux =
193         SOC_DAPM_ENUM("Differential Source", es8311_diff_src_enum);
194 
195 static const char *const es8311_dmic_src_txt[] = {
196         "Disabled",
197         "DMIC from MIC1P",
198 };
199 static SOC_ENUM_SINGLE_DECL(
200         es8311_dmic_src_enum, ES8311_SYS10,
201         ES8311_SYS10_DMIC_ON_SHIFT, es8311_dmic_src_txt);
202 static const struct snd_kcontrol_new es8311_dmic_src_mux =
203         SOC_DAPM_ENUM("Digital Mic Source", es8311_dmic_src_enum);
204 
205 static const char * const es8311_aif1tx_src_txt[] = {
206         "ADC + ADC",
207         "ADC + 0",
208         "0 + ADC",
209         "0 + 0",
210         "DACL + ADC",
211         "ADC + DACR",
212         "DACL + DACR",
213 };
214 static SOC_ENUM_SINGLE_DECL(
215         es8311_aif1tx_src_enum, ES8311_GPIO,
216         ES8311_GPIO_ADCDAT_SEL_SHIFT, es8311_aif1tx_src_txt);
217 static const struct snd_kcontrol_new es8311_aif1tx_src_mux =
218         SOC_DAPM_ENUM("AIF1TX Source", es8311_aif1tx_src_enum);
219 
220 static const char * const es8311_dac_src_txt[] = {
221         "Left",
222         "Right"
223 };
224 static SOC_ENUM_SINGLE_DECL(
225         es8311_dac_src_enum, ES8311_SDP_IN,
226         ES8311_SDP_IN_SEL_SHIFT, es8311_dac_src_txt);
227 static const struct snd_kcontrol_new es8311_dac_src_mux =
228         SOC_DAPM_ENUM("Mono DAC Source", es8311_dac_src_enum);
229 
230 static const struct snd_soc_dapm_widget es8311_dapm_widgets[] = {
231         SND_SOC_DAPM_SUPPLY("Bias", ES8311_SYS3, ES8311_SYS3_PDN_IBIASGEN_SHIFT,
232                             1, NULL, 0),
233         SND_SOC_DAPM_SUPPLY("Analog power", ES8311_SYS3,
234                             ES8311_SYS3_PDN_ANA_SHIFT, 1, NULL, 0),
235         SND_SOC_DAPM_SUPPLY("Vref", ES8311_SYS3, ES8311_SYS3_PDN_VREF_SHIFT, 1,
236                             NULL, 0),
237 
238         /* Capture path */
239         SND_SOC_DAPM_INPUT("DMIC"),
240         SND_SOC_DAPM_INPUT("MIC1"),
241         SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0,
242                          &es8311_diff_src_mux),
243         SND_SOC_DAPM_SUPPLY("ADC Bias Gen", ES8311_SYS3,
244                             ES8311_SYS3_PDN_ADCBIASGEN_SHIFT, 1, NULL, 0),
245         SND_SOC_DAPM_SUPPLY("ADC Vref Gen", ES8311_SYS3,
246                             ES8311_SYS3_PDN_ADCVREFGEN_SHIFT, 1, NULL, 0),
247         SND_SOC_DAPM_SUPPLY("ADC Clock", ES8311_CLKMGR1,
248                             ES8311_CLKMGR1_CLKADC_ON_SHIFT, 0, NULL, 0),
249         SND_SOC_DAPM_SUPPLY("ADC Analog Clock", ES8311_CLKMGR1,
250                             ES8311_CLKMGR1_ANACLKADC_ON_SHIFT, 0, NULL, 0),
251         SND_SOC_DAPM_PGA("PGA", ES8311_SYS4, ES8311_SYS4_PDN_PGA_SHIFT, 1, NULL,
252                          0),
253         SND_SOC_DAPM_ADC("Mono ADC", NULL, ES8311_SYS4,
254                          ES8311_SYS4_PDN_MOD_SHIFT, 1),
255         SND_SOC_DAPM_MUX("Digital Mic Mux", SND_SOC_NOPM, 0, 0,
256                          &es8311_dmic_src_mux),
257         SND_SOC_DAPM_MUX("AIF1TX Source Mux", SND_SOC_NOPM, 0, 0,
258                          &es8311_aif1tx_src_mux),
259         SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, ES8311_SDP_OUT,
260                              ES8311_SDP_MUTE_SHIFT, 1),
261 
262         /* Playback path */
263         SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, ES8311_SDP_IN,
264                             ES8311_SDP_MUTE_SHIFT, 1),
265         SND_SOC_DAPM_MUX("Mono DAC Source Mux", SND_SOC_NOPM, 0, 0,
266                          &es8311_dac_src_mux),
267         SND_SOC_DAPM_DAC("Mono DAC", NULL, ES8311_SYS8,
268                          ES8311_SYS8_PDN_DAC_SHIFT, 1),
269         SND_SOC_DAPM_SUPPLY("DAC Clock", ES8311_CLKMGR1,
270                             ES8311_CLKMGR1_CLKDAC_ON_SHIFT, 0, NULL, 0),
271         SND_SOC_DAPM_SUPPLY("DAC Analog Clock", ES8311_CLKMGR1,
272                             ES8311_CLKMGR1_ANACLKDAC_ON_SHIFT, 0, NULL, 0),
273         SND_SOC_DAPM_SUPPLY("DAC Vref Gen", ES8311_SYS3,
274                             ES8311_SYS3_PDN_DACVREFGEN_SHIFT, 1, NULL, 0),
275         SND_SOC_DAPM_OUTPUT("OUT"),
276 };
277 
278 static const struct snd_soc_dapm_route es8311_dapm_routes[] = {
279         /* Capture Path */
280         { "MIC1", NULL, "Bias" },
281         { "MIC1", NULL, "Analog power" },
282         { "MIC1", NULL, "Vref" },
283         { "Differential Mux", "MIC1P-MIC1N", "MIC1" },
284         { "PGA", NULL, "Differential Mux" },
285         { "Mono ADC", NULL, "PGA" },
286         { "Mono ADC", NULL, "ADC Bias Gen" },
287         { "Mono ADC", NULL, "ADC Vref Gen" },
288         { "Mono ADC", NULL, "ADC Clock" },
289         { "Mono ADC", NULL, "ADC Analog Clock" },
290         { "Digital Mic Mux", "Disabled", "Mono ADC" },
291         { "Digital Mic Mux", "DMIC from MIC1P", "DMIC" },
292 
293         { "AIF1TX Source Mux", "ADC + ADC", "Digital Mic Mux" },
294         { "AIF1TX Source Mux", "ADC + 0", "Digital Mic Mux" },
295         { "AIF1TX Source Mux", "0 + ADC", "Digital Mic Mux" },
296         { "AIF1TX Source Mux", "DACL + ADC", "Digital Mic Mux" },
297         { "AIF1TX Source Mux", "ADC + DACR", "Digital Mic Mux" },
298 
299         { "AIF1TX", NULL, "AIF1TX Source Mux" },
300 
301         /* Playback Path */
302         { "Mono DAC Source Mux", "Left", "AIF1RX" },
303         { "Mono DAC Source Mux", "Right", "AIF1RX" },
304         { "Mono DAC", NULL, "Mono DAC Source Mux" },
305         { "Mono DAC", NULL, "DAC Clock" },
306         { "Mono DAC", NULL, "DAC Analog Clock" },
307         { "OUT", NULL, "Mono DAC" },
308         { "OUT", NULL, "Bias" },
309         { "OUT", NULL, "Analog power" },
310         { "OUT", NULL, "Vref" },
311         { "OUT", NULL, "DAC Vref Gen" },
312 };
313 
314 /* Bit clock divider values:
315  * from 1 to 20: the register takes the div value - 1
316  * above 20: the register takes the corresponding idx of the div value
317  *           in the following table + 20
318  */
319 #define ES8311_BCLK_DIV_IDX_OFFSET 20
320 static const unsigned int es8311_bclk_divs[] = {
321         22, 24, 25, 30, 32, 33, 34, 36, 44, 48, 66, 72
322 };
323 
324 struct es8311_mclk_coeff {
325         unsigned int rate;
326         unsigned int mclk;
327         unsigned int div;
328         unsigned int mult;
329         unsigned int div_adc_dac;
330 };
331 
332 #define ES8311_MCLK_MAX_FREQ 49200000
333 
334 /* Coefficients for common master clock frequencies based on clock table from
335  * documentation. Limited to have a ratio of adc (or dac) clock to lrclk equal
336  * to 256. This to keep the default adc and dac oversampling and adc scale
337  * settings. Internal mclk dividers and multipliers are dynamically adjusted to
338  * support, respectively, multiples (up to x8) and factors (/2,4,8) of listed
339  * mclks frequencies (see es8311_cmp_adj_mclk_coeff).
340  * All rates are supported when mclk/rate ratio is 32, 64, 128, 256, 384 or 512
341  * (upper limit due to max mclk freq of 49.2MHz).
342  */
343 static const struct es8311_mclk_coeff es8311_mclk_coeffs[] = {
344         { 8000, 2048000, 1, 1, 1 },
345         { 8000, 6144000, 3, 1, 1 },
346         { 8000, 18432000, 3, 1, 3 },
347         { 11025, 2822400, 1, 1, 1 },
348         { 11025, 8467200, 3, 1, 1 },
349         { 16000, 4096000, 1, 1, 1 },
350         { 16000, 12288000, 3, 1, 1 },
351         { 16000, 18432000, 3, 2, 3 },
352         { 22050, 5644800, 1, 1, 1 },
353         { 22050, 16934400, 3, 1, 1 },
354         { 32000, 8192000, 1, 1, 1 },
355         { 32000, 12288000, 3, 2, 1 },
356         { 32000, 18432000, 3, 4, 3 },
357         { 44100, 11289600, 1, 1, 1 },
358         { 44100, 33868800, 3, 1, 1 },
359         { 48000, 12288000, 1, 1, 1 },
360         { 48000, 18432000, 3, 2, 1 },
361         { 64000, 8192000, 1, 2, 1 },
362         { 64000, 12288000, 3, 4, 1 },
363         { 88200, 11289600, 1, 2, 1 },
364         { 88200, 33868800, 3, 2, 1 },
365         { 96000, 12288000, 1, 2, 1 },
366         { 96000, 18432000, 3, 4, 1 },
367 };
368 
369 /* Compare coeff with provided mclk_freq and adjust it if needed.
370  * If frequencies match, return 0 and the unaltered coeff copy into out_coeff.
371  * If mclk_freq is a valid multiple or factor of coeff mclk freq, return 0 and
372  * the adjusted coeff copy into out_coeff.
373  * Return -EINVAL otherwise.
374  */
375 static int es8311_cmp_adj_mclk_coeff(unsigned int mclk_freq,
376                                      const struct es8311_mclk_coeff *coeff,
377                                      struct es8311_mclk_coeff *out_coeff)
378 {
379         if (WARN_ON_ONCE(!coeff))
380                 return -EINVAL;
381 
382         unsigned int div = coeff->div;
383         unsigned int mult = coeff->mult;
384         bool match = false;
385 
386         if (coeff->mclk == mclk_freq) {
387                 match = true;
388         } else if (mclk_freq % coeff->mclk == 0) {
389                 div = mclk_freq / coeff->mclk;
390                 div *= coeff->div;
391                 if (div <= 8)
392                         match = true;
393         } else if (coeff->mclk % mclk_freq == 0) {
394                 mult = coeff->mclk / mclk_freq;
395                 if (mult == 2 || mult == 4 || mult == 8) {
396                         mult *= coeff->mult;
397                         if (mult <= 8)
398                                 match = true;
399                 }
400         }
401         if (!match)
402                 return -EINVAL;
403         if (out_coeff) {
404                 *out_coeff = *coeff;
405                 out_coeff->div = div;
406                 out_coeff->mult = mult;
407         }
408         return 0;
409 }
410 
411 static int es8311_get_mclk_coeff(unsigned int mclk_freq, unsigned int rate,
412                                  struct es8311_mclk_coeff *out_coeff)
413 {
414         for (unsigned int i = 0; i < ARRAY_SIZE(es8311_mclk_coeffs); i++) {
415                 const struct es8311_mclk_coeff *coeff = &es8311_mclk_coeffs[i];
416 
417                 if (coeff->rate != rate)
418                         continue;
419 
420                 int ret =
421                         es8311_cmp_adj_mclk_coeff(mclk_freq, coeff, out_coeff);
422                 if (ret == 0)
423                         return 0;
424         }
425         return -EINVAL;
426 }
427 
428 static void es8311_set_sysclk_constraints(unsigned int mclk_freq,
429                                           struct es8311_priv *es8311)
430 {
431         unsigned int count = 0;
432 
433         for (unsigned int i = 0; i < ARRAY_SIZE(es8311_mclk_coeffs) &&
434              count < ARRAY_SIZE(es8311->rates); i++) {
435                 const struct es8311_mclk_coeff *coeff = &es8311_mclk_coeffs[i];
436 
437                 if (count > 0 && coeff->rate == es8311->rates[count - 1])
438                         continue;
439 
440                 int ret = es8311_cmp_adj_mclk_coeff(mclk_freq, coeff, NULL);
441                 if (ret == 0)
442                         es8311->rates[count++] = coeff->rate;
443         }
444         if (count) {
445                 es8311->constraints.list = es8311->rates;
446                 es8311->constraints.count = count;
447         }
448 }
449 
450 static int es8311_mute(struct snd_soc_dai *dai, int mute, int direction)
451 {
452         struct snd_soc_component *component = dai->component;
453         struct es8311_priv *es8311 = snd_soc_component_get_drvdata(component);
454 
455         if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
456                 unsigned int mask = ES8311_DAC1_DAC_DSMMUTE |
457                                     ES8311_DAC1_DAC_DEMMUTE;
458                 unsigned int val = mute ? mask : 0;
459 
460                 regmap_update_bits(es8311->regmap, ES8311_DAC1, mask, val);
461         }
462 
463         return 0;
464 }
465 
466 static int es8311_startup(struct snd_pcm_substream *substream,
467                           struct snd_soc_dai *dai)
468 {
469         struct snd_soc_component *component = dai->component;
470         struct es8311_priv *es8311 = snd_soc_component_get_drvdata(component);
471 
472         if (es8311->constraints.list) {
473                 snd_pcm_hw_constraint_list(substream->runtime, 0,
474                                            SNDRV_PCM_HW_PARAM_RATE,
475                                            &es8311->constraints);
476         }
477 
478         return 0;
479 }
480 
481 static int es8311_hw_params(struct snd_pcm_substream *substream,
482                             struct snd_pcm_hw_params *params,
483                             struct snd_soc_dai *dai)
484 {
485         struct snd_soc_component *component = dai->component;
486         struct es8311_priv *es8311 = snd_soc_component_get_drvdata(component);
487         unsigned int wl;
488         int par_width = params_width(params);
489 
490         switch (par_width) {
491         case 16:
492                 wl = ES8311_SDP_WL_16;
493                 break;
494         case 18:
495                 wl = ES8311_SDP_WL_18;
496                 break;
497         case 20:
498                 wl = ES8311_SDP_WL_20;
499                 break;
500         case 24:
501                 wl = ES8311_SDP_WL_24;
502                 break;
503         case 32:
504                 wl = ES8311_SDP_WL_32;
505                 break;
506         default:
507                 return -EINVAL;
508         }
509         unsigned int width = (unsigned int)par_width;
510 
511         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
512                 snd_soc_component_update_bits(component, ES8311_SDP_IN,
513                                               ES8311_SDP_WL_MASK,
514                                               wl << ES8311_SDP_WL_SHIFT);
515         } else {
516                 snd_soc_component_update_bits(component, ES8311_SDP_OUT,
517                                               ES8311_SDP_WL_MASK,
518                                               wl << ES8311_SDP_WL_SHIFT);
519         }
520 
521         if (es8311->mclk_freq > ES8311_MCLK_MAX_FREQ) {
522                 dev_err(component->dev, "mclk frequency %lu too high\n",
523                         es8311->mclk_freq);
524                 return -EINVAL;
525         }
526 
527         unsigned int mclk_freq = es8311->mclk_freq;
528         unsigned int rate = params_rate(params);
529         unsigned int clkmgr = ES8311_CLKMGR1_MCLK_ON;
530 
531         if (!mclk_freq) {
532                 if (es8311->provider) {
533                         dev_err(component->dev,
534                                 "mclk not configured, cannot run as master\n");
535                         return -EINVAL;
536                 }
537                 dev_dbg(component->dev,
538                         "mclk not configured, use bclk as internal mclk\n");
539 
540                 clkmgr = ES8311_CLKMGR1_MCLK_SEL;
541 
542                 mclk_freq = rate * width * 2;
543         }
544 
545         struct es8311_mclk_coeff coeff;
546         int ret = es8311_get_mclk_coeff(mclk_freq, rate, &coeff);
547         if (ret) {
548                 dev_err(component->dev, "unable to find mclk coefficient\n");
549                 return ret;
550         }
551 
552         unsigned int mask = ES8311_CLKMGR1_MCLK_SEL | ES8311_CLKMGR1_MCLK_ON |
553                             ES8311_CLKMGR1_BCLK_ON;
554 
555         clkmgr |= ES8311_CLKMGR1_BCLK_ON;
556         snd_soc_component_update_bits(component, ES8311_CLKMGR1, mask, clkmgr);
557 
558         if (WARN_ON_ONCE(coeff.div == 0 || coeff.div > 8 ||
559                          coeff.div_adc_dac == 0 || coeff.div_adc_dac > 8))
560                 return -EINVAL;
561 
562         unsigned int mult;
563 
564         switch (coeff.mult) {
565         case 1:
566                 mult = 0;
567                 break;
568         case 2:
569                 mult = 1;
570                 break;
571         case 4:
572                 mult = 2;
573                 break;
574         case 8:
575                 mult = 3;
576                 break;
577         default:
578                 WARN_ON_ONCE(true);
579                 return -EINVAL;
580         }
581 
582         mask = ES8311_CLKMGR2_DIV_PRE_MASK | ES8311_CLKMGR2_MULT_PRE_MASK;
583         clkmgr = (coeff.div - 1) << ES8311_CLKMGR2_DIV_PRE_SHIFT |
584                  mult << ES8311_CLKMGR2_MULT_PRE_SHIFT;
585         snd_soc_component_update_bits(component, ES8311_CLKMGR2, mask, clkmgr);
586 
587         mask = ES8311_CLKMGR5_ADC_DIV_MASK | ES8311_CLKMGR5_DAC_DIV_MASK;
588         clkmgr = (coeff.div_adc_dac - 1) << ES8311_CLKMGR5_ADC_DIV_SHIFT |
589                  (coeff.div_adc_dac - 1) << ES8311_CLKMGR5_DAC_DIV_SHIFT;
590         snd_soc_component_update_bits(component, ES8311_CLKMGR5, mask, clkmgr);
591 
592         if (es8311->provider) {
593                 unsigned int div_lrclk = mclk_freq / rate;
594 
595                 if (WARN_ON_ONCE(div_lrclk == 0 ||
596                                  div_lrclk > ES8311_CLKMGR_LRCLK_DIV_MAX + 1))
597                         return -EINVAL;
598 
599                 mask = ES8311_CLKMGR7_LRCLK_DIV_H_MASK;
600                 clkmgr = (div_lrclk - 1) >> 8;
601                 snd_soc_component_update_bits(component, ES8311_CLKMGR7, mask,
602                                               clkmgr);
603                 clkmgr = (div_lrclk - 1) & 0xFF;
604                 snd_soc_component_write(component, ES8311_CLKMGR8, clkmgr);
605 
606                 if (div_lrclk % (2 * width) != 0) {
607                         dev_err(component->dev,
608                                 "unable to divide mclk %u to generate bclk\n",
609                                 mclk_freq);
610                         return -EINVAL;
611                 }
612 
613                 unsigned int div_bclk = div_lrclk / (2 * width);
614 
615                 mask = ES8311_CLKMGR6_DIV_BCLK_MASK;
616                 if (div_bclk <= ES8311_BCLK_DIV_IDX_OFFSET) {
617                         clkmgr = div_bclk - 1;
618                 } else {
619                         unsigned int i;
620 
621                         for (i = 0; i < ARRAY_SIZE(es8311_bclk_divs); i++) {
622                                 if (es8311_bclk_divs[i] == div_bclk)
623                                         break;
624                         }
625                         if (i == ARRAY_SIZE(es8311_bclk_divs)) {
626                                 dev_err(component->dev,
627                                         "bclk divider %u not supported\n",
628                                         div_bclk);
629                                 return -EINVAL;
630                         }
631 
632                         clkmgr = i + ES8311_BCLK_DIV_IDX_OFFSET;
633                 }
634                 snd_soc_component_update_bits(component, ES8311_CLKMGR6, mask,
635                                               clkmgr);
636         }
637 
638         return 0;
639 }
640 
641 static int es8311_set_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
642                              unsigned int freq, int dir)
643 {
644         struct snd_soc_component *component = codec_dai->component;
645         struct es8311_priv *es8311 = snd_soc_component_get_drvdata(component);
646 
647         if (freq > ES8311_MCLK_MAX_FREQ) {
648                 dev_err(component->dev, "invalid frequency %u: too high\n",
649                         freq);
650                 return -EINVAL;
651         }
652 
653         if (es8311->mclk_freq == freq)
654                 return 0;
655 
656         es8311->mclk_freq = freq;
657         es8311->constraints.list = NULL;
658         es8311->constraints.count = 0;
659 
660         if (freq == 0)
661                 return 0;
662 
663         int ret = clk_set_rate(es8311->mclk, freq);
664         if (ret) {
665                 dev_err(component->dev, "unable to set mclk rate\n");
666                 return ret;
667         }
668 
669         es8311_set_sysclk_constraints(freq, es8311);
670 
671         return ret;
672 }
673 
674 static int es8311_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
675 {
676         struct snd_soc_component *component = codec_dai->component;
677         struct es8311_priv *es8311 = snd_soc_component_get_drvdata(component);
678 
679         switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
680         case SND_SOC_DAIFMT_CBP_CFP:
681                 /* Master mode */
682                 es8311->provider = true;
683 
684                 snd_soc_component_update_bits(component, ES8311_RESET,
685                                               ES8311_RESET_MSC,
686                                               ES8311_RESET_MSC);
687                 break;
688         case SND_SOC_DAIFMT_CBC_CFC:
689                 /* Slave mode */
690                 es8311->provider = false;
691                 snd_soc_component_update_bits(component, ES8311_RESET,
692                                               ES8311_RESET_MSC, 0);
693                 break;
694         default:
695                 return -EINVAL;
696         }
697 
698         unsigned int sdp = 0;
699 
700         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
701         case SND_SOC_DAIFMT_I2S:
702                 sdp |= ES8311_SDP_FMT_I2S;
703                 break;
704         case SND_SOC_DAIFMT_LEFT_J:
705                 sdp |= ES8311_SDP_FMT_LEFT_J;
706                 break;
707         case SND_SOC_DAIFMT_RIGHT_J:
708                 dev_err(component->dev, "right justified mode not supported\n");
709                 return -EINVAL;
710         case SND_SOC_DAIFMT_DSP_B:
711                 sdp |= ES8311_SDP_LRP;
712                 fallthrough;
713         case SND_SOC_DAIFMT_DSP_A:
714                 sdp |= ES8311_SDP_FMT_DSP;
715                 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
716                 case SND_SOC_DAIFMT_NB_NF:
717                 case SND_SOC_DAIFMT_IB_NF:
718                         break;
719                 default:
720                         dev_err(component->dev,
721                                 "inverted fsync not supported in dsp mode\n");
722                         return -EINVAL;
723                 }
724                 break;
725         default:
726                 return -EINVAL;
727         }
728 
729         unsigned int clkmgr = 0;
730 
731         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
732         case SND_SOC_DAIFMT_NB_NF:
733                 break;
734         case SND_SOC_DAIFMT_NB_IF:
735                 sdp |= ES8311_SDP_LRP;
736                 break;
737         case SND_SOC_DAIFMT_IB_NF:
738                 clkmgr |= ES8311_CLKMGR6_BCLK_INV;
739                 break;
740         case SND_SOC_DAIFMT_IB_IF:
741                 clkmgr |= ES8311_CLKMGR6_BCLK_INV;
742                 sdp |= ES8311_SDP_LRP;
743                 break;
744         default:
745                 return -EINVAL;
746         }
747 
748         unsigned int mask = ES8311_CLKMGR6_BCLK_INV;
749 
750         snd_soc_component_update_bits(component, ES8311_CLKMGR6, mask, clkmgr);
751 
752         mask = ES8311_SDP_FMT_MASK | ES8311_SDP_LRP;
753         snd_soc_component_update_bits(component, ES8311_SDP_IN, mask, sdp);
754         snd_soc_component_update_bits(component, ES8311_SDP_OUT, mask, sdp);
755 
756         return 0;
757 }
758 
759 static int es8311_set_bias_level(struct snd_soc_component *component,
760                                  enum snd_soc_bias_level level)
761 {
762         struct es8311_priv *es8311 = snd_soc_component_get_drvdata(component);
763 
764         switch (level) {
765         case SND_SOC_BIAS_ON:
766                 break;
767         case SND_SOC_BIAS_PREPARE:
768                 break;
769         case SND_SOC_BIAS_STANDBY:
770                 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
771                         int ret = clk_prepare_enable(es8311->mclk);
772                         if (ret) {
773                                 dev_err(component->dev,
774                                         "unable to prepare mclk\n");
775                                 return ret;
776                         }
777 
778                         snd_soc_component_update_bits(
779                                 component, ES8311_SYS3,
780                                 ES8311_SYS3_PDN_VMIDSEL_MASK,
781                                 ES8311_SYS3_PDN_VMIDSEL_STARTUP_NORMAL_SPEED);
782                 }
783 
784                 break;
785         case SND_SOC_BIAS_OFF:
786                 clk_disable_unprepare(es8311->mclk);
787                 snd_soc_component_update_bits(
788                         component, ES8311_SYS3, ES8311_SYS3_PDN_VMIDSEL_MASK,
789                         ES8311_SYS3_PDN_VMIDSEL_POWER_DOWN);
790                 break;
791         default:
792                 break;
793         }
794         return 0;
795 }
796 
797 static const struct snd_soc_dai_ops es8311_dai_ops = {
798         .startup = es8311_startup,
799         .hw_params = es8311_hw_params,
800         .mute_stream = es8311_mute,
801         .set_sysclk = es8311_set_sysclk,
802         .set_fmt = es8311_set_dai_fmt,
803         .no_capture_mute = 1,
804 };
805 
806 static struct snd_soc_dai_driver es8311_dai = {
807         .name = "es8311",
808         .playback = {
809                 .stream_name = "AIF1 Playback",
810                 .channels_min = 1,
811                 .channels_max = 2,
812                 .rates = ES8311_RATES,
813                 .formats = ES8311_FORMATS,
814         },
815         .capture = {
816                 .stream_name = "AIF1 Capture",
817                 .channels_min = 1,
818                 .channels_max = 2,
819                 .rates = ES8311_RATES,
820                 .formats = ES8311_FORMATS,
821         },
822         .ops = &es8311_dai_ops,
823         .symmetric_rate = 1,
824 };
825 
826 static void es8311_reset(struct snd_soc_component *component, bool reset)
827 {
828         /* Reset procedure:
829          * (1) power down state machine and reset codec blocks then,
830          * (2) after a short delay, power up state machine and leave reset mode.
831          * Specific delay is not documented, using the same as es8316.
832          */
833         unsigned int mask = ES8311_RESET_CSM_ON | ES8311_RESET_RST_MASK;
834 
835         if (reset) {
836                 /* Enter reset mode */
837                 snd_soc_component_update_bits(component, ES8311_RESET, mask,
838                                               ES8311_RESET_RST_MASK);
839         } else {
840                 /* Leave reset mode */
841                 usleep_range(5000, 5500);
842                 snd_soc_component_update_bits(component, ES8311_RESET, mask,
843                                               ES8311_RESET_CSM_ON);
844         }
845 }
846 
847 static int es8311_suspend(struct snd_soc_component *component)
848 {
849         struct es8311_priv *es8311;
850 
851         es8311 = snd_soc_component_get_drvdata(component);
852 
853         es8311_reset(component, true);
854 
855         regcache_cache_only(es8311->regmap, true);
856         regcache_mark_dirty(es8311->regmap);
857 
858         return 0;
859 }
860 
861 static int es8311_resume(struct snd_soc_component *component)
862 {
863         struct es8311_priv *es8311;
864 
865         es8311 = snd_soc_component_get_drvdata(component);
866 
867         es8311_reset(component, false);
868 
869         regcache_cache_only(es8311->regmap, false);
870         regcache_sync(es8311->regmap);
871 
872         return 0;
873 }
874 
875 static int es8311_component_probe(struct snd_soc_component *component)
876 {
877         struct es8311_priv *es8311;
878 
879         es8311 = snd_soc_component_get_drvdata(component);
880 
881         es8311->mclk = devm_clk_get_optional(component->dev, "mclk");
882         if (IS_ERR(es8311->mclk)) {
883                 dev_err(component->dev, "invalid mclk\n");
884                 return PTR_ERR(es8311->mclk);
885         }
886 
887         es8311->mclk_freq = clk_get_rate(es8311->mclk);
888         if (es8311->mclk_freq > 0 && es8311->mclk_freq < ES8311_MCLK_MAX_FREQ)
889                 es8311_set_sysclk_constraints(es8311->mclk_freq, es8311);
890 
891         es8311_reset(component, true);
892         es8311_reset(component, false);
893 
894         /* Set minimal power up time */
895         snd_soc_component_write(component, ES8311_SYS1, 0);
896         snd_soc_component_write(component, ES8311_SYS2, 0);
897 
898         return 0;
899 }
900 
901 static const struct regmap_config es8311_regmap_config = {
902         .reg_bits = 8,
903         .val_bits = 8,
904         .max_register = ES8311_REG_MAX,
905         .cache_type = REGCACHE_MAPLE,
906         .use_single_read = true,
907         .use_single_write = true,
908 };
909 
910 static const struct snd_soc_component_driver es8311_component_driver = {
911         .probe = es8311_component_probe,
912         .suspend = es8311_suspend,
913         .resume = es8311_resume,
914         .set_bias_level = es8311_set_bias_level,
915         .controls = es8311_snd_controls,
916         .num_controls = ARRAY_SIZE(es8311_snd_controls),
917         .dapm_widgets = es8311_dapm_widgets,
918         .num_dapm_widgets = ARRAY_SIZE(es8311_dapm_widgets),
919         .dapm_routes = es8311_dapm_routes,
920         .num_dapm_routes = ARRAY_SIZE(es8311_dapm_routes),
921         .use_pmdown_time = 1,
922         .endianness = 1,
923 };
924 
925 static int es8311_i2c_probe(struct i2c_client *i2c_client)
926 {
927         struct es8311_priv *es8311;
928 
929         struct device *dev = &i2c_client->dev;
930 
931         es8311 = devm_kzalloc(dev, sizeof(*es8311), GFP_KERNEL);
932         if (es8311 == NULL)
933                 return -ENOMEM;
934 
935         es8311->regmap =
936                 devm_regmap_init_i2c(i2c_client, &es8311_regmap_config);
937         if (IS_ERR(es8311->regmap))
938                 return PTR_ERR(es8311->regmap);
939 
940         i2c_set_clientdata(i2c_client, es8311);
941 
942         return devm_snd_soc_register_component(dev, &es8311_component_driver,
943                                                &es8311_dai, 1);
944 }
945 
946 static const struct i2c_device_id es8311_id[] = {
947         { "es8311" },
948         { }
949 };
950 MODULE_DEVICE_TABLE(i2c, es8311_id);
951 
952 static const struct of_device_id es8311_of_match[] = {
953         {
954                 .compatible = "everest,es8311",
955         },
956         {}
957 };
958 MODULE_DEVICE_TABLE(of, es8311_of_match);
959 
960 static struct i2c_driver es8311_i2c_driver = {
961         .driver = {
962                 .name           = "es8311",
963                 .of_match_table = es8311_of_match,
964         },
965         .probe = es8311_i2c_probe,
966         .id_table = es8311_id,
967 };
968 
969 module_i2c_driver(es8311_i2c_driver);
970 
971 MODULE_DESCRIPTION("ASoC ES8311 driver");
972 MODULE_AUTHOR("Matteo Martelli <matteomartelli3@gmail.com>");
973 MODULE_LICENSE("GPL");
974 

~ [ 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