Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.17.
  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
 29struct 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
 38static const DECLARE_TLV_DB_SCALE(es8311_adc_vol_tlv, -9550, 50, 0);
 39static const DECLARE_TLV_DB_SCALE(es8311_pga_gain_tlv, 0, 300, 0);
 40static 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
 59static const char *const es8311_level_winsize_txt[] = {
 60	"0.25db/2LRCK",
 61	ES8311_DB_LRCK_STEPS
 62};
 63
 64static SOC_ENUM_SINGLE_DECL(
 65	es8311_alc_winsize, ES8311_ADC4,
 66	ES8311_ADC4_ALC_WINSIZE_SHIFT, es8311_level_winsize_txt);
 67static 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
 77static const char *const es8311_ramprate_txt[] = {
 78	"Disabled",
 79	ES8311_DB_LRCK_STEPS
 80};
 81static SOC_ENUM_SINGLE_DECL(
 82	es8311_adc_ramprate, ES8311_ADC1,
 83	ES8311_ADC1_RAMPRATE_SHIFT, es8311_ramprate_txt);
 84
 85static 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};
103static SOC_ENUM_SINGLE_DECL(
104	es8311_automute_winsize, ES8311_ADC6,
105	ES8311_ADC6_AUTOMUTE_WS_SHIFT, es8311_automute_winsize_txt);
106static 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);
110static const DECLARE_TLV_DB_SCALE(es8311_automute_vol_tlv, -2800, 400, 0);
111
112static const DECLARE_TLV_DB_SCALE(es8311_dac_vol_tlv, -9550, 50, 0);
113static SOC_ENUM_SINGLE_DECL(
114	es8311_drc_winsize, ES8311_DAC4,
115	ES8311_DAC4_DRC_WINSIZE_SHIFT, es8311_level_winsize_txt);
116static SOC_ENUM_SINGLE_DECL(
117	es8311_dac_ramprate, ES8311_DAC6,
118	ES8311_DAC6_RAMPRATE_SHIFT, es8311_ramprate_txt);
119
120static const char *const es8311_out_mode_txt[] = {
121	"Lineout",
122	"Headphones"
123};
124static SOC_ENUM_SINGLE_DECL(
125	es8311_out_mode, ES8311_SYS9,
126	ES8311_SYS9_HPSW_SHIFT, es8311_out_mode_txt);
127
128static 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
185static const char *const es8311_diff_src_txt[] = {
186	"Disabled",
187	"MIC1P-MIC1N",
188};
189static SOC_ENUM_SINGLE_DECL(
190	es8311_diff_src_enum, ES8311_SYS10,
191	ES8311_SYS10_LINESEL_SHIFT, es8311_diff_src_txt);
192static const struct snd_kcontrol_new es8311_diff_src_mux =
193	SOC_DAPM_ENUM("Differential Source", es8311_diff_src_enum);
194
195static const char *const es8311_dmic_src_txt[] = {
196	"Disabled",
197	"DMIC from MIC1P",
198};
199static SOC_ENUM_SINGLE_DECL(
200	es8311_dmic_src_enum, ES8311_SYS10,
201	ES8311_SYS10_DMIC_ON_SHIFT, es8311_dmic_src_txt);
202static const struct snd_kcontrol_new es8311_dmic_src_mux =
203	SOC_DAPM_ENUM("Digital Mic Source", es8311_dmic_src_enum);
204
205static 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};
214static SOC_ENUM_SINGLE_DECL(
215	es8311_aif1tx_src_enum, ES8311_GPIO,
216	ES8311_GPIO_ADCDAT_SEL_SHIFT, es8311_aif1tx_src_txt);
217static const struct snd_kcontrol_new es8311_aif1tx_src_mux =
218	SOC_DAPM_ENUM("AIF1TX Source", es8311_aif1tx_src_enum);
219
220static const char * const es8311_dac_src_txt[] = {
221	"Left",
222	"Right"
223};
224static SOC_ENUM_SINGLE_DECL(
225	es8311_dac_src_enum, ES8311_SDP_IN,
226	ES8311_SDP_IN_SEL_SHIFT, es8311_dac_src_txt);
227static const struct snd_kcontrol_new es8311_dac_src_mux =
228	SOC_DAPM_ENUM("Mono DAC Source", es8311_dac_src_enum);
229
230static 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
278static 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
320static const unsigned int es8311_bclk_divs[] = {
321	22, 24, 25, 30, 32, 33, 34, 36, 44, 48, 66, 72
322};
323
324struct 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 */
343static 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 */
375static 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
411static 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
428static 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
450static 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
466static 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
481static 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
641static 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
674static 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
759static 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
797static 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
806static 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
826static 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
847static 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
861static 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
875static 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
901static 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
910static 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
925static 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
946static const struct i2c_device_id es8311_id[] = {
947	{ "es8311" },
948	{ }
949};
950MODULE_DEVICE_TABLE(i2c, es8311_id);
951
952static const struct of_device_id es8311_of_match[] = {
953	{
954		.compatible = "everest,es8311",
955	},
956	{}
957};
958MODULE_DEVICE_TABLE(of, es8311_of_match);
959
960static 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
969module_i2c_driver(es8311_i2c_driver);
970
971MODULE_DESCRIPTION("ASoC ES8311 driver");
972MODULE_AUTHOR("Matteo Martelli <matteomartelli3@gmail.com>");
973MODULE_LICENSE("GPL");