brintos

brintos / linux-shallow public Read only

0
0
Text · 27.1 KiB · f557e33 Raw
974 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * es8311.c -- es8311 ALSA SoC audio driver4 *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 1023#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_STEPS62};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_STEPS80};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 - 1316 * above 20: the register takes the corresponding idx of the div value317 *           in the following table + 20318 */319#define ES8311_BCLK_DIV_IDX_OFFSET 20320static const unsigned int es8311_bclk_divs[] = {321	22, 24, 25, 30, 32, 33, 34, 36, 44, 48, 66, 72322};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 49200000333 334/* Coefficients for common master clock frequencies based on clock table from335 * documentation. Limited to have a ratio of adc (or dac) clock to lrclk equal336 * to 256. This to keep the default adc and dac oversampling and adc scale337 * settings. Internal mclk dividers and multipliers are dynamically adjusted to338 * support, respectively, multiples (up to x8) and factors (/2,4,8) of listed339 * mclks frequencies (see es8311_cmp_adj_mclk_coeff).340 * All rates are supported when mclk/rate ratio is 32, 64, 128, 256, 384 or 512341 * (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 and372 * 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");974