brintos

brintos / linux-shallow public Read only

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