brintos

brintos / linux-shallow public Read only

0
0
Text · 48.8 KiB · 8bb8fef Raw
1542 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * DA9055 ALSA Soc codec driver4 *5 * Copyright (c) 2012 Dialog Semiconductor6 *7 * Tested on (Samsung SMDK6410 board + DA9055 EVB) using I2S and I2C8 * Written by David Chen <david.chen@diasemi.com> and9 * Ashish Chavan <ashish.chavan@kpitcummins.com>10 */11 12#include <linux/delay.h>13#include <linux/i2c.h>14#include <linux/regmap.h>15#include <linux/slab.h>16#include <linux/module.h>17#include <linux/of.h>18#include <sound/pcm.h>19#include <sound/pcm_params.h>20#include <sound/soc.h>21#include <sound/initval.h>22#include <sound/tlv.h>23#include <sound/da9055.h>24 25/* DA9055 register space */26 27/* Status Registers */28#define DA9055_STATUS1			0x0229#define DA9055_PLL_STATUS		0x0330#define DA9055_AUX_L_GAIN_STATUS	0x0431#define DA9055_AUX_R_GAIN_STATUS	0x0532#define DA9055_MIC_L_GAIN_STATUS	0x0633#define DA9055_MIC_R_GAIN_STATUS	0x0734#define DA9055_MIXIN_L_GAIN_STATUS	0x0835#define DA9055_MIXIN_R_GAIN_STATUS	0x0936#define DA9055_ADC_L_GAIN_STATUS	0x0A37#define DA9055_ADC_R_GAIN_STATUS	0x0B38#define DA9055_DAC_L_GAIN_STATUS	0x0C39#define DA9055_DAC_R_GAIN_STATUS	0x0D40#define DA9055_HP_L_GAIN_STATUS		0x0E41#define DA9055_HP_R_GAIN_STATUS		0x0F42#define DA9055_LINE_GAIN_STATUS		0x1043 44/* System Initialisation Registers */45#define DA9055_CIF_CTRL			0x2046#define DA9055_DIG_ROUTING_AIF		0X2147#define DA9055_SR			0x2248#define DA9055_REFERENCES		0x2349#define DA9055_PLL_FRAC_TOP		0x2450#define DA9055_PLL_FRAC_BOT		0x2551#define DA9055_PLL_INTEGER		0x2652#define DA9055_PLL_CTRL			0x2753#define DA9055_AIF_CLK_MODE		0x2854#define DA9055_AIF_CTRL			0x2955#define DA9055_DIG_ROUTING_DAC		0x2A56#define DA9055_ALC_CTRL1		0x2B57 58/* Input - Gain, Select and Filter Registers */59#define DA9055_AUX_L_GAIN		0x3060#define DA9055_AUX_R_GAIN		0x3161#define DA9055_MIXIN_L_SELECT		0x3262#define DA9055_MIXIN_R_SELECT		0x3363#define DA9055_MIXIN_L_GAIN		0x3464#define DA9055_MIXIN_R_GAIN		0x3565#define DA9055_ADC_L_GAIN		0x3666#define DA9055_ADC_R_GAIN		0x3767#define DA9055_ADC_FILTERS1		0x3868#define DA9055_MIC_L_GAIN		0x3969#define DA9055_MIC_R_GAIN		0x3A70 71/* Output - Gain, Select and Filter Registers */72#define DA9055_DAC_FILTERS5		0x4073#define DA9055_DAC_FILTERS2		0x4174#define DA9055_DAC_FILTERS3		0x4275#define DA9055_DAC_FILTERS4		0x4376#define DA9055_DAC_FILTERS1		0x4477#define DA9055_DAC_L_GAIN		0x4578#define DA9055_DAC_R_GAIN		0x4679#define DA9055_CP_CTRL			0x4780#define DA9055_HP_L_GAIN		0x4881#define DA9055_HP_R_GAIN		0x4982#define DA9055_LINE_GAIN		0x4A83#define DA9055_MIXOUT_L_SELECT		0x4B84#define DA9055_MIXOUT_R_SELECT		0x4C85 86/* System Controller Registers */87#define DA9055_SYSTEM_MODES_INPUT	0x5088#define DA9055_SYSTEM_MODES_OUTPUT	0x5189 90/* Control Registers */91#define DA9055_AUX_L_CTRL		0x6092#define DA9055_AUX_R_CTRL		0x6193#define DA9055_MIC_BIAS_CTRL		0x6294#define DA9055_MIC_L_CTRL		0x6395#define DA9055_MIC_R_CTRL		0x6496#define DA9055_MIXIN_L_CTRL		0x6597#define DA9055_MIXIN_R_CTRL		0x6698#define DA9055_ADC_L_CTRL		0x6799#define DA9055_ADC_R_CTRL		0x68100#define DA9055_DAC_L_CTRL		0x69101#define DA9055_DAC_R_CTRL		0x6A102#define DA9055_HP_L_CTRL		0x6B103#define DA9055_HP_R_CTRL		0x6C104#define DA9055_LINE_CTRL		0x6D105#define DA9055_MIXOUT_L_CTRL		0x6E106#define DA9055_MIXOUT_R_CTRL		0x6F107 108/* Configuration Registers */109#define DA9055_LDO_CTRL			0x90110#define DA9055_IO_CTRL			0x91111#define DA9055_GAIN_RAMP_CTRL		0x92112#define DA9055_MIC_CONFIG		0x93113#define DA9055_PC_COUNT			0x94114#define DA9055_CP_VOL_THRESHOLD1	0x95115#define DA9055_CP_DELAY			0x96116#define DA9055_CP_DETECTOR		0x97117#define DA9055_AIF_OFFSET		0x98118#define DA9055_DIG_CTRL			0x99119#define DA9055_ALC_CTRL2		0x9A120#define DA9055_ALC_CTRL3		0x9B121#define DA9055_ALC_NOISE		0x9C122#define DA9055_ALC_TARGET_MIN		0x9D123#define DA9055_ALC_TARGET_MAX		0x9E124#define DA9055_ALC_GAIN_LIMITS		0x9F125#define DA9055_ALC_ANA_GAIN_LIMITS	0xA0126#define DA9055_ALC_ANTICLIP_CTRL	0xA1127#define DA9055_ALC_ANTICLIP_LEVEL	0xA2128#define DA9055_ALC_OFFSET_OP2M_L	0xA6129#define DA9055_ALC_OFFSET_OP2U_L	0xA7130#define DA9055_ALC_OFFSET_OP2M_R	0xAB131#define DA9055_ALC_OFFSET_OP2U_R	0xAC132#define DA9055_ALC_CIC_OP_LVL_CTRL	0xAD133#define DA9055_ALC_CIC_OP_LVL_DATA	0xAE134#define DA9055_DAC_NG_SETUP_TIME	0xAF135#define DA9055_DAC_NG_OFF_THRESHOLD	0xB0136#define DA9055_DAC_NG_ON_THRESHOLD	0xB1137#define DA9055_DAC_NG_CTRL		0xB2138 139/* SR bit fields */140#define DA9055_SR_8000			(0x1 << 0)141#define DA9055_SR_11025			(0x2 << 0)142#define DA9055_SR_12000			(0x3 << 0)143#define DA9055_SR_16000			(0x5 << 0)144#define DA9055_SR_22050			(0x6 << 0)145#define DA9055_SR_24000			(0x7 << 0)146#define DA9055_SR_32000			(0x9 << 0)147#define DA9055_SR_44100			(0xA << 0)148#define DA9055_SR_48000			(0xB << 0)149#define DA9055_SR_88200			(0xE << 0)150#define DA9055_SR_96000			(0xF << 0)151 152/* REFERENCES bit fields */153#define DA9055_BIAS_EN			(1 << 3)154#define DA9055_VMID_EN			(1 << 7)155 156/* PLL_CTRL bit fields */157#define DA9055_PLL_INDIV_10_20_MHZ	(1 << 2)158#define DA9055_PLL_SRM_EN		(1 << 6)159#define DA9055_PLL_EN			(1 << 7)160 161/* AIF_CLK_MODE bit fields */162#define DA9055_AIF_BCLKS_PER_WCLK_32	(0 << 0)163#define DA9055_AIF_BCLKS_PER_WCLK_64	(1 << 0)164#define DA9055_AIF_BCLKS_PER_WCLK_128	(2 << 0)165#define DA9055_AIF_BCLKS_PER_WCLK_256	(3 << 0)166#define DA9055_AIF_CLK_EN_SLAVE_MODE	(0 << 7)167#define DA9055_AIF_CLK_EN_MASTER_MODE	(1 << 7)168 169/* AIF_CTRL bit fields */170#define DA9055_AIF_FORMAT_I2S_MODE	(0 << 0)171#define DA9055_AIF_FORMAT_LEFT_J	(1 << 0)172#define DA9055_AIF_FORMAT_RIGHT_J	(2 << 0)173#define DA9055_AIF_FORMAT_DSP		(3 << 0)174#define DA9055_AIF_WORD_S16_LE		(0 << 2)175#define DA9055_AIF_WORD_S20_3LE		(1 << 2)176#define DA9055_AIF_WORD_S24_LE		(2 << 2)177#define DA9055_AIF_WORD_S32_LE		(3 << 2)178 179/* MIC_L_CTRL bit fields */180#define DA9055_MIC_L_MUTE_EN		(1 << 6)181 182/* MIC_R_CTRL bit fields */183#define DA9055_MIC_R_MUTE_EN		(1 << 6)184 185/* MIXIN_L_CTRL bit fields */186#define DA9055_MIXIN_L_MIX_EN		(1 << 3)187 188/* MIXIN_R_CTRL bit fields */189#define DA9055_MIXIN_R_MIX_EN		(1 << 3)190 191/* ADC_L_CTRL bit fields */192#define DA9055_ADC_L_EN			(1 << 7)193 194/* ADC_R_CTRL bit fields */195#define DA9055_ADC_R_EN			(1 << 7)196 197/* DAC_L_CTRL bit fields */198#define DA9055_DAC_L_MUTE_EN		(1 << 6)199 200/* DAC_R_CTRL bit fields */201#define DA9055_DAC_R_MUTE_EN		(1 << 6)202 203/* HP_L_CTRL bit fields */204#define DA9055_HP_L_AMP_OE		(1 << 3)205 206/* HP_R_CTRL bit fields */207#define DA9055_HP_R_AMP_OE		(1 << 3)208 209/* LINE_CTRL bit fields */210#define DA9055_LINE_AMP_OE		(1 << 3)211 212/* MIXOUT_L_CTRL bit fields */213#define DA9055_MIXOUT_L_MIX_EN		(1 << 3)214 215/* MIXOUT_R_CTRL bit fields */216#define DA9055_MIXOUT_R_MIX_EN		(1 << 3)217 218/* MIC bias select bit fields */219#define DA9055_MICBIAS2_EN		(1 << 6)220 221/* ALC_CIC_OP_LEVEL_CTRL bit fields */222#define DA9055_ALC_DATA_MIDDLE		(2 << 0)223#define DA9055_ALC_DATA_TOP		(3 << 0)224#define DA9055_ALC_CIC_OP_CHANNEL_LEFT	(0 << 7)225#define DA9055_ALC_CIC_OP_CHANNEL_RIGHT	(1 << 7)226 227#define DA9055_AIF_BCLK_MASK		(3 << 0)228#define DA9055_AIF_CLK_MODE_MASK	(1 << 7)229#define DA9055_AIF_FORMAT_MASK		(3 << 0)230#define DA9055_AIF_WORD_LENGTH_MASK	(3 << 2)231#define DA9055_GAIN_RAMPING_EN		(1 << 5)232#define DA9055_MICBIAS_LEVEL_MASK	(3 << 4)233 234#define DA9055_ALC_OFFSET_15_8		0x00FF00235#define DA9055_ALC_OFFSET_17_16		0x030000236#define DA9055_ALC_AVG_ITERATIONS	5237 238struct pll_div {239	int fref;240	int fout;241	u8 frac_top;242	u8 frac_bot;243	u8 integer;244	u8 mode;	/* 0 = slave, 1 = master */245};246 247/* PLL divisor table */248static const struct pll_div da9055_pll_div[] = {249	/* for MASTER mode, fs = 44.1Khz and its harmonics */250	{11289600, 2822400, 0x00, 0x00, 0x20, 1},	/* MCLK=11.2896Mhz */251	{12000000, 2822400, 0x03, 0x61, 0x1E, 1},	/* MCLK=12Mhz */252	{12288000, 2822400, 0x0C, 0xCC, 0x1D, 1},	/* MCLK=12.288Mhz */253	{13000000, 2822400, 0x19, 0x45, 0x1B, 1},	/* MCLK=13Mhz */254	{13500000, 2822400, 0x18, 0x56, 0x1A, 1},	/* MCLK=13.5Mhz */255	{14400000, 2822400, 0x02, 0xD0, 0x19, 1},	/* MCLK=14.4Mhz */256	{19200000, 2822400, 0x1A, 0x1C, 0x12, 1},	/* MCLK=19.2Mhz */257	{19680000, 2822400, 0x0B, 0x6D, 0x12, 1},	/* MCLK=19.68Mhz */258	{19800000, 2822400, 0x07, 0xDD, 0x12, 1},	/* MCLK=19.8Mhz */259	/* for MASTER mode, fs = 48Khz and its harmonics */260	{11289600, 3072000, 0x1A, 0x8E, 0x22, 1},	/* MCLK=11.2896Mhz */261	{12000000, 3072000, 0x18, 0x93, 0x20, 1},	/* MCLK=12Mhz */262	{12288000, 3072000, 0x00, 0x00, 0x20, 1},	/* MCLK=12.288Mhz */263	{13000000, 3072000, 0x07, 0xEA, 0x1E, 1},	/* MCLK=13Mhz */264	{13500000, 3072000, 0x04, 0x11, 0x1D, 1},	/* MCLK=13.5Mhz */265	{14400000, 3072000, 0x09, 0xD0, 0x1B, 1},	/* MCLK=14.4Mhz */266	{19200000, 3072000, 0x0F, 0x5C, 0x14, 1},	/* MCLK=19.2Mhz */267	{19680000, 3072000, 0x1F, 0x60, 0x13, 1},	/* MCLK=19.68Mhz */268	{19800000, 3072000, 0x1B, 0x80, 0x13, 1},	/* MCLK=19.8Mhz */269	/* for SLAVE mode with SRM */270	{11289600, 2822400, 0x0D, 0x47, 0x21, 0},	/* MCLK=11.2896Mhz */271	{12000000, 2822400, 0x0D, 0xFA, 0x1F, 0},	/* MCLK=12Mhz */272	{12288000, 2822400, 0x16, 0x66, 0x1E, 0},	/* MCLK=12.288Mhz */273	{13000000, 2822400, 0x00, 0x98, 0x1D, 0},	/* MCLK=13Mhz */274	{13500000, 2822400, 0x1E, 0x33, 0x1B, 0},	/* MCLK=13.5Mhz */275	{14400000, 2822400, 0x06, 0x50, 0x1A, 0},	/* MCLK=14.4Mhz */276	{19200000, 2822400, 0x14, 0xBC, 0x13, 0},	/* MCLK=19.2Mhz */277	{19680000, 2822400, 0x05, 0x66, 0x13, 0},	/* MCLK=19.68Mhz */278	{19800000, 2822400, 0x01, 0xAE, 0x13, 0},	/* MCLK=19.8Mhz  */279};280 281enum clk_src {282	DA9055_CLKSRC_MCLK283};284 285/* Gain and Volume */286 287static const DECLARE_TLV_DB_RANGE(aux_vol_tlv,288	0x0, 0x10, TLV_DB_SCALE_ITEM(-5400, 0, 0),289	/* -54dB to 15dB */290	0x11, 0x3f, TLV_DB_SCALE_ITEM(-5400, 150, 0)291);292 293static const DECLARE_TLV_DB_RANGE(digital_gain_tlv,294	0x0, 0x07, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),295	/* -78dB to 12dB */296	0x08, 0x7f, TLV_DB_SCALE_ITEM(-7800, 75, 0)297);298 299static const DECLARE_TLV_DB_RANGE(alc_analog_gain_tlv,300	0x0, 0x0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),301	/* 0dB to 36dB */302	0x01, 0x07, TLV_DB_SCALE_ITEM(0, 600, 0)303);304 305static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, -600, 600, 0);306static const DECLARE_TLV_DB_SCALE(mixin_gain_tlv, -450, 150, 0);307static const DECLARE_TLV_DB_SCALE(eq_gain_tlv, -1050, 150, 0);308static const DECLARE_TLV_DB_SCALE(hp_vol_tlv, -5700, 100, 0);309static const DECLARE_TLV_DB_SCALE(lineout_vol_tlv, -4800, 100, 0);310static const DECLARE_TLV_DB_SCALE(alc_threshold_tlv, -9450, 150, 0);311static const DECLARE_TLV_DB_SCALE(alc_gain_tlv, 0, 600, 0);312 313/* ADC and DAC high pass filter cutoff value */314static const char * const da9055_hpf_cutoff_txt[] = {315	"Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000"316};317 318static SOC_ENUM_SINGLE_DECL(da9055_dac_hpf_cutoff,319			    DA9055_DAC_FILTERS1, 4, da9055_hpf_cutoff_txt);320 321static SOC_ENUM_SINGLE_DECL(da9055_adc_hpf_cutoff,322			    DA9055_ADC_FILTERS1, 4, da9055_hpf_cutoff_txt);323 324/* ADC and DAC voice mode (8kHz) high pass cutoff value */325static const char * const da9055_vf_cutoff_txt[] = {326	"2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"327};328 329static SOC_ENUM_SINGLE_DECL(da9055_dac_vf_cutoff,330			    DA9055_DAC_FILTERS1, 0, da9055_vf_cutoff_txt);331 332static SOC_ENUM_SINGLE_DECL(da9055_adc_vf_cutoff,333			    DA9055_ADC_FILTERS1, 0, da9055_vf_cutoff_txt);334 335/* Gain ramping rate value */336static const char * const da9055_gain_ramping_txt[] = {337	"nominal rate", "nominal rate * 4", "nominal rate * 8",338	"nominal rate / 8"339};340 341static SOC_ENUM_SINGLE_DECL(da9055_gain_ramping_rate,342			    DA9055_GAIN_RAMP_CTRL, 0, da9055_gain_ramping_txt);343 344/* DAC noise gate setup time value */345static const char * const da9055_dac_ng_setup_time_txt[] = {346	"256 samples", "512 samples", "1024 samples", "2048 samples"347};348 349static SOC_ENUM_SINGLE_DECL(da9055_dac_ng_setup_time,350			    DA9055_DAC_NG_SETUP_TIME, 0,351			    da9055_dac_ng_setup_time_txt);352 353/* DAC noise gate rampup rate value */354static const char * const da9055_dac_ng_rampup_txt[] = {355	"0.02 ms/dB", "0.16 ms/dB"356};357 358static SOC_ENUM_SINGLE_DECL(da9055_dac_ng_rampup_rate,359			    DA9055_DAC_NG_SETUP_TIME, 2,360			    da9055_dac_ng_rampup_txt);361 362/* DAC noise gate rampdown rate value */363static const char * const da9055_dac_ng_rampdown_txt[] = {364	"0.64 ms/dB", "20.48 ms/dB"365};366 367static SOC_ENUM_SINGLE_DECL(da9055_dac_ng_rampdown_rate,368			    DA9055_DAC_NG_SETUP_TIME, 3,369			    da9055_dac_ng_rampdown_txt);370 371/* DAC soft mute rate value */372static const char * const da9055_dac_soft_mute_rate_txt[] = {373	"1", "2", "4", "8", "16", "32", "64"374};375 376static SOC_ENUM_SINGLE_DECL(da9055_dac_soft_mute_rate,377			    DA9055_DAC_FILTERS5, 4,378			    da9055_dac_soft_mute_rate_txt);379 380/* DAC routing select */381static const char * const da9055_dac_src_txt[] = {382	"ADC output left", "ADC output right", "AIF input left",383	"AIF input right"384};385 386static SOC_ENUM_SINGLE_DECL(da9055_dac_l_src,387			    DA9055_DIG_ROUTING_DAC, 0, da9055_dac_src_txt);388 389static SOC_ENUM_SINGLE_DECL(da9055_dac_r_src,390			    DA9055_DIG_ROUTING_DAC, 4, da9055_dac_src_txt);391 392/* MIC PGA Left source select */393static const char * const da9055_mic_l_src_txt[] = {394	"MIC1_P_N", "MIC1_P", "MIC1_N", "MIC2_L"395};396 397static SOC_ENUM_SINGLE_DECL(da9055_mic_l_src,398			    DA9055_MIXIN_L_SELECT, 4, da9055_mic_l_src_txt);399 400/* MIC PGA Right source select */401static const char * const da9055_mic_r_src_txt[] = {402	"MIC2_R_L", "MIC2_R", "MIC2_L"403};404 405static SOC_ENUM_SINGLE_DECL(da9055_mic_r_src,406			    DA9055_MIXIN_R_SELECT, 4, da9055_mic_r_src_txt);407 408/* ALC Input Signal Tracking rate select */409static const char * const da9055_signal_tracking_rate_txt[] = {410	"1/4", "1/16", "1/256", "1/65536"411};412 413static SOC_ENUM_SINGLE_DECL(da9055_integ_attack_rate,414			    DA9055_ALC_CTRL3, 4,415			    da9055_signal_tracking_rate_txt);416 417static SOC_ENUM_SINGLE_DECL(da9055_integ_release_rate,418			    DA9055_ALC_CTRL3, 6,419			    da9055_signal_tracking_rate_txt);420 421/* ALC Attack Rate select */422static const char * const da9055_attack_rate_txt[] = {423	"44/fs", "88/fs", "176/fs", "352/fs", "704/fs", "1408/fs", "2816/fs",424	"5632/fs", "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"425};426 427static SOC_ENUM_SINGLE_DECL(da9055_attack_rate,428			    DA9055_ALC_CTRL2, 0, da9055_attack_rate_txt);429 430/* ALC Release Rate select */431static const char * const da9055_release_rate_txt[] = {432	"176/fs", "352/fs", "704/fs", "1408/fs", "2816/fs", "5632/fs",433	"11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"434};435 436static SOC_ENUM_SINGLE_DECL(da9055_release_rate,437			    DA9055_ALC_CTRL2, 4, da9055_release_rate_txt);438 439/* ALC Hold Time select */440static const char * const da9055_hold_time_txt[] = {441	"62/fs", "124/fs", "248/fs", "496/fs", "992/fs", "1984/fs", "3968/fs",442	"7936/fs", "15872/fs", "31744/fs", "63488/fs", "126976/fs",443	"253952/fs", "507904/fs", "1015808/fs", "2031616/fs"444};445 446static SOC_ENUM_SINGLE_DECL(da9055_hold_time,447			    DA9055_ALC_CTRL3, 0, da9055_hold_time_txt);448 449static int da9055_get_alc_data(struct snd_soc_component *component, u8 reg_val)450{451	int mid_data, top_data;452	int sum = 0;453	u8 iteration;454 455	for (iteration = 0; iteration < DA9055_ALC_AVG_ITERATIONS;456	     iteration++) {457		/* Select the left or right channel and capture data */458		snd_soc_component_write(component, DA9055_ALC_CIC_OP_LVL_CTRL, reg_val);459 460		/* Select middle 8 bits for read back from data register */461		snd_soc_component_write(component, DA9055_ALC_CIC_OP_LVL_CTRL,462			      reg_val | DA9055_ALC_DATA_MIDDLE);463		mid_data = snd_soc_component_read(component, DA9055_ALC_CIC_OP_LVL_DATA);464 465		/* Select top 8 bits for read back from data register */466		snd_soc_component_write(component, DA9055_ALC_CIC_OP_LVL_CTRL,467			      reg_val | DA9055_ALC_DATA_TOP);468		top_data = snd_soc_component_read(component, DA9055_ALC_CIC_OP_LVL_DATA);469 470		sum += ((mid_data << 8) | (top_data << 16));471	}472 473	return sum / DA9055_ALC_AVG_ITERATIONS;474}475 476static int da9055_put_alc_sw(struct snd_kcontrol *kcontrol,477			     struct snd_ctl_elem_value *ucontrol)478{479	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);480	u8 reg_val, adc_left, adc_right, mic_left, mic_right;481	int avg_left_data, avg_right_data, offset_l, offset_r;482 483	if (ucontrol->value.integer.value[0]) {484		/*485		 * While enabling ALC (or ALC sync mode), calibration of the DC486		 * offsets must be done first487		 */488 489		/* Save current values from Mic control registers */490		mic_left = snd_soc_component_read(component, DA9055_MIC_L_CTRL);491		mic_right = snd_soc_component_read(component, DA9055_MIC_R_CTRL);492 493		/* Mute Mic PGA Left and Right */494		snd_soc_component_update_bits(component, DA9055_MIC_L_CTRL,495				    DA9055_MIC_L_MUTE_EN, DA9055_MIC_L_MUTE_EN);496		snd_soc_component_update_bits(component, DA9055_MIC_R_CTRL,497				    DA9055_MIC_R_MUTE_EN, DA9055_MIC_R_MUTE_EN);498 499		/* Save current values from ADC control registers */500		adc_left = snd_soc_component_read(component, DA9055_ADC_L_CTRL);501		adc_right = snd_soc_component_read(component, DA9055_ADC_R_CTRL);502 503		/* Enable ADC Left and Right */504		snd_soc_component_update_bits(component, DA9055_ADC_L_CTRL,505				    DA9055_ADC_L_EN, DA9055_ADC_L_EN);506		snd_soc_component_update_bits(component, DA9055_ADC_R_CTRL,507				    DA9055_ADC_R_EN, DA9055_ADC_R_EN);508 509		/* Calculate average for Left and Right data */510		/* Left Data */511		avg_left_data = da9055_get_alc_data(component,512				DA9055_ALC_CIC_OP_CHANNEL_LEFT);513		/* Right Data */514		avg_right_data = da9055_get_alc_data(component,515				 DA9055_ALC_CIC_OP_CHANNEL_RIGHT);516 517		/* Calculate DC offset */518		offset_l = -avg_left_data;519		offset_r = -avg_right_data;520 521		reg_val = (offset_l & DA9055_ALC_OFFSET_15_8) >> 8;522		snd_soc_component_write(component, DA9055_ALC_OFFSET_OP2M_L, reg_val);523		reg_val = (offset_l & DA9055_ALC_OFFSET_17_16) >> 16;524		snd_soc_component_write(component, DA9055_ALC_OFFSET_OP2U_L, reg_val);525 526		reg_val = (offset_r & DA9055_ALC_OFFSET_15_8) >> 8;527		snd_soc_component_write(component, DA9055_ALC_OFFSET_OP2M_R, reg_val);528		reg_val = (offset_r & DA9055_ALC_OFFSET_17_16) >> 16;529		snd_soc_component_write(component, DA9055_ALC_OFFSET_OP2U_R, reg_val);530 531		/* Restore original values of ADC control registers */532		snd_soc_component_write(component, DA9055_ADC_L_CTRL, adc_left);533		snd_soc_component_write(component, DA9055_ADC_R_CTRL, adc_right);534 535		/* Restore original values of Mic control registers */536		snd_soc_component_write(component, DA9055_MIC_L_CTRL, mic_left);537		snd_soc_component_write(component, DA9055_MIC_R_CTRL, mic_right);538	}539 540	return snd_soc_put_volsw(kcontrol, ucontrol);541}542 543static const struct snd_kcontrol_new da9055_snd_controls[] = {544 545	/* Volume controls */546	SOC_DOUBLE_R_TLV("Mic Volume",547			 DA9055_MIC_L_GAIN, DA9055_MIC_R_GAIN,548			 0, 0x7, 0, mic_vol_tlv),549	SOC_DOUBLE_R_TLV("Aux Volume",550			 DA9055_AUX_L_GAIN, DA9055_AUX_R_GAIN,551			 0, 0x3f, 0, aux_vol_tlv),552	SOC_DOUBLE_R_TLV("Mixin PGA Volume",553			 DA9055_MIXIN_L_GAIN, DA9055_MIXIN_R_GAIN,554			 0, 0xf, 0, mixin_gain_tlv),555	SOC_DOUBLE_R_TLV("ADC Volume",556			 DA9055_ADC_L_GAIN, DA9055_ADC_R_GAIN,557			 0, 0x7f, 0, digital_gain_tlv),558 559	SOC_DOUBLE_R_TLV("DAC Volume",560			 DA9055_DAC_L_GAIN, DA9055_DAC_R_GAIN,561			 0, 0x7f, 0, digital_gain_tlv),562	SOC_DOUBLE_R_TLV("Headphone Volume",563			 DA9055_HP_L_GAIN, DA9055_HP_R_GAIN,564			 0, 0x3f, 0, hp_vol_tlv),565	SOC_SINGLE_TLV("Lineout Volume", DA9055_LINE_GAIN, 0, 0x3f, 0,566		       lineout_vol_tlv),567 568	/* DAC Equalizer controls */569	SOC_SINGLE("DAC EQ Switch", DA9055_DAC_FILTERS4, 7, 1, 0),570	SOC_SINGLE_TLV("DAC EQ1 Volume", DA9055_DAC_FILTERS2, 0, 0xf, 0,571		       eq_gain_tlv),572	SOC_SINGLE_TLV("DAC EQ2 Volume", DA9055_DAC_FILTERS2, 4, 0xf, 0,573		       eq_gain_tlv),574	SOC_SINGLE_TLV("DAC EQ3 Volume", DA9055_DAC_FILTERS3, 0, 0xf, 0,575		       eq_gain_tlv),576	SOC_SINGLE_TLV("DAC EQ4 Volume", DA9055_DAC_FILTERS3, 4, 0xf, 0,577		       eq_gain_tlv),578	SOC_SINGLE_TLV("DAC EQ5 Volume", DA9055_DAC_FILTERS4, 0, 0xf, 0,579		       eq_gain_tlv),580 581	/* High Pass Filter and Voice Mode controls */582	SOC_SINGLE("ADC HPF Switch", DA9055_ADC_FILTERS1, 7, 1, 0),583	SOC_ENUM("ADC HPF Cutoff", da9055_adc_hpf_cutoff),584	SOC_SINGLE("ADC Voice Mode Switch", DA9055_ADC_FILTERS1, 3, 1, 0),585	SOC_ENUM("ADC Voice Cutoff", da9055_adc_vf_cutoff),586 587	SOC_SINGLE("DAC HPF Switch", DA9055_DAC_FILTERS1, 7, 1, 0),588	SOC_ENUM("DAC HPF Cutoff", da9055_dac_hpf_cutoff),589	SOC_SINGLE("DAC Voice Mode Switch", DA9055_DAC_FILTERS1, 3, 1, 0),590	SOC_ENUM("DAC Voice Cutoff", da9055_dac_vf_cutoff),591 592	/* Mute controls */593	SOC_DOUBLE_R("Mic Switch", DA9055_MIC_L_CTRL,594		     DA9055_MIC_R_CTRL, 6, 1, 0),595	SOC_DOUBLE_R("Aux Switch", DA9055_AUX_L_CTRL,596		     DA9055_AUX_R_CTRL, 6, 1, 0),597	SOC_DOUBLE_R("Mixin PGA Switch", DA9055_MIXIN_L_CTRL,598		     DA9055_MIXIN_R_CTRL, 6, 1, 0),599	SOC_DOUBLE_R("ADC Switch", DA9055_ADC_L_CTRL,600		     DA9055_ADC_R_CTRL, 6, 1, 0),601	SOC_DOUBLE_R("Headphone Switch", DA9055_HP_L_CTRL,602		     DA9055_HP_R_CTRL, 6, 1, 0),603	SOC_SINGLE("Lineout Switch", DA9055_LINE_CTRL, 6, 1, 0),604	SOC_SINGLE("DAC Soft Mute Switch", DA9055_DAC_FILTERS5, 7, 1, 0),605	SOC_ENUM("DAC Soft Mute Rate", da9055_dac_soft_mute_rate),606 607	/* Zero Cross controls */608	SOC_DOUBLE_R("Aux ZC Switch", DA9055_AUX_L_CTRL,609		     DA9055_AUX_R_CTRL, 4, 1, 0),610	SOC_DOUBLE_R("Mixin PGA ZC Switch", DA9055_MIXIN_L_CTRL,611		     DA9055_MIXIN_R_CTRL, 4, 1, 0),612	SOC_DOUBLE_R("Headphone ZC Switch", DA9055_HP_L_CTRL,613		     DA9055_HP_R_CTRL, 4, 1, 0),614	SOC_SINGLE("Lineout ZC Switch", DA9055_LINE_CTRL, 4, 1, 0),615 616	/* Gain Ramping controls */617	SOC_DOUBLE_R("Aux Gain Ramping Switch", DA9055_AUX_L_CTRL,618		     DA9055_AUX_R_CTRL, 5, 1, 0),619	SOC_DOUBLE_R("Mixin Gain Ramping Switch", DA9055_MIXIN_L_CTRL,620		     DA9055_MIXIN_R_CTRL, 5, 1, 0),621	SOC_DOUBLE_R("ADC Gain Ramping Switch", DA9055_ADC_L_CTRL,622		     DA9055_ADC_R_CTRL, 5, 1, 0),623	SOC_DOUBLE_R("DAC Gain Ramping Switch", DA9055_DAC_L_CTRL,624		     DA9055_DAC_R_CTRL, 5, 1, 0),625	SOC_DOUBLE_R("Headphone Gain Ramping Switch", DA9055_HP_L_CTRL,626		     DA9055_HP_R_CTRL, 5, 1, 0),627	SOC_SINGLE("Lineout Gain Ramping Switch", DA9055_LINE_CTRL, 5, 1, 0),628	SOC_ENUM("Gain Ramping Rate", da9055_gain_ramping_rate),629 630	/* DAC Noise Gate controls */631	SOC_SINGLE("DAC NG Switch", DA9055_DAC_NG_CTRL, 7, 1, 0),632	SOC_SINGLE("DAC NG ON Threshold", DA9055_DAC_NG_ON_THRESHOLD,633		   0, 0x7, 0),634	SOC_SINGLE("DAC NG OFF Threshold", DA9055_DAC_NG_OFF_THRESHOLD,635		   0, 0x7, 0),636	SOC_ENUM("DAC NG Setup Time", da9055_dac_ng_setup_time),637	SOC_ENUM("DAC NG Rampup Rate", da9055_dac_ng_rampup_rate),638	SOC_ENUM("DAC NG Rampdown Rate", da9055_dac_ng_rampdown_rate),639 640	/* DAC Invertion control */641	SOC_SINGLE("DAC Left Invert", DA9055_DIG_CTRL, 3, 1, 0),642	SOC_SINGLE("DAC Right Invert", DA9055_DIG_CTRL, 7, 1, 0),643 644	/* DMIC controls */645	SOC_DOUBLE_R("DMIC Switch", DA9055_MIXIN_L_SELECT,646		     DA9055_MIXIN_R_SELECT, 7, 1, 0),647 648	/* ALC Controls */649	SOC_DOUBLE_EXT("ALC Switch", DA9055_ALC_CTRL1, 3, 7, 1, 0,650		       snd_soc_get_volsw, da9055_put_alc_sw),651	SOC_SINGLE_EXT("ALC Sync Mode Switch", DA9055_ALC_CTRL1, 1, 1, 0,652		       snd_soc_get_volsw, da9055_put_alc_sw),653	SOC_SINGLE("ALC Offset Switch", DA9055_ALC_CTRL1, 0, 1, 0),654	SOC_SINGLE("ALC Anticlip Mode Switch", DA9055_ALC_ANTICLIP_CTRL,655		   7, 1, 0),656	SOC_SINGLE("ALC Anticlip Level", DA9055_ALC_ANTICLIP_LEVEL,657		   0, 0x7f, 0),658	SOC_SINGLE_TLV("ALC Min Threshold Volume", DA9055_ALC_TARGET_MIN,659		       0, 0x3f, 1, alc_threshold_tlv),660	SOC_SINGLE_TLV("ALC Max Threshold Volume", DA9055_ALC_TARGET_MAX,661		       0, 0x3f, 1, alc_threshold_tlv),662	SOC_SINGLE_TLV("ALC Noise Threshold Volume", DA9055_ALC_NOISE,663		       0, 0x3f, 1, alc_threshold_tlv),664	SOC_SINGLE_TLV("ALC Max Gain Volume", DA9055_ALC_GAIN_LIMITS,665		       4, 0xf, 0, alc_gain_tlv),666	SOC_SINGLE_TLV("ALC Max Attenuation Volume", DA9055_ALC_GAIN_LIMITS,667		       0, 0xf, 0, alc_gain_tlv),668	SOC_SINGLE_TLV("ALC Min Analog Gain Volume",669		       DA9055_ALC_ANA_GAIN_LIMITS,670		       0, 0x7, 0, alc_analog_gain_tlv),671	SOC_SINGLE_TLV("ALC Max Analog Gain Volume",672		       DA9055_ALC_ANA_GAIN_LIMITS,673		       4, 0x7, 0, alc_analog_gain_tlv),674	SOC_ENUM("ALC Attack Rate", da9055_attack_rate),675	SOC_ENUM("ALC Release Rate", da9055_release_rate),676	SOC_ENUM("ALC Hold Time", da9055_hold_time),677	/*678	 * Rate at which input signal envelope is tracked as the signal gets679	 * larger680	 */681	SOC_ENUM("ALC Integ Attack Rate", da9055_integ_attack_rate),682	/*683	 * Rate at which input signal envelope is tracked as the signal gets684	 * smaller685	 */686	SOC_ENUM("ALC Integ Release Rate", da9055_integ_release_rate),687};688 689/* DAPM Controls */690 691/* Mic PGA Left Source */692static const struct snd_kcontrol_new da9055_mic_l_mux_controls =693SOC_DAPM_ENUM("Route", da9055_mic_l_src);694 695/* Mic PGA Right Source */696static const struct snd_kcontrol_new da9055_mic_r_mux_controls =697SOC_DAPM_ENUM("Route", da9055_mic_r_src);698 699/* In Mixer Left */700static const struct snd_kcontrol_new da9055_dapm_mixinl_controls[] = {701	SOC_DAPM_SINGLE("Aux Left Switch", DA9055_MIXIN_L_SELECT, 0, 1, 0),702	SOC_DAPM_SINGLE("Mic Left Switch", DA9055_MIXIN_L_SELECT, 1, 1, 0),703	SOC_DAPM_SINGLE("Mic Right Switch", DA9055_MIXIN_L_SELECT, 2, 1, 0),704};705 706/* In Mixer Right */707static const struct snd_kcontrol_new da9055_dapm_mixinr_controls[] = {708	SOC_DAPM_SINGLE("Aux Right Switch", DA9055_MIXIN_R_SELECT, 0, 1, 0),709	SOC_DAPM_SINGLE("Mic Right Switch", DA9055_MIXIN_R_SELECT, 1, 1, 0),710	SOC_DAPM_SINGLE("Mic Left Switch", DA9055_MIXIN_R_SELECT, 2, 1, 0),711	SOC_DAPM_SINGLE("Mixin Left Switch", DA9055_MIXIN_R_SELECT, 3, 1, 0),712};713 714/* DAC Left Source */715static const struct snd_kcontrol_new da9055_dac_l_mux_controls =716SOC_DAPM_ENUM("Route", da9055_dac_l_src);717 718/* DAC Right Source */719static const struct snd_kcontrol_new da9055_dac_r_mux_controls =720SOC_DAPM_ENUM("Route", da9055_dac_r_src);721 722/* Out Mixer Left */723static const struct snd_kcontrol_new da9055_dapm_mixoutl_controls[] = {724	SOC_DAPM_SINGLE("Aux Left Switch", DA9055_MIXOUT_L_SELECT, 0, 1, 0),725	SOC_DAPM_SINGLE("Mixin Left Switch", DA9055_MIXOUT_L_SELECT, 1, 1, 0),726	SOC_DAPM_SINGLE("Mixin Right Switch", DA9055_MIXOUT_L_SELECT, 2, 1, 0),727	SOC_DAPM_SINGLE("DAC Left Switch", DA9055_MIXOUT_L_SELECT, 3, 1, 0),728	SOC_DAPM_SINGLE("Aux Left Invert Switch", DA9055_MIXOUT_L_SELECT,729			4, 1, 0),730	SOC_DAPM_SINGLE("Mixin Left Invert Switch", DA9055_MIXOUT_L_SELECT,731			5, 1, 0),732	SOC_DAPM_SINGLE("Mixin Right Invert Switch", DA9055_MIXOUT_L_SELECT,733			6, 1, 0),734};735 736/* Out Mixer Right */737static const struct snd_kcontrol_new da9055_dapm_mixoutr_controls[] = {738	SOC_DAPM_SINGLE("Aux Right Switch", DA9055_MIXOUT_R_SELECT, 0, 1, 0),739	SOC_DAPM_SINGLE("Mixin Right Switch", DA9055_MIXOUT_R_SELECT, 1, 1, 0),740	SOC_DAPM_SINGLE("Mixin Left Switch", DA9055_MIXOUT_R_SELECT, 2, 1, 0),741	SOC_DAPM_SINGLE("DAC Right Switch", DA9055_MIXOUT_R_SELECT, 3, 1, 0),742	SOC_DAPM_SINGLE("Aux Right Invert Switch", DA9055_MIXOUT_R_SELECT,743			4, 1, 0),744	SOC_DAPM_SINGLE("Mixin Right Invert Switch", DA9055_MIXOUT_R_SELECT,745			5, 1, 0),746	SOC_DAPM_SINGLE("Mixin Left Invert Switch", DA9055_MIXOUT_R_SELECT,747			6, 1, 0),748};749 750/* Headphone Output Enable */751static const struct snd_kcontrol_new da9055_dapm_hp_l_control =752SOC_DAPM_SINGLE("Switch", DA9055_HP_L_CTRL, 3, 1, 0);753 754static const struct snd_kcontrol_new da9055_dapm_hp_r_control =755SOC_DAPM_SINGLE("Switch", DA9055_HP_R_CTRL, 3, 1, 0);756 757/* Lineout Output Enable */758static const struct snd_kcontrol_new da9055_dapm_lineout_control =759SOC_DAPM_SINGLE("Switch", DA9055_LINE_CTRL, 3, 1, 0);760 761/* DAPM widgets */762static const struct snd_soc_dapm_widget da9055_dapm_widgets[] = {763	/* Input Side */764 765	/* Input Lines */766	SND_SOC_DAPM_INPUT("MIC1"),767	SND_SOC_DAPM_INPUT("MIC2"),768	SND_SOC_DAPM_INPUT("AUXL"),769	SND_SOC_DAPM_INPUT("AUXR"),770 771	/* MUXs for Mic PGA source selection */772	SND_SOC_DAPM_MUX("Mic Left Source", SND_SOC_NOPM, 0, 0,773			 &da9055_mic_l_mux_controls),774	SND_SOC_DAPM_MUX("Mic Right Source", SND_SOC_NOPM, 0, 0,775			 &da9055_mic_r_mux_controls),776 777	/* Input PGAs */778	SND_SOC_DAPM_PGA("Mic Left", DA9055_MIC_L_CTRL, 7, 0, NULL, 0),779	SND_SOC_DAPM_PGA("Mic Right", DA9055_MIC_R_CTRL, 7, 0, NULL, 0),780	SND_SOC_DAPM_PGA("Aux Left", DA9055_AUX_L_CTRL, 7, 0, NULL, 0),781	SND_SOC_DAPM_PGA("Aux Right", DA9055_AUX_R_CTRL, 7, 0, NULL, 0),782	SND_SOC_DAPM_PGA("MIXIN Left", DA9055_MIXIN_L_CTRL, 7, 0, NULL, 0),783	SND_SOC_DAPM_PGA("MIXIN Right", DA9055_MIXIN_R_CTRL, 7, 0, NULL, 0),784 785	SND_SOC_DAPM_SUPPLY("Mic Bias", DA9055_MIC_BIAS_CTRL, 7, 0, NULL, 0),786	SND_SOC_DAPM_SUPPLY("AIF", DA9055_AIF_CTRL, 7, 0, NULL, 0),787	SND_SOC_DAPM_SUPPLY("Charge Pump", DA9055_CP_CTRL, 7, 0, NULL, 0),788 789	/* Input Mixers */790	SND_SOC_DAPM_MIXER("In Mixer Left", SND_SOC_NOPM, 0, 0,791			   &da9055_dapm_mixinl_controls[0],792			   ARRAY_SIZE(da9055_dapm_mixinl_controls)),793	SND_SOC_DAPM_MIXER("In Mixer Right", SND_SOC_NOPM, 0, 0,794			   &da9055_dapm_mixinr_controls[0],795			   ARRAY_SIZE(da9055_dapm_mixinr_controls)),796 797	/* ADCs */798	SND_SOC_DAPM_ADC("ADC Left", "Capture", DA9055_ADC_L_CTRL, 7, 0),799	SND_SOC_DAPM_ADC("ADC Right", "Capture", DA9055_ADC_R_CTRL, 7, 0),800 801	/* Output Side */802 803	/* MUXs for DAC source selection */804	SND_SOC_DAPM_MUX("DAC Left Source", SND_SOC_NOPM, 0, 0,805			 &da9055_dac_l_mux_controls),806	SND_SOC_DAPM_MUX("DAC Right Source", SND_SOC_NOPM, 0, 0,807			 &da9055_dac_r_mux_controls),808 809	/* AIF input */810	SND_SOC_DAPM_AIF_IN("AIFIN Left", "Playback", 0, SND_SOC_NOPM, 0, 0),811	SND_SOC_DAPM_AIF_IN("AIFIN Right", "Playback", 0, SND_SOC_NOPM, 0, 0),812 813	/* DACs */814	SND_SOC_DAPM_DAC("DAC Left", "Playback", DA9055_DAC_L_CTRL, 7, 0),815	SND_SOC_DAPM_DAC("DAC Right", "Playback", DA9055_DAC_R_CTRL, 7, 0),816 817	/* Output Mixers */818	SND_SOC_DAPM_MIXER("Out Mixer Left", SND_SOC_NOPM, 0, 0,819			   &da9055_dapm_mixoutl_controls[0],820			   ARRAY_SIZE(da9055_dapm_mixoutl_controls)),821	SND_SOC_DAPM_MIXER("Out Mixer Right", SND_SOC_NOPM, 0, 0,822			   &da9055_dapm_mixoutr_controls[0],823			   ARRAY_SIZE(da9055_dapm_mixoutr_controls)),824 825	/* Output Enable Switches */826	SND_SOC_DAPM_SWITCH("Headphone Left Enable", SND_SOC_NOPM, 0, 0,827			    &da9055_dapm_hp_l_control),828	SND_SOC_DAPM_SWITCH("Headphone Right Enable", SND_SOC_NOPM, 0, 0,829			    &da9055_dapm_hp_r_control),830	SND_SOC_DAPM_SWITCH("Lineout Enable", SND_SOC_NOPM, 0, 0,831			    &da9055_dapm_lineout_control),832 833	/* Output PGAs */834	SND_SOC_DAPM_PGA("MIXOUT Left", DA9055_MIXOUT_L_CTRL, 7, 0, NULL, 0),835	SND_SOC_DAPM_PGA("MIXOUT Right", DA9055_MIXOUT_R_CTRL, 7, 0, NULL, 0),836	SND_SOC_DAPM_PGA("Lineout", DA9055_LINE_CTRL, 7, 0, NULL, 0),837	SND_SOC_DAPM_PGA("Headphone Left", DA9055_HP_L_CTRL, 7, 0, NULL, 0),838	SND_SOC_DAPM_PGA("Headphone Right", DA9055_HP_R_CTRL, 7, 0, NULL, 0),839 840	/* Output Lines */841	SND_SOC_DAPM_OUTPUT("HPL"),842	SND_SOC_DAPM_OUTPUT("HPR"),843	SND_SOC_DAPM_OUTPUT("LINE"),844};845 846/* DAPM audio route definition */847static const struct snd_soc_dapm_route da9055_audio_map[] = {848	/* Dest       Connecting Widget    source */849 850	/* Input path */851	{"Mic Left Source", "MIC1_P_N", "MIC1"},852	{"Mic Left Source", "MIC1_P", "MIC1"},853	{"Mic Left Source", "MIC1_N", "MIC1"},854	{"Mic Left Source", "MIC2_L", "MIC2"},855 856	{"Mic Right Source", "MIC2_R_L", "MIC2"},857	{"Mic Right Source", "MIC2_R", "MIC2"},858	{"Mic Right Source", "MIC2_L", "MIC2"},859 860	{"Mic Left", NULL, "Mic Left Source"},861	{"Mic Right", NULL, "Mic Right Source"},862 863	{"Aux Left", NULL, "AUXL"},864	{"Aux Right", NULL, "AUXR"},865 866	{"In Mixer Left", "Mic Left Switch", "Mic Left"},867	{"In Mixer Left", "Mic Right Switch", "Mic Right"},868	{"In Mixer Left", "Aux Left Switch", "Aux Left"},869 870	{"In Mixer Right", "Mic Right Switch", "Mic Right"},871	{"In Mixer Right", "Mic Left Switch", "Mic Left"},872	{"In Mixer Right", "Aux Right Switch", "Aux Right"},873	{"In Mixer Right", "Mixin Left Switch", "MIXIN Left"},874 875	{"MIXIN Left", NULL, "In Mixer Left"},876	{"ADC Left", NULL, "MIXIN Left"},877 878	{"MIXIN Right", NULL, "In Mixer Right"},879	{"ADC Right", NULL, "MIXIN Right"},880 881	{"ADC Left", NULL, "AIF"},882	{"ADC Right", NULL, "AIF"},883 884	/* Output path */885	{"AIFIN Left", NULL, "AIF"},886	{"AIFIN Right", NULL, "AIF"},887 888	{"DAC Left Source", "ADC output left", "ADC Left"},889	{"DAC Left Source", "ADC output right", "ADC Right"},890	{"DAC Left Source", "AIF input left", "AIFIN Left"},891	{"DAC Left Source", "AIF input right", "AIFIN Right"},892 893	{"DAC Right Source", "ADC output left", "ADC Left"},894	{"DAC Right Source", "ADC output right", "ADC Right"},895	{"DAC Right Source", "AIF input left", "AIFIN Left"},896	{"DAC Right Source", "AIF input right", "AIFIN Right"},897 898	{"DAC Left", NULL, "DAC Left Source"},899	{"DAC Right", NULL, "DAC Right Source"},900 901	{"Out Mixer Left", "Aux Left Switch", "Aux Left"},902	{"Out Mixer Left", "Mixin Left Switch", "MIXIN Left"},903	{"Out Mixer Left", "Mixin Right Switch", "MIXIN Right"},904	{"Out Mixer Left", "Aux Left Invert Switch", "Aux Left"},905	{"Out Mixer Left", "Mixin Left Invert Switch", "MIXIN Left"},906	{"Out Mixer Left", "Mixin Right Invert Switch", "MIXIN Right"},907	{"Out Mixer Left", "DAC Left Switch", "DAC Left"},908 909	{"Out Mixer Right", "Aux Right Switch", "Aux Right"},910	{"Out Mixer Right", "Mixin Right Switch", "MIXIN Right"},911	{"Out Mixer Right", "Mixin Left Switch", "MIXIN Left"},912	{"Out Mixer Right", "Aux Right Invert Switch", "Aux Right"},913	{"Out Mixer Right", "Mixin Right Invert Switch", "MIXIN Right"},914	{"Out Mixer Right", "Mixin Left Invert Switch", "MIXIN Left"},915	{"Out Mixer Right", "DAC Right Switch", "DAC Right"},916 917	{"MIXOUT Left", NULL, "Out Mixer Left"},918	{"Headphone Left Enable", "Switch", "MIXOUT Left"},919	{"Headphone Left", NULL, "Headphone Left Enable"},920	{"Headphone Left", NULL, "Charge Pump"},921	{"HPL", NULL, "Headphone Left"},922 923	{"MIXOUT Right", NULL, "Out Mixer Right"},924	{"Headphone Right Enable", "Switch", "MIXOUT Right"},925	{"Headphone Right", NULL, "Headphone Right Enable"},926	{"Headphone Right", NULL, "Charge Pump"},927	{"HPR", NULL, "Headphone Right"},928 929	{"MIXOUT Right", NULL, "Out Mixer Right"},930	{"Lineout Enable", "Switch", "MIXOUT Right"},931	{"Lineout", NULL, "Lineout Enable"},932	{"LINE", NULL, "Lineout"},933};934 935/* Codec private data */936struct da9055_priv {937	struct regmap *regmap;938	unsigned int mclk_rate;939	int master;940	struct da9055_platform_data *pdata;941};942 943static const struct reg_default da9055_reg_defaults[] = {944	{ 0x21, 0x10 },945	{ 0x22, 0x0A },946	{ 0x23, 0x00 },947	{ 0x24, 0x00 },948	{ 0x25, 0x00 },949	{ 0x26, 0x00 },950	{ 0x27, 0x0C },951	{ 0x28, 0x01 },952	{ 0x29, 0x08 },953	{ 0x2A, 0x32 },954	{ 0x2B, 0x00 },955	{ 0x30, 0x35 },956	{ 0x31, 0x35 },957	{ 0x32, 0x00 },958	{ 0x33, 0x00 },959	{ 0x34, 0x03 },960	{ 0x35, 0x03 },961	{ 0x36, 0x6F },962	{ 0x37, 0x6F },963	{ 0x38, 0x80 },964	{ 0x39, 0x01 },965	{ 0x3A, 0x01 },966	{ 0x40, 0x00 },967	{ 0x41, 0x88 },968	{ 0x42, 0x88 },969	{ 0x43, 0x08 },970	{ 0x44, 0x80 },971	{ 0x45, 0x6F },972	{ 0x46, 0x6F },973	{ 0x47, 0x61 },974	{ 0x48, 0x35 },975	{ 0x49, 0x35 },976	{ 0x4A, 0x35 },977	{ 0x4B, 0x00 },978	{ 0x4C, 0x00 },979	{ 0x60, 0x44 },980	{ 0x61, 0x44 },981	{ 0x62, 0x00 },982	{ 0x63, 0x40 },983	{ 0x64, 0x40 },984	{ 0x65, 0x40 },985	{ 0x66, 0x40 },986	{ 0x67, 0x40 },987	{ 0x68, 0x40 },988	{ 0x69, 0x48 },989	{ 0x6A, 0x40 },990	{ 0x6B, 0x41 },991	{ 0x6C, 0x40 },992	{ 0x6D, 0x40 },993	{ 0x6E, 0x10 },994	{ 0x6F, 0x10 },995	{ 0x90, 0x80 },996	{ 0x92, 0x02 },997	{ 0x93, 0x00 },998	{ 0x99, 0x00 },999	{ 0x9A, 0x00 },1000	{ 0x9B, 0x00 },1001	{ 0x9C, 0x3F },1002	{ 0x9D, 0x00 },1003	{ 0x9E, 0x3F },1004	{ 0x9F, 0xFF },1005	{ 0xA0, 0x71 },1006	{ 0xA1, 0x00 },1007	{ 0xA2, 0x00 },1008	{ 0xA6, 0x00 },1009	{ 0xA7, 0x00 },1010	{ 0xAB, 0x00 },1011	{ 0xAC, 0x00 },1012	{ 0xAD, 0x00 },1013	{ 0xAF, 0x08 },1014	{ 0xB0, 0x00 },1015	{ 0xB1, 0x00 },1016	{ 0xB2, 0x00 },1017};1018 1019static bool da9055_volatile_register(struct device *dev,1020				     unsigned int reg)1021{1022	switch (reg) {1023	case DA9055_STATUS1:1024	case DA9055_PLL_STATUS:1025	case DA9055_AUX_L_GAIN_STATUS:1026	case DA9055_AUX_R_GAIN_STATUS:1027	case DA9055_MIC_L_GAIN_STATUS:1028	case DA9055_MIC_R_GAIN_STATUS:1029	case DA9055_MIXIN_L_GAIN_STATUS:1030	case DA9055_MIXIN_R_GAIN_STATUS:1031	case DA9055_ADC_L_GAIN_STATUS:1032	case DA9055_ADC_R_GAIN_STATUS:1033	case DA9055_DAC_L_GAIN_STATUS:1034	case DA9055_DAC_R_GAIN_STATUS:1035	case DA9055_HP_L_GAIN_STATUS:1036	case DA9055_HP_R_GAIN_STATUS:1037	case DA9055_LINE_GAIN_STATUS:1038	case DA9055_ALC_CIC_OP_LVL_DATA:1039		return true;1040	default:1041		return false;1042	}1043}1044 1045/* Set DAI word length */1046static int da9055_hw_params(struct snd_pcm_substream *substream,1047			    struct snd_pcm_hw_params *params,1048			    struct snd_soc_dai *dai)1049{1050	struct snd_soc_component *component = dai->component;1051	struct da9055_priv *da9055 = snd_soc_component_get_drvdata(component);1052	u8 aif_ctrl, fs;1053	u32 sysclk;1054 1055	switch (params_width(params)) {1056	case 16:1057		aif_ctrl = DA9055_AIF_WORD_S16_LE;1058		break;1059	case 20:1060		aif_ctrl = DA9055_AIF_WORD_S20_3LE;1061		break;1062	case 24:1063		aif_ctrl = DA9055_AIF_WORD_S24_LE;1064		break;1065	case 32:1066		aif_ctrl = DA9055_AIF_WORD_S32_LE;1067		break;1068	default:1069		return -EINVAL;1070	}1071 1072	/* Set AIF format */1073	snd_soc_component_update_bits(component, DA9055_AIF_CTRL, DA9055_AIF_WORD_LENGTH_MASK,1074			    aif_ctrl);1075 1076	switch (params_rate(params)) {1077	case 8000:1078		fs		= DA9055_SR_8000;1079		sysclk		= 3072000;1080		break;1081	case 11025:1082		fs		= DA9055_SR_11025;1083		sysclk		= 2822400;1084		break;1085	case 12000:1086		fs		= DA9055_SR_12000;1087		sysclk		= 3072000;1088		break;1089	case 16000:1090		fs		= DA9055_SR_16000;1091		sysclk		= 3072000;1092		break;1093	case 22050:1094		fs		= DA9055_SR_22050;1095		sysclk		= 2822400;1096		break;1097	case 32000:1098		fs		= DA9055_SR_32000;1099		sysclk		= 3072000;1100		break;1101	case 44100:1102		fs		= DA9055_SR_44100;1103		sysclk		= 2822400;1104		break;1105	case 48000:1106		fs		= DA9055_SR_48000;1107		sysclk		= 3072000;1108		break;1109	case 88200:1110		fs		= DA9055_SR_88200;1111		sysclk		= 2822400;1112		break;1113	case 96000:1114		fs		= DA9055_SR_96000;1115		sysclk		= 3072000;1116		break;1117	default:1118		return -EINVAL;1119	}1120 1121	if (da9055->mclk_rate) {1122		/* PLL Mode, Write actual FS */1123		snd_soc_component_write(component, DA9055_SR, fs);1124	} else {1125		/*1126		 * Non-PLL Mode1127		 * When PLL is bypassed, chip assumes constant MCLK of1128		 * 12.288MHz and uses sample rate value to divide this MCLK1129		 * to derive its sys clk. As sys clk has to be 256 * Fs, we1130		 * need to write constant sample rate i.e. 48KHz.1131		 */1132		snd_soc_component_write(component, DA9055_SR, DA9055_SR_48000);1133	}1134 1135	if (da9055->mclk_rate && (da9055->mclk_rate != sysclk)) {1136		/* PLL Mode */1137		if (!da9055->master) {1138			/* PLL slave mode, enable PLL and also SRM */1139			snd_soc_component_update_bits(component, DA9055_PLL_CTRL,1140					    DA9055_PLL_EN | DA9055_PLL_SRM_EN,1141					    DA9055_PLL_EN | DA9055_PLL_SRM_EN);1142		} else {1143			/* PLL master mode, only enable PLL */1144			snd_soc_component_update_bits(component, DA9055_PLL_CTRL,1145					    DA9055_PLL_EN, DA9055_PLL_EN);1146		}1147	} else {1148		/* Non PLL Mode, disable PLL */1149		snd_soc_component_update_bits(component, DA9055_PLL_CTRL, DA9055_PLL_EN, 0);1150	}1151 1152	return 0;1153}1154 1155/* Set DAI mode and Format */1156static int da9055_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)1157{1158	struct snd_soc_component *component = codec_dai->component;1159	struct da9055_priv *da9055 = snd_soc_component_get_drvdata(component);1160	u8 aif_clk_mode, aif_ctrl, mode;1161 1162	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {1163	case SND_SOC_DAIFMT_CBM_CFM:1164		/* DA9055 in I2S Master Mode */1165		mode = 1;1166		aif_clk_mode = DA9055_AIF_CLK_EN_MASTER_MODE;1167		break;1168	case SND_SOC_DAIFMT_CBS_CFS:1169		/* DA9055 in I2S Slave Mode */1170		mode = 0;1171		aif_clk_mode = DA9055_AIF_CLK_EN_SLAVE_MODE;1172		break;1173	default:1174		return -EINVAL;1175	}1176 1177	/* Don't allow change of mode if PLL is enabled */1178	if ((snd_soc_component_read(component, DA9055_PLL_CTRL) & DA9055_PLL_EN) &&1179	    (da9055->master != mode))1180		return -EINVAL;1181 1182	da9055->master = mode;1183 1184	/* Only I2S is supported */1185	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {1186	case SND_SOC_DAIFMT_I2S:1187		aif_ctrl = DA9055_AIF_FORMAT_I2S_MODE;1188		break;1189	case SND_SOC_DAIFMT_LEFT_J:1190		aif_ctrl = DA9055_AIF_FORMAT_LEFT_J;1191		break;1192	case SND_SOC_DAIFMT_RIGHT_J:1193		aif_ctrl = DA9055_AIF_FORMAT_RIGHT_J;1194		break;1195	case SND_SOC_DAIFMT_DSP_A:1196		aif_ctrl = DA9055_AIF_FORMAT_DSP;1197		break;1198	default:1199		return -EINVAL;1200	}1201 1202	/* By default only 32 BCLK per WCLK is supported */1203	aif_clk_mode |= DA9055_AIF_BCLKS_PER_WCLK_32;1204 1205	snd_soc_component_update_bits(component, DA9055_AIF_CLK_MODE,1206			    (DA9055_AIF_CLK_MODE_MASK | DA9055_AIF_BCLK_MASK),1207			    aif_clk_mode);1208	snd_soc_component_update_bits(component, DA9055_AIF_CTRL, DA9055_AIF_FORMAT_MASK,1209			    aif_ctrl);1210	return 0;1211}1212 1213static int da9055_mute(struct snd_soc_dai *dai, int mute, int direction)1214{1215	struct snd_soc_component *component = dai->component;1216 1217	if (mute) {1218		snd_soc_component_update_bits(component, DA9055_DAC_L_CTRL,1219				    DA9055_DAC_L_MUTE_EN, DA9055_DAC_L_MUTE_EN);1220		snd_soc_component_update_bits(component, DA9055_DAC_R_CTRL,1221				    DA9055_DAC_R_MUTE_EN, DA9055_DAC_R_MUTE_EN);1222	} else {1223		snd_soc_component_update_bits(component, DA9055_DAC_L_CTRL,1224				    DA9055_DAC_L_MUTE_EN, 0);1225		snd_soc_component_update_bits(component, DA9055_DAC_R_CTRL,1226				    DA9055_DAC_R_MUTE_EN, 0);1227	}1228 1229	return 0;1230}1231 1232#define DA9055_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\1233			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)1234 1235static int da9055_set_dai_sysclk(struct snd_soc_dai *codec_dai,1236				 int clk_id, unsigned int freq, int dir)1237{1238	struct snd_soc_component *component = codec_dai->component;1239	struct da9055_priv *da9055 = snd_soc_component_get_drvdata(component);1240 1241	switch (clk_id) {1242	case DA9055_CLKSRC_MCLK:1243		switch (freq) {1244		case 11289600:1245		case 12000000:1246		case 12288000:1247		case 13000000:1248		case 13500000:1249		case 14400000:1250		case 19200000:1251		case 19680000:1252		case 19800000:1253			da9055->mclk_rate = freq;1254			return 0;1255		default:1256			dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",1257				freq);1258			return -EINVAL;1259		}1260		break;1261	default:1262		dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);1263		return -EINVAL;1264	}1265}1266 1267/*1268 * da9055_set_dai_pll	: Configure the codec PLL1269 * @param codec_dai	: Pointer to codec DAI1270 * @param pll_id	: da9055 has only one pll, so pll_id is always zero1271 * @param fref		: Input MCLK frequency1272 * @param fout		: FsDM value1273 * @return int		: Zero for success, negative error code for error1274 *1275 * Note: Supported PLL input frequencies are 11.2896MHz, 12MHz, 12.288MHz,1276 *	 13MHz, 13.5MHz, 14.4MHz, 19.2MHz, 19.6MHz and 19.8MHz1277 */1278static int da9055_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,1279			      int source, unsigned int fref, unsigned int fout)1280{1281	struct snd_soc_component *component = codec_dai->component;1282	struct da9055_priv *da9055 = snd_soc_component_get_drvdata(component);1283 1284	u8 pll_frac_top, pll_frac_bot, pll_integer, cnt;1285 1286	/* Disable PLL before setting the divisors */1287	snd_soc_component_update_bits(component, DA9055_PLL_CTRL, DA9055_PLL_EN, 0);1288 1289	/* In slave mode, there is only one set of divisors */1290	if (!da9055->master && (fout != 2822400))1291		goto pll_err;1292 1293	/* Search pll div array for correct divisors */1294	for (cnt = 0; cnt < ARRAY_SIZE(da9055_pll_div); cnt++) {1295		/* Check fref, mode  and fout */1296		if ((fref == da9055_pll_div[cnt].fref) &&1297		    (da9055->master ==  da9055_pll_div[cnt].mode) &&1298		    (fout == da9055_pll_div[cnt].fout)) {1299			/* All match, pick up divisors */1300			pll_frac_top = da9055_pll_div[cnt].frac_top;1301			pll_frac_bot = da9055_pll_div[cnt].frac_bot;1302			pll_integer = da9055_pll_div[cnt].integer;1303			break;1304		}1305	}1306	if (cnt >= ARRAY_SIZE(da9055_pll_div))1307		goto pll_err;1308 1309	/* Write PLL dividers */1310	snd_soc_component_write(component, DA9055_PLL_FRAC_TOP, pll_frac_top);1311	snd_soc_component_write(component, DA9055_PLL_FRAC_BOT, pll_frac_bot);1312	snd_soc_component_write(component, DA9055_PLL_INTEGER, pll_integer);1313 1314	return 0;1315pll_err:1316	dev_err(codec_dai->dev, "Error in setting up PLL\n");1317	return -EINVAL;1318}1319 1320/* DAI operations */1321static const struct snd_soc_dai_ops da9055_dai_ops = {1322	.hw_params	= da9055_hw_params,1323	.set_fmt	= da9055_set_dai_fmt,1324	.set_sysclk	= da9055_set_dai_sysclk,1325	.set_pll	= da9055_set_dai_pll,1326	.mute_stream	= da9055_mute,1327	.no_capture_mute = 1,1328};1329 1330static struct snd_soc_dai_driver da9055_dai = {1331	.name = "da9055-hifi",1332	/* Playback Capabilities */1333	.playback = {1334		.stream_name = "Playback",1335		.channels_min = 1,1336		.channels_max = 2,1337		.rates = SNDRV_PCM_RATE_8000_96000,1338		.formats = DA9055_FORMATS,1339	},1340	/* Capture Capabilities */1341	.capture = {1342		.stream_name = "Capture",1343		.channels_min = 1,1344		.channels_max = 2,1345		.rates = SNDRV_PCM_RATE_8000_96000,1346		.formats = DA9055_FORMATS,1347	},1348	.ops = &da9055_dai_ops,1349	.symmetric_rate = 1,1350};1351 1352static int da9055_set_bias_level(struct snd_soc_component *component,1353				 enum snd_soc_bias_level level)1354{1355	switch (level) {1356	case SND_SOC_BIAS_ON:1357	case SND_SOC_BIAS_PREPARE:1358		break;1359	case SND_SOC_BIAS_STANDBY:1360		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {1361			/* Enable VMID reference & master bias */1362			snd_soc_component_update_bits(component, DA9055_REFERENCES,1363					    DA9055_VMID_EN | DA9055_BIAS_EN,1364					    DA9055_VMID_EN | DA9055_BIAS_EN);1365		}1366		break;1367	case SND_SOC_BIAS_OFF:1368		/* Disable VMID reference & master bias */1369		snd_soc_component_update_bits(component, DA9055_REFERENCES,1370				    DA9055_VMID_EN | DA9055_BIAS_EN, 0);1371		break;1372	}1373	return 0;1374}1375 1376static int da9055_probe(struct snd_soc_component *component)1377{1378	struct da9055_priv *da9055 = snd_soc_component_get_drvdata(component);1379 1380	/* Enable all Gain Ramps */1381	snd_soc_component_update_bits(component, DA9055_AUX_L_CTRL,1382			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);1383	snd_soc_component_update_bits(component, DA9055_AUX_R_CTRL,1384			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);1385	snd_soc_component_update_bits(component, DA9055_MIXIN_L_CTRL,1386			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);1387	snd_soc_component_update_bits(component, DA9055_MIXIN_R_CTRL,1388			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);1389	snd_soc_component_update_bits(component, DA9055_ADC_L_CTRL,1390			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);1391	snd_soc_component_update_bits(component, DA9055_ADC_R_CTRL,1392			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);1393	snd_soc_component_update_bits(component, DA9055_DAC_L_CTRL,1394			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);1395	snd_soc_component_update_bits(component, DA9055_DAC_R_CTRL,1396			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);1397	snd_soc_component_update_bits(component, DA9055_HP_L_CTRL,1398			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);1399	snd_soc_component_update_bits(component, DA9055_HP_R_CTRL,1400			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);1401	snd_soc_component_update_bits(component, DA9055_LINE_CTRL,1402			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);1403 1404	/*1405	 * There are two separate control bits for input and output mixers.1406	 * One to enable corresponding amplifier and other to enable its1407	 * output. As amplifier bits are related to power control, they are1408	 * being managed by DAPM while other (non power related) bits are1409	 * enabled here1410	 */1411	snd_soc_component_update_bits(component, DA9055_MIXIN_L_CTRL,1412			    DA9055_MIXIN_L_MIX_EN, DA9055_MIXIN_L_MIX_EN);1413	snd_soc_component_update_bits(component, DA9055_MIXIN_R_CTRL,1414			    DA9055_MIXIN_R_MIX_EN, DA9055_MIXIN_R_MIX_EN);1415 1416	snd_soc_component_update_bits(component, DA9055_MIXOUT_L_CTRL,1417			    DA9055_MIXOUT_L_MIX_EN, DA9055_MIXOUT_L_MIX_EN);1418	snd_soc_component_update_bits(component, DA9055_MIXOUT_R_CTRL,1419			    DA9055_MIXOUT_R_MIX_EN, DA9055_MIXOUT_R_MIX_EN);1420 1421	/* Set this as per your system configuration */1422	snd_soc_component_write(component, DA9055_PLL_CTRL, DA9055_PLL_INDIV_10_20_MHZ);1423 1424	/* Set platform data values */1425	if (da9055->pdata) {1426		/* set mic bias source */1427		if (da9055->pdata->micbias_source) {1428			snd_soc_component_update_bits(component, DA9055_MIXIN_R_SELECT,1429					    DA9055_MICBIAS2_EN,1430					    DA9055_MICBIAS2_EN);1431		} else {1432			snd_soc_component_update_bits(component, DA9055_MIXIN_R_SELECT,1433					    DA9055_MICBIAS2_EN, 0);1434		}1435		/* set mic bias voltage */1436		switch (da9055->pdata->micbias) {1437		case DA9055_MICBIAS_2_2V:1438		case DA9055_MICBIAS_2_1V:1439		case DA9055_MICBIAS_1_8V:1440		case DA9055_MICBIAS_1_6V:1441			snd_soc_component_update_bits(component, DA9055_MIC_CONFIG,1442					    DA9055_MICBIAS_LEVEL_MASK,1443					    (da9055->pdata->micbias) << 4);1444			break;1445		}1446	}1447	return 0;1448}1449 1450static const struct snd_soc_component_driver soc_component_dev_da9055 = {1451	.probe			= da9055_probe,1452	.set_bias_level		= da9055_set_bias_level,1453	.controls		= da9055_snd_controls,1454	.num_controls		= ARRAY_SIZE(da9055_snd_controls),1455	.dapm_widgets		= da9055_dapm_widgets,1456	.num_dapm_widgets	= ARRAY_SIZE(da9055_dapm_widgets),1457	.dapm_routes		= da9055_audio_map,1458	.num_dapm_routes	= ARRAY_SIZE(da9055_audio_map),1459	.idle_bias_on		= 1,1460	.use_pmdown_time	= 1,1461	.endianness		= 1,1462};1463 1464static const struct regmap_config da9055_regmap_config = {1465	.reg_bits = 8,1466	.val_bits = 8,1467 1468	.reg_defaults = da9055_reg_defaults,1469	.num_reg_defaults = ARRAY_SIZE(da9055_reg_defaults),1470	.volatile_reg = da9055_volatile_register,1471	.cache_type = REGCACHE_RBTREE,1472};1473 1474static int da9055_i2c_probe(struct i2c_client *i2c)1475{1476	struct da9055_priv *da9055;1477	struct da9055_platform_data *pdata = dev_get_platdata(&i2c->dev);1478	int ret;1479 1480	da9055 = devm_kzalloc(&i2c->dev, sizeof(struct da9055_priv),1481			      GFP_KERNEL);1482	if (!da9055)1483		return -ENOMEM;1484 1485	if (pdata)1486		da9055->pdata = pdata;1487 1488	i2c_set_clientdata(i2c, da9055);1489 1490	da9055->regmap = devm_regmap_init_i2c(i2c, &da9055_regmap_config);1491	if (IS_ERR(da9055->regmap)) {1492		ret = PTR_ERR(da9055->regmap);1493		dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);1494		return ret;1495	}1496 1497	ret = devm_snd_soc_register_component(&i2c->dev,1498			&soc_component_dev_da9055, &da9055_dai, 1);1499	if (ret < 0) {1500		dev_err(&i2c->dev, "Failed to register da9055 component: %d\n",1501			ret);1502	}1503	return ret;1504}1505 1506/*1507 * DO NOT change the device Ids. The naming is intentionally specific as both1508 * the CODEC and PMIC parts of this chip are instantiated separately as I2C1509 * devices (both have configurable I2C addresses, and are to all intents and1510 * purposes separate). As a result there are specific DA9055 Ids for CODEC1511 * and PMIC, which must be different to operate together.1512 */1513static const struct i2c_device_id da9055_i2c_id[] = {1514	{ "da9055-codec" },1515	{ }1516};1517MODULE_DEVICE_TABLE(i2c, da9055_i2c_id);1518 1519#ifdef CONFIG_OF1520static const struct of_device_id da9055_of_match[] = {1521	{ .compatible = "dlg,da9055-codec", },1522	{ }1523};1524MODULE_DEVICE_TABLE(of, da9055_of_match);1525#endif1526 1527/* I2C codec control layer */1528static struct i2c_driver da9055_i2c_driver = {1529	.driver = {1530		.name = "da9055-codec",1531		.of_match_table = of_match_ptr(da9055_of_match),1532	},1533	.probe		= da9055_i2c_probe,1534	.id_table	= da9055_i2c_id,1535};1536 1537module_i2c_driver(da9055_i2c_driver);1538 1539MODULE_DESCRIPTION("ASoC DA9055 Codec driver");1540MODULE_AUTHOR("David Chen, Ashish Chavan");1541MODULE_LICENSE("GPL");1542