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