brintos

brintos / linux-shallow public Read only

0
0
Text · 46.4 KiB · 7a01b1d Raw
1663 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * cs35l35.c -- CS35L35 ALSA SoC audio driver4 *5 * Copyright 2017 Cirrus Logic, Inc.6 *7 * Author: Brian Austin <brian.austin@cirrus.com>8 */9 10#include <linux/module.h>11#include <linux/moduleparam.h>12#include <linux/kernel.h>13#include <linux/init.h>14#include <linux/delay.h>15#include <linux/i2c.h>16#include <linux/slab.h>17#include <linux/platform_device.h>18#include <linux/regulator/consumer.h>19#include <linux/gpio/consumer.h>20#include <linux/of.h>21#include <linux/regmap.h>22#include <sound/core.h>23#include <sound/pcm.h>24#include <sound/pcm_params.h>25#include <sound/soc.h>26#include <sound/soc-dapm.h>27#include <sound/initval.h>28#include <sound/tlv.h>29#include <sound/cs35l35.h>30#include <linux/completion.h>31 32#include "cs35l35.h"33#include "cirrus_legacy.h"34 35/*36 * Some fields take zero as a valid value so use a high bit flag that won't37 * get written to the device to mark those.38 */39#define CS35L35_VALID_PDATA 0x8000000040 41static const struct reg_default cs35l35_reg[] = {42	{CS35L35_PWRCTL1,		0x01},43	{CS35L35_PWRCTL2,		0x11},44	{CS35L35_PWRCTL3,		0x00},45	{CS35L35_CLK_CTL1,		0x04},46	{CS35L35_CLK_CTL2,		0x12},47	{CS35L35_CLK_CTL3,		0xCF},48	{CS35L35_SP_FMT_CTL1,		0x20},49	{CS35L35_SP_FMT_CTL2,		0x00},50	{CS35L35_SP_FMT_CTL3,		0x02},51	{CS35L35_MAG_COMP_CTL,		0x00},52	{CS35L35_AMP_INP_DRV_CTL,	0x01},53	{CS35L35_AMP_DIG_VOL_CTL,	0x12},54	{CS35L35_AMP_DIG_VOL,		0x00},55	{CS35L35_ADV_DIG_VOL,		0x00},56	{CS35L35_PROTECT_CTL,		0x06},57	{CS35L35_AMP_GAIN_AUD_CTL,	0x13},58	{CS35L35_AMP_GAIN_PDM_CTL,	0x00},59	{CS35L35_AMP_GAIN_ADV_CTL,	0x00},60	{CS35L35_GPI_CTL,		0x00},61	{CS35L35_BST_CVTR_V_CTL,	0x00},62	{CS35L35_BST_PEAK_I,		0x07},63	{CS35L35_BST_RAMP_CTL,		0x85},64	{CS35L35_BST_CONV_COEF_1,	0x24},65	{CS35L35_BST_CONV_COEF_2,	0x24},66	{CS35L35_BST_CONV_SLOPE_COMP,	0x4E},67	{CS35L35_BST_CONV_SW_FREQ,	0x04},68	{CS35L35_CLASS_H_CTL,		0x0B},69	{CS35L35_CLASS_H_HEADRM_CTL,	0x0B},70	{CS35L35_CLASS_H_RELEASE_RATE,	0x08},71	{CS35L35_CLASS_H_FET_DRIVE_CTL, 0x41},72	{CS35L35_CLASS_H_VP_CTL,	0xC5},73	{CS35L35_VPBR_CTL,		0x0A},74	{CS35L35_VPBR_VOL_CTL,		0x90},75	{CS35L35_VPBR_TIMING_CTL,	0x6A},76	{CS35L35_VPBR_MODE_VOL_CTL,	0x00},77	{CS35L35_SPKR_MON_CTL,		0xC0},78	{CS35L35_IMON_SCALE_CTL,	0x30},79	{CS35L35_AUDIN_RXLOC_CTL,	0x00},80	{CS35L35_ADVIN_RXLOC_CTL,	0x80},81	{CS35L35_VMON_TXLOC_CTL,	0x00},82	{CS35L35_IMON_TXLOC_CTL,	0x80},83	{CS35L35_VPMON_TXLOC_CTL,	0x04},84	{CS35L35_VBSTMON_TXLOC_CTL,	0x84},85	{CS35L35_VPBR_STATUS_TXLOC_CTL,	0x04},86	{CS35L35_ZERO_FILL_LOC_CTL,	0x00},87	{CS35L35_AUDIN_DEPTH_CTL,	0x0F},88	{CS35L35_SPKMON_DEPTH_CTL,	0x0F},89	{CS35L35_SUPMON_DEPTH_CTL,	0x0F},90	{CS35L35_ZEROFILL_DEPTH_CTL,	0x00},91	{CS35L35_MULT_DEV_SYNCH1,	0x02},92	{CS35L35_MULT_DEV_SYNCH2,	0x80},93	{CS35L35_PROT_RELEASE_CTL,	0x00},94	{CS35L35_DIAG_MODE_REG_LOCK,	0x00},95	{CS35L35_DIAG_MODE_CTL_1,	0x40},96	{CS35L35_DIAG_MODE_CTL_2,	0x00},97	{CS35L35_INT_MASK_1,		0xFF},98	{CS35L35_INT_MASK_2,		0xFF},99	{CS35L35_INT_MASK_3,		0xFF},100	{CS35L35_INT_MASK_4,		0xFF},101 102};103 104static bool cs35l35_volatile_register(struct device *dev, unsigned int reg)105{106	switch (reg) {107	case CS35L35_INT_STATUS_1:108	case CS35L35_INT_STATUS_2:109	case CS35L35_INT_STATUS_3:110	case CS35L35_INT_STATUS_4:111	case CS35L35_PLL_STATUS:112	case CS35L35_OTP_TRIM_STATUS:113		return true;114	default:115		return false;116	}117}118 119static bool cs35l35_readable_register(struct device *dev, unsigned int reg)120{121	switch (reg) {122	case CS35L35_DEVID_AB ... CS35L35_PWRCTL3:123	case CS35L35_CLK_CTL1 ... CS35L35_SP_FMT_CTL3:124	case CS35L35_MAG_COMP_CTL ... CS35L35_AMP_GAIN_AUD_CTL:125	case CS35L35_AMP_GAIN_PDM_CTL ... CS35L35_BST_PEAK_I:126	case CS35L35_BST_RAMP_CTL ... CS35L35_BST_CONV_SW_FREQ:127	case CS35L35_CLASS_H_CTL ... CS35L35_CLASS_H_VP_CTL:128	case CS35L35_CLASS_H_STATUS:129	case CS35L35_VPBR_CTL ... CS35L35_VPBR_MODE_VOL_CTL:130	case CS35L35_VPBR_ATTEN_STATUS:131	case CS35L35_SPKR_MON_CTL:132	case CS35L35_IMON_SCALE_CTL ... CS35L35_ZEROFILL_DEPTH_CTL:133	case CS35L35_MULT_DEV_SYNCH1 ... CS35L35_PROT_RELEASE_CTL:134	case CS35L35_DIAG_MODE_REG_LOCK ... CS35L35_DIAG_MODE_CTL_2:135	case CS35L35_INT_MASK_1 ... CS35L35_PLL_STATUS:136	case CS35L35_OTP_TRIM_STATUS:137		return true;138	default:139		return false;140	}141}142 143static bool cs35l35_precious_register(struct device *dev, unsigned int reg)144{145	switch (reg) {146	case CS35L35_INT_STATUS_1:147	case CS35L35_INT_STATUS_2:148	case CS35L35_INT_STATUS_3:149	case CS35L35_INT_STATUS_4:150	case CS35L35_PLL_STATUS:151	case CS35L35_OTP_TRIM_STATUS:152		return true;153	default:154		return false;155	}156}157 158static void cs35l35_reset(struct cs35l35_private *cs35l35)159{160	gpiod_set_value_cansleep(cs35l35->reset_gpio, 0);161	usleep_range(2000, 2100);162	gpiod_set_value_cansleep(cs35l35->reset_gpio, 1);163	usleep_range(1000, 1100);164}165 166static int cs35l35_wait_for_pdn(struct cs35l35_private *cs35l35)167{168	int ret;169 170	if (cs35l35->pdata.ext_bst) {171		usleep_range(5000, 5500);172		return 0;173	}174 175	reinit_completion(&cs35l35->pdn_done);176 177	ret = wait_for_completion_timeout(&cs35l35->pdn_done,178					  msecs_to_jiffies(100));179	if (ret == 0) {180		dev_err(cs35l35->dev, "PDN_DONE did not complete\n");181		return -ETIMEDOUT;182	}183 184	return 0;185}186 187static int cs35l35_sdin_event(struct snd_soc_dapm_widget *w,188		struct snd_kcontrol *kcontrol, int event)189{190	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);191	struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);192	int ret = 0;193 194	switch (event) {195	case SND_SOC_DAPM_PRE_PMU:196		regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,197					CS35L35_MCLK_DIS_MASK,198					0 << CS35L35_MCLK_DIS_SHIFT);199		regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,200					CS35L35_DISCHG_FILT_MASK,201					0 << CS35L35_DISCHG_FILT_SHIFT);202		regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,203					CS35L35_PDN_ALL_MASK, 0);204		break;205	case SND_SOC_DAPM_POST_PMD:206		regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,207					CS35L35_DISCHG_FILT_MASK,208					1 << CS35L35_DISCHG_FILT_SHIFT);209		regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,210					  CS35L35_PDN_ALL_MASK, 1);211 212		/* Already muted, so disable volume ramp for faster shutdown */213		regmap_update_bits(cs35l35->regmap, CS35L35_AMP_DIG_VOL_CTL,214				   CS35L35_AMP_DIGSFT_MASK, 0);215 216		ret = cs35l35_wait_for_pdn(cs35l35);217 218		regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,219					CS35L35_MCLK_DIS_MASK,220					1 << CS35L35_MCLK_DIS_SHIFT);221 222		regmap_update_bits(cs35l35->regmap, CS35L35_AMP_DIG_VOL_CTL,223				   CS35L35_AMP_DIGSFT_MASK,224				   1 << CS35L35_AMP_DIGSFT_SHIFT);225		break;226	default:227		dev_err(component->dev, "Invalid event = 0x%x\n", event);228		ret = -EINVAL;229	}230	return ret;231}232 233static int cs35l35_main_amp_event(struct snd_soc_dapm_widget *w,234		struct snd_kcontrol *kcontrol, int event)235{236	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);237	struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);238	unsigned int reg[4];239	int i;240 241	switch (event) {242	case SND_SOC_DAPM_PRE_PMU:243		if (cs35l35->pdata.bst_pdn_fet_on)244			regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,245				CS35L35_PDN_BST_MASK,246				0 << CS35L35_PDN_BST_FETON_SHIFT);247		else248			regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,249				CS35L35_PDN_BST_MASK,250				0 << CS35L35_PDN_BST_FETOFF_SHIFT);251		break;252	case SND_SOC_DAPM_POST_PMU:253		usleep_range(5000, 5100);254		/* If in PDM mode we must use VP for Voltage control */255		if (cs35l35->pdm_mode)256			regmap_update_bits(cs35l35->regmap,257					CS35L35_BST_CVTR_V_CTL,258					CS35L35_BST_CTL_MASK,259					0 << CS35L35_BST_CTL_SHIFT);260 261		regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,262			CS35L35_AMP_MUTE_MASK, 0);263 264		for (i = 0; i < 2; i++)265			regmap_bulk_read(cs35l35->regmap, CS35L35_INT_STATUS_1,266					&reg, ARRAY_SIZE(reg));267 268		break;269	case SND_SOC_DAPM_PRE_PMD:270		regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,271				CS35L35_AMP_MUTE_MASK,272				1 << CS35L35_AMP_MUTE_SHIFT);273		if (cs35l35->pdata.bst_pdn_fet_on)274			regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,275				CS35L35_PDN_BST_MASK,276				1 << CS35L35_PDN_BST_FETON_SHIFT);277		else278			regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,279				CS35L35_PDN_BST_MASK,280				1 << CS35L35_PDN_BST_FETOFF_SHIFT);281		break;282	case SND_SOC_DAPM_POST_PMD:283		usleep_range(5000, 5100);284		/*285		 * If PDM mode we should switch back to pdata value286		 * for Voltage control when we go down287		 */288		if (cs35l35->pdm_mode)289			regmap_update_bits(cs35l35->regmap,290					CS35L35_BST_CVTR_V_CTL,291					CS35L35_BST_CTL_MASK,292					cs35l35->pdata.bst_vctl293					<< CS35L35_BST_CTL_SHIFT);294 295		break;296	default:297		dev_err(component->dev, "Invalid event = 0x%x\n", event);298	}299	return 0;300}301 302static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1);303static DECLARE_TLV_DB_SCALE(dig_vol_tlv, -10200, 50, 0);304 305static const struct snd_kcontrol_new cs35l35_aud_controls[] = {306	SOC_SINGLE_SX_TLV("Digital Audio Volume", CS35L35_AMP_DIG_VOL,307		      0, 0x34, 0xE4, dig_vol_tlv),308	SOC_SINGLE_TLV("Analog Audio Volume", CS35L35_AMP_GAIN_AUD_CTL, 0, 19, 0,309			amp_gain_tlv),310	SOC_SINGLE_TLV("PDM Volume", CS35L35_AMP_GAIN_PDM_CTL, 0, 19, 0,311			amp_gain_tlv),312};313 314static const struct snd_kcontrol_new cs35l35_adv_controls[] = {315	SOC_SINGLE_SX_TLV("Digital Advisory Volume", CS35L35_ADV_DIG_VOL,316		      0, 0x34, 0xE4, dig_vol_tlv),317	SOC_SINGLE_TLV("Analog Advisory Volume", CS35L35_AMP_GAIN_ADV_CTL, 0, 19, 0,318			amp_gain_tlv),319};320 321static const struct snd_soc_dapm_widget cs35l35_dapm_widgets[] = {322	SND_SOC_DAPM_AIF_IN_E("SDIN", NULL, 0, CS35L35_PWRCTL3, 1, 1,323				cs35l35_sdin_event, SND_SOC_DAPM_PRE_PMU |324				SND_SOC_DAPM_POST_PMD),325	SND_SOC_DAPM_AIF_OUT("SDOUT", NULL, 0, CS35L35_PWRCTL3, 2, 1),326 327	SND_SOC_DAPM_OUTPUT("SPK"),328 329	SND_SOC_DAPM_INPUT("VP"),330	SND_SOC_DAPM_INPUT("VBST"),331	SND_SOC_DAPM_INPUT("ISENSE"),332	SND_SOC_DAPM_INPUT("VSENSE"),333 334	SND_SOC_DAPM_ADC("VMON ADC", NULL, CS35L35_PWRCTL2, 7, 1),335	SND_SOC_DAPM_ADC("IMON ADC", NULL, CS35L35_PWRCTL2, 6, 1),336	SND_SOC_DAPM_ADC("VPMON ADC", NULL, CS35L35_PWRCTL3, 3, 1),337	SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, CS35L35_PWRCTL3, 4, 1),338	SND_SOC_DAPM_ADC("CLASS H", NULL, CS35L35_PWRCTL2, 5, 1),339 340	SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L35_PWRCTL2, 0, 1, NULL, 0,341		cs35l35_main_amp_event, SND_SOC_DAPM_PRE_PMU |342				SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU |343				SND_SOC_DAPM_PRE_PMD),344};345 346static const struct snd_soc_dapm_route cs35l35_audio_map[] = {347	{"VPMON ADC", NULL, "VP"},348	{"VBSTMON ADC", NULL, "VBST"},349	{"IMON ADC", NULL, "ISENSE"},350	{"VMON ADC", NULL, "VSENSE"},351	{"SDOUT", NULL, "IMON ADC"},352	{"SDOUT", NULL, "VMON ADC"},353	{"SDOUT", NULL, "VBSTMON ADC"},354	{"SDOUT", NULL, "VPMON ADC"},355	{"AMP Capture", NULL, "SDOUT"},356 357	{"SDIN", NULL, "AMP Playback"},358	{"CLASS H", NULL, "SDIN"},359	{"Main AMP", NULL, "CLASS H"},360	{"SPK", NULL, "Main AMP"},361};362 363static int cs35l35_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)364{365	struct snd_soc_component *component = codec_dai->component;366	struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);367 368	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {369	case SND_SOC_DAIFMT_CBP_CFP:370		regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,371				    CS35L35_MS_MASK, 1 << CS35L35_MS_SHIFT);372		cs35l35->clock_consumer = false;373		break;374	case SND_SOC_DAIFMT_CBC_CFC:375		regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,376				    CS35L35_MS_MASK, 0 << CS35L35_MS_SHIFT);377		cs35l35->clock_consumer = true;378		break;379	default:380		return -EINVAL;381	}382 383	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {384	case SND_SOC_DAIFMT_I2S:385		cs35l35->i2s_mode = true;386		cs35l35->pdm_mode = false;387		break;388	case SND_SOC_DAIFMT_PDM:389		cs35l35->pdm_mode = true;390		cs35l35->i2s_mode = false;391		break;392	default:393		return -EINVAL;394	}395 396	return 0;397}398 399struct cs35l35_sysclk_config {400	int sysclk;401	int srate;402	u8 clk_cfg;403};404 405static struct cs35l35_sysclk_config cs35l35_clk_ctl[] = {406 407	/* SYSCLK, Sample Rate, Serial Port Cfg */408	{5644800, 44100, 0x00},409	{5644800, 88200, 0x40},410	{6144000, 48000, 0x10},411	{6144000, 96000, 0x50},412	{11289600, 44100, 0x01},413	{11289600, 88200, 0x41},414	{11289600, 176400, 0x81},415	{12000000, 44100, 0x03},416	{12000000, 48000, 0x13},417	{12000000, 88200, 0x43},418	{12000000, 96000, 0x53},419	{12000000, 176400, 0x83},420	{12000000, 192000, 0x93},421	{12288000, 48000, 0x11},422	{12288000, 96000, 0x51},423	{12288000, 192000, 0x91},424	{13000000, 44100, 0x07},425	{13000000, 48000, 0x17},426	{13000000, 88200, 0x47},427	{13000000, 96000, 0x57},428	{13000000, 176400, 0x87},429	{13000000, 192000, 0x97},430	{22579200, 44100, 0x02},431	{22579200, 88200, 0x42},432	{22579200, 176400, 0x82},433	{24000000, 44100, 0x0B},434	{24000000, 48000, 0x1B},435	{24000000, 88200, 0x4B},436	{24000000, 96000, 0x5B},437	{24000000, 176400, 0x8B},438	{24000000, 192000, 0x9B},439	{24576000, 48000, 0x12},440	{24576000, 96000, 0x52},441	{24576000, 192000, 0x92},442	{26000000, 44100, 0x0F},443	{26000000, 48000, 0x1F},444	{26000000, 88200, 0x4F},445	{26000000, 96000, 0x5F},446	{26000000, 176400, 0x8F},447	{26000000, 192000, 0x9F},448};449 450static int cs35l35_get_clk_config(int sysclk, int srate)451{452	int i;453 454	for (i = 0; i < ARRAY_SIZE(cs35l35_clk_ctl); i++) {455		if (cs35l35_clk_ctl[i].sysclk == sysclk &&456			cs35l35_clk_ctl[i].srate == srate)457			return cs35l35_clk_ctl[i].clk_cfg;458	}459	return -EINVAL;460}461 462static int cs35l35_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 cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);468	struct classh_cfg *classh = &cs35l35->pdata.classh_algo;469	int srate = params_rate(params);470	int ret = 0;471	u8 sp_sclks;472	int audin_format;473	int errata_chk;474 475	int clk_ctl = cs35l35_get_clk_config(cs35l35->sysclk, srate);476 477	if (clk_ctl < 0) {478		dev_err(component->dev, "Invalid CLK:Rate %d:%d\n",479			cs35l35->sysclk, srate);480		return -EINVAL;481	}482 483	ret = regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL2,484			  CS35L35_CLK_CTL2_MASK, clk_ctl);485	if (ret != 0) {486		dev_err(component->dev, "Failed to set port config %d\n", ret);487		return ret;488	}489 490	/*491	 * Rev A0 Errata492	 * When configured for the weak-drive detection path (CH_WKFET_DIS = 0)493	 * the Class H algorithm does not enable weak-drive operation for494	 * nonzero values of CH_WKFET_DELAY if SP_RATE = 01 or 10495	 */496	errata_chk = (clk_ctl & CS35L35_SP_RATE_MASK) >> CS35L35_SP_RATE_SHIFT;497 498	if (classh->classh_wk_fet_disable == 0x00 &&499		(errata_chk == 0x01 || errata_chk == 0x02)) {500		ret = regmap_update_bits(cs35l35->regmap,501					CS35L35_CLASS_H_FET_DRIVE_CTL,502					CS35L35_CH_WKFET_DEL_MASK,503					0 << CS35L35_CH_WKFET_DEL_SHIFT);504		if (ret != 0) {505			dev_err(component->dev, "Failed to set fet config %d\n",506				ret);507			return ret;508		}509	}510 511	/*512	 * You can pull more Monitor data from the SDOUT pin than going to SDIN513	 * Just make sure your SCLK is fast enough to fill the frame514	 */515	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {516		switch (params_width(params)) {517		case 8:518			audin_format = CS35L35_SDIN_DEPTH_8;519			break;520		case 16:521			audin_format = CS35L35_SDIN_DEPTH_16;522			break;523		case 24:524			audin_format = CS35L35_SDIN_DEPTH_24;525			break;526		default:527			dev_err(component->dev, "Unsupported Width %d\n",528				params_width(params));529			return -EINVAL;530		}531		regmap_update_bits(cs35l35->regmap,532				CS35L35_AUDIN_DEPTH_CTL,533				CS35L35_AUDIN_DEPTH_MASK,534				audin_format <<535				CS35L35_AUDIN_DEPTH_SHIFT);536		if (cs35l35->pdata.stereo) {537			regmap_update_bits(cs35l35->regmap,538					CS35L35_AUDIN_DEPTH_CTL,539					CS35L35_ADVIN_DEPTH_MASK,540					audin_format <<541					CS35L35_ADVIN_DEPTH_SHIFT);542		}543	}544 545	if (cs35l35->i2s_mode) {546		/* We have to take the SCLK to derive num sclks547		 * to configure the CLOCK_CTL3 register correctly548		 */549		if ((cs35l35->sclk / srate) % 4) {550			dev_err(component->dev, "Unsupported sclk/fs ratio %d:%d\n",551					cs35l35->sclk, srate);552			return -EINVAL;553		}554		sp_sclks = ((cs35l35->sclk / srate) / 4) - 1;555 556		/* Only certain ratios supported when device is a clock consumer */557		if (cs35l35->clock_consumer) {558			switch (sp_sclks) {559			case CS35L35_SP_SCLKS_32FS:560			case CS35L35_SP_SCLKS_48FS:561			case CS35L35_SP_SCLKS_64FS:562				break;563			default:564				dev_err(component->dev, "ratio not supported\n");565				return -EINVAL;566			}567		} else {568			/* Only certain ratios supported when device is a clock provider */569			switch (sp_sclks) {570			case CS35L35_SP_SCLKS_32FS:571			case CS35L35_SP_SCLKS_64FS:572				break;573			default:574				dev_err(component->dev, "ratio not supported\n");575				return -EINVAL;576			}577		}578		ret = regmap_update_bits(cs35l35->regmap,579					CS35L35_CLK_CTL3,580					CS35L35_SP_SCLKS_MASK, sp_sclks <<581					CS35L35_SP_SCLKS_SHIFT);582		if (ret != 0) {583			dev_err(component->dev, "Failed to set fsclk %d\n", ret);584			return ret;585		}586	}587 588	return ret;589}590 591static const unsigned int cs35l35_src_rates[] = {592	44100, 48000, 88200, 96000, 176400, 192000593};594 595static const struct snd_pcm_hw_constraint_list cs35l35_constraints = {596	.count  = ARRAY_SIZE(cs35l35_src_rates),597	.list   = cs35l35_src_rates,598};599 600static int cs35l35_pcm_startup(struct snd_pcm_substream *substream,601			       struct snd_soc_dai *dai)602{603	struct snd_soc_component *component = dai->component;604	struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);605 606	if (!substream->runtime)607		return 0;608 609	snd_pcm_hw_constraint_list(substream->runtime, 0,610				SNDRV_PCM_HW_PARAM_RATE, &cs35l35_constraints);611 612	regmap_update_bits(cs35l35->regmap, CS35L35_AMP_INP_DRV_CTL,613					CS35L35_PDM_MODE_MASK,614					0 << CS35L35_PDM_MODE_SHIFT);615 616	return 0;617}618 619static const unsigned int cs35l35_pdm_rates[] = {620	44100, 48000, 88200, 96000621};622 623static const struct snd_pcm_hw_constraint_list cs35l35_pdm_constraints = {624	.count  = ARRAY_SIZE(cs35l35_pdm_rates),625	.list   = cs35l35_pdm_rates,626};627 628static int cs35l35_pdm_startup(struct snd_pcm_substream *substream,629			       struct snd_soc_dai *dai)630{631	struct snd_soc_component *component = dai->component;632	struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);633 634	if (!substream->runtime)635		return 0;636 637	snd_pcm_hw_constraint_list(substream->runtime, 0,638				SNDRV_PCM_HW_PARAM_RATE,639				&cs35l35_pdm_constraints);640 641	regmap_update_bits(cs35l35->regmap, CS35L35_AMP_INP_DRV_CTL,642					CS35L35_PDM_MODE_MASK,643					1 << CS35L35_PDM_MODE_SHIFT);644 645	return 0;646}647 648static int cs35l35_dai_set_sysclk(struct snd_soc_dai *dai,649				int clk_id, unsigned int freq, int dir)650{651	struct snd_soc_component *component = dai->component;652	struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);653 654	/* Need the SCLK Frequency regardless of sysclk source for I2S */655	cs35l35->sclk = freq;656 657	return 0;658}659 660static const struct snd_soc_dai_ops cs35l35_ops = {661	.startup = cs35l35_pcm_startup,662	.set_fmt = cs35l35_set_dai_fmt,663	.hw_params = cs35l35_hw_params,664	.set_sysclk = cs35l35_dai_set_sysclk,665};666 667static const struct snd_soc_dai_ops cs35l35_pdm_ops = {668	.startup = cs35l35_pdm_startup,669	.set_fmt = cs35l35_set_dai_fmt,670	.hw_params = cs35l35_hw_params,671};672 673static struct snd_soc_dai_driver cs35l35_dai[] = {674	{675		.name = "cs35l35-pcm",676		.id = 0,677		.playback = {678			.stream_name = "AMP Playback",679			.channels_min = 1,680			.channels_max = 8,681			.rates = SNDRV_PCM_RATE_KNOT,682			.formats = CS35L35_FORMATS,683		},684		.capture = {685			.stream_name = "AMP Capture",686			.channels_min = 1,687			.channels_max = 8,688			.rates = SNDRV_PCM_RATE_KNOT,689			.formats = CS35L35_FORMATS,690		},691		.ops = &cs35l35_ops,692		.symmetric_rate = 1,693	},694	{695		.name = "cs35l35-pdm",696		.id = 1,697		.playback = {698			.stream_name = "PDM Playback",699			.channels_min = 1,700			.channels_max = 2,701			.rates = SNDRV_PCM_RATE_KNOT,702			.formats = CS35L35_FORMATS,703		},704		.ops = &cs35l35_pdm_ops,705	},706};707 708static int cs35l35_component_set_sysclk(struct snd_soc_component *component,709				int clk_id, int source, unsigned int freq,710				int dir)711{712	struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);713	int clksrc;714	int ret = 0;715 716	switch (clk_id) {717	case 0:718		clksrc = CS35L35_CLK_SOURCE_MCLK;719		break;720	case 1:721		clksrc = CS35L35_CLK_SOURCE_SCLK;722		break;723	case 2:724		clksrc = CS35L35_CLK_SOURCE_PDM;725		break;726	default:727		dev_err(component->dev, "Invalid CLK Source\n");728		return -EINVAL;729	}730 731	switch (freq) {732	case 5644800:733	case 6144000:734	case 11289600:735	case 12000000:736	case 12288000:737	case 13000000:738	case 22579200:739	case 24000000:740	case 24576000:741	case 26000000:742		cs35l35->sysclk = freq;743		break;744	default:745		dev_err(component->dev, "Invalid CLK Frequency Input : %d\n", freq);746		return -EINVAL;747	}748 749	ret = regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,750				CS35L35_CLK_SOURCE_MASK,751				clksrc << CS35L35_CLK_SOURCE_SHIFT);752	if (ret != 0) {753		dev_err(component->dev, "Failed to set sysclk %d\n", ret);754		return ret;755	}756 757	return ret;758}759 760static int cs35l35_boost_inductor(struct cs35l35_private *cs35l35,761				  int inductor)762{763	struct regmap *regmap = cs35l35->regmap;764	unsigned int bst_ipk = 0;765 766	/*767	 * Digital Boost Converter Configuration for feedback,768	 * ramping, switching frequency, and estimation block seeding.769	 */770 771	regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,772			   CS35L35_BST_CONV_SWFREQ_MASK, 0x00);773 774	regmap_read(regmap, CS35L35_BST_PEAK_I, &bst_ipk);775	bst_ipk &= CS35L35_BST_IPK_MASK;776 777	switch (inductor) {778	case 1000: /* 1 uH */779		regmap_write(regmap, CS35L35_BST_CONV_COEF_1, 0x24);780		regmap_write(regmap, CS35L35_BST_CONV_COEF_2, 0x24);781		regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,782				   CS35L35_BST_CONV_LBST_MASK, 0x00);783 784		if (bst_ipk < 0x04)785			regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x1B);786		else787			regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x4E);788		break;789	case 1200: /* 1.2 uH */790		regmap_write(regmap, CS35L35_BST_CONV_COEF_1, 0x20);791		regmap_write(regmap, CS35L35_BST_CONV_COEF_2, 0x20);792		regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,793				   CS35L35_BST_CONV_LBST_MASK, 0x01);794 795		if (bst_ipk < 0x04)796			regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x1B);797		else798			regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x47);799		break;800	case 1500: /* 1.5uH */801		regmap_write(regmap, CS35L35_BST_CONV_COEF_1, 0x20);802		regmap_write(regmap, CS35L35_BST_CONV_COEF_2, 0x20);803		regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,804				   CS35L35_BST_CONV_LBST_MASK, 0x02);805 806		if (bst_ipk < 0x04)807			regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x1B);808		else809			regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x3C);810		break;811	case 2200: /* 2.2uH */812		regmap_write(regmap, CS35L35_BST_CONV_COEF_1, 0x19);813		regmap_write(regmap, CS35L35_BST_CONV_COEF_2, 0x25);814		regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,815				   CS35L35_BST_CONV_LBST_MASK, 0x03);816 817		if (bst_ipk < 0x04)818			regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x1B);819		else820			regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x23);821		break;822	default:823		dev_err(cs35l35->dev, "Invalid Inductor Value %d uH\n",824			inductor);825		return -EINVAL;826	}827	return 0;828}829 830static int cs35l35_component_probe(struct snd_soc_component *component)831{832	struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);833	struct classh_cfg *classh = &cs35l35->pdata.classh_algo;834	struct monitor_cfg *monitor_config = &cs35l35->pdata.mon_cfg;835	int ret;836 837	/* Set Platform Data */838	if (cs35l35->pdata.bst_vctl)839		regmap_update_bits(cs35l35->regmap, CS35L35_BST_CVTR_V_CTL,840				CS35L35_BST_CTL_MASK,841				cs35l35->pdata.bst_vctl);842 843	if (cs35l35->pdata.bst_ipk)844		regmap_update_bits(cs35l35->regmap, CS35L35_BST_PEAK_I,845				CS35L35_BST_IPK_MASK,846				cs35l35->pdata.bst_ipk <<847				CS35L35_BST_IPK_SHIFT);848 849	ret = cs35l35_boost_inductor(cs35l35, cs35l35->pdata.boost_ind);850	if (ret)851		return ret;852 853	if (cs35l35->pdata.gain_zc)854		regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,855				CS35L35_AMP_GAIN_ZC_MASK,856				cs35l35->pdata.gain_zc <<857				CS35L35_AMP_GAIN_ZC_SHIFT);858 859	if (cs35l35->pdata.aud_channel)860		regmap_update_bits(cs35l35->regmap,861				CS35L35_AUDIN_RXLOC_CTL,862				CS35L35_AUD_IN_LR_MASK,863				cs35l35->pdata.aud_channel <<864				CS35L35_AUD_IN_LR_SHIFT);865 866	if (cs35l35->pdata.stereo) {867		regmap_update_bits(cs35l35->regmap,868				CS35L35_ADVIN_RXLOC_CTL,869				CS35L35_ADV_IN_LR_MASK,870				cs35l35->pdata.adv_channel <<871				CS35L35_ADV_IN_LR_SHIFT);872		if (cs35l35->pdata.shared_bst)873			regmap_update_bits(cs35l35->regmap, CS35L35_CLASS_H_CTL,874					CS35L35_CH_STEREO_MASK,875					1 << CS35L35_CH_STEREO_SHIFT);876		ret = snd_soc_add_component_controls(component, cs35l35_adv_controls,877					ARRAY_SIZE(cs35l35_adv_controls));878		if (ret)879			return ret;880	}881 882	if (cs35l35->pdata.sp_drv_str)883		regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,884				CS35L35_SP_DRV_MASK,885				cs35l35->pdata.sp_drv_str <<886				CS35L35_SP_DRV_SHIFT);887	if (cs35l35->pdata.sp_drv_unused)888		regmap_update_bits(cs35l35->regmap, CS35L35_SP_FMT_CTL3,889				   CS35L35_SP_I2S_DRV_MASK,890				   cs35l35->pdata.sp_drv_unused <<891				   CS35L35_SP_I2S_DRV_SHIFT);892 893	if (classh->classh_algo_enable) {894		if (classh->classh_bst_override)895			regmap_update_bits(cs35l35->regmap,896					CS35L35_CLASS_H_CTL,897					CS35L35_CH_BST_OVR_MASK,898					classh->classh_bst_override <<899					CS35L35_CH_BST_OVR_SHIFT);900		if (classh->classh_bst_max_limit)901			regmap_update_bits(cs35l35->regmap,902					CS35L35_CLASS_H_CTL,903					CS35L35_CH_BST_LIM_MASK,904					classh->classh_bst_max_limit <<905					CS35L35_CH_BST_LIM_SHIFT);906		if (classh->classh_mem_depth)907			regmap_update_bits(cs35l35->regmap,908					CS35L35_CLASS_H_CTL,909					CS35L35_CH_MEM_DEPTH_MASK,910					classh->classh_mem_depth <<911					CS35L35_CH_MEM_DEPTH_SHIFT);912		if (classh->classh_headroom)913			regmap_update_bits(cs35l35->regmap,914					CS35L35_CLASS_H_HEADRM_CTL,915					CS35L35_CH_HDRM_CTL_MASK,916					classh->classh_headroom <<917					CS35L35_CH_HDRM_CTL_SHIFT);918		if (classh->classh_release_rate)919			regmap_update_bits(cs35l35->regmap,920					CS35L35_CLASS_H_RELEASE_RATE,921					CS35L35_CH_REL_RATE_MASK,922					classh->classh_release_rate <<923					CS35L35_CH_REL_RATE_SHIFT);924		if (classh->classh_wk_fet_disable)925			regmap_update_bits(cs35l35->regmap,926					CS35L35_CLASS_H_FET_DRIVE_CTL,927					CS35L35_CH_WKFET_DIS_MASK,928					classh->classh_wk_fet_disable <<929					CS35L35_CH_WKFET_DIS_SHIFT);930		if (classh->classh_wk_fet_delay)931			regmap_update_bits(cs35l35->regmap,932					CS35L35_CLASS_H_FET_DRIVE_CTL,933					CS35L35_CH_WKFET_DEL_MASK,934					classh->classh_wk_fet_delay <<935					CS35L35_CH_WKFET_DEL_SHIFT);936		if (classh->classh_wk_fet_thld)937			regmap_update_bits(cs35l35->regmap,938					CS35L35_CLASS_H_FET_DRIVE_CTL,939					CS35L35_CH_WKFET_THLD_MASK,940					classh->classh_wk_fet_thld <<941					CS35L35_CH_WKFET_THLD_SHIFT);942		if (classh->classh_vpch_auto)943			regmap_update_bits(cs35l35->regmap,944					CS35L35_CLASS_H_VP_CTL,945					CS35L35_CH_VP_AUTO_MASK,946					classh->classh_vpch_auto <<947					CS35L35_CH_VP_AUTO_SHIFT);948		if (classh->classh_vpch_rate)949			regmap_update_bits(cs35l35->regmap,950					CS35L35_CLASS_H_VP_CTL,951					CS35L35_CH_VP_RATE_MASK,952					classh->classh_vpch_rate <<953					CS35L35_CH_VP_RATE_SHIFT);954		if (classh->classh_vpch_man)955			regmap_update_bits(cs35l35->regmap,956					CS35L35_CLASS_H_VP_CTL,957					CS35L35_CH_VP_MAN_MASK,958					classh->classh_vpch_man <<959					CS35L35_CH_VP_MAN_SHIFT);960	}961 962	if (monitor_config->is_present) {963		if (monitor_config->vmon_specs) {964			regmap_update_bits(cs35l35->regmap,965					CS35L35_SPKMON_DEPTH_CTL,966					CS35L35_VMON_DEPTH_MASK,967					monitor_config->vmon_dpth <<968					CS35L35_VMON_DEPTH_SHIFT);969			regmap_update_bits(cs35l35->regmap,970					CS35L35_VMON_TXLOC_CTL,971					CS35L35_MON_TXLOC_MASK,972					monitor_config->vmon_loc <<973					CS35L35_MON_TXLOC_SHIFT);974			regmap_update_bits(cs35l35->regmap,975					CS35L35_VMON_TXLOC_CTL,976					CS35L35_MON_FRM_MASK,977					monitor_config->vmon_frm <<978					CS35L35_MON_FRM_SHIFT);979		}980		if (monitor_config->imon_specs) {981			regmap_update_bits(cs35l35->regmap,982					CS35L35_SPKMON_DEPTH_CTL,983					CS35L35_IMON_DEPTH_MASK,984					monitor_config->imon_dpth <<985					CS35L35_IMON_DEPTH_SHIFT);986			regmap_update_bits(cs35l35->regmap,987					CS35L35_IMON_TXLOC_CTL,988					CS35L35_MON_TXLOC_MASK,989					monitor_config->imon_loc <<990					CS35L35_MON_TXLOC_SHIFT);991			regmap_update_bits(cs35l35->regmap,992					CS35L35_IMON_TXLOC_CTL,993					CS35L35_MON_FRM_MASK,994					monitor_config->imon_frm <<995					CS35L35_MON_FRM_SHIFT);996			regmap_update_bits(cs35l35->regmap,997					CS35L35_IMON_SCALE_CTL,998					CS35L35_IMON_SCALE_MASK,999					monitor_config->imon_scale <<1000					CS35L35_IMON_SCALE_SHIFT);1001		}1002		if (monitor_config->vpmon_specs) {1003			regmap_update_bits(cs35l35->regmap,1004					CS35L35_SUPMON_DEPTH_CTL,1005					CS35L35_VPMON_DEPTH_MASK,1006					monitor_config->vpmon_dpth <<1007					CS35L35_VPMON_DEPTH_SHIFT);1008			regmap_update_bits(cs35l35->regmap,1009					CS35L35_VPMON_TXLOC_CTL,1010					CS35L35_MON_TXLOC_MASK,1011					monitor_config->vpmon_loc <<1012					CS35L35_MON_TXLOC_SHIFT);1013			regmap_update_bits(cs35l35->regmap,1014					CS35L35_VPMON_TXLOC_CTL,1015					CS35L35_MON_FRM_MASK,1016					monitor_config->vpmon_frm <<1017					CS35L35_MON_FRM_SHIFT);1018		}1019		if (monitor_config->vbstmon_specs) {1020			regmap_update_bits(cs35l35->regmap,1021					CS35L35_SUPMON_DEPTH_CTL,1022					CS35L35_VBSTMON_DEPTH_MASK,1023					monitor_config->vpmon_dpth <<1024					CS35L35_VBSTMON_DEPTH_SHIFT);1025			regmap_update_bits(cs35l35->regmap,1026					CS35L35_VBSTMON_TXLOC_CTL,1027					CS35L35_MON_TXLOC_MASK,1028					monitor_config->vbstmon_loc <<1029					CS35L35_MON_TXLOC_SHIFT);1030			regmap_update_bits(cs35l35->regmap,1031					CS35L35_VBSTMON_TXLOC_CTL,1032					CS35L35_MON_FRM_MASK,1033					monitor_config->vbstmon_frm <<1034					CS35L35_MON_FRM_SHIFT);1035		}1036		if (monitor_config->vpbrstat_specs) {1037			regmap_update_bits(cs35l35->regmap,1038					CS35L35_SUPMON_DEPTH_CTL,1039					CS35L35_VPBRSTAT_DEPTH_MASK,1040					monitor_config->vpbrstat_dpth <<1041					CS35L35_VPBRSTAT_DEPTH_SHIFT);1042			regmap_update_bits(cs35l35->regmap,1043					CS35L35_VPBR_STATUS_TXLOC_CTL,1044					CS35L35_MON_TXLOC_MASK,1045					monitor_config->vpbrstat_loc <<1046					CS35L35_MON_TXLOC_SHIFT);1047			regmap_update_bits(cs35l35->regmap,1048					CS35L35_VPBR_STATUS_TXLOC_CTL,1049					CS35L35_MON_FRM_MASK,1050					monitor_config->vpbrstat_frm <<1051					CS35L35_MON_FRM_SHIFT);1052		}1053		if (monitor_config->zerofill_specs) {1054			regmap_update_bits(cs35l35->regmap,1055					CS35L35_SUPMON_DEPTH_CTL,1056					CS35L35_ZEROFILL_DEPTH_MASK,1057					monitor_config->zerofill_dpth <<1058					CS35L35_ZEROFILL_DEPTH_SHIFT);1059			regmap_update_bits(cs35l35->regmap,1060					CS35L35_ZERO_FILL_LOC_CTL,1061					CS35L35_MON_TXLOC_MASK,1062					monitor_config->zerofill_loc <<1063					CS35L35_MON_TXLOC_SHIFT);1064			regmap_update_bits(cs35l35->regmap,1065					CS35L35_ZERO_FILL_LOC_CTL,1066					CS35L35_MON_FRM_MASK,1067					monitor_config->zerofill_frm <<1068					CS35L35_MON_FRM_SHIFT);1069		}1070	}1071 1072	return 0;1073}1074 1075static const struct snd_soc_component_driver soc_component_dev_cs35l35 = {1076	.probe			= cs35l35_component_probe,1077	.set_sysclk		= cs35l35_component_set_sysclk,1078	.dapm_widgets		= cs35l35_dapm_widgets,1079	.num_dapm_widgets	= ARRAY_SIZE(cs35l35_dapm_widgets),1080	.dapm_routes		= cs35l35_audio_map,1081	.num_dapm_routes	= ARRAY_SIZE(cs35l35_audio_map),1082	.controls		= cs35l35_aud_controls,1083	.num_controls		= ARRAY_SIZE(cs35l35_aud_controls),1084	.idle_bias_on		= 1,1085	.use_pmdown_time	= 1,1086	.endianness		= 1,1087};1088 1089static const struct regmap_config cs35l35_regmap = {1090	.reg_bits = 8,1091	.val_bits = 8,1092 1093	.max_register = CS35L35_MAX_REGISTER,1094	.reg_defaults = cs35l35_reg,1095	.num_reg_defaults = ARRAY_SIZE(cs35l35_reg),1096	.volatile_reg = cs35l35_volatile_register,1097	.readable_reg = cs35l35_readable_register,1098	.precious_reg = cs35l35_precious_register,1099	.cache_type = REGCACHE_MAPLE,1100	.use_single_read = true,1101	.use_single_write = true,1102};1103 1104static irqreturn_t cs35l35_irq(int irq, void *data)1105{1106	struct cs35l35_private *cs35l35 = data;1107	unsigned int sticky1, sticky2, sticky3, sticky4;1108	unsigned int mask1, mask2, mask3, mask4, current1;1109 1110	/* ack the irq by reading all status registers */1111	regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_4, &sticky4);1112	regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_3, &sticky3);1113	regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_2, &sticky2);1114	regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_1, &sticky1);1115 1116	regmap_read(cs35l35->regmap, CS35L35_INT_MASK_4, &mask4);1117	regmap_read(cs35l35->regmap, CS35L35_INT_MASK_3, &mask3);1118	regmap_read(cs35l35->regmap, CS35L35_INT_MASK_2, &mask2);1119	regmap_read(cs35l35->regmap, CS35L35_INT_MASK_1, &mask1);1120 1121	/* Check to see if unmasked bits are active */1122	if (!(sticky1 & ~mask1) && !(sticky2 & ~mask2) && !(sticky3 & ~mask3)1123			&& !(sticky4 & ~mask4))1124		return IRQ_NONE;1125 1126	if (sticky2 & CS35L35_PDN_DONE)1127		complete(&cs35l35->pdn_done);1128 1129	/* read the current values */1130	regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_1, &current1);1131 1132	/* handle the interrupts */1133	if (sticky1 & CS35L35_CAL_ERR) {1134		dev_crit(cs35l35->dev, "Calibration Error\n");1135 1136		/* error is no longer asserted; safe to reset */1137		if (!(current1 & CS35L35_CAL_ERR)) {1138			pr_debug("%s : Cal error release\n", __func__);1139			regmap_update_bits(cs35l35->regmap,1140					CS35L35_PROT_RELEASE_CTL,1141					CS35L35_CAL_ERR_RLS, 0);1142			regmap_update_bits(cs35l35->regmap,1143					CS35L35_PROT_RELEASE_CTL,1144					CS35L35_CAL_ERR_RLS,1145					CS35L35_CAL_ERR_RLS);1146			regmap_update_bits(cs35l35->regmap,1147					CS35L35_PROT_RELEASE_CTL,1148					CS35L35_CAL_ERR_RLS, 0);1149		}1150	}1151 1152	if (sticky1 & CS35L35_AMP_SHORT) {1153		dev_crit(cs35l35->dev, "AMP Short Error\n");1154		/* error is no longer asserted; safe to reset */1155		if (!(current1 & CS35L35_AMP_SHORT)) {1156			dev_dbg(cs35l35->dev, "Amp short error release\n");1157			regmap_update_bits(cs35l35->regmap,1158					CS35L35_PROT_RELEASE_CTL,1159					CS35L35_SHORT_RLS, 0);1160			regmap_update_bits(cs35l35->regmap,1161					CS35L35_PROT_RELEASE_CTL,1162					CS35L35_SHORT_RLS,1163					CS35L35_SHORT_RLS);1164			regmap_update_bits(cs35l35->regmap,1165					CS35L35_PROT_RELEASE_CTL,1166					CS35L35_SHORT_RLS, 0);1167		}1168	}1169 1170	if (sticky1 & CS35L35_OTW) {1171		dev_warn(cs35l35->dev, "Over temperature warning\n");1172 1173		/* error is no longer asserted; safe to reset */1174		if (!(current1 & CS35L35_OTW)) {1175			dev_dbg(cs35l35->dev, "Over temperature warn release\n");1176			regmap_update_bits(cs35l35->regmap,1177					CS35L35_PROT_RELEASE_CTL,1178					CS35L35_OTW_RLS, 0);1179			regmap_update_bits(cs35l35->regmap,1180					CS35L35_PROT_RELEASE_CTL,1181					CS35L35_OTW_RLS,1182					CS35L35_OTW_RLS);1183			regmap_update_bits(cs35l35->regmap,1184					CS35L35_PROT_RELEASE_CTL,1185					CS35L35_OTW_RLS, 0);1186		}1187	}1188 1189	if (sticky1 & CS35L35_OTE) {1190		dev_crit(cs35l35->dev, "Over temperature error\n");1191		/* error is no longer asserted; safe to reset */1192		if (!(current1 & CS35L35_OTE)) {1193			dev_dbg(cs35l35->dev, "Over temperature error release\n");1194			regmap_update_bits(cs35l35->regmap,1195					CS35L35_PROT_RELEASE_CTL,1196					CS35L35_OTE_RLS, 0);1197			regmap_update_bits(cs35l35->regmap,1198					CS35L35_PROT_RELEASE_CTL,1199					CS35L35_OTE_RLS,1200					CS35L35_OTE_RLS);1201			regmap_update_bits(cs35l35->regmap,1202					CS35L35_PROT_RELEASE_CTL,1203					CS35L35_OTE_RLS, 0);1204		}1205	}1206 1207	if (sticky3 & CS35L35_BST_HIGH) {1208		dev_crit(cs35l35->dev, "VBST error: powering off!\n");1209		regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,1210			CS35L35_PDN_AMP, CS35L35_PDN_AMP);1211		regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,1212			CS35L35_PDN_ALL, CS35L35_PDN_ALL);1213	}1214 1215	if (sticky3 & CS35L35_LBST_SHORT) {1216		dev_crit(cs35l35->dev, "LBST error: powering off!\n");1217		regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,1218			CS35L35_PDN_AMP, CS35L35_PDN_AMP);1219		regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,1220			CS35L35_PDN_ALL, CS35L35_PDN_ALL);1221	}1222 1223	if (sticky2 & CS35L35_VPBR_ERR)1224		dev_dbg(cs35l35->dev, "Error: Reactive Brownout\n");1225 1226	if (sticky4 & CS35L35_VMON_OVFL)1227		dev_dbg(cs35l35->dev, "Error: VMON overflow\n");1228 1229	if (sticky4 & CS35L35_IMON_OVFL)1230		dev_dbg(cs35l35->dev, "Error: IMON overflow\n");1231 1232	return IRQ_HANDLED;1233}1234 1235 1236static int cs35l35_handle_of_data(struct i2c_client *i2c_client,1237				struct cs35l35_platform_data *pdata)1238{1239	struct device_node *np = i2c_client->dev.of_node;1240	struct device_node *classh, *signal_format;1241	struct classh_cfg *classh_config = &pdata->classh_algo;1242	struct monitor_cfg *monitor_config = &pdata->mon_cfg;1243	unsigned int val32 = 0;1244	u8 monitor_array[4];1245	const int imon_array_size = ARRAY_SIZE(monitor_array);1246	const int mon_array_size = imon_array_size - 1;1247	int ret = 0;1248 1249	if (!np)1250		return 0;1251 1252	pdata->bst_pdn_fet_on = of_property_read_bool(np,1253					"cirrus,boost-pdn-fet-on");1254 1255	ret = of_property_read_u32(np, "cirrus,boost-ctl-millivolt", &val32);1256	if (ret >= 0) {1257		if (val32 < 2600 || val32 > 9000) {1258			dev_err(&i2c_client->dev,1259				"Invalid Boost Voltage %d mV\n", val32);1260			return -EINVAL;1261		}1262		pdata->bst_vctl = ((val32 - 2600) / 100) + 1;1263	}1264 1265	ret = of_property_read_u32(np, "cirrus,boost-peak-milliamp", &val32);1266	if (ret >= 0) {1267		if (val32 < 1680 || val32 > 4480) {1268			dev_err(&i2c_client->dev,1269				"Invalid Boost Peak Current %u mA\n", val32);1270			return -EINVAL;1271		}1272 1273		pdata->bst_ipk = ((val32 - 1680) / 110) | CS35L35_VALID_PDATA;1274	}1275 1276	ret = of_property_read_u32(np, "cirrus,boost-ind-nanohenry", &val32);1277	if (ret >= 0) {1278		pdata->boost_ind = val32;1279	} else {1280		dev_err(&i2c_client->dev, "Inductor not specified.\n");1281		return -EINVAL;1282	}1283 1284	if (of_property_read_u32(np, "cirrus,sp-drv-strength", &val32) >= 0)1285		pdata->sp_drv_str = val32;1286	if (of_property_read_u32(np, "cirrus,sp-drv-unused", &val32) >= 0)1287		pdata->sp_drv_unused = val32 | CS35L35_VALID_PDATA;1288 1289	pdata->stereo = of_property_read_bool(np, "cirrus,stereo-config");1290 1291	if (pdata->stereo) {1292		ret = of_property_read_u32(np, "cirrus,audio-channel", &val32);1293		if (ret >= 0)1294			pdata->aud_channel = val32;1295 1296		ret = of_property_read_u32(np, "cirrus,advisory-channel",1297					   &val32);1298		if (ret >= 0)1299			pdata->adv_channel = val32;1300 1301		pdata->shared_bst = of_property_read_bool(np,1302						"cirrus,shared-boost");1303	}1304 1305	pdata->ext_bst = of_property_read_bool(np, "cirrus,external-boost");1306 1307	pdata->gain_zc = of_property_read_bool(np, "cirrus,amp-gain-zc");1308 1309	classh = of_get_child_by_name(np, "cirrus,classh-internal-algo");1310	classh_config->classh_algo_enable = (classh != NULL);1311 1312	if (classh_config->classh_algo_enable) {1313		classh_config->classh_bst_override =1314			of_property_read_bool(np, "cirrus,classh-bst-overide");1315 1316		ret = of_property_read_u32(classh,1317					   "cirrus,classh-bst-max-limit",1318					   &val32);1319		if (ret >= 0) {1320			val32 |= CS35L35_VALID_PDATA;1321			classh_config->classh_bst_max_limit = val32;1322		}1323 1324		ret = of_property_read_u32(classh,1325					   "cirrus,classh-bst-max-limit",1326					   &val32);1327		if (ret >= 0) {1328			val32 |= CS35L35_VALID_PDATA;1329			classh_config->classh_bst_max_limit = val32;1330		}1331 1332		ret = of_property_read_u32(classh, "cirrus,classh-mem-depth",1333					   &val32);1334		if (ret >= 0) {1335			val32 |= CS35L35_VALID_PDATA;1336			classh_config->classh_mem_depth = val32;1337		}1338 1339		ret = of_property_read_u32(classh, "cirrus,classh-release-rate",1340					   &val32);1341		if (ret >= 0)1342			classh_config->classh_release_rate = val32;1343 1344		ret = of_property_read_u32(classh, "cirrus,classh-headroom",1345					   &val32);1346		if (ret >= 0) {1347			val32 |= CS35L35_VALID_PDATA;1348			classh_config->classh_headroom = val32;1349		}1350 1351		ret = of_property_read_u32(classh,1352					   "cirrus,classh-wk-fet-disable",1353					   &val32);1354		if (ret >= 0)1355			classh_config->classh_wk_fet_disable = val32;1356 1357		ret = of_property_read_u32(classh, "cirrus,classh-wk-fet-delay",1358					   &val32);1359		if (ret >= 0) {1360			val32 |= CS35L35_VALID_PDATA;1361			classh_config->classh_wk_fet_delay = val32;1362		}1363 1364		ret = of_property_read_u32(classh, "cirrus,classh-wk-fet-thld",1365					   &val32);1366		if (ret >= 0)1367			classh_config->classh_wk_fet_thld = val32;1368 1369		ret = of_property_read_u32(classh, "cirrus,classh-vpch-auto",1370					   &val32);1371		if (ret >= 0) {1372			val32 |= CS35L35_VALID_PDATA;1373			classh_config->classh_vpch_auto = val32;1374		}1375 1376		ret = of_property_read_u32(classh, "cirrus,classh-vpch-rate",1377					   &val32);1378		if (ret >= 0) {1379			val32 |= CS35L35_VALID_PDATA;1380			classh_config->classh_vpch_rate = val32;1381		}1382 1383		ret = of_property_read_u32(classh, "cirrus,classh-vpch-man",1384					   &val32);1385		if (ret >= 0)1386			classh_config->classh_vpch_man = val32;1387	}1388	of_node_put(classh);1389 1390	/* frame depth location */1391	signal_format = of_get_child_by_name(np, "cirrus,monitor-signal-format");1392	monitor_config->is_present = signal_format ? true : false;1393	if (monitor_config->is_present) {1394		ret = of_property_read_u8_array(signal_format, "cirrus,imon",1395						monitor_array, imon_array_size);1396		if (!ret) {1397			monitor_config->imon_specs = true;1398			monitor_config->imon_dpth = monitor_array[0];1399			monitor_config->imon_loc = monitor_array[1];1400			monitor_config->imon_frm = monitor_array[2];1401			monitor_config->imon_scale = monitor_array[3];1402		}1403		ret = of_property_read_u8_array(signal_format, "cirrus,vmon",1404						monitor_array, mon_array_size);1405		if (!ret) {1406			monitor_config->vmon_specs = true;1407			monitor_config->vmon_dpth = monitor_array[0];1408			monitor_config->vmon_loc = monitor_array[1];1409			monitor_config->vmon_frm = monitor_array[2];1410		}1411		ret = of_property_read_u8_array(signal_format, "cirrus,vpmon",1412						monitor_array, mon_array_size);1413		if (!ret) {1414			monitor_config->vpmon_specs = true;1415			monitor_config->vpmon_dpth = monitor_array[0];1416			monitor_config->vpmon_loc = monitor_array[1];1417			monitor_config->vpmon_frm = monitor_array[2];1418		}1419		ret = of_property_read_u8_array(signal_format, "cirrus,vbstmon",1420						monitor_array, mon_array_size);1421		if (!ret) {1422			monitor_config->vbstmon_specs = true;1423			monitor_config->vbstmon_dpth = monitor_array[0];1424			monitor_config->vbstmon_loc = monitor_array[1];1425			monitor_config->vbstmon_frm = monitor_array[2];1426		}1427		ret = of_property_read_u8_array(signal_format, "cirrus,vpbrstat",1428						monitor_array, mon_array_size);1429		if (!ret) {1430			monitor_config->vpbrstat_specs = true;1431			monitor_config->vpbrstat_dpth = monitor_array[0];1432			monitor_config->vpbrstat_loc = monitor_array[1];1433			monitor_config->vpbrstat_frm = monitor_array[2];1434		}1435		ret = of_property_read_u8_array(signal_format, "cirrus,zerofill",1436						monitor_array, mon_array_size);1437		if (!ret) {1438			monitor_config->zerofill_specs = true;1439			monitor_config->zerofill_dpth = monitor_array[0];1440			monitor_config->zerofill_loc = monitor_array[1];1441			monitor_config->zerofill_frm = monitor_array[2];1442		}1443	}1444	of_node_put(signal_format);1445 1446	return 0;1447}1448 1449/* Errata Rev A0 */1450static const struct reg_sequence cs35l35_errata_patch[] = {1451 1452	{ 0x7F, 0x99 },1453	{ 0x00, 0x99 },1454	{ 0x52, 0x22 },1455	{ 0x04, 0x14 },1456	{ 0x6D, 0x44 },1457	{ 0x24, 0x10 },1458	{ 0x58, 0xC4 },1459	{ 0x00, 0x98 },1460	{ 0x18, 0x08 },1461	{ 0x00, 0x00 },1462	{ 0x7F, 0x00 },1463};1464 1465static int cs35l35_i2c_probe(struct i2c_client *i2c_client)1466{1467	struct cs35l35_private *cs35l35;1468	struct device *dev = &i2c_client->dev;1469	struct cs35l35_platform_data *pdata = dev_get_platdata(dev);1470	int i, devid;1471	int ret;1472	unsigned int reg;1473 1474	cs35l35 = devm_kzalloc(dev, sizeof(struct cs35l35_private), GFP_KERNEL);1475	if (!cs35l35)1476		return -ENOMEM;1477 1478	cs35l35->dev = dev;1479 1480	i2c_set_clientdata(i2c_client, cs35l35);1481	cs35l35->regmap = devm_regmap_init_i2c(i2c_client, &cs35l35_regmap);1482	if (IS_ERR(cs35l35->regmap)) {1483		ret = PTR_ERR(cs35l35->regmap);1484		dev_err(dev, "regmap_init() failed: %d\n", ret);1485		return ret;1486	}1487 1488	for (i = 0; i < ARRAY_SIZE(cs35l35_supplies); i++)1489		cs35l35->supplies[i].supply = cs35l35_supplies[i];1490 1491	cs35l35->num_supplies = ARRAY_SIZE(cs35l35_supplies);1492 1493	ret = devm_regulator_bulk_get(dev, cs35l35->num_supplies,1494				      cs35l35->supplies);1495	if (ret != 0) {1496		dev_err(dev, "Failed to request core supplies: %d\n", ret);1497		return ret;1498	}1499 1500	if (pdata) {1501		cs35l35->pdata = *pdata;1502	} else {1503		pdata = devm_kzalloc(dev, sizeof(struct cs35l35_platform_data),1504				     GFP_KERNEL);1505		if (!pdata)1506			return -ENOMEM;1507		if (i2c_client->dev.of_node) {1508			ret = cs35l35_handle_of_data(i2c_client, pdata);1509			if (ret != 0)1510				return ret;1511 1512		}1513		cs35l35->pdata = *pdata;1514	}1515 1516	ret = regulator_bulk_enable(cs35l35->num_supplies,1517					cs35l35->supplies);1518	if (ret != 0) {1519		dev_err(dev, "Failed to enable core supplies: %d\n", ret);1520		return ret;1521	}1522 1523	/* returning NULL can be valid if in stereo mode */1524	cs35l35->reset_gpio = devm_gpiod_get_optional(dev, "reset",1525						      GPIOD_OUT_LOW);1526	if (IS_ERR(cs35l35->reset_gpio)) {1527		ret = PTR_ERR(cs35l35->reset_gpio);1528		cs35l35->reset_gpio = NULL;1529		if (ret == -EBUSY) {1530			dev_info(dev,1531				 "Reset line busy, assuming shared reset\n");1532		} else {1533			dev_err(dev, "Failed to get reset GPIO: %d\n", ret);1534			goto err;1535		}1536	}1537 1538	cs35l35_reset(cs35l35);1539 1540	init_completion(&cs35l35->pdn_done);1541 1542	ret = devm_request_threaded_irq(dev, i2c_client->irq, NULL, cs35l35_irq,1543					IRQF_ONESHOT | IRQF_TRIGGER_LOW |1544					IRQF_SHARED, "cs35l35", cs35l35);1545	if (ret != 0) {1546		dev_err(dev, "Failed to request IRQ: %d\n", ret);1547		goto err;1548	}1549	/* initialize codec */1550	devid = cirrus_read_device_id(cs35l35->regmap, CS35L35_DEVID_AB);1551	if (devid < 0) {1552		ret = devid;1553		dev_err(dev, "Failed to read device ID: %d\n", ret);1554		goto err;1555	}1556 1557	if (devid != CS35L35_CHIP_ID) {1558		dev_err(dev, "CS35L35 Device ID (%X). Expected ID %X\n",1559			devid, CS35L35_CHIP_ID);1560		ret = -ENODEV;1561		goto err;1562	}1563 1564	ret = regmap_read(cs35l35->regmap, CS35L35_REV_ID, &reg);1565	if (ret < 0) {1566		dev_err(dev, "Get Revision ID failed: %d\n", ret);1567		goto err;1568	}1569 1570	ret = regmap_register_patch(cs35l35->regmap, cs35l35_errata_patch,1571				    ARRAY_SIZE(cs35l35_errata_patch));1572	if (ret < 0) {1573		dev_err(dev, "Failed to apply errata patch: %d\n", ret);1574		goto err;1575	}1576 1577	dev_info(dev, "Cirrus Logic CS35L35 (%x), Revision: %02X\n",1578		 devid, reg & 0xFF);1579 1580	/* Set the INT Masks for critical errors */1581	regmap_write(cs35l35->regmap, CS35L35_INT_MASK_1,1582				CS35L35_INT1_CRIT_MASK);1583	regmap_write(cs35l35->regmap, CS35L35_INT_MASK_2,1584				CS35L35_INT2_CRIT_MASK);1585	regmap_write(cs35l35->regmap, CS35L35_INT_MASK_3,1586				CS35L35_INT3_CRIT_MASK);1587	regmap_write(cs35l35->regmap, CS35L35_INT_MASK_4,1588				CS35L35_INT4_CRIT_MASK);1589 1590	regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,1591			CS35L35_PWR2_PDN_MASK,1592			CS35L35_PWR2_PDN_MASK);1593 1594	if (cs35l35->pdata.bst_pdn_fet_on)1595		regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,1596					CS35L35_PDN_BST_MASK,1597					1 << CS35L35_PDN_BST_FETON_SHIFT);1598	else1599		regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,1600					CS35L35_PDN_BST_MASK,1601					1 << CS35L35_PDN_BST_FETOFF_SHIFT);1602 1603	regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL3,1604			CS35L35_PWR3_PDN_MASK,1605			CS35L35_PWR3_PDN_MASK);1606 1607	regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,1608		CS35L35_AMP_MUTE_MASK, 1 << CS35L35_AMP_MUTE_SHIFT);1609 1610	ret = devm_snd_soc_register_component(dev, &soc_component_dev_cs35l35,1611					cs35l35_dai, ARRAY_SIZE(cs35l35_dai));1612	if (ret < 0) {1613		dev_err(dev, "Failed to register component: %d\n", ret);1614		goto err;1615	}1616 1617	return 0;1618 1619err:1620	regulator_bulk_disable(cs35l35->num_supplies,1621			       cs35l35->supplies);1622	gpiod_set_value_cansleep(cs35l35->reset_gpio, 0);1623 1624	return ret;1625}1626 1627static void cs35l35_i2c_remove(struct i2c_client *i2c_client)1628{1629	struct cs35l35_private *cs35l35 = i2c_get_clientdata(i2c_client);1630 1631	regulator_bulk_disable(cs35l35->num_supplies, cs35l35->supplies);1632	gpiod_set_value_cansleep(cs35l35->reset_gpio, 0);1633}1634 1635static const struct of_device_id cs35l35_of_match[] = {1636	{.compatible = "cirrus,cs35l35"},1637	{},1638};1639MODULE_DEVICE_TABLE(of, cs35l35_of_match);1640 1641static const struct i2c_device_id cs35l35_id[] = {1642	{"cs35l35"},1643	{}1644};1645 1646MODULE_DEVICE_TABLE(i2c, cs35l35_id);1647 1648static struct i2c_driver cs35l35_i2c_driver = {1649	.driver = {1650		.name = "cs35l35",1651		.of_match_table = cs35l35_of_match,1652	},1653	.id_table = cs35l35_id,1654	.probe = cs35l35_i2c_probe,1655	.remove = cs35l35_i2c_remove,1656};1657 1658module_i2c_driver(cs35l35_i2c_driver);1659 1660MODULE_DESCRIPTION("ASoC CS35L35 driver");1661MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");1662MODULE_LICENSE("GPL");1663