brintos

brintos / linux-shallow public Read only

0
0
Text · 56.0 KiB · b49c690 Raw
1943 lines · c
1// SPDX-License-Identifier: GPL-2.02//3// cs35l36.c -- CS35L36 ALSA SoC audio driver4//5// Copyright 2018 Cirrus Logic, Inc.6//7// Author: James Schulman <james.schulman@cirrus.com>8 9#include <linux/module.h>10#include <linux/moduleparam.h>11#include <linux/kernel.h>12#include <linux/init.h>13#include <linux/delay.h>14#include <linux/i2c.h>15#include <linux/slab.h>16#include <linux/workqueue.h>17#include <linux/platform_device.h>18#include <linux/regulator/consumer.h>19#include <linux/gpio/consumer.h>20#include <linux/irq.h>21#include <linux/of.h>22#include <linux/regmap.h>23#include <sound/core.h>24#include <sound/pcm.h>25#include <sound/pcm_params.h>26#include <sound/soc.h>27#include <sound/soc-dapm.h>28#include <sound/initval.h>29#include <sound/tlv.h>30#include <sound/cs35l36.h>31#include <linux/completion.h>32 33#include "cs35l36.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 CS35L36_VALID_PDATA 0x8000000040 41static const char * const cs35l36_supplies[] = {42	"VA",43	"VP",44};45 46struct  cs35l36_private {47	struct device *dev;48	struct cs35l36_platform_data pdata;49	struct regmap *regmap;50	struct regulator_bulk_data supplies[2];51	int num_supplies;52	int clksrc;53	int chip_version;54	int rev_id;55	int ldm_mode_sel;56	struct gpio_desc *reset_gpio;57};58 59struct cs35l36_pll_config {60	int freq;61	int clk_cfg;62	int fll_igain;63};64 65static const struct cs35l36_pll_config cs35l36_pll_sysclk[] = {66	{32768,		0x00, 0x05},67	{8000,		0x01, 0x03},68	{11025,		0x02, 0x03},69	{12000,		0x03, 0x03},70	{16000,		0x04, 0x04},71	{22050,		0x05, 0x04},72	{24000,		0x06, 0x04},73	{32000,		0x07, 0x05},74	{44100,		0x08, 0x05},75	{48000,		0x09, 0x05},76	{88200,		0x0A, 0x06},77	{96000,		0x0B, 0x06},78	{128000,	0x0C, 0x07},79	{176400,	0x0D, 0x07},80	{192000,	0x0E, 0x07},81	{256000,	0x0F, 0x08},82	{352800,	0x10, 0x08},83	{384000,	0x11, 0x08},84	{512000,	0x12, 0x09},85	{705600,	0x13, 0x09},86	{750000,	0x14, 0x09},87	{768000,	0x15, 0x09},88	{1000000,	0x16, 0x0A},89	{1024000,	0x17, 0x0A},90	{1200000,	0x18, 0x0A},91	{1411200,	0x19, 0x0A},92	{1500000,	0x1A, 0x0A},93	{1536000,	0x1B, 0x0A},94	{2000000,	0x1C, 0x0A},95	{2048000,	0x1D, 0x0A},96	{2400000,	0x1E, 0x0A},97	{2822400,	0x1F, 0x0A},98	{3000000,	0x20, 0x0A},99	{3072000,	0x21, 0x0A},100	{3200000,	0x22, 0x0A},101	{4000000,	0x23, 0x0A},102	{4096000,	0x24, 0x0A},103	{4800000,	0x25, 0x0A},104	{5644800,	0x26, 0x0A},105	{6000000,	0x27, 0x0A},106	{6144000,	0x28, 0x0A},107	{6250000,	0x29, 0x08},108	{6400000,	0x2A, 0x0A},109	{6500000,	0x2B, 0x08},110	{6750000,	0x2C, 0x09},111	{7526400,	0x2D, 0x0A},112	{8000000,	0x2E, 0x0A},113	{8192000,	0x2F, 0x0A},114	{9600000,	0x30, 0x0A},115	{11289600,	0x31, 0x0A},116	{12000000,	0x32, 0x0A},117	{12288000,	0x33, 0x0A},118	{12500000,	0x34, 0x08},119	{12800000,	0x35, 0x0A},120	{13000000,	0x36, 0x0A},121	{13500000,	0x37, 0x0A},122	{19200000,	0x38, 0x0A},123	{22579200,	0x39, 0x0A},124	{24000000,	0x3A, 0x0A},125	{24576000,	0x3B, 0x0A},126	{25000000,	0x3C, 0x0A},127	{25600000,	0x3D, 0x0A},128	{26000000,	0x3E, 0x0A},129	{27000000,	0x3F, 0x0A},130};131 132static struct reg_default cs35l36_reg[] = {133	{CS35L36_TESTKEY_CTRL,			0x00000000},134	{CS35L36_USERKEY_CTL,			0x00000000},135	{CS35L36_OTP_CTRL1,			0x00002460},136	{CS35L36_OTP_CTRL2,			0x00000000},137	{CS35L36_OTP_CTRL3,			0x00000000},138	{CS35L36_OTP_CTRL4,			0x00000000},139	{CS35L36_OTP_CTRL5,			0x00000000},140	{CS35L36_PAC_CTL1,			0x00000004},141	{CS35L36_PAC_CTL2,			0x00000000},142	{CS35L36_PAC_CTL3,			0x00000000},143	{CS35L36_PWR_CTRL1,			0x00000000},144	{CS35L36_PWR_CTRL2,			0x00003321},145	{CS35L36_PWR_CTRL3,			0x01000010},146	{CS35L36_CTRL_OVRRIDE,			0x00000002},147	{CS35L36_AMP_OUT_MUTE,			0x00000000},148	{CS35L36_OTP_TRIM_STATUS,		0x00000000},149	{CS35L36_DISCH_FILT,			0x00000000},150	{CS35L36_PROTECT_REL_ERR,		0x00000000},151	{CS35L36_PAD_INTERFACE,			0x00000038},152	{CS35L36_PLL_CLK_CTRL,			0x00000010},153	{CS35L36_GLOBAL_CLK_CTRL,		0x00000003},154	{CS35L36_ADC_CLK_CTRL,			0x00000000},155	{CS35L36_SWIRE_CLK_CTRL,		0x00000000},156	{CS35L36_SP_SCLK_CLK_CTRL,		0x00000000},157	{CS35L36_MDSYNC_EN,			0x00000000},158	{CS35L36_MDSYNC_TX_ID,			0x00000000},159	{CS35L36_MDSYNC_PWR_CTRL,		0x00000000},160	{CS35L36_MDSYNC_DATA_TX,		0x00000000},161	{CS35L36_MDSYNC_TX_STATUS,		0x00000002},162	{CS35L36_MDSYNC_RX_STATUS,		0x00000000},163	{CS35L36_MDSYNC_ERR_STATUS,		0x00000000},164	{CS35L36_BSTCVRT_VCTRL1,		0x00000000},165	{CS35L36_BSTCVRT_VCTRL2,		0x00000001},166	{CS35L36_BSTCVRT_PEAK_CUR,		0x0000004A},167	{CS35L36_BSTCVRT_SFT_RAMP,		0x00000003},168	{CS35L36_BSTCVRT_COEFF,			0x00002424},169	{CS35L36_BSTCVRT_SLOPE_LBST,		0x00005800},170	{CS35L36_BSTCVRT_SW_FREQ,		0x00010000},171	{CS35L36_BSTCVRT_DCM_CTRL,		0x00002001},172	{CS35L36_BSTCVRT_DCM_MODE_FORCE,	0x00000000},173	{CS35L36_BSTCVRT_OVERVOLT_CTRL,		0x00000130},174	{CS35L36_VPI_LIMIT_MODE,		0x00000000},175	{CS35L36_VPI_LIMIT_MINMAX,		0x00003000},176	{CS35L36_VPI_VP_THLD,			0x00101010},177	{CS35L36_VPI_TRACK_CTRL,		0x00000000},178	{CS35L36_VPI_TRIG_MODE_CTRL,		0x00000000},179	{CS35L36_VPI_TRIG_STEPS,		0x00000000},180	{CS35L36_VI_SPKMON_FILT,		0x00000003},181	{CS35L36_VI_SPKMON_GAIN,		0x00000909},182	{CS35L36_VI_SPKMON_IP_SEL,		0x00000000},183	{CS35L36_DTEMP_WARN_THLD,		0x00000002},184	{CS35L36_DTEMP_STATUS,			0x00000000},185	{CS35L36_VPVBST_FS_SEL,			0x00000001},186	{CS35L36_VPVBST_VP_CTRL,		0x000001C0},187	{CS35L36_VPVBST_VBST_CTRL,		0x000001C0},188	{CS35L36_ASP_TX_PIN_CTRL,		0x00000028},189	{CS35L36_ASP_RATE_CTRL,			0x00090000},190	{CS35L36_ASP_FORMAT,			0x00000002},191	{CS35L36_ASP_FRAME_CTRL,		0x00180018},192	{CS35L36_ASP_TX1_TX2_SLOT,		0x00010000},193	{CS35L36_ASP_TX3_TX4_SLOT,		0x00030002},194	{CS35L36_ASP_TX5_TX6_SLOT,		0x00050004},195	{CS35L36_ASP_TX7_TX8_SLOT,		0x00070006},196	{CS35L36_ASP_RX1_SLOT,			0x00000000},197	{CS35L36_ASP_RX_TX_EN,			0x00000000},198	{CS35L36_ASP_RX1_SEL,			0x00000008},199	{CS35L36_ASP_TX1_SEL,			0x00000018},200	{CS35L36_ASP_TX2_SEL,			0x00000019},201	{CS35L36_ASP_TX3_SEL,			0x00000028},202	{CS35L36_ASP_TX4_SEL,			0x00000029},203	{CS35L36_ASP_TX5_SEL,			0x00000020},204	{CS35L36_ASP_TX6_SEL,			0x00000000},205	{CS35L36_SWIRE_P1_TX1_SEL,		0x00000018},206	{CS35L36_SWIRE_P1_TX2_SEL,		0x00000019},207	{CS35L36_SWIRE_P2_TX1_SEL,		0x00000028},208	{CS35L36_SWIRE_P2_TX2_SEL,		0x00000029},209	{CS35L36_SWIRE_P2_TX3_SEL,		0x00000020},210	{CS35L36_SWIRE_DP1_FIFO_CFG,		0x0000001B},211	{CS35L36_SWIRE_DP2_FIFO_CFG,		0x0000001B},212	{CS35L36_SWIRE_DP3_FIFO_CFG,		0x0000001B},213	{CS35L36_SWIRE_PCM_RX_DATA,		0x00000000},214	{CS35L36_SWIRE_FS_SEL,			0x00000001},215	{CS35L36_AMP_DIG_VOL_CTRL,		0x00008000},216	{CS35L36_VPBR_CFG,			0x02AA1905},217	{CS35L36_VBBR_CFG,			0x02AA1905},218	{CS35L36_VPBR_STATUS,			0x00000000},219	{CS35L36_VBBR_STATUS,			0x00000000},220	{CS35L36_OVERTEMP_CFG,			0x00000001},221	{CS35L36_AMP_ERR_VOL,			0x00000000},222	{CS35L36_CLASSH_CFG,			0x000B0405},223	{CS35L36_CLASSH_FET_DRV_CFG,		0x00000111},224	{CS35L36_NG_CFG,			0x00000033},225	{CS35L36_AMP_GAIN_CTRL,			0x00000273},226	{CS35L36_PWM_MOD_IO_CTRL,		0x00000000},227	{CS35L36_PWM_MOD_STATUS,		0x00000000},228	{CS35L36_DAC_MSM_CFG,			0x00000000},229	{CS35L36_AMP_SLOPE_CTRL,		0x00000B00},230	{CS35L36_AMP_PDM_VOLUME,		0x00000000},231	{CS35L36_AMP_PDM_RATE_CTRL,		0x00000000},232	{CS35L36_PDM_CH_SEL,			0x00000000},233	{CS35L36_AMP_NG_CTRL,			0x0000212F},234	{CS35L36_PDM_HIGHFILT_CTRL,		0x00000000},235	{CS35L36_PAC_INT0_CTRL,			0x00000001},236	{CS35L36_PAC_INT1_CTRL,			0x00000001},237	{CS35L36_PAC_INT2_CTRL,			0x00000001},238	{CS35L36_PAC_INT3_CTRL,			0x00000001},239	{CS35L36_PAC_INT4_CTRL,			0x00000001},240	{CS35L36_PAC_INT5_CTRL,			0x00000001},241	{CS35L36_PAC_INT6_CTRL,			0x00000001},242	{CS35L36_PAC_INT7_CTRL,			0x00000001},243};244 245static bool cs35l36_readable_reg(struct device *dev, unsigned int reg)246{247	switch (reg) {248	case CS35L36_SW_RESET:249	case CS35L36_SW_REV:250	case CS35L36_HW_REV:251	case CS35L36_TESTKEY_CTRL:252	case CS35L36_USERKEY_CTL:253	case CS35L36_OTP_MEM30:254	case CS35L36_OTP_CTRL1:255	case CS35L36_OTP_CTRL2:256	case CS35L36_OTP_CTRL3:257	case CS35L36_OTP_CTRL4:258	case CS35L36_OTP_CTRL5:259	case CS35L36_PAC_CTL1:260	case CS35L36_PAC_CTL2:261	case CS35L36_PAC_CTL3:262	case CS35L36_DEVICE_ID:263	case CS35L36_FAB_ID:264	case CS35L36_REV_ID:265	case CS35L36_PWR_CTRL1:266	case CS35L36_PWR_CTRL2:267	case CS35L36_PWR_CTRL3:268	case CS35L36_CTRL_OVRRIDE:269	case CS35L36_AMP_OUT_MUTE:270	case CS35L36_OTP_TRIM_STATUS:271	case CS35L36_DISCH_FILT:272	case CS35L36_PROTECT_REL_ERR:273	case CS35L36_PAD_INTERFACE:274	case CS35L36_PLL_CLK_CTRL:275	case CS35L36_GLOBAL_CLK_CTRL:276	case CS35L36_ADC_CLK_CTRL:277	case CS35L36_SWIRE_CLK_CTRL:278	case CS35L36_SP_SCLK_CLK_CTRL:279	case CS35L36_TST_FS_MON0:280	case CS35L36_MDSYNC_EN:281	case CS35L36_MDSYNC_TX_ID:282	case CS35L36_MDSYNC_PWR_CTRL:283	case CS35L36_MDSYNC_DATA_TX:284	case CS35L36_MDSYNC_TX_STATUS:285	case CS35L36_MDSYNC_RX_STATUS:286	case CS35L36_MDSYNC_ERR_STATUS:287	case CS35L36_BSTCVRT_VCTRL1:288	case CS35L36_BSTCVRT_VCTRL2:289	case CS35L36_BSTCVRT_PEAK_CUR:290	case CS35L36_BSTCVRT_SFT_RAMP:291	case CS35L36_BSTCVRT_COEFF:292	case CS35L36_BSTCVRT_SLOPE_LBST:293	case CS35L36_BSTCVRT_SW_FREQ:294	case CS35L36_BSTCVRT_DCM_CTRL:295	case CS35L36_BSTCVRT_DCM_MODE_FORCE:296	case CS35L36_BSTCVRT_OVERVOLT_CTRL:297	case CS35L36_BST_TST_MANUAL:298	case CS35L36_BST_ANA2_TEST:299	case CS35L36_VPI_LIMIT_MODE:300	case CS35L36_VPI_LIMIT_MINMAX:301	case CS35L36_VPI_VP_THLD:302	case CS35L36_VPI_TRACK_CTRL:303	case CS35L36_VPI_TRIG_MODE_CTRL:304	case CS35L36_VPI_TRIG_STEPS:305	case CS35L36_VI_SPKMON_FILT:306	case CS35L36_VI_SPKMON_GAIN:307	case CS35L36_VI_SPKMON_IP_SEL:308	case CS35L36_DTEMP_WARN_THLD:309	case CS35L36_DTEMP_STATUS:310	case CS35L36_VPVBST_FS_SEL:311	case CS35L36_VPVBST_VP_CTRL:312	case CS35L36_VPVBST_VBST_CTRL:313	case CS35L36_ASP_TX_PIN_CTRL:314	case CS35L36_ASP_RATE_CTRL:315	case CS35L36_ASP_FORMAT:316	case CS35L36_ASP_FRAME_CTRL:317	case CS35L36_ASP_TX1_TX2_SLOT:318	case CS35L36_ASP_TX3_TX4_SLOT:319	case CS35L36_ASP_TX5_TX6_SLOT:320	case CS35L36_ASP_TX7_TX8_SLOT:321	case CS35L36_ASP_RX1_SLOT:322	case CS35L36_ASP_RX_TX_EN:323	case CS35L36_ASP_RX1_SEL:324	case CS35L36_ASP_TX1_SEL:325	case CS35L36_ASP_TX2_SEL:326	case CS35L36_ASP_TX3_SEL:327	case CS35L36_ASP_TX4_SEL:328	case CS35L36_ASP_TX5_SEL:329	case CS35L36_ASP_TX6_SEL:330	case CS35L36_SWIRE_P1_TX1_SEL:331	case CS35L36_SWIRE_P1_TX2_SEL:332	case CS35L36_SWIRE_P2_TX1_SEL:333	case CS35L36_SWIRE_P2_TX2_SEL:334	case CS35L36_SWIRE_P2_TX3_SEL:335	case CS35L36_SWIRE_DP1_FIFO_CFG:336	case CS35L36_SWIRE_DP2_FIFO_CFG:337	case CS35L36_SWIRE_DP3_FIFO_CFG:338	case CS35L36_SWIRE_PCM_RX_DATA:339	case CS35L36_SWIRE_FS_SEL:340	case CS35L36_AMP_DIG_VOL_CTRL:341	case CS35L36_VPBR_CFG:342	case CS35L36_VBBR_CFG:343	case CS35L36_VPBR_STATUS:344	case CS35L36_VBBR_STATUS:345	case CS35L36_OVERTEMP_CFG:346	case CS35L36_AMP_ERR_VOL:347	case CS35L36_CLASSH_CFG:348	case CS35L36_CLASSH_FET_DRV_CFG:349	case CS35L36_NG_CFG:350	case CS35L36_AMP_GAIN_CTRL:351	case CS35L36_PWM_MOD_IO_CTRL:352	case CS35L36_PWM_MOD_STATUS:353	case CS35L36_DAC_MSM_CFG:354	case CS35L36_AMP_SLOPE_CTRL:355	case CS35L36_AMP_PDM_VOLUME:356	case CS35L36_AMP_PDM_RATE_CTRL:357	case CS35L36_PDM_CH_SEL:358	case CS35L36_AMP_NG_CTRL:359	case CS35L36_PDM_HIGHFILT_CTRL:360	case CS35L36_INT1_STATUS:361	case CS35L36_INT2_STATUS:362	case CS35L36_INT3_STATUS:363	case CS35L36_INT4_STATUS:364	case CS35L36_INT1_RAW_STATUS:365	case CS35L36_INT2_RAW_STATUS:366	case CS35L36_INT3_RAW_STATUS:367	case CS35L36_INT4_RAW_STATUS:368	case CS35L36_INT1_MASK:369	case CS35L36_INT2_MASK:370	case CS35L36_INT3_MASK:371	case CS35L36_INT4_MASK:372	case CS35L36_INT1_EDGE_LVL_CTRL:373	case CS35L36_INT3_EDGE_LVL_CTRL:374	case CS35L36_PAC_INT_STATUS:375	case CS35L36_PAC_INT_RAW_STATUS:376	case CS35L36_PAC_INT_FLUSH_CTRL:377	case CS35L36_PAC_INT0_CTRL:378	case CS35L36_PAC_INT1_CTRL:379	case CS35L36_PAC_INT2_CTRL:380	case CS35L36_PAC_INT3_CTRL:381	case CS35L36_PAC_INT4_CTRL:382	case CS35L36_PAC_INT5_CTRL:383	case CS35L36_PAC_INT6_CTRL:384	case CS35L36_PAC_INT7_CTRL:385		return true;386	default:387		if (reg >= CS35L36_PAC_PMEM_WORD0 &&388			reg <= CS35L36_PAC_PMEM_WORD1023)389			return true;390		else391			return false;392	}393}394 395static bool cs35l36_precious_reg(struct device *dev, unsigned int reg)396{397	switch (reg) {398	case CS35L36_TESTKEY_CTRL:399	case CS35L36_USERKEY_CTL:400	case CS35L36_TST_FS_MON0:401		return true;402	default:403		return false;404	}405}406 407static bool cs35l36_volatile_reg(struct device *dev, unsigned int reg)408{409	switch (reg) {410	case CS35L36_SW_RESET:411	case CS35L36_SW_REV:412	case CS35L36_HW_REV:413	case CS35L36_TESTKEY_CTRL:414	case CS35L36_USERKEY_CTL:415	case CS35L36_DEVICE_ID:416	case CS35L36_FAB_ID:417	case CS35L36_REV_ID:418	case CS35L36_INT1_STATUS:419	case CS35L36_INT2_STATUS:420	case CS35L36_INT3_STATUS:421	case CS35L36_INT4_STATUS:422	case CS35L36_INT1_RAW_STATUS:423	case CS35L36_INT2_RAW_STATUS:424	case CS35L36_INT3_RAW_STATUS:425	case CS35L36_INT4_RAW_STATUS:426	case CS35L36_INT1_MASK:427	case CS35L36_INT2_MASK:428	case CS35L36_INT3_MASK:429	case CS35L36_INT4_MASK:430	case CS35L36_INT1_EDGE_LVL_CTRL:431	case CS35L36_INT3_EDGE_LVL_CTRL:432	case CS35L36_PAC_INT_STATUS:433	case CS35L36_PAC_INT_RAW_STATUS:434	case CS35L36_PAC_INT_FLUSH_CTRL:435		return true;436	default:437		if (reg >= CS35L36_PAC_PMEM_WORD0 &&438			reg <= CS35L36_PAC_PMEM_WORD1023)439			return true;440		else441			return false;442	}443}444 445static const DECLARE_TLV_DB_RANGE(dig_vol_tlv, 0, 912,446				  TLV_DB_MINMAX_ITEM(-10200, 1200));447static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1);448 449static const char * const cs35l36_pcm_sftramp_text[] =  {450	"Off", ".5ms", "1ms", "2ms", "4ms", "8ms", "15ms", "30ms"};451 452static SOC_ENUM_SINGLE_DECL(pcm_sft_ramp, CS35L36_AMP_DIG_VOL_CTRL, 0,453			    cs35l36_pcm_sftramp_text);454 455static int cs35l36_ldm_sel_get(struct snd_kcontrol *kcontrol,456			       struct snd_ctl_elem_value *ucontrol)457{458	struct snd_soc_component *component =459			snd_soc_kcontrol_component(kcontrol);460	struct cs35l36_private *cs35l36 =461			snd_soc_component_get_drvdata(component);462 463	ucontrol->value.integer.value[0] = cs35l36->ldm_mode_sel;464 465	return 0;466}467 468static int cs35l36_ldm_sel_put(struct snd_kcontrol *kcontrol,469			       struct snd_ctl_elem_value *ucontrol)470{471	struct snd_soc_component *component =472			snd_soc_kcontrol_component(kcontrol);473	struct cs35l36_private *cs35l36 =474			snd_soc_component_get_drvdata(component);475	int val = (ucontrol->value.integer.value[0]) ? CS35L36_NG_AMP_EN_MASK :476						       0;477 478	cs35l36->ldm_mode_sel = val;479 480	regmap_update_bits(cs35l36->regmap, CS35L36_NG_CFG,481			   CS35L36_NG_AMP_EN_MASK, val);482 483	return 0;484}485 486static const struct snd_kcontrol_new cs35l36_aud_controls[] = {487	SOC_SINGLE_SX_TLV("Digital PCM Volume", CS35L36_AMP_DIG_VOL_CTRL,488		3, 0x4D0, 0x390, dig_vol_tlv),489	SOC_SINGLE_TLV("Analog PCM Volume", CS35L36_AMP_GAIN_CTRL, 5, 0x13, 0,490		amp_gain_tlv),491	SOC_ENUM("PCM Soft Ramp", pcm_sft_ramp),492	SOC_SINGLE("Amp Gain Zero-Cross Switch", CS35L36_AMP_GAIN_CTRL,493		CS35L36_AMP_ZC_SHIFT, 1, 0),494	SOC_SINGLE("PDM LDM Enter Ramp Switch", CS35L36_DAC_MSM_CFG,495		CS35L36_PDM_LDM_ENTER_SHIFT, 1, 0),496	SOC_SINGLE("PDM LDM Exit Ramp Switch", CS35L36_DAC_MSM_CFG,497		CS35L36_PDM_LDM_EXIT_SHIFT, 1, 0),498	SOC_SINGLE_BOOL_EXT("LDM Select Switch", 0, cs35l36_ldm_sel_get,499		cs35l36_ldm_sel_put),500};501 502static int cs35l36_main_amp_event(struct snd_soc_dapm_widget *w,503				  struct snd_kcontrol *kcontrol, int event)504{505	struct snd_soc_component *component =506			snd_soc_dapm_to_component(w->dapm);507	struct cs35l36_private *cs35l36 =508			snd_soc_component_get_drvdata(component);509	u32 reg;510 511	switch (event) {512	case SND_SOC_DAPM_POST_PMU:513		regmap_update_bits(cs35l36->regmap, CS35L36_PWR_CTRL1,514				   CS35L36_GLOBAL_EN_MASK,515				   1 << CS35L36_GLOBAL_EN_SHIFT);516 517		usleep_range(2000, 2100);518 519		regmap_read(cs35l36->regmap, CS35L36_INT4_RAW_STATUS, &reg);520 521		if (WARN_ON_ONCE(reg & CS35L36_PLL_UNLOCK_MASK))522			dev_crit(cs35l36->dev, "PLL Unlocked\n");523 524		regmap_update_bits(cs35l36->regmap, CS35L36_ASP_RX1_SEL,525				   CS35L36_PCM_RX_SEL_MASK,526				   CS35L36_PCM_RX_SEL_PCM);527		regmap_update_bits(cs35l36->regmap, CS35L36_AMP_OUT_MUTE,528				   CS35L36_AMP_MUTE_MASK,529				   0 << CS35L36_AMP_MUTE_SHIFT);530		break;531	case SND_SOC_DAPM_PRE_PMD:532		regmap_update_bits(cs35l36->regmap, CS35L36_ASP_RX1_SEL,533				   CS35L36_PCM_RX_SEL_MASK,534				   CS35L36_PCM_RX_SEL_ZERO);535		regmap_update_bits(cs35l36->regmap, CS35L36_AMP_OUT_MUTE,536				   CS35L36_AMP_MUTE_MASK,537				   1 << CS35L36_AMP_MUTE_SHIFT);538		break;539	case SND_SOC_DAPM_POST_PMD:540		regmap_update_bits(cs35l36->regmap, CS35L36_PWR_CTRL1,541				   CS35L36_GLOBAL_EN_MASK,542				   0 << CS35L36_GLOBAL_EN_SHIFT);543 544		usleep_range(2000, 2100);545		break;546	default:547		dev_dbg(component->dev, "Invalid event = 0x%x\n", event);548		return -EINVAL;549	}550 551	return 0;552}553 554static int cs35l36_boost_event(struct snd_soc_dapm_widget *w,555			       struct snd_kcontrol *kcontrol, int event)556{557	struct snd_soc_component *component =558			snd_soc_dapm_to_component(w->dapm);559	struct cs35l36_private *cs35l36 =560			snd_soc_component_get_drvdata(component);561 562	switch (event) {563	case SND_SOC_DAPM_POST_PMU:564		if (!cs35l36->pdata.extern_boost)565			regmap_update_bits(cs35l36->regmap, CS35L36_PWR_CTRL2,566					   CS35L36_BST_EN_MASK,567					   CS35L36_BST_EN <<568					   CS35L36_BST_EN_SHIFT);569		break;570	case SND_SOC_DAPM_POST_PMD:571		if (!cs35l36->pdata.extern_boost)572			regmap_update_bits(cs35l36->regmap, CS35L36_PWR_CTRL2,573					   CS35L36_BST_EN_MASK,574					   CS35L36_BST_DIS_VP <<575					   CS35L36_BST_EN_SHIFT);576		break;577	default:578		dev_dbg(component->dev, "Invalid event = 0x%x\n", event);579		return -EINVAL;580	}581 582	return 0;583}584 585static const char * const cs35l36_chan_text[] = {586	"RX1",587	"RX2",588};589 590static SOC_ENUM_SINGLE_DECL(chansel_enum, CS35L36_ASP_RX1_SLOT, 0,591			    cs35l36_chan_text);592 593static const struct snd_kcontrol_new cs35l36_chan_mux =594		SOC_DAPM_ENUM("Input Mux", chansel_enum);595 596static const struct snd_kcontrol_new amp_enable_ctrl =597		SOC_DAPM_SINGLE_AUTODISABLE("Switch", CS35L36_AMP_OUT_MUTE,598					    CS35L36_AMP_MUTE_SHIFT, 1, 1);599 600static const struct snd_kcontrol_new boost_ctrl =601		SOC_DAPM_SINGLE_VIRT("Switch", 1);602 603static const char * const asp_tx_src_text[] = {604	"Zero Fill", "ASPRX1", "VMON", "IMON", "ERRVOL", "VPMON", "VBSTMON"605};606 607static const unsigned int asp_tx_src_values[] = {608	0x00, 0x08, 0x18, 0x19, 0x20, 0x28, 0x29609};610 611static SOC_VALUE_ENUM_SINGLE_DECL(asp_tx1_src_enum, CS35L36_ASP_TX1_SEL, 0,612				  CS35L36_APS_TX_SEL_MASK, asp_tx_src_text,613				  asp_tx_src_values);614 615static const struct snd_kcontrol_new asp_tx1_src =616		SOC_DAPM_ENUM("ASPTX1SRC", asp_tx1_src_enum);617 618static SOC_VALUE_ENUM_SINGLE_DECL(asp_tx2_src_enum, CS35L36_ASP_TX2_SEL, 0,619				  CS35L36_APS_TX_SEL_MASK, asp_tx_src_text,620				  asp_tx_src_values);621 622static const struct snd_kcontrol_new asp_tx2_src =623		SOC_DAPM_ENUM("ASPTX2SRC", asp_tx2_src_enum);624 625static SOC_VALUE_ENUM_SINGLE_DECL(asp_tx3_src_enum, CS35L36_ASP_TX3_SEL, 0,626				  CS35L36_APS_TX_SEL_MASK, asp_tx_src_text,627				  asp_tx_src_values);628 629static const struct snd_kcontrol_new asp_tx3_src =630		SOC_DAPM_ENUM("ASPTX3SRC", asp_tx3_src_enum);631 632static SOC_VALUE_ENUM_SINGLE_DECL(asp_tx4_src_enum, CS35L36_ASP_TX4_SEL, 0,633				  CS35L36_APS_TX_SEL_MASK, asp_tx_src_text,634				  asp_tx_src_values);635 636static const struct snd_kcontrol_new asp_tx4_src =637		SOC_DAPM_ENUM("ASPTX4SRC", asp_tx4_src_enum);638 639static SOC_VALUE_ENUM_SINGLE_DECL(asp_tx5_src_enum, CS35L36_ASP_TX5_SEL, 0,640				  CS35L36_APS_TX_SEL_MASK, asp_tx_src_text,641				  asp_tx_src_values);642 643static const struct snd_kcontrol_new asp_tx5_src =644		SOC_DAPM_ENUM("ASPTX5SRC", asp_tx5_src_enum);645 646static SOC_VALUE_ENUM_SINGLE_DECL(asp_tx6_src_enum, CS35L36_ASP_TX6_SEL, 0,647				  CS35L36_APS_TX_SEL_MASK, asp_tx_src_text,648				  asp_tx_src_values);649 650static const struct snd_kcontrol_new asp_tx6_src =651		SOC_DAPM_ENUM("ASPTX6SRC", asp_tx6_src_enum);652 653static const struct snd_soc_dapm_widget cs35l36_dapm_widgets[] = {654	SND_SOC_DAPM_MUX("Channel Mux", SND_SOC_NOPM, 0, 0, &cs35l36_chan_mux),655	SND_SOC_DAPM_AIF_IN("SDIN", NULL, 0, CS35L36_ASP_RX_TX_EN, 16, 0),656 657	SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L36_PWR_CTRL2, 0, 0, NULL, 0,658			       cs35l36_main_amp_event, SND_SOC_DAPM_POST_PMD |659			       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),660 661	SND_SOC_DAPM_OUTPUT("SPK"),662	SND_SOC_DAPM_SWITCH("AMP Enable", SND_SOC_NOPM, 0, 1, &amp_enable_ctrl),663	SND_SOC_DAPM_MIXER("CLASS H", CS35L36_PWR_CTRL3, 4, 0, NULL, 0),664	SND_SOC_DAPM_SWITCH_E("BOOST Enable", SND_SOC_NOPM, 0, 0, &boost_ctrl,665			      cs35l36_boost_event, SND_SOC_DAPM_POST_PMD |666			      SND_SOC_DAPM_POST_PMU),667 668	SND_SOC_DAPM_AIF_OUT("ASPTX1", NULL, 0, CS35L36_ASP_RX_TX_EN, 0, 0),669	SND_SOC_DAPM_AIF_OUT("ASPTX2", NULL, 1, CS35L36_ASP_RX_TX_EN, 1, 0),670	SND_SOC_DAPM_AIF_OUT("ASPTX3", NULL, 2, CS35L36_ASP_RX_TX_EN, 2, 0),671	SND_SOC_DAPM_AIF_OUT("ASPTX4", NULL, 3, CS35L36_ASP_RX_TX_EN, 3, 0),672	SND_SOC_DAPM_AIF_OUT("ASPTX5", NULL, 4, CS35L36_ASP_RX_TX_EN, 4, 0),673	SND_SOC_DAPM_AIF_OUT("ASPTX6", NULL, 5, CS35L36_ASP_RX_TX_EN, 5, 0),674 675	SND_SOC_DAPM_MUX("ASPTX1SRC", SND_SOC_NOPM, 0, 0, &asp_tx1_src),676	SND_SOC_DAPM_MUX("ASPTX2SRC", SND_SOC_NOPM, 0, 0, &asp_tx2_src),677	SND_SOC_DAPM_MUX("ASPTX3SRC", SND_SOC_NOPM, 0, 0, &asp_tx3_src),678	SND_SOC_DAPM_MUX("ASPTX4SRC", SND_SOC_NOPM, 0, 0, &asp_tx4_src),679	SND_SOC_DAPM_MUX("ASPTX5SRC", SND_SOC_NOPM, 0, 0, &asp_tx5_src),680	SND_SOC_DAPM_MUX("ASPTX6SRC", SND_SOC_NOPM, 0, 0, &asp_tx6_src),681 682	SND_SOC_DAPM_ADC("VMON ADC", NULL, CS35L36_PWR_CTRL2, 12, 0),683	SND_SOC_DAPM_ADC("IMON ADC", NULL, CS35L36_PWR_CTRL2, 13, 0),684	SND_SOC_DAPM_ADC("VPMON ADC", NULL, CS35L36_PWR_CTRL2, 8, 0),685	SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, CS35L36_PWR_CTRL2, 9, 0),686 687	SND_SOC_DAPM_INPUT("VP"),688	SND_SOC_DAPM_INPUT("VBST"),689	SND_SOC_DAPM_INPUT("VSENSE"),690};691 692static const struct snd_soc_dapm_route cs35l36_audio_map[] = {693	{"VPMON ADC", NULL, "VP"},694	{"VBSTMON ADC", NULL, "VBST"},695	{"IMON ADC", NULL, "VSENSE"},696	{"VMON ADC", NULL, "VSENSE"},697 698	{"ASPTX1SRC", "IMON", "IMON ADC"},699	{"ASPTX1SRC", "VMON", "VMON ADC"},700	{"ASPTX1SRC", "VBSTMON", "VBSTMON ADC"},701	{"ASPTX1SRC", "VPMON", "VPMON ADC"},702 703	{"ASPTX2SRC", "IMON", "IMON ADC"},704	{"ASPTX2SRC", "VMON", "VMON ADC"},705	{"ASPTX2SRC", "VBSTMON", "VBSTMON ADC"},706	{"ASPTX2SRC", "VPMON", "VPMON ADC"},707 708	{"ASPTX3SRC", "IMON", "IMON ADC"},709	{"ASPTX3SRC", "VMON", "VMON ADC"},710	{"ASPTX3SRC", "VBSTMON", "VBSTMON ADC"},711	{"ASPTX3SRC", "VPMON", "VPMON ADC"},712 713	{"ASPTX4SRC", "IMON", "IMON ADC"},714	{"ASPTX4SRC", "VMON", "VMON ADC"},715	{"ASPTX4SRC", "VBSTMON", "VBSTMON ADC"},716	{"ASPTX4SRC", "VPMON", "VPMON ADC"},717 718	{"ASPTX5SRC", "IMON", "IMON ADC"},719	{"ASPTX5SRC", "VMON", "VMON ADC"},720	{"ASPTX5SRC", "VBSTMON", "VBSTMON ADC"},721	{"ASPTX5SRC", "VPMON", "VPMON ADC"},722 723	{"ASPTX6SRC", "IMON", "IMON ADC"},724	{"ASPTX6SRC", "VMON", "VMON ADC"},725	{"ASPTX6SRC", "VBSTMON", "VBSTMON ADC"},726	{"ASPTX6SRC", "VPMON", "VPMON ADC"},727 728	{"ASPTX1", NULL, "ASPTX1SRC"},729	{"ASPTX2", NULL, "ASPTX2SRC"},730	{"ASPTX3", NULL, "ASPTX3SRC"},731	{"ASPTX4", NULL, "ASPTX4SRC"},732	{"ASPTX5", NULL, "ASPTX5SRC"},733	{"ASPTX6", NULL, "ASPTX6SRC"},734 735	{"AMP Capture", NULL, "ASPTX1"},736	{"AMP Capture", NULL, "ASPTX2"},737	{"AMP Capture", NULL, "ASPTX3"},738	{"AMP Capture", NULL, "ASPTX4"},739	{"AMP Capture", NULL, "ASPTX5"},740	{"AMP Capture", NULL, "ASPTX6"},741 742	{"AMP Enable", "Switch", "AMP Playback"},743	{"SDIN", NULL, "AMP Enable"},744	{"Channel Mux", "RX1", "SDIN"},745	{"Channel Mux", "RX2", "SDIN"},746	{"BOOST Enable", "Switch", "Channel Mux"},747	{"CLASS H", NULL, "BOOST Enable"},748	{"Main AMP", NULL, "Channel Mux"},749	{"Main AMP", NULL, "CLASS H"},750	{"SPK", NULL, "Main AMP"},751};752 753static int cs35l36_set_dai_fmt(struct snd_soc_dai *component_dai,754			       unsigned int fmt)755{756	struct cs35l36_private *cs35l36 =757			snd_soc_component_get_drvdata(component_dai->component);758	unsigned int asp_fmt, lrclk_fmt, sclk_fmt, clock_provider, clk_frc;759 760	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {761	case SND_SOC_DAIFMT_CBP_CFP:762		clock_provider = 1;763		break;764	case SND_SOC_DAIFMT_CBC_CFC:765		clock_provider = 0;766		break;767	default:768		return -EINVAL;769	}770 771	regmap_update_bits(cs35l36->regmap, CS35L36_ASP_TX_PIN_CTRL,772				CS35L36_SCLK_MSTR_MASK,773				clock_provider << CS35L36_SCLK_MSTR_SHIFT);774	regmap_update_bits(cs35l36->regmap, CS35L36_ASP_RATE_CTRL,775				CS35L36_LRCLK_MSTR_MASK,776				clock_provider << CS35L36_LRCLK_MSTR_SHIFT);777 778	switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) {779	case SND_SOC_DAIFMT_CONT:780		clk_frc = 1;781		break;782	case SND_SOC_DAIFMT_GATED:783		clk_frc = 0;784		break;785	default:786		return -EINVAL;787	}788 789	regmap_update_bits(cs35l36->regmap, CS35L36_ASP_TX_PIN_CTRL,790			   CS35L36_SCLK_FRC_MASK, clk_frc <<791			   CS35L36_SCLK_FRC_SHIFT);792	regmap_update_bits(cs35l36->regmap, CS35L36_ASP_RATE_CTRL,793			   CS35L36_LRCLK_FRC_MASK, clk_frc <<794			   CS35L36_LRCLK_FRC_SHIFT);795 796	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {797	case SND_SOC_DAIFMT_DSP_A:798		asp_fmt = 0;799		break;800	case SND_SOC_DAIFMT_I2S:801		asp_fmt = 2;802		break;803	default:804		return -EINVAL;805	}806 807	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {808	case SND_SOC_DAIFMT_NB_IF:809		lrclk_fmt = 1;810		sclk_fmt = 0;811		break;812	case SND_SOC_DAIFMT_IB_NF:813		lrclk_fmt = 0;814		sclk_fmt = 1;815		break;816	case SND_SOC_DAIFMT_IB_IF:817		lrclk_fmt = 1;818		sclk_fmt = 1;819		break;820	case SND_SOC_DAIFMT_NB_NF:821		lrclk_fmt = 0;822		sclk_fmt = 0;823		break;824	default:825		return -EINVAL;826	}827 828	regmap_update_bits(cs35l36->regmap, CS35L36_ASP_RATE_CTRL,829			   CS35L36_LRCLK_INV_MASK,830			   lrclk_fmt << CS35L36_LRCLK_INV_SHIFT);831	regmap_update_bits(cs35l36->regmap, CS35L36_ASP_TX_PIN_CTRL,832			   CS35L36_SCLK_INV_MASK,833			   sclk_fmt << CS35L36_SCLK_INV_SHIFT);834	regmap_update_bits(cs35l36->regmap, CS35L36_ASP_FORMAT,835			   CS35L36_ASP_FMT_MASK, asp_fmt);836 837	return 0;838}839 840struct cs35l36_global_fs_config {841	int rate;842	int fs_cfg;843};844 845static const struct cs35l36_global_fs_config cs35l36_fs_rates[] = {846	{12000, 0x01},847	{24000, 0x02},848	{48000, 0x03},849	{96000, 0x04},850	{192000, 0x05},851	{384000, 0x06},852	{11025, 0x09},853	{22050, 0x0A},854	{44100, 0x0B},855	{88200, 0x0C},856	{176400, 0x0D},857	{8000, 0x11},858	{16000, 0x12},859	{32000, 0x13},860};861 862static int cs35l36_pcm_hw_params(struct snd_pcm_substream *substream,863				 struct snd_pcm_hw_params *params,864				 struct snd_soc_dai *dai)865{866	struct cs35l36_private *cs35l36 =867			snd_soc_component_get_drvdata(dai->component);868	unsigned int asp_width, global_fs = params_rate(params);869	int i;870 871	for (i = 0; i < ARRAY_SIZE(cs35l36_fs_rates); i++) {872		if (global_fs == cs35l36_fs_rates[i].rate)873			regmap_update_bits(cs35l36->regmap,874					   CS35L36_GLOBAL_CLK_CTRL,875					   CS35L36_GLOBAL_FS_MASK,876					   cs35l36_fs_rates[i].fs_cfg <<877					   CS35L36_GLOBAL_FS_SHIFT);878	}879 880	switch (params_width(params)) {881	case 16:882		asp_width = CS35L36_ASP_WIDTH_16;883		break;884	case 24:885		asp_width = CS35L36_ASP_WIDTH_24;886		break;887	case 32:888		asp_width = CS35L36_ASP_WIDTH_32;889		break;890	default:891		return -EINVAL;892	}893 894	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {895		regmap_update_bits(cs35l36->regmap, CS35L36_ASP_FRAME_CTRL,896				   CS35L36_ASP_RX_WIDTH_MASK,897				   asp_width << CS35L36_ASP_RX_WIDTH_SHIFT);898	} else {899		regmap_update_bits(cs35l36->regmap, CS35L36_ASP_FRAME_CTRL,900				   CS35L36_ASP_TX_WIDTH_MASK,901				   asp_width << CS35L36_ASP_TX_WIDTH_SHIFT);902	}903 904	return 0;905}906 907static int cs35l36_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,908				  unsigned int freq, int dir)909{910	struct snd_soc_component *component = dai->component;911	struct cs35l36_private *cs35l36 =912			snd_soc_component_get_drvdata(component);913	int fs1, fs2;914 915	if (freq > CS35L36_FS_NOM_6MHZ) {916		fs1 = CS35L36_FS1_DEFAULT_VAL;917		fs2 = CS35L36_FS2_DEFAULT_VAL;918	} else {919		fs1 = 3 * DIV_ROUND_UP(CS35L36_FS_NOM_6MHZ * 4, freq) + 4;920		fs2 = 5 * DIV_ROUND_UP(CS35L36_FS_NOM_6MHZ * 4, freq) + 4;921	}922 923	regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,924			CS35L36_TEST_UNLOCK1);925	regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,926			CS35L36_TEST_UNLOCK2);927 928	regmap_update_bits(cs35l36->regmap, CS35L36_TST_FS_MON0,929			   CS35L36_FS1_WINDOW_MASK | CS35L36_FS2_WINDOW_MASK,930			   fs1 | (fs2 << CS35L36_FS2_WINDOW_SHIFT));931 932	regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,933			CS35L36_TEST_LOCK1);934	regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,935			CS35L36_TEST_LOCK2);936	return 0;937}938 939static const struct cs35l36_pll_config *cs35l36_get_clk_config(940		struct cs35l36_private *cs35l36, int freq)941{942	int i;943 944	for (i = 0; i < ARRAY_SIZE(cs35l36_pll_sysclk); i++) {945		if (cs35l36_pll_sysclk[i].freq == freq)946			return &cs35l36_pll_sysclk[i];947	}948 949	return NULL;950}951 952static const struct snd_soc_dai_ops cs35l36_ops = {953	.set_fmt = cs35l36_set_dai_fmt,954	.hw_params = cs35l36_pcm_hw_params,955	.set_sysclk = cs35l36_dai_set_sysclk,956};957 958#define CS35L36_RATES (		    \959	SNDRV_PCM_RATE_8000_48000 | \960	SNDRV_PCM_RATE_12000 |	    \961	SNDRV_PCM_RATE_24000 |	    \962	SNDRV_PCM_RATE_88200 |	    \963	SNDRV_PCM_RATE_96000 |	    \964	SNDRV_PCM_RATE_176400 |	    \965	SNDRV_PCM_RATE_192000 |	    \966	SNDRV_PCM_RATE_384000)967 968static struct snd_soc_dai_driver cs35l36_dai[] = {969	{970		.name = "cs35l36-pcm",971		.id = 0,972		.playback = {973			.stream_name = "AMP Playback",974			.channels_min = 1,975			.channels_max = 8,976			.rates = CS35L36_RATES,977			.formats = CS35L36_RX_FORMATS,978		},979		.capture = {980			.stream_name = "AMP Capture",981			.channels_min = 1,982			.channels_max = 8,983			.rates = CS35L36_RATES,984			.formats = CS35L36_TX_FORMATS,985		},986		.ops = &cs35l36_ops,987		.symmetric_rate = 1,988	},989};990 991static int cs35l36_component_set_sysclk(struct snd_soc_component *component,992				int clk_id, int source, unsigned int freq,993				int dir)994{995	struct cs35l36_private *cs35l36 =996			snd_soc_component_get_drvdata(component);997	const struct cs35l36_pll_config *clk_cfg;998	int prev_clksrc;999	bool pdm_switch;1000 1001	prev_clksrc = cs35l36->clksrc;1002 1003	switch (clk_id) {1004	case 0:1005		cs35l36->clksrc = CS35L36_PLLSRC_SCLK;1006		break;1007	case 1:1008		cs35l36->clksrc = CS35L36_PLLSRC_LRCLK;1009		break;1010	case 2:1011		cs35l36->clksrc = CS35L36_PLLSRC_PDMCLK;1012		break;1013	case 3:1014		cs35l36->clksrc = CS35L36_PLLSRC_SELF;1015		break;1016	case 4:1017		cs35l36->clksrc = CS35L36_PLLSRC_MCLK;1018		break;1019	default:1020		return -EINVAL;1021	}1022 1023	clk_cfg = cs35l36_get_clk_config(cs35l36, freq);1024	if (clk_cfg == NULL) {1025		dev_err(component->dev, "Invalid CLK Config Freq: %d\n", freq);1026		return -EINVAL;1027	}1028 1029	regmap_update_bits(cs35l36->regmap, CS35L36_PLL_CLK_CTRL,1030			   CS35L36_PLL_OPENLOOP_MASK,1031			   1 << CS35L36_PLL_OPENLOOP_SHIFT);1032	regmap_update_bits(cs35l36->regmap, CS35L36_PLL_CLK_CTRL,1033			   CS35L36_REFCLK_FREQ_MASK,1034			   clk_cfg->clk_cfg << CS35L36_REFCLK_FREQ_SHIFT);1035	regmap_update_bits(cs35l36->regmap, CS35L36_PLL_CLK_CTRL,1036			   CS35L36_PLL_REFCLK_EN_MASK,1037			   0 << CS35L36_PLL_REFCLK_EN_SHIFT);1038	regmap_update_bits(cs35l36->regmap, CS35L36_PLL_CLK_CTRL,1039			   CS35L36_PLL_CLK_SEL_MASK,1040			   cs35l36->clksrc);1041	regmap_update_bits(cs35l36->regmap, CS35L36_PLL_CLK_CTRL,1042			   CS35L36_PLL_OPENLOOP_MASK,1043			   0 << CS35L36_PLL_OPENLOOP_SHIFT);1044	regmap_update_bits(cs35l36->regmap, CS35L36_PLL_CLK_CTRL,1045			   CS35L36_PLL_REFCLK_EN_MASK,1046			   1 << CS35L36_PLL_REFCLK_EN_SHIFT);1047 1048	if (cs35l36->rev_id == CS35L36_REV_A0) {1049		regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,1050			     CS35L36_TEST_UNLOCK1);1051		regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,1052			     CS35L36_TEST_UNLOCK2);1053 1054		regmap_write(cs35l36->regmap, CS35L36_DCO_CTRL, 0x00036DA8);1055		regmap_write(cs35l36->regmap, CS35L36_MISC_CTRL, 0x0100EE0E);1056 1057		regmap_update_bits(cs35l36->regmap, CS35L36_PLL_LOOP_PARAMS,1058				   CS35L36_PLL_IGAIN_MASK,1059				   CS35L36_PLL_IGAIN <<1060				   CS35L36_PLL_IGAIN_SHIFT);1061		regmap_update_bits(cs35l36->regmap, CS35L36_PLL_LOOP_PARAMS,1062				   CS35L36_PLL_FFL_IGAIN_MASK,1063				   clk_cfg->fll_igain);1064 1065		regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,1066			     CS35L36_TEST_LOCK1);1067		regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,1068			     CS35L36_TEST_LOCK2);1069	}1070 1071	if (cs35l36->clksrc == CS35L36_PLLSRC_PDMCLK) {1072		pdm_switch = cs35l36->ldm_mode_sel &&1073			     (prev_clksrc != CS35L36_PLLSRC_PDMCLK);1074 1075		if (pdm_switch)1076			regmap_update_bits(cs35l36->regmap, CS35L36_NG_CFG,1077					   CS35L36_NG_DELAY_MASK,1078					   0 << CS35L36_NG_DELAY_SHIFT);1079 1080		regmap_update_bits(cs35l36->regmap, CS35L36_DAC_MSM_CFG,1081				   CS35L36_PDM_MODE_MASK,1082				   1 << CS35L36_PDM_MODE_SHIFT);1083 1084		if (pdm_switch)1085			regmap_update_bits(cs35l36->regmap, CS35L36_NG_CFG,1086					   CS35L36_NG_DELAY_MASK,1087					   3 << CS35L36_NG_DELAY_SHIFT);1088	} else {1089		pdm_switch = cs35l36->ldm_mode_sel &&1090			     (prev_clksrc == CS35L36_PLLSRC_PDMCLK);1091 1092		if (pdm_switch)1093			regmap_update_bits(cs35l36->regmap, CS35L36_NG_CFG,1094					   CS35L36_NG_DELAY_MASK,1095					   0 << CS35L36_NG_DELAY_SHIFT);1096 1097		regmap_update_bits(cs35l36->regmap, CS35L36_DAC_MSM_CFG,1098				   CS35L36_PDM_MODE_MASK,1099				   0 << CS35L36_PDM_MODE_SHIFT);1100 1101		if (pdm_switch)1102			regmap_update_bits(cs35l36->regmap, CS35L36_NG_CFG,1103					   CS35L36_NG_DELAY_MASK,1104					   3 << CS35L36_NG_DELAY_SHIFT);1105	}1106 1107	return 0;1108}1109 1110static int cs35l36_boost_inductor(struct cs35l36_private *cs35l36, int inductor)1111{1112	regmap_update_bits(cs35l36->regmap, CS35L36_BSTCVRT_COEFF,1113			   CS35L36_BSTCVRT_K1_MASK, 0x3C);1114	regmap_update_bits(cs35l36->regmap, CS35L36_BSTCVRT_COEFF,1115			   CS35L36_BSTCVRT_K2_MASK,1116			   0x3C << CS35L36_BSTCVRT_K2_SHIFT);1117	regmap_update_bits(cs35l36->regmap, CS35L36_BSTCVRT_SW_FREQ,1118			   CS35L36_BSTCVRT_CCMFREQ_MASK, 0x00);1119 1120	switch (inductor) {1121	case 1000: /* 1 uH */1122		regmap_update_bits(cs35l36->regmap, CS35L36_BSTCVRT_SLOPE_LBST,1123				   CS35L36_BSTCVRT_SLOPE_MASK,1124				   0x75 << CS35L36_BSTCVRT_SLOPE_SHIFT);1125		regmap_update_bits(cs35l36->regmap, CS35L36_BSTCVRT_SLOPE_LBST,1126				   CS35L36_BSTCVRT_LBSTVAL_MASK, 0x00);1127		break;1128	case 1200: /* 1.2 uH */1129		regmap_update_bits(cs35l36->regmap, CS35L36_BSTCVRT_SLOPE_LBST,1130				   CS35L36_BSTCVRT_SLOPE_MASK,1131				   0x6B << CS35L36_BSTCVRT_SLOPE_SHIFT);1132		regmap_update_bits(cs35l36->regmap, CS35L36_BSTCVRT_SLOPE_LBST,1133				   CS35L36_BSTCVRT_LBSTVAL_MASK, 0x01);1134		break;1135	default:1136		dev_err(cs35l36->dev, "%s Invalid Inductor Value %d uH\n",1137			__func__, inductor);1138		return -EINVAL;1139	}1140 1141	return 0;1142}1143 1144static int cs35l36_component_probe(struct snd_soc_component *component)1145{1146	struct cs35l36_private *cs35l36 =1147			snd_soc_component_get_drvdata(component);1148	int ret;1149 1150	if ((cs35l36->rev_id == CS35L36_REV_A0) && cs35l36->pdata.dcm_mode) {1151		regmap_update_bits(cs35l36->regmap, CS35L36_BSTCVRT_DCM_CTRL,1152				   CS35L36_DCM_AUTO_MASK,1153				   CS35L36_DCM_AUTO_MASK);1154 1155		regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,1156			     CS35L36_TEST_UNLOCK1);1157		regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,1158			     CS35L36_TEST_UNLOCK2);1159 1160		regmap_update_bits(cs35l36->regmap, CS35L36_BST_TST_MANUAL,1161				   CS35L36_BST_MAN_IPKCOMP_MASK,1162				   0 << CS35L36_BST_MAN_IPKCOMP_SHIFT);1163		regmap_update_bits(cs35l36->regmap, CS35L36_BST_TST_MANUAL,1164				   CS35L36_BST_MAN_IPKCOMP_EN_MASK,1165				   CS35L36_BST_MAN_IPKCOMP_EN_MASK);1166 1167		regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,1168				CS35L36_TEST_LOCK1);1169		regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,1170				CS35L36_TEST_LOCK2);1171	}1172 1173	if (cs35l36->pdata.amp_pcm_inv)1174		regmap_update_bits(cs35l36->regmap, CS35L36_AMP_DIG_VOL_CTRL,1175				   CS35L36_AMP_PCM_INV_MASK,1176				   CS35L36_AMP_PCM_INV_MASK);1177 1178	if (cs35l36->pdata.multi_amp_mode)1179		regmap_update_bits(cs35l36->regmap, CS35L36_ASP_TX_PIN_CTRL,1180				   CS35L36_ASP_TX_HIZ_MASK,1181				   CS35L36_ASP_TX_HIZ_MASK);1182 1183	if (cs35l36->pdata.imon_pol_inv)1184		regmap_update_bits(cs35l36->regmap, CS35L36_VI_SPKMON_FILT,1185				   CS35L36_IMON_POL_MASK, 0);1186 1187	if (cs35l36->pdata.vmon_pol_inv)1188		regmap_update_bits(cs35l36->regmap, CS35L36_VI_SPKMON_FILT,1189				   CS35L36_VMON_POL_MASK, 0);1190 1191	if (cs35l36->pdata.bst_vctl)1192		regmap_update_bits(cs35l36->regmap, CS35L36_BSTCVRT_VCTRL1,1193				   CS35L35_BSTCVRT_CTL_MASK,1194				   cs35l36->pdata.bst_vctl);1195 1196	if (cs35l36->pdata.bst_vctl_sel)1197		regmap_update_bits(cs35l36->regmap, CS35L36_BSTCVRT_VCTRL2,1198				   CS35L35_BSTCVRT_CTL_SEL_MASK,1199				   cs35l36->pdata.bst_vctl_sel);1200 1201	if (cs35l36->pdata.bst_ipk)1202		regmap_update_bits(cs35l36->regmap, CS35L36_BSTCVRT_PEAK_CUR,1203				   CS35L36_BST_IPK_MASK,1204				   cs35l36->pdata.bst_ipk);1205 1206	if (cs35l36->pdata.boost_ind) {1207		ret = cs35l36_boost_inductor(cs35l36, cs35l36->pdata.boost_ind);1208		if (ret < 0) {1209			dev_err(cs35l36->dev,1210				"Boost inductor config failed(%d)\n", ret);1211			return ret;1212		}1213	}1214 1215	if (cs35l36->pdata.temp_warn_thld)1216		regmap_update_bits(cs35l36->regmap, CS35L36_DTEMP_WARN_THLD,1217				   CS35L36_TEMP_THLD_MASK,1218				   cs35l36->pdata.temp_warn_thld);1219 1220	if (cs35l36->pdata.irq_drv_sel)1221		regmap_update_bits(cs35l36->regmap, CS35L36_PAD_INTERFACE,1222				   CS35L36_INT_DRV_SEL_MASK,1223				   cs35l36->pdata.irq_drv_sel <<1224				   CS35L36_INT_DRV_SEL_SHIFT);1225 1226	if (cs35l36->pdata.irq_gpio_sel)1227		regmap_update_bits(cs35l36->regmap, CS35L36_PAD_INTERFACE,1228				   CS35L36_INT_GPIO_SEL_MASK,1229				   cs35l36->pdata.irq_gpio_sel <<1230				   CS35L36_INT_GPIO_SEL_SHIFT);1231 1232	/*1233	 * Rev B0 has 2 versions1234	 * L36 is 10V1235	 * L37 is 12V1236	 * If L36 we need to clamp some values for safety1237	 * after probe has setup dt values. We want to make1238	 * sure we dont miss any values set in probe1239	 */1240	if (cs35l36->chip_version == CS35L36_10V_L36) {1241		regmap_update_bits(cs35l36->regmap,1242				   CS35L36_BSTCVRT_OVERVOLT_CTRL,1243				   CS35L36_BST_OVP_THLD_MASK,1244				   CS35L36_BST_OVP_THLD_11V);1245 1246		regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,1247			     CS35L36_TEST_UNLOCK1);1248		regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,1249			     CS35L36_TEST_UNLOCK2);1250 1251		regmap_update_bits(cs35l36->regmap, CS35L36_BST_ANA2_TEST,1252				   CS35L36_BST_OVP_TRIM_MASK,1253				   CS35L36_BST_OVP_TRIM_11V <<1254				   CS35L36_BST_OVP_TRIM_SHIFT);1255		regmap_update_bits(cs35l36->regmap, CS35L36_BSTCVRT_VCTRL2,1256				   CS35L36_BST_CTRL_LIM_MASK,1257				   1 << CS35L36_BST_CTRL_LIM_SHIFT);1258		regmap_update_bits(cs35l36->regmap, CS35L36_BSTCVRT_VCTRL1,1259				   CS35L35_BSTCVRT_CTL_MASK,1260				   CS35L36_BST_CTRL_10V_CLAMP);1261		regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,1262			     CS35L36_TEST_LOCK1);1263		regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,1264			     CS35L36_TEST_LOCK2);1265	}1266 1267	/*1268	 * RevA and B require the disabling of1269	 * SYNC_GLOBAL_OVR when GLOBAL_EN = 0.1270	 * Just turn it off from default1271	 */1272	regmap_update_bits(cs35l36->regmap, CS35L36_CTRL_OVRRIDE,1273			   CS35L36_SYNC_GLOBAL_OVR_MASK,1274			   0 << CS35L36_SYNC_GLOBAL_OVR_SHIFT);1275 1276	return 0;1277}1278 1279static const struct snd_soc_component_driver soc_component_dev_cs35l36 = {1280	.probe			= &cs35l36_component_probe,1281	.set_sysclk		= cs35l36_component_set_sysclk,1282	.dapm_widgets		= cs35l36_dapm_widgets,1283	.num_dapm_widgets	= ARRAY_SIZE(cs35l36_dapm_widgets),1284	.dapm_routes		= cs35l36_audio_map,1285	.num_dapm_routes	= ARRAY_SIZE(cs35l36_audio_map),1286	.controls		= cs35l36_aud_controls,1287	.num_controls		= ARRAY_SIZE(cs35l36_aud_controls),1288	.idle_bias_on		= 1,1289	.use_pmdown_time	= 1,1290	.endianness		= 1,1291};1292 1293static const struct regmap_config cs35l36_regmap = {1294	.reg_bits = 32,1295	.val_bits = 32,1296	.reg_stride = 4,1297	.max_register = CS35L36_PAC_PMEM_WORD1023,1298	.reg_defaults = cs35l36_reg,1299	.num_reg_defaults = ARRAY_SIZE(cs35l36_reg),1300	.precious_reg = cs35l36_precious_reg,1301	.volatile_reg = cs35l36_volatile_reg,1302	.readable_reg = cs35l36_readable_reg,1303	.cache_type = REGCACHE_MAPLE,1304};1305 1306static irqreturn_t cs35l36_irq(int irq, void *data)1307{1308	struct cs35l36_private *cs35l36 = data;1309	unsigned int status[4];1310	unsigned int masks[4];1311	int ret = IRQ_NONE;1312 1313	/* ack the irq by reading all status registers */1314	regmap_bulk_read(cs35l36->regmap, CS35L36_INT1_STATUS, status,1315			 ARRAY_SIZE(status));1316 1317	regmap_bulk_read(cs35l36->regmap, CS35L36_INT1_MASK, masks,1318			 ARRAY_SIZE(masks));1319 1320	/* Check to see if unmasked bits are active */1321	if (!(status[0] & ~masks[0]) && !(status[1] & ~masks[1]) &&1322		!(status[2] & ~masks[2]) && !(status[3] & ~masks[3])) {1323		return IRQ_NONE;1324	}1325 1326	/*1327	 * The following interrupts require a1328	 * protection release cycle to get the1329	 * speaker out of Safe-Mode.1330	 */1331	if (status[2] & CS35L36_AMP_SHORT_ERR) {1332		dev_crit(cs35l36->dev, "Amp short error\n");1333		regmap_update_bits(cs35l36->regmap, CS35L36_PROTECT_REL_ERR,1334				   CS35L36_AMP_SHORT_ERR_RLS, 0);1335		regmap_update_bits(cs35l36->regmap, CS35L36_PROTECT_REL_ERR,1336				   CS35L36_AMP_SHORT_ERR_RLS,1337				   CS35L36_AMP_SHORT_ERR_RLS);1338		regmap_update_bits(cs35l36->regmap, CS35L36_PROTECT_REL_ERR,1339				   CS35L36_AMP_SHORT_ERR_RLS, 0);1340		regmap_update_bits(cs35l36->regmap, CS35L36_INT3_STATUS,1341				   CS35L36_AMP_SHORT_ERR,1342				   CS35L36_AMP_SHORT_ERR);1343		ret = IRQ_HANDLED;1344	}1345 1346	if (status[0] & CS35L36_TEMP_WARN) {1347		dev_crit(cs35l36->dev, "Over temperature warning\n");1348		regmap_update_bits(cs35l36->regmap, CS35L36_PROTECT_REL_ERR,1349				   CS35L36_TEMP_WARN_ERR_RLS, 0);1350		regmap_update_bits(cs35l36->regmap, CS35L36_PROTECT_REL_ERR,1351				   CS35L36_TEMP_WARN_ERR_RLS,1352				   CS35L36_TEMP_WARN_ERR_RLS);1353		regmap_update_bits(cs35l36->regmap, CS35L36_PROTECT_REL_ERR,1354				   CS35L36_TEMP_WARN_ERR_RLS, 0);1355		regmap_update_bits(cs35l36->regmap, CS35L36_INT1_STATUS,1356				   CS35L36_TEMP_WARN, CS35L36_TEMP_WARN);1357		ret = IRQ_HANDLED;1358	}1359 1360	if (status[0] & CS35L36_TEMP_ERR) {1361		dev_crit(cs35l36->dev, "Over temperature error\n");1362		regmap_update_bits(cs35l36->regmap, CS35L36_PROTECT_REL_ERR,1363				   CS35L36_TEMP_ERR_RLS, 0);1364		regmap_update_bits(cs35l36->regmap, CS35L36_PROTECT_REL_ERR,1365				   CS35L36_TEMP_ERR_RLS, CS35L36_TEMP_ERR_RLS);1366		regmap_update_bits(cs35l36->regmap, CS35L36_PROTECT_REL_ERR,1367				   CS35L36_TEMP_ERR_RLS, 0);1368		regmap_update_bits(cs35l36->regmap, CS35L36_INT1_STATUS,1369				   CS35L36_TEMP_ERR, CS35L36_TEMP_ERR);1370		ret = IRQ_HANDLED;1371	}1372 1373	if (status[0] & CS35L36_BST_OVP_ERR) {1374		dev_crit(cs35l36->dev, "VBST Over Voltage error\n");1375		regmap_update_bits(cs35l36->regmap, CS35L36_PROTECT_REL_ERR,1376				   CS35L36_TEMP_ERR_RLS, 0);1377		regmap_update_bits(cs35l36->regmap, CS35L36_PROTECT_REL_ERR,1378				   CS35L36_TEMP_ERR_RLS, CS35L36_TEMP_ERR_RLS);1379		regmap_update_bits(cs35l36->regmap, CS35L36_PROTECT_REL_ERR,1380				   CS35L36_TEMP_ERR_RLS, 0);1381		regmap_update_bits(cs35l36->regmap, CS35L36_INT1_STATUS,1382				   CS35L36_BST_OVP_ERR, CS35L36_BST_OVP_ERR);1383		ret = IRQ_HANDLED;1384	}1385 1386	if (status[0] & CS35L36_BST_DCM_UVP_ERR) {1387		dev_crit(cs35l36->dev, "DCM VBST Under Voltage Error\n");1388		regmap_update_bits(cs35l36->regmap, CS35L36_PROTECT_REL_ERR,1389				   CS35L36_BST_UVP_ERR_RLS, 0);1390		regmap_update_bits(cs35l36->regmap, CS35L36_PROTECT_REL_ERR,1391				   CS35L36_BST_UVP_ERR_RLS,1392				   CS35L36_BST_UVP_ERR_RLS);1393		regmap_update_bits(cs35l36->regmap, CS35L36_PROTECT_REL_ERR,1394				   CS35L36_BST_UVP_ERR_RLS, 0);1395		regmap_update_bits(cs35l36->regmap, CS35L36_INT1_STATUS,1396				   CS35L36_BST_DCM_UVP_ERR,1397				   CS35L36_BST_DCM_UVP_ERR);1398		ret = IRQ_HANDLED;1399	}1400 1401	if (status[0] & CS35L36_BST_SHORT_ERR) {1402		dev_crit(cs35l36->dev, "LBST SHORT error!\n");1403		regmap_update_bits(cs35l36->regmap, CS35L36_PROTECT_REL_ERR,1404				   CS35L36_BST_SHORT_ERR_RLS, 0);1405		regmap_update_bits(cs35l36->regmap, CS35L36_PROTECT_REL_ERR,1406				   CS35L36_BST_SHORT_ERR_RLS,1407				   CS35L36_BST_SHORT_ERR_RLS);1408		regmap_update_bits(cs35l36->regmap, CS35L36_PROTECT_REL_ERR,1409				   CS35L36_BST_SHORT_ERR_RLS, 0);1410		regmap_update_bits(cs35l36->regmap, CS35L36_INT1_STATUS,1411				   CS35L36_BST_SHORT_ERR,1412				   CS35L36_BST_SHORT_ERR);1413		ret = IRQ_HANDLED;1414	}1415 1416	return ret;1417}1418 1419static int cs35l36_handle_of_data(struct i2c_client *i2c_client,1420				struct cs35l36_platform_data *pdata)1421{1422	struct device_node *np = i2c_client->dev.of_node;1423	struct cs35l36_vpbr_cfg *vpbr_config = &pdata->vpbr_config;1424	struct device_node *vpbr_node;1425	unsigned int val;1426	int ret;1427 1428	if (!np)1429		return 0;1430 1431	ret = of_property_read_u32(np, "cirrus,boost-ctl-millivolt", &val);1432	if (!ret) {1433		if (val < 2550 || val > 12000) {1434			dev_err(&i2c_client->dev,1435				"Invalid Boost Voltage %d mV\n", val);1436			return -EINVAL;1437		}1438		pdata->bst_vctl = (((val - 2550) / 100) + 1) << 1;1439	} else {1440		dev_err(&i2c_client->dev,1441			"Unable to find required parameter 'cirrus,boost-ctl-millivolt'");1442		return -EINVAL;1443	}1444 1445	ret = of_property_read_u32(np, "cirrus,boost-ctl-select", &val);1446	if (!ret)1447		pdata->bst_vctl_sel = val | CS35L36_VALID_PDATA;1448 1449	ret = of_property_read_u32(np, "cirrus,boost-peak-milliamp", &val);1450	if (!ret) {1451		if (val < 1600 || val > 4500) {1452			dev_err(&i2c_client->dev,1453				"Invalid Boost Peak Current %u mA\n", val);1454			return -EINVAL;1455		}1456 1457		pdata->bst_ipk = (val - 1600) / 50;1458	} else {1459		dev_err(&i2c_client->dev,1460			"Unable to find required parameter 'cirrus,boost-peak-milliamp'");1461		return -EINVAL;1462	}1463 1464	pdata->multi_amp_mode = of_property_read_bool(np,1465					"cirrus,multi-amp-mode");1466 1467	pdata->dcm_mode = of_property_read_bool(np,1468					"cirrus,dcm-mode-enable");1469 1470	pdata->amp_pcm_inv = of_property_read_bool(np,1471					"cirrus,amp-pcm-inv");1472 1473	pdata->imon_pol_inv = of_property_read_bool(np,1474					"cirrus,imon-pol-inv");1475 1476	pdata->vmon_pol_inv = of_property_read_bool(np,1477					"cirrus,vmon-pol-inv");1478 1479	if (of_property_read_u32(np, "cirrus,temp-warn-threshold", &val) >= 0)1480		pdata->temp_warn_thld = val | CS35L36_VALID_PDATA;1481 1482	if (of_property_read_u32(np, "cirrus,boost-ind-nanohenry", &val) >= 0) {1483		pdata->boost_ind = val;1484	} else {1485		dev_err(&i2c_client->dev, "Inductor not specified.\n");1486		return -EINVAL;1487	}1488 1489	if (of_property_read_u32(np, "cirrus,irq-drive-select", &val) >= 0)1490		pdata->irq_drv_sel = val | CS35L36_VALID_PDATA;1491 1492	if (of_property_read_u32(np, "cirrus,irq-gpio-select", &val) >= 0)1493		pdata->irq_gpio_sel = val | CS35L36_VALID_PDATA;1494 1495	/* VPBR Config */1496	vpbr_node = of_get_child_by_name(np, "cirrus,vpbr-config");1497	vpbr_config->is_present = vpbr_node ? true : false;1498	if (vpbr_config->is_present) {1499		if (of_property_read_u32(vpbr_node, "cirrus,vpbr-en",1500					 &val) >= 0)1501			vpbr_config->vpbr_en = val;1502		if (of_property_read_u32(vpbr_node, "cirrus,vpbr-thld",1503					 &val) >= 0)1504			vpbr_config->vpbr_thld = val;1505		if (of_property_read_u32(vpbr_node, "cirrus,vpbr-atk-rate",1506					 &val) >= 0)1507			vpbr_config->vpbr_atk_rate = val;1508		if (of_property_read_u32(vpbr_node, "cirrus,vpbr-atk-vol",1509					 &val) >= 0)1510			vpbr_config->vpbr_atk_vol = val;1511		if (of_property_read_u32(vpbr_node, "cirrus,vpbr-max-attn",1512					 &val) >= 0)1513			vpbr_config->vpbr_max_attn = val;1514		if (of_property_read_u32(vpbr_node, "cirrus,vpbr-wait",1515					 &val) >= 0)1516			vpbr_config->vpbr_wait = val;1517		if (of_property_read_u32(vpbr_node, "cirrus,vpbr-rel-rate",1518					 &val) >= 0)1519			vpbr_config->vpbr_rel_rate = val;1520		if (of_property_read_u32(vpbr_node, "cirrus,vpbr-mute-en",1521					 &val) >= 0)1522			vpbr_config->vpbr_mute_en = val;1523	}1524	of_node_put(vpbr_node);1525 1526	return 0;1527}1528 1529static int cs35l36_pac(struct cs35l36_private *cs35l36)1530{1531	int ret, count;1532	unsigned int val;1533 1534	if (cs35l36->rev_id != CS35L36_REV_B0)1535		return 0;1536 1537	/*1538	 * Magic code for internal PAC1539	 */1540	regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,1541		     CS35L36_TEST_UNLOCK1);1542	regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,1543		     CS35L36_TEST_UNLOCK2);1544 1545	usleep_range(9500, 10500);1546 1547	regmap_write(cs35l36->regmap, CS35L36_PAC_CTL1,1548		     CS35L36_PAC_RESET);1549	regmap_write(cs35l36->regmap, CS35L36_PAC_CTL3,1550		     CS35L36_PAC_MEM_ACCESS);1551	regmap_write(cs35l36->regmap, CS35L36_PAC_PMEM_WORD0,1552		     CS35L36_B0_PAC_PATCH);1553 1554	regmap_write(cs35l36->regmap, CS35L36_PAC_CTL3,1555		     CS35L36_PAC_MEM_ACCESS_CLR);1556	regmap_write(cs35l36->regmap, CS35L36_PAC_CTL1,1557		     CS35L36_PAC_ENABLE_MASK);1558 1559	usleep_range(9500, 10500);1560 1561	ret = regmap_read(cs35l36->regmap, CS35L36_INT4_STATUS, &val);1562	if (ret < 0) {1563		dev_err(cs35l36->dev, "Failed to read int4_status %d\n", ret);1564		return ret;1565	}1566 1567	count = 0;1568	while (!(val & CS35L36_MCU_CONFIG_CLR)) {1569		usleep_range(100, 200);1570		count++;1571 1572		ret = regmap_read(cs35l36->regmap, CS35L36_INT4_STATUS,1573				  &val);1574		if (ret < 0) {1575			dev_err(cs35l36->dev, "Failed to read int4_status %d\n",1576				ret);1577			return ret;1578		}1579 1580		if (count >= 100)1581			return -EINVAL;1582	}1583 1584	regmap_write(cs35l36->regmap, CS35L36_INT4_STATUS,1585		     CS35L36_MCU_CONFIG_CLR);1586	regmap_update_bits(cs35l36->regmap, CS35L36_PAC_CTL1,1587			   CS35L36_PAC_ENABLE_MASK, 0);1588 1589	regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,1590		     CS35L36_TEST_LOCK1);1591	regmap_write(cs35l36->regmap, CS35L36_TESTKEY_CTRL,1592		     CS35L36_TEST_LOCK2);1593 1594	return 0;1595}1596 1597static void cs35l36_apply_vpbr_config(struct cs35l36_private *cs35l36)1598{1599	struct cs35l36_platform_data *pdata = &cs35l36->pdata;1600	struct cs35l36_vpbr_cfg *vpbr_config = &pdata->vpbr_config;1601 1602	regmap_update_bits(cs35l36->regmap, CS35L36_PWR_CTRL3,1603			   CS35L36_VPBR_EN_MASK,1604			   vpbr_config->vpbr_en <<1605			   CS35L36_VPBR_EN_SHIFT);1606	regmap_update_bits(cs35l36->regmap, CS35L36_VPBR_CFG,1607			   CS35L36_VPBR_THLD_MASK,1608			   vpbr_config->vpbr_thld <<1609			   CS35L36_VPBR_THLD_SHIFT);1610	regmap_update_bits(cs35l36->regmap, CS35L36_VPBR_CFG,1611			   CS35L36_VPBR_MAX_ATTN_MASK,1612			   vpbr_config->vpbr_max_attn <<1613			   CS35L36_VPBR_MAX_ATTN_SHIFT);1614	regmap_update_bits(cs35l36->regmap, CS35L36_VPBR_CFG,1615			   CS35L36_VPBR_ATK_VOL_MASK,1616			   vpbr_config->vpbr_atk_vol <<1617			   CS35L36_VPBR_ATK_VOL_SHIFT);1618	regmap_update_bits(cs35l36->regmap, CS35L36_VPBR_CFG,1619			   CS35L36_VPBR_ATK_RATE_MASK,1620			   vpbr_config->vpbr_atk_rate <<1621			   CS35L36_VPBR_ATK_RATE_SHIFT);1622	regmap_update_bits(cs35l36->regmap, CS35L36_VPBR_CFG,1623			   CS35L36_VPBR_WAIT_MASK,1624			   vpbr_config->vpbr_wait <<1625			   CS35L36_VPBR_WAIT_SHIFT);1626	regmap_update_bits(cs35l36->regmap, CS35L36_VPBR_CFG,1627			   CS35L36_VPBR_REL_RATE_MASK,1628			   vpbr_config->vpbr_rel_rate <<1629			   CS35L36_VPBR_REL_RATE_SHIFT);1630	regmap_update_bits(cs35l36->regmap, CS35L36_VPBR_CFG,1631			   CS35L36_VPBR_MUTE_EN_MASK,1632			   vpbr_config->vpbr_mute_en <<1633			   CS35L36_VPBR_MUTE_EN_SHIFT);1634}1635 1636static const struct reg_sequence cs35l36_reva0_errata_patch[] = {1637	{ CS35L36_TESTKEY_CTRL,		CS35L36_TEST_UNLOCK1 },1638	{ CS35L36_TESTKEY_CTRL,		CS35L36_TEST_UNLOCK2 },1639	/* Errata Writes */1640	{ CS35L36_OTP_CTRL1,		0x00002060 },1641	{ CS35L36_OTP_CTRL2,		0x00000001 },1642	{ CS35L36_OTP_CTRL1,		0x00002460 },1643	{ CS35L36_OTP_CTRL2,		0x00000001 },1644	{ 0x00002088,			0x012A1838 },1645	{ 0x00003014,			0x0100EE0E },1646	{ 0x00003008,			0x0008184A },1647	{ 0x00007418,			0x509001C8 },1648	{ 0x00007064,			0x0929A800 },1649	{ 0x00002D10,			0x0002C01C },1650	{ 0x0000410C,			0x00000A11 },1651	{ 0x00006E08,			0x8B19140C },1652	{ 0x00006454,			0x0300000A },1653	{ CS35L36_AMP_NG_CTRL,		0x000020EF },1654	{ 0x00007E34,			0x0000000E },1655	{ 0x0000410C,			0x00000A11 },1656	{ 0x00007410,			0x20514B00 },1657	/* PAC Config */1658	{ CS35L36_CTRL_OVRRIDE,		0x00000000 },1659	{ CS35L36_PAC_INT0_CTRL,	0x00860001 },1660	{ CS35L36_PAC_INT1_CTRL,	0x00860001 },1661	{ CS35L36_PAC_INT2_CTRL,	0x00860001 },1662	{ CS35L36_PAC_INT3_CTRL,	0x00860001 },1663	{ CS35L36_PAC_INT4_CTRL,	0x00860001 },1664	{ CS35L36_PAC_INT5_CTRL,	0x00860001 },1665	{ CS35L36_PAC_INT6_CTRL,	0x00860001 },1666	{ CS35L36_PAC_INT7_CTRL,	0x00860001 },1667	{ CS35L36_PAC_INT_FLUSH_CTRL,	0x000000FF },1668	{ CS35L36_TESTKEY_CTRL,		CS35L36_TEST_LOCK1 },1669	{ CS35L36_TESTKEY_CTRL,		CS35L36_TEST_LOCK2 },1670};1671 1672static const struct reg_sequence cs35l36_revb0_errata_patch[] = {1673	{ CS35L36_TESTKEY_CTRL,	CS35L36_TEST_UNLOCK1 },1674	{ CS35L36_TESTKEY_CTRL, CS35L36_TEST_UNLOCK2 },1675	{ 0x00007064,		0x0929A800 },1676	{ 0x00007850,		0x00002FA9 },1677	{ 0x00007854,		0x0003F1D5 },1678	{ 0x00007858,		0x0003F5E3 },1679	{ 0x0000785C,		0x00001137 },1680	{ 0x00007860,		0x0001A7A5 },1681	{ 0x00007864,		0x0002F16A },1682	{ 0x00007868,		0x00003E21 },1683	{ 0x00007848,		0x00000001 },1684	{ 0x00003854,		0x05180240 },1685	{ 0x00007418,		0x509001C8 },1686	{ 0x0000394C,		0x028764BD },1687	{ CS35L36_TESTKEY_CTRL,	CS35L36_TEST_LOCK1 },1688	{ CS35L36_TESTKEY_CTRL, CS35L36_TEST_LOCK2 },1689};1690 1691static int cs35l36_i2c_probe(struct i2c_client *i2c_client)1692{1693	struct cs35l36_private *cs35l36;1694	struct device *dev = &i2c_client->dev;1695	struct cs35l36_platform_data *pdata = dev_get_platdata(dev);1696	struct irq_data *irq_d;1697	int ret, irq_pol, chip_irq_pol, i;1698	u32 reg_id, reg_revid, l37_id_reg;1699 1700	cs35l36 = devm_kzalloc(dev, sizeof(struct cs35l36_private), GFP_KERNEL);1701	if (!cs35l36)1702		return -ENOMEM;1703 1704	cs35l36->dev = dev;1705 1706	i2c_set_clientdata(i2c_client, cs35l36);1707	cs35l36->regmap = devm_regmap_init_i2c(i2c_client, &cs35l36_regmap);1708	if (IS_ERR(cs35l36->regmap)) {1709		ret = PTR_ERR(cs35l36->regmap);1710		dev_err(dev, "regmap_init() failed: %d\n", ret);1711		return ret;1712	}1713 1714	cs35l36->num_supplies = ARRAY_SIZE(cs35l36_supplies);1715	for (i = 0; i < ARRAY_SIZE(cs35l36_supplies); i++)1716		cs35l36->supplies[i].supply = cs35l36_supplies[i];1717 1718	ret = devm_regulator_bulk_get(dev, cs35l36->num_supplies,1719				      cs35l36->supplies);1720	if (ret != 0) {1721		dev_err(dev, "Failed to request core supplies: %d\n", ret);1722		return ret;1723	}1724 1725	if (pdata) {1726		cs35l36->pdata = *pdata;1727	} else {1728		pdata = devm_kzalloc(dev, sizeof(struct cs35l36_platform_data),1729				     GFP_KERNEL);1730		if (!pdata)1731			return -ENOMEM;1732 1733		if (i2c_client->dev.of_node) {1734			ret = cs35l36_handle_of_data(i2c_client, pdata);1735			if (ret != 0)1736				return ret;1737 1738		}1739 1740		cs35l36->pdata = *pdata;1741	}1742 1743	ret = regulator_bulk_enable(cs35l36->num_supplies, cs35l36->supplies);1744	if (ret != 0) {1745		dev_err(dev, "Failed to enable core supplies: %d\n", ret);1746		return ret;1747	}1748 1749	/* returning NULL can be an option if in stereo mode */1750	cs35l36->reset_gpio = devm_gpiod_get_optional(dev, "reset",1751						      GPIOD_OUT_LOW);1752	if (IS_ERR(cs35l36->reset_gpio)) {1753		ret = PTR_ERR(cs35l36->reset_gpio);1754		cs35l36->reset_gpio = NULL;1755		if (ret == -EBUSY) {1756			dev_info(dev, "Reset line busy, assuming shared reset\n");1757		} else {1758			dev_err(dev, "Failed to get reset GPIO: %d\n", ret);1759			goto err_disable_regs;1760		}1761	}1762 1763	if (cs35l36->reset_gpio)1764		gpiod_set_value_cansleep(cs35l36->reset_gpio, 1);1765 1766	usleep_range(2000, 2100);1767 1768	/* initialize amplifier */1769	ret = regmap_read(cs35l36->regmap, CS35L36_SW_RESET, &reg_id);1770	if (ret < 0) {1771		dev_err(dev, "Get Device ID failed %d\n", ret);1772		goto err;1773	}1774 1775	if (reg_id != CS35L36_CHIP_ID) {1776		dev_err(dev, "Device ID (%X). Expected ID %X\n", reg_id,1777			CS35L36_CHIP_ID);1778		ret = -ENODEV;1779		goto err;1780	}1781 1782	ret = regmap_read(cs35l36->regmap, CS35L36_REV_ID, &reg_revid);1783	if (ret < 0) {1784		dev_err(&i2c_client->dev, "Get Revision ID failed %d\n", ret);1785		goto err;1786	}1787 1788	cs35l36->rev_id = reg_revid >> 8;1789 1790	ret = regmap_read(cs35l36->regmap, CS35L36_OTP_MEM30, &l37_id_reg);1791	if (ret < 0) {1792		dev_err(&i2c_client->dev, "Failed to read otp_id Register %d\n",1793			ret);1794		goto err;1795	}1796 1797	if ((l37_id_reg & CS35L36_OTP_REV_MASK) == CS35L36_OTP_REV_L37)1798		cs35l36->chip_version = CS35L36_12V_L37;1799	else1800		cs35l36->chip_version = CS35L36_10V_L36;1801 1802	switch (cs35l36->rev_id) {1803	case CS35L36_REV_A0:1804		ret = regmap_register_patch(cs35l36->regmap,1805				cs35l36_reva0_errata_patch,1806				ARRAY_SIZE(cs35l36_reva0_errata_patch));1807		if (ret < 0) {1808			dev_err(dev, "Failed to apply A0 errata patch %d\n",1809				ret);1810			goto err;1811		}1812		break;1813	case CS35L36_REV_B0:1814		ret = cs35l36_pac(cs35l36);1815		if (ret < 0) {1816			dev_err(dev, "Failed to Trim OTP %d\n", ret);1817			goto err;1818		}1819 1820		ret = regmap_register_patch(cs35l36->regmap,1821				cs35l36_revb0_errata_patch,1822				ARRAY_SIZE(cs35l36_revb0_errata_patch));1823		if (ret < 0) {1824			dev_err(dev, "Failed to apply B0 errata patch %d\n",1825				ret);1826			goto err;1827		}1828		break;1829	}1830 1831	if (pdata->vpbr_config.is_present)1832		cs35l36_apply_vpbr_config(cs35l36);1833 1834	irq_d = irq_get_irq_data(i2c_client->irq);1835	if (!irq_d) {1836		dev_err(&i2c_client->dev, "Invalid IRQ: %d\n", i2c_client->irq);1837		ret = -ENODEV;1838		goto err;1839	}1840 1841	irq_pol = irqd_get_trigger_type(irq_d);1842 1843	switch (irq_pol) {1844	case IRQF_TRIGGER_FALLING:1845	case IRQF_TRIGGER_LOW:1846		chip_irq_pol = 0;1847		break;1848	case IRQF_TRIGGER_RISING:1849	case IRQF_TRIGGER_HIGH:1850		chip_irq_pol = 1;1851		break;1852	default:1853		dev_err(cs35l36->dev, "Invalid IRQ polarity: %d\n", irq_pol);1854		ret = -EINVAL;1855		goto err;1856	}1857 1858	regmap_update_bits(cs35l36->regmap, CS35L36_PAD_INTERFACE,1859			   CS35L36_INT_POL_SEL_MASK,1860			   chip_irq_pol << CS35L36_INT_POL_SEL_SHIFT);1861 1862	ret = devm_request_threaded_irq(dev, i2c_client->irq, NULL, cs35l36_irq,1863					IRQF_ONESHOT | irq_pol, "cs35l36",1864					cs35l36);1865	if (ret != 0) {1866		dev_err(dev, "Failed to request IRQ: %d\n", ret);1867		goto err;1868	}1869 1870	regmap_update_bits(cs35l36->regmap, CS35L36_PAD_INTERFACE,1871			   CS35L36_INT_OUTPUT_EN_MASK, 1);1872 1873	/* Set interrupt masks for critical errors */1874	regmap_write(cs35l36->regmap, CS35L36_INT1_MASK,1875		     CS35L36_INT1_MASK_DEFAULT);1876	regmap_write(cs35l36->regmap, CS35L36_INT3_MASK,1877		     CS35L36_INT3_MASK_DEFAULT);1878 1879	dev_info(&i2c_client->dev, "Cirrus Logic CS35L%d, Revision: %02X\n",1880		 cs35l36->chip_version, reg_revid >> 8);1881 1882	ret =  devm_snd_soc_register_component(dev, &soc_component_dev_cs35l36,1883					       cs35l36_dai,1884					       ARRAY_SIZE(cs35l36_dai));1885	if (ret < 0) {1886		dev_err(dev, "%s: Register component failed %d\n", __func__,1887			ret);1888		goto err;1889	}1890 1891	return 0;1892 1893err:1894	gpiod_set_value_cansleep(cs35l36->reset_gpio, 0);1895 1896err_disable_regs:1897	regulator_bulk_disable(cs35l36->num_supplies, cs35l36->supplies);1898	return ret;1899}1900 1901static void cs35l36_i2c_remove(struct i2c_client *client)1902{1903	struct cs35l36_private *cs35l36 = i2c_get_clientdata(client);1904 1905	/* Reset interrupt masks for device removal */1906	regmap_write(cs35l36->regmap, CS35L36_INT1_MASK,1907		     CS35L36_INT1_MASK_RESET);1908	regmap_write(cs35l36->regmap, CS35L36_INT3_MASK,1909		     CS35L36_INT3_MASK_RESET);1910 1911	if (cs35l36->reset_gpio)1912		gpiod_set_value_cansleep(cs35l36->reset_gpio, 0);1913 1914	regulator_bulk_disable(cs35l36->num_supplies, cs35l36->supplies);1915}1916static const struct of_device_id cs35l36_of_match[] = {1917	{.compatible = "cirrus,cs35l36"},1918	{},1919};1920MODULE_DEVICE_TABLE(of, cs35l36_of_match);1921 1922static const struct i2c_device_id cs35l36_id[] = {1923	{"cs35l36"},1924	{}1925};1926 1927MODULE_DEVICE_TABLE(i2c, cs35l36_id);1928 1929static struct i2c_driver cs35l36_i2c_driver = {1930	.driver = {1931		.name = "cs35l36",1932		.of_match_table = cs35l36_of_match,1933	},1934	.id_table = cs35l36_id,1935	.probe = cs35l36_i2c_probe,1936	.remove = cs35l36_i2c_remove,1937};1938module_i2c_driver(cs35l36_i2c_driver);1939 1940MODULE_DESCRIPTION("ASoC CS35L36 driver");1941MODULE_AUTHOR("James Schulman, Cirrus Logic Inc, <james.schulman@cirrus.com>");1942MODULE_LICENSE("GPL");1943