1*48e27874SAdam Thomson /* 2*48e27874SAdam Thomson * da732x.c --- Dialog DA732X ALSA SoC Audio Driver 3*48e27874SAdam Thomson * 4*48e27874SAdam Thomson * Copyright (C) 2012 Dialog Semiconductor GmbH 5*48e27874SAdam Thomson * 6*48e27874SAdam Thomson * Author: Michal Hajduk <Michal.Hajduk@diasemi.com> 7*48e27874SAdam Thomson * 8*48e27874SAdam Thomson * This program is free software; you can redistribute it and/or modify 9*48e27874SAdam Thomson * it under the terms of the GNU General Public License version 2 as 10*48e27874SAdam Thomson * published by the Free Software Foundation. 11*48e27874SAdam Thomson */ 12*48e27874SAdam Thomson 13*48e27874SAdam Thomson #include <linux/module.h> 14*48e27874SAdam Thomson #include <linux/moduleparam.h> 15*48e27874SAdam Thomson #include <linux/init.h> 16*48e27874SAdam Thomson #include <linux/delay.h> 17*48e27874SAdam Thomson #include <linux/pm.h> 18*48e27874SAdam Thomson #include <linux/i2c.h> 19*48e27874SAdam Thomson #include <linux/regmap.h> 20*48e27874SAdam Thomson #include <linux/platform_device.h> 21*48e27874SAdam Thomson #include <linux/slab.h> 22*48e27874SAdam Thomson #include <linux/sysfs.h> 23*48e27874SAdam Thomson #include <sound/core.h> 24*48e27874SAdam Thomson #include <sound/pcm.h> 25*48e27874SAdam Thomson #include <sound/pcm_params.h> 26*48e27874SAdam Thomson #include <sound/soc.h> 27*48e27874SAdam Thomson #include <sound/soc-dapm.h> 28*48e27874SAdam Thomson #include <sound/initval.h> 29*48e27874SAdam Thomson #include <sound/tlv.h> 30*48e27874SAdam Thomson #include <asm/div64.h> 31*48e27874SAdam Thomson 32*48e27874SAdam Thomson #include "da732x.h" 33*48e27874SAdam Thomson #include "da732x_reg.h" 34*48e27874SAdam Thomson 35*48e27874SAdam Thomson 36*48e27874SAdam Thomson struct da732x_priv { 37*48e27874SAdam Thomson struct regmap *regmap; 38*48e27874SAdam Thomson struct snd_soc_codec *codec; 39*48e27874SAdam Thomson 40*48e27874SAdam Thomson unsigned int sysclk; 41*48e27874SAdam Thomson bool pll_en; 42*48e27874SAdam Thomson }; 43*48e27874SAdam Thomson 44*48e27874SAdam Thomson /* 45*48e27874SAdam Thomson * da732x register cache - default settings 46*48e27874SAdam Thomson */ 47*48e27874SAdam Thomson static struct reg_default da732x_reg_cache[] = { 48*48e27874SAdam Thomson { DA732X_REG_REF1 , 0x02 }, 49*48e27874SAdam Thomson { DA732X_REG_BIAS_EN , 0x80 }, 50*48e27874SAdam Thomson { DA732X_REG_BIAS1 , 0x00 }, 51*48e27874SAdam Thomson { DA732X_REG_BIAS2 , 0x00 }, 52*48e27874SAdam Thomson { DA732X_REG_BIAS3 , 0x00 }, 53*48e27874SAdam Thomson { DA732X_REG_BIAS4 , 0x00 }, 54*48e27874SAdam Thomson { DA732X_REG_MICBIAS2 , 0x00 }, 55*48e27874SAdam Thomson { DA732X_REG_MICBIAS1 , 0x00 }, 56*48e27874SAdam Thomson { DA732X_REG_MICDET , 0x00 }, 57*48e27874SAdam Thomson { DA732X_REG_MIC1_PRE , 0x01 }, 58*48e27874SAdam Thomson { DA732X_REG_MIC1 , 0x40 }, 59*48e27874SAdam Thomson { DA732X_REG_MIC2_PRE , 0x01 }, 60*48e27874SAdam Thomson { DA732X_REG_MIC2 , 0x40 }, 61*48e27874SAdam Thomson { DA732X_REG_AUX1L , 0x75 }, 62*48e27874SAdam Thomson { DA732X_REG_AUX1R , 0x75 }, 63*48e27874SAdam Thomson { DA732X_REG_MIC3_PRE , 0x01 }, 64*48e27874SAdam Thomson { DA732X_REG_MIC3 , 0x40 }, 65*48e27874SAdam Thomson { DA732X_REG_INP_PINBIAS , 0x00 }, 66*48e27874SAdam Thomson { DA732X_REG_INP_ZC_EN , 0x00 }, 67*48e27874SAdam Thomson { DA732X_REG_INP_MUX , 0x50 }, 68*48e27874SAdam Thomson { DA732X_REG_HP_DET , 0x00 }, 69*48e27874SAdam Thomson { DA732X_REG_HPL_DAC_OFFSET , 0x00 }, 70*48e27874SAdam Thomson { DA732X_REG_HPL_DAC_OFF_CNTL , 0x00 }, 71*48e27874SAdam Thomson { DA732X_REG_HPL_OUT_OFFSET , 0x00 }, 72*48e27874SAdam Thomson { DA732X_REG_HPL , 0x40 }, 73*48e27874SAdam Thomson { DA732X_REG_HPL_VOL , 0x0F }, 74*48e27874SAdam Thomson { DA732X_REG_HPR_DAC_OFFSET , 0x00 }, 75*48e27874SAdam Thomson { DA732X_REG_HPR_DAC_OFF_CNTL , 0x00 }, 76*48e27874SAdam Thomson { DA732X_REG_HPR_OUT_OFFSET , 0x00 }, 77*48e27874SAdam Thomson { DA732X_REG_HPR , 0x40 }, 78*48e27874SAdam Thomson { DA732X_REG_HPR_VOL , 0x0F }, 79*48e27874SAdam Thomson { DA732X_REG_LIN2 , 0x4F }, 80*48e27874SAdam Thomson { DA732X_REG_LIN3 , 0x4F }, 81*48e27874SAdam Thomson { DA732X_REG_LIN4 , 0x4F }, 82*48e27874SAdam Thomson { DA732X_REG_OUT_ZC_EN , 0x00 }, 83*48e27874SAdam Thomson { DA732X_REG_HP_LIN1_GNDSEL , 0x00 }, 84*48e27874SAdam Thomson { DA732X_REG_CP_HP1 , 0x0C }, 85*48e27874SAdam Thomson { DA732X_REG_CP_HP2 , 0x03 }, 86*48e27874SAdam Thomson { DA732X_REG_CP_CTRL1 , 0x00 }, 87*48e27874SAdam Thomson { DA732X_REG_CP_CTRL2 , 0x99 }, 88*48e27874SAdam Thomson { DA732X_REG_CP_CTRL3 , 0x25 }, 89*48e27874SAdam Thomson { DA732X_REG_CP_LEVEL_MASK , 0x3F }, 90*48e27874SAdam Thomson { DA732X_REG_CP_DET , 0x00 }, 91*48e27874SAdam Thomson { DA732X_REG_CP_STATUS , 0x00 }, 92*48e27874SAdam Thomson { DA732X_REG_CP_THRESH1 , 0x00 }, 93*48e27874SAdam Thomson { DA732X_REG_CP_THRESH2 , 0x00 }, 94*48e27874SAdam Thomson { DA732X_REG_CP_THRESH3 , 0x00 }, 95*48e27874SAdam Thomson { DA732X_REG_CP_THRESH4 , 0x00 }, 96*48e27874SAdam Thomson { DA732X_REG_CP_THRESH5 , 0x00 }, 97*48e27874SAdam Thomson { DA732X_REG_CP_THRESH6 , 0x00 }, 98*48e27874SAdam Thomson { DA732X_REG_CP_THRESH7 , 0x00 }, 99*48e27874SAdam Thomson { DA732X_REG_CP_THRESH8 , 0x00 }, 100*48e27874SAdam Thomson { DA732X_REG_PLL_DIV_LO , 0x00 }, 101*48e27874SAdam Thomson { DA732X_REG_PLL_DIV_MID , 0x00 }, 102*48e27874SAdam Thomson { DA732X_REG_PLL_DIV_HI , 0x00 }, 103*48e27874SAdam Thomson { DA732X_REG_PLL_CTRL , 0x02 }, 104*48e27874SAdam Thomson { DA732X_REG_CLK_CTRL , 0xaa }, 105*48e27874SAdam Thomson { DA732X_REG_CLK_DSP , 0x07 }, 106*48e27874SAdam Thomson { DA732X_REG_CLK_EN1 , 0x00 }, 107*48e27874SAdam Thomson { DA732X_REG_CLK_EN2 , 0x00 }, 108*48e27874SAdam Thomson { DA732X_REG_CLK_EN3 , 0x00 }, 109*48e27874SAdam Thomson { DA732X_REG_CLK_EN4 , 0x00 }, 110*48e27874SAdam Thomson { DA732X_REG_CLK_EN5 , 0x00 }, 111*48e27874SAdam Thomson { DA732X_REG_AIF_MCLK , 0x00 }, 112*48e27874SAdam Thomson { DA732X_REG_AIFA1 , 0x02 }, 113*48e27874SAdam Thomson { DA732X_REG_AIFA2 , 0x00 }, 114*48e27874SAdam Thomson { DA732X_REG_AIFA3 , 0x08 }, 115*48e27874SAdam Thomson { DA732X_REG_AIFB1 , 0x02 }, 116*48e27874SAdam Thomson { DA732X_REG_AIFB2 , 0x00 }, 117*48e27874SAdam Thomson { DA732X_REG_AIFB3 , 0x08 }, 118*48e27874SAdam Thomson { DA732X_REG_PC_CTRL , 0xC0 }, 119*48e27874SAdam Thomson { DA732X_REG_DATA_ROUTE , 0x00 }, 120*48e27874SAdam Thomson { DA732X_REG_DSP_CTRL , 0x00 }, 121*48e27874SAdam Thomson { DA732X_REG_CIF_CTRL2 , 0x00 }, 122*48e27874SAdam Thomson { DA732X_REG_HANDSHAKE , 0x00 }, 123*48e27874SAdam Thomson { DA732X_REG_SPARE1_OUT , 0x00 }, 124*48e27874SAdam Thomson { DA732X_REG_SPARE2_OUT , 0x00 }, 125*48e27874SAdam Thomson { DA732X_REG_SPARE1_IN , 0x00 }, 126*48e27874SAdam Thomson { DA732X_REG_ADC1_PD , 0x00 }, 127*48e27874SAdam Thomson { DA732X_REG_ADC1_HPF , 0x00 }, 128*48e27874SAdam Thomson { DA732X_REG_ADC1_SEL , 0x00 }, 129*48e27874SAdam Thomson { DA732X_REG_ADC1_EQ12 , 0x00 }, 130*48e27874SAdam Thomson { DA732X_REG_ADC1_EQ34 , 0x00 }, 131*48e27874SAdam Thomson { DA732X_REG_ADC1_EQ5 , 0x00 }, 132*48e27874SAdam Thomson { DA732X_REG_ADC2_PD , 0x00 }, 133*48e27874SAdam Thomson { DA732X_REG_ADC2_HPF , 0x00 }, 134*48e27874SAdam Thomson { DA732X_REG_ADC2_SEL , 0x00 }, 135*48e27874SAdam Thomson { DA732X_REG_ADC2_EQ12 , 0x00 }, 136*48e27874SAdam Thomson { DA732X_REG_ADC2_EQ34 , 0x00 }, 137*48e27874SAdam Thomson { DA732X_REG_ADC2_EQ5 , 0x00 }, 138*48e27874SAdam Thomson { DA732X_REG_DAC1_HPF , 0x00 }, 139*48e27874SAdam Thomson { DA732X_REG_DAC1_L_VOL , 0x00 }, 140*48e27874SAdam Thomson { DA732X_REG_DAC1_R_VOL , 0x00 }, 141*48e27874SAdam Thomson { DA732X_REG_DAC1_SEL , 0x00 }, 142*48e27874SAdam Thomson { DA732X_REG_DAC1_SOFTMUTE , 0x00 }, 143*48e27874SAdam Thomson { DA732X_REG_DAC1_EQ12 , 0x00 }, 144*48e27874SAdam Thomson { DA732X_REG_DAC1_EQ34 , 0x00 }, 145*48e27874SAdam Thomson { DA732X_REG_DAC1_EQ5 , 0x00 }, 146*48e27874SAdam Thomson { DA732X_REG_DAC2_HPF , 0x00 }, 147*48e27874SAdam Thomson { DA732X_REG_DAC2_L_VOL , 0x00 }, 148*48e27874SAdam Thomson { DA732X_REG_DAC2_R_VOL , 0x00 }, 149*48e27874SAdam Thomson { DA732X_REG_DAC2_SEL , 0x00 }, 150*48e27874SAdam Thomson { DA732X_REG_DAC2_SOFTMUTE , 0x00 }, 151*48e27874SAdam Thomson { DA732X_REG_DAC2_EQ12 , 0x00 }, 152*48e27874SAdam Thomson { DA732X_REG_DAC2_EQ34 , 0x00 }, 153*48e27874SAdam Thomson { DA732X_REG_DAC2_EQ5 , 0x00 }, 154*48e27874SAdam Thomson { DA732X_REG_DAC3_HPF , 0x00 }, 155*48e27874SAdam Thomson { DA732X_REG_DAC3_VOL , 0x00 }, 156*48e27874SAdam Thomson { DA732X_REG_DAC3_SEL , 0x00 }, 157*48e27874SAdam Thomson { DA732X_REG_DAC3_SOFTMUTE , 0x00 }, 158*48e27874SAdam Thomson { DA732X_REG_DAC3_EQ12 , 0x00 }, 159*48e27874SAdam Thomson { DA732X_REG_DAC3_EQ34 , 0x00 }, 160*48e27874SAdam Thomson { DA732X_REG_DAC3_EQ5 , 0x00 }, 161*48e27874SAdam Thomson { DA732X_REG_BIQ_BYP , 0x00 }, 162*48e27874SAdam Thomson { DA732X_REG_DMA_CMD , 0x00 }, 163*48e27874SAdam Thomson { DA732X_REG_DMA_ADDR0 , 0x00 }, 164*48e27874SAdam Thomson { DA732X_REG_DMA_ADDR1 , 0x00 }, 165*48e27874SAdam Thomson { DA732X_REG_DMA_DATA0 , 0x00 }, 166*48e27874SAdam Thomson { DA732X_REG_DMA_DATA1 , 0x00 }, 167*48e27874SAdam Thomson { DA732X_REG_DMA_DATA2 , 0x00 }, 168*48e27874SAdam Thomson { DA732X_REG_DMA_DATA3 , 0x00 }, 169*48e27874SAdam Thomson { DA732X_REG_UNLOCK , 0x00 }, 170*48e27874SAdam Thomson }; 171*48e27874SAdam Thomson 172*48e27874SAdam Thomson static inline int da732x_get_input_div(struct snd_soc_codec *codec, int sysclk) 173*48e27874SAdam Thomson { 174*48e27874SAdam Thomson int val; 175*48e27874SAdam Thomson int ret; 176*48e27874SAdam Thomson 177*48e27874SAdam Thomson if (sysclk < DA732X_MCLK_10MHZ) { 178*48e27874SAdam Thomson val = DA732X_MCLK_RET_0_10MHZ; 179*48e27874SAdam Thomson ret = DA732X_MCLK_VAL_0_10MHZ; 180*48e27874SAdam Thomson } else if ((sysclk >= DA732X_MCLK_10MHZ) && 181*48e27874SAdam Thomson (sysclk < DA732X_MCLK_20MHZ)) { 182*48e27874SAdam Thomson val = DA732X_MCLK_RET_10_20MHZ; 183*48e27874SAdam Thomson ret = DA732X_MCLK_VAL_10_20MHZ; 184*48e27874SAdam Thomson } else if ((sysclk >= DA732X_MCLK_20MHZ) && 185*48e27874SAdam Thomson (sysclk < DA732X_MCLK_40MHZ)) { 186*48e27874SAdam Thomson val = DA732X_MCLK_RET_20_40MHZ; 187*48e27874SAdam Thomson ret = DA732X_MCLK_VAL_20_40MHZ; 188*48e27874SAdam Thomson } else if ((sysclk >= DA732X_MCLK_40MHZ) && 189*48e27874SAdam Thomson (sysclk <= DA732X_MCLK_54MHZ)) { 190*48e27874SAdam Thomson val = DA732X_MCLK_RET_40_54MHZ; 191*48e27874SAdam Thomson ret = DA732X_MCLK_VAL_40_54MHZ; 192*48e27874SAdam Thomson } else { 193*48e27874SAdam Thomson return -EINVAL; 194*48e27874SAdam Thomson } 195*48e27874SAdam Thomson 196*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_PLL_CTRL, val); 197*48e27874SAdam Thomson 198*48e27874SAdam Thomson return ret; 199*48e27874SAdam Thomson } 200*48e27874SAdam Thomson 201*48e27874SAdam Thomson static void da732x_set_charge_pump(struct snd_soc_codec *codec, int state) 202*48e27874SAdam Thomson { 203*48e27874SAdam Thomson switch (state) { 204*48e27874SAdam Thomson case DA732X_ENABLE_CP: 205*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_CLK_EN2, DA732X_CP_CLK_EN); 206*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_CP_HP2, DA732X_HP_CP_EN | 207*48e27874SAdam Thomson DA732X_HP_CP_REG | DA732X_HP_CP_PULSESKIP); 208*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA732X_CP_EN | 209*48e27874SAdam Thomson DA732X_CP_CTRL_CPVDD1); 210*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_CP_CTRL2, 211*48e27874SAdam Thomson DA732X_CP_MANAGE_MAGNITUDE | DA732X_CP_BOOST); 212*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_CP_CTRL3, DA732X_CP_1MHZ); 213*48e27874SAdam Thomson break; 214*48e27874SAdam Thomson case DA732X_DISABLE_CP: 215*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_CLK_EN2, DA732X_CP_CLK_DIS); 216*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_CP_HP2, DA732X_HP_CP_DIS); 217*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA723X_CP_DIS); 218*48e27874SAdam Thomson break; 219*48e27874SAdam Thomson default: 220*48e27874SAdam Thomson pr_err(KERN_ERR "Wrong charge pump state\n"); 221*48e27874SAdam Thomson break; 222*48e27874SAdam Thomson } 223*48e27874SAdam Thomson } 224*48e27874SAdam Thomson 225*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(mic_boost_tlv, DA732X_MIC_PRE_VOL_DB_MIN, 226*48e27874SAdam Thomson DA732X_MIC_PRE_VOL_DB_INC, 0); 227*48e27874SAdam Thomson 228*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(mic_pga_tlv, DA732X_MIC_VOL_DB_MIN, 229*48e27874SAdam Thomson DA732X_MIC_VOL_DB_INC, 0); 230*48e27874SAdam Thomson 231*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(aux_pga_tlv, DA732X_AUX_VOL_DB_MIN, 232*48e27874SAdam Thomson DA732X_AUX_VOL_DB_INC, 0); 233*48e27874SAdam Thomson 234*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(hp_pga_tlv, DA732X_HP_VOL_DB_MIN, 235*48e27874SAdam Thomson DA732X_AUX_VOL_DB_INC, 0); 236*48e27874SAdam Thomson 237*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(lin2_pga_tlv, DA732X_LIN2_VOL_DB_MIN, 238*48e27874SAdam Thomson DA732X_LIN2_VOL_DB_INC, 0); 239*48e27874SAdam Thomson 240*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(lin3_pga_tlv, DA732X_LIN3_VOL_DB_MIN, 241*48e27874SAdam Thomson DA732X_LIN3_VOL_DB_INC, 0); 242*48e27874SAdam Thomson 243*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(lin4_pga_tlv, DA732X_LIN4_VOL_DB_MIN, 244*48e27874SAdam Thomson DA732X_LIN4_VOL_DB_INC, 0); 245*48e27874SAdam Thomson 246*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(adc_pga_tlv, DA732X_ADC_VOL_DB_MIN, 247*48e27874SAdam Thomson DA732X_ADC_VOL_DB_INC, 0); 248*48e27874SAdam Thomson 249*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(dac_pga_tlv, DA732X_DAC_VOL_DB_MIN, 250*48e27874SAdam Thomson DA732X_DAC_VOL_DB_INC, 0); 251*48e27874SAdam Thomson 252*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(eq_band_pga_tlv, DA732X_EQ_BAND_VOL_DB_MIN, 253*48e27874SAdam Thomson DA732X_EQ_BAND_VOL_DB_INC, 0); 254*48e27874SAdam Thomson 255*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(eq_overall_tlv, DA732X_EQ_OVERALL_VOL_DB_MIN, 256*48e27874SAdam Thomson DA732X_EQ_OVERALL_VOL_DB_INC, 0); 257*48e27874SAdam Thomson 258*48e27874SAdam Thomson /* High Pass Filter */ 259*48e27874SAdam Thomson static const char *da732x_hpf_mode[] = { 260*48e27874SAdam Thomson "Disable", "Music", "Voice", 261*48e27874SAdam Thomson }; 262*48e27874SAdam Thomson 263*48e27874SAdam Thomson static const char *da732x_hpf_music[] = { 264*48e27874SAdam Thomson "1.8Hz", "3.75Hz", "7.5Hz", "15Hz", 265*48e27874SAdam Thomson }; 266*48e27874SAdam Thomson 267*48e27874SAdam Thomson static const char *da732x_hpf_voice[] = { 268*48e27874SAdam Thomson "2.5Hz", "25Hz", "50Hz", "100Hz", 269*48e27874SAdam Thomson "150Hz", "200Hz", "300Hz", "400Hz" 270*48e27874SAdam Thomson }; 271*48e27874SAdam Thomson 272*48e27874SAdam Thomson static const struct soc_enum da732x_dac1_hpf_mode_enum[] = { 273*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MODE_SHIFT, 274*48e27874SAdam Thomson DA732X_HPF_MODE_MAX, da732x_hpf_mode) 275*48e27874SAdam Thomson }; 276*48e27874SAdam Thomson 277*48e27874SAdam Thomson static const struct soc_enum da732x_dac2_hpf_mode_enum[] = { 278*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MODE_SHIFT, 279*48e27874SAdam Thomson DA732X_HPF_MODE_MAX, da732x_hpf_mode) 280*48e27874SAdam Thomson }; 281*48e27874SAdam Thomson 282*48e27874SAdam Thomson static const struct soc_enum da732x_dac3_hpf_mode_enum[] = { 283*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MODE_SHIFT, 284*48e27874SAdam Thomson DA732X_HPF_MODE_MAX, da732x_hpf_mode) 285*48e27874SAdam Thomson }; 286*48e27874SAdam Thomson 287*48e27874SAdam Thomson static const struct soc_enum da732x_adc1_hpf_mode_enum[] = { 288*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MODE_SHIFT, 289*48e27874SAdam Thomson DA732X_HPF_MODE_MAX, da732x_hpf_mode) 290*48e27874SAdam Thomson }; 291*48e27874SAdam Thomson 292*48e27874SAdam Thomson static const struct soc_enum da732x_adc2_hpf_mode_enum[] = { 293*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MODE_SHIFT, 294*48e27874SAdam Thomson DA732X_HPF_MODE_MAX, da732x_hpf_mode) 295*48e27874SAdam Thomson }; 296*48e27874SAdam Thomson 297*48e27874SAdam Thomson static const struct soc_enum da732x_dac1_hp_filter_enum[] = { 298*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MUSIC_SHIFT, 299*48e27874SAdam Thomson DA732X_HPF_MUSIC_MAX, da732x_hpf_music) 300*48e27874SAdam Thomson }; 301*48e27874SAdam Thomson 302*48e27874SAdam Thomson static const struct soc_enum da732x_dac2_hp_filter_enum[] = { 303*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MUSIC_SHIFT, 304*48e27874SAdam Thomson DA732X_HPF_MUSIC_MAX, da732x_hpf_music) 305*48e27874SAdam Thomson }; 306*48e27874SAdam Thomson 307*48e27874SAdam Thomson static const struct soc_enum da732x_dac3_hp_filter_enum[] = { 308*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MUSIC_SHIFT, 309*48e27874SAdam Thomson DA732X_HPF_MUSIC_MAX, da732x_hpf_music) 310*48e27874SAdam Thomson }; 311*48e27874SAdam Thomson 312*48e27874SAdam Thomson static const struct soc_enum da732x_adc1_hp_filter_enum[] = { 313*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MUSIC_SHIFT, 314*48e27874SAdam Thomson DA732X_HPF_MUSIC_MAX, da732x_hpf_music) 315*48e27874SAdam Thomson }; 316*48e27874SAdam Thomson 317*48e27874SAdam Thomson static const struct soc_enum da732x_adc2_hp_filter_enum[] = { 318*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MUSIC_SHIFT, 319*48e27874SAdam Thomson DA732X_HPF_MUSIC_MAX, da732x_hpf_music) 320*48e27874SAdam Thomson }; 321*48e27874SAdam Thomson 322*48e27874SAdam Thomson static const struct soc_enum da732x_dac1_voice_filter_enum[] = { 323*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_VOICE_SHIFT, 324*48e27874SAdam Thomson DA732X_HPF_VOICE_MAX, da732x_hpf_voice) 325*48e27874SAdam Thomson }; 326*48e27874SAdam Thomson 327*48e27874SAdam Thomson static const struct soc_enum da732x_dac2_voice_filter_enum[] = { 328*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_VOICE_SHIFT, 329*48e27874SAdam Thomson DA732X_HPF_VOICE_MAX, da732x_hpf_voice) 330*48e27874SAdam Thomson }; 331*48e27874SAdam Thomson 332*48e27874SAdam Thomson static const struct soc_enum da732x_dac3_voice_filter_enum[] = { 333*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_VOICE_SHIFT, 334*48e27874SAdam Thomson DA732X_HPF_VOICE_MAX, da732x_hpf_voice) 335*48e27874SAdam Thomson }; 336*48e27874SAdam Thomson 337*48e27874SAdam Thomson static const struct soc_enum da732x_adc1_voice_filter_enum[] = { 338*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_VOICE_SHIFT, 339*48e27874SAdam Thomson DA732X_HPF_VOICE_MAX, da732x_hpf_voice) 340*48e27874SAdam Thomson }; 341*48e27874SAdam Thomson 342*48e27874SAdam Thomson static const struct soc_enum da732x_adc2_voice_filter_enum[] = { 343*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_VOICE_SHIFT, 344*48e27874SAdam Thomson DA732X_HPF_VOICE_MAX, da732x_hpf_voice) 345*48e27874SAdam Thomson }; 346*48e27874SAdam Thomson 347*48e27874SAdam Thomson 348*48e27874SAdam Thomson static int da732x_hpf_set(struct snd_kcontrol *kcontrol, 349*48e27874SAdam Thomson struct snd_ctl_elem_value *ucontrol) 350*48e27874SAdam Thomson { 351*48e27874SAdam Thomson struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 352*48e27874SAdam Thomson struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value; 353*48e27874SAdam Thomson unsigned int reg = enum_ctrl->reg; 354*48e27874SAdam Thomson unsigned int sel = ucontrol->value.integer.value[0]; 355*48e27874SAdam Thomson unsigned int bits; 356*48e27874SAdam Thomson 357*48e27874SAdam Thomson switch (sel) { 358*48e27874SAdam Thomson case DA732X_HPF_DISABLED: 359*48e27874SAdam Thomson bits = DA732X_HPF_DIS; 360*48e27874SAdam Thomson break; 361*48e27874SAdam Thomson case DA732X_HPF_VOICE: 362*48e27874SAdam Thomson bits = DA732X_HPF_VOICE_EN; 363*48e27874SAdam Thomson break; 364*48e27874SAdam Thomson case DA732X_HPF_MUSIC: 365*48e27874SAdam Thomson bits = DA732X_HPF_MUSIC_EN; 366*48e27874SAdam Thomson break; 367*48e27874SAdam Thomson default: 368*48e27874SAdam Thomson return -EINVAL; 369*48e27874SAdam Thomson } 370*48e27874SAdam Thomson 371*48e27874SAdam Thomson snd_soc_update_bits(codec, reg, DA732X_HPF_MASK, bits); 372*48e27874SAdam Thomson 373*48e27874SAdam Thomson return 0; 374*48e27874SAdam Thomson } 375*48e27874SAdam Thomson 376*48e27874SAdam Thomson static int da732x_hpf_get(struct snd_kcontrol *kcontrol, 377*48e27874SAdam Thomson struct snd_ctl_elem_value *ucontrol) 378*48e27874SAdam Thomson { 379*48e27874SAdam Thomson struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 380*48e27874SAdam Thomson struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value; 381*48e27874SAdam Thomson unsigned int reg = enum_ctrl->reg; 382*48e27874SAdam Thomson int val; 383*48e27874SAdam Thomson 384*48e27874SAdam Thomson val = snd_soc_read(codec, reg) & DA732X_HPF_MASK; 385*48e27874SAdam Thomson 386*48e27874SAdam Thomson switch (val) { 387*48e27874SAdam Thomson case DA732X_HPF_VOICE_EN: 388*48e27874SAdam Thomson ucontrol->value.integer.value[0] = DA732X_HPF_VOICE; 389*48e27874SAdam Thomson break; 390*48e27874SAdam Thomson case DA732X_HPF_MUSIC_EN: 391*48e27874SAdam Thomson ucontrol->value.integer.value[0] = DA732X_HPF_MUSIC; 392*48e27874SAdam Thomson break; 393*48e27874SAdam Thomson default: 394*48e27874SAdam Thomson ucontrol->value.integer.value[0] = DA732X_HPF_DISABLED; 395*48e27874SAdam Thomson break; 396*48e27874SAdam Thomson } 397*48e27874SAdam Thomson 398*48e27874SAdam Thomson return 0; 399*48e27874SAdam Thomson } 400*48e27874SAdam Thomson 401*48e27874SAdam Thomson static const struct snd_kcontrol_new da732x_snd_controls[] = { 402*48e27874SAdam Thomson /* Input PGAs */ 403*48e27874SAdam Thomson SOC_SINGLE_RANGE_TLV("MIC1 Boost Volume", DA732X_REG_MIC1_PRE, 404*48e27874SAdam Thomson DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN, 405*48e27874SAdam Thomson DA732X_MICBOOST_MAX, 0, mic_boost_tlv), 406*48e27874SAdam Thomson SOC_SINGLE_RANGE_TLV("MIC2 Boost Volume", DA732X_REG_MIC2_PRE, 407*48e27874SAdam Thomson DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN, 408*48e27874SAdam Thomson DA732X_MICBOOST_MAX, 0, mic_boost_tlv), 409*48e27874SAdam Thomson SOC_SINGLE_RANGE_TLV("MIC3 Boost Volume", DA732X_REG_MIC3_PRE, 410*48e27874SAdam Thomson DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN, 411*48e27874SAdam Thomson DA732X_MICBOOST_MAX, 0, mic_boost_tlv), 412*48e27874SAdam Thomson 413*48e27874SAdam Thomson /* MICs */ 414*48e27874SAdam Thomson SOC_SINGLE("MIC1 Switch", DA732X_REG_MIC1, DA732X_MIC_MUTE_SHIFT, 415*48e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 416*48e27874SAdam Thomson SOC_SINGLE_RANGE_TLV("MIC1 Volume", DA732X_REG_MIC1, 417*48e27874SAdam Thomson DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN, 418*48e27874SAdam Thomson DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv), 419*48e27874SAdam Thomson SOC_SINGLE("MIC2 Switch", DA732X_REG_MIC2, DA732X_MIC_MUTE_SHIFT, 420*48e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 421*48e27874SAdam Thomson SOC_SINGLE_RANGE_TLV("MIC2 Volume", DA732X_REG_MIC2, 422*48e27874SAdam Thomson DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN, 423*48e27874SAdam Thomson DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv), 424*48e27874SAdam Thomson SOC_SINGLE("MIC3 Switch", DA732X_REG_MIC3, DA732X_MIC_MUTE_SHIFT, 425*48e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 426*48e27874SAdam Thomson SOC_SINGLE_RANGE_TLV("MIC3 Volume", DA732X_REG_MIC3, 427*48e27874SAdam Thomson DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN, 428*48e27874SAdam Thomson DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv), 429*48e27874SAdam Thomson 430*48e27874SAdam Thomson /* AUXs */ 431*48e27874SAdam Thomson SOC_SINGLE("AUX1L Switch", DA732X_REG_AUX1L, DA732X_AUX_MUTE_SHIFT, 432*48e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 433*48e27874SAdam Thomson SOC_SINGLE_TLV("AUX1L Volume", DA732X_REG_AUX1L, 434*48e27874SAdam Thomson DA732X_AUX_VOL_SHIFT, DA732X_AUX_VOL_VAL_MAX, 435*48e27874SAdam Thomson DA732X_NO_INVERT, aux_pga_tlv), 436*48e27874SAdam Thomson SOC_SINGLE("AUX1R Switch", DA732X_REG_AUX1R, DA732X_AUX_MUTE_SHIFT, 437*48e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 438*48e27874SAdam Thomson SOC_SINGLE_TLV("AUX1R Volume", DA732X_REG_AUX1R, 439*48e27874SAdam Thomson DA732X_AUX_VOL_SHIFT, DA732X_AUX_VOL_VAL_MAX, 440*48e27874SAdam Thomson DA732X_NO_INVERT, aux_pga_tlv), 441*48e27874SAdam Thomson 442*48e27874SAdam Thomson /* ADCs */ 443*48e27874SAdam Thomson SOC_DOUBLE_TLV("ADC1 Volume", DA732X_REG_ADC1_SEL, 444*48e27874SAdam Thomson DA732X_ADCL_VOL_SHIFT, DA732X_ADCR_VOL_SHIFT, 445*48e27874SAdam Thomson DA732X_ADC_VOL_VAL_MAX, DA732X_INVERT, adc_pga_tlv), 446*48e27874SAdam Thomson 447*48e27874SAdam Thomson SOC_DOUBLE_TLV("ADC2 Volume", DA732X_REG_ADC2_SEL, 448*48e27874SAdam Thomson DA732X_ADCL_VOL_SHIFT, DA732X_ADCR_VOL_SHIFT, 449*48e27874SAdam Thomson DA732X_ADC_VOL_VAL_MAX, DA732X_INVERT, adc_pga_tlv), 450*48e27874SAdam Thomson 451*48e27874SAdam Thomson /* DACs */ 452*48e27874SAdam Thomson SOC_DOUBLE("Digital Playback DAC12 Switch", DA732X_REG_DAC1_SEL, 453*48e27874SAdam Thomson DA732X_DACL_MUTE_SHIFT, DA732X_DACR_MUTE_SHIFT, 454*48e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 455*48e27874SAdam Thomson SOC_DOUBLE_R_TLV("Digital Playback DAC12 Volume", DA732X_REG_DAC1_L_VOL, 456*48e27874SAdam Thomson DA732X_REG_DAC1_R_VOL, DA732X_DAC_VOL_SHIFT, 457*48e27874SAdam Thomson DA732X_DAC_VOL_VAL_MAX, DA732X_INVERT, dac_pga_tlv), 458*48e27874SAdam Thomson SOC_SINGLE("Digital Playback DAC3 Switch", DA732X_REG_DAC2_SEL, 459*48e27874SAdam Thomson DA732X_DACL_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), 460*48e27874SAdam Thomson SOC_SINGLE_TLV("Digital Playback DAC3 Volume", DA732X_REG_DAC2_L_VOL, 461*48e27874SAdam Thomson DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX, 462*48e27874SAdam Thomson DA732X_INVERT, dac_pga_tlv), 463*48e27874SAdam Thomson SOC_SINGLE("Digital Playback DAC4 Switch", DA732X_REG_DAC2_SEL, 464*48e27874SAdam Thomson DA732X_DACR_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), 465*48e27874SAdam Thomson SOC_SINGLE_TLV("Digital Playback DAC4 Volume", DA732X_REG_DAC2_R_VOL, 466*48e27874SAdam Thomson DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX, 467*48e27874SAdam Thomson DA732X_INVERT, dac_pga_tlv), 468*48e27874SAdam Thomson SOC_SINGLE("Digital Playback DAC5 Switch", DA732X_REG_DAC3_SEL, 469*48e27874SAdam Thomson DA732X_DACL_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), 470*48e27874SAdam Thomson SOC_SINGLE_TLV("Digital Playback DAC5 Volume", DA732X_REG_DAC3_VOL, 471*48e27874SAdam Thomson DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX, 472*48e27874SAdam Thomson DA732X_INVERT, dac_pga_tlv), 473*48e27874SAdam Thomson 474*48e27874SAdam Thomson /* High Pass Filters */ 475*48e27874SAdam Thomson SOC_ENUM_EXT("DAC1 High Pass Filter Mode", 476*48e27874SAdam Thomson da732x_dac1_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), 477*48e27874SAdam Thomson SOC_ENUM("DAC1 High Pass Filter", da732x_dac1_hp_filter_enum), 478*48e27874SAdam Thomson SOC_ENUM("DAC1 Voice Filter", da732x_dac1_voice_filter_enum), 479*48e27874SAdam Thomson 480*48e27874SAdam Thomson SOC_ENUM_EXT("DAC2 High Pass Filter Mode", 481*48e27874SAdam Thomson da732x_dac2_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), 482*48e27874SAdam Thomson SOC_ENUM("DAC2 High Pass Filter", da732x_dac2_hp_filter_enum), 483*48e27874SAdam Thomson SOC_ENUM("DAC2 Voice Filter", da732x_dac2_voice_filter_enum), 484*48e27874SAdam Thomson 485*48e27874SAdam Thomson SOC_ENUM_EXT("DAC3 High Pass Filter Mode", 486*48e27874SAdam Thomson da732x_dac3_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), 487*48e27874SAdam Thomson SOC_ENUM("DAC3 High Pass Filter", da732x_dac3_hp_filter_enum), 488*48e27874SAdam Thomson SOC_ENUM("DAC3 Filter Mode", da732x_dac3_voice_filter_enum), 489*48e27874SAdam Thomson 490*48e27874SAdam Thomson SOC_ENUM_EXT("ADC1 High Pass Filter Mode", 491*48e27874SAdam Thomson da732x_adc1_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), 492*48e27874SAdam Thomson SOC_ENUM("ADC1 High Pass Filter", da732x_adc1_hp_filter_enum), 493*48e27874SAdam Thomson SOC_ENUM("ADC1 Voice Filter", da732x_adc1_voice_filter_enum), 494*48e27874SAdam Thomson 495*48e27874SAdam Thomson SOC_ENUM_EXT("ADC2 High Pass Filter Mode", 496*48e27874SAdam Thomson da732x_adc2_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), 497*48e27874SAdam Thomson SOC_ENUM("ADC2 High Pass Filter", da732x_adc2_hp_filter_enum), 498*48e27874SAdam Thomson SOC_ENUM("ADC2 Voice Filter", da732x_adc2_voice_filter_enum), 499*48e27874SAdam Thomson 500*48e27874SAdam Thomson /* Equalizers */ 501*48e27874SAdam Thomson SOC_SINGLE("ADC1 EQ Switch", DA732X_REG_ADC1_EQ5, 502*48e27874SAdam Thomson DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), 503*48e27874SAdam Thomson SOC_SINGLE_TLV("ADC1 EQ Band 1 Volume", DA732X_REG_ADC1_EQ12, 504*48e27874SAdam Thomson DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, 505*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 506*48e27874SAdam Thomson SOC_SINGLE_TLV("ADC1 EQ Band 2 Volume", DA732X_REG_ADC1_EQ12, 507*48e27874SAdam Thomson DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, 508*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 509*48e27874SAdam Thomson SOC_SINGLE_TLV("ADC1 EQ Band 3 Volume", DA732X_REG_ADC1_EQ34, 510*48e27874SAdam Thomson DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, 511*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 512*48e27874SAdam Thomson SOC_SINGLE_TLV("ADC1 EQ Band 4 Volume", DA732X_REG_ADC1_EQ34, 513*48e27874SAdam Thomson DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, 514*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 515*48e27874SAdam Thomson SOC_SINGLE_TLV("ADC1 EQ Band 5 Volume", DA732X_REG_ADC1_EQ5, 516*48e27874SAdam Thomson DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, 517*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 518*48e27874SAdam Thomson SOC_SINGLE_TLV("ADC1 EQ Overall Volume", DA732X_REG_ADC1_EQ5, 519*48e27874SAdam Thomson DA732X_EQ_OVERALL_SHIFT, DA732X_EQ_OVERALL_VOL_VAL_MAX, 520*48e27874SAdam Thomson DA732X_INVERT, eq_overall_tlv), 521*48e27874SAdam Thomson 522*48e27874SAdam Thomson SOC_SINGLE("ADC2 EQ Switch", DA732X_REG_ADC2_EQ5, 523*48e27874SAdam Thomson DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), 524*48e27874SAdam Thomson SOC_SINGLE_TLV("ADC2 EQ Band 1 Volume", DA732X_REG_ADC2_EQ12, 525*48e27874SAdam Thomson DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, 526*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 527*48e27874SAdam Thomson SOC_SINGLE_TLV("ADC2 EQ Band 2 Volume", DA732X_REG_ADC2_EQ12, 528*48e27874SAdam Thomson DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, 529*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 530*48e27874SAdam Thomson SOC_SINGLE_TLV("ADC2 EQ Band 3 Volume", DA732X_REG_ADC2_EQ34, 531*48e27874SAdam Thomson DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, 532*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 533*48e27874SAdam Thomson SOC_SINGLE_TLV("ACD2 EQ Band 4 Volume", DA732X_REG_ADC2_EQ34, 534*48e27874SAdam Thomson DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, 535*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 536*48e27874SAdam Thomson SOC_SINGLE_TLV("ACD2 EQ Band 5 Volume", DA732X_REG_ADC2_EQ5, 537*48e27874SAdam Thomson DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, 538*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 539*48e27874SAdam Thomson SOC_SINGLE_TLV("ADC2 EQ Overall Volume", DA732X_REG_ADC1_EQ5, 540*48e27874SAdam Thomson DA732X_EQ_OVERALL_SHIFT, DA732X_EQ_OVERALL_VOL_VAL_MAX, 541*48e27874SAdam Thomson DA732X_INVERT, eq_overall_tlv), 542*48e27874SAdam Thomson 543*48e27874SAdam Thomson SOC_SINGLE("DAC1 EQ Switch", DA732X_REG_DAC1_EQ5, 544*48e27874SAdam Thomson DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), 545*48e27874SAdam Thomson SOC_SINGLE_TLV("DAC1 EQ Band 1 Volume", DA732X_REG_DAC1_EQ12, 546*48e27874SAdam Thomson DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, 547*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 548*48e27874SAdam Thomson SOC_SINGLE_TLV("DAC1 EQ Band 2 Volume", DA732X_REG_DAC1_EQ12, 549*48e27874SAdam Thomson DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, 550*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 551*48e27874SAdam Thomson SOC_SINGLE_TLV("DAC1 EQ Band 3 Volume", DA732X_REG_DAC1_EQ34, 552*48e27874SAdam Thomson DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, 553*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 554*48e27874SAdam Thomson SOC_SINGLE_TLV("DAC1 EQ Band 4 Volume", DA732X_REG_DAC1_EQ34, 555*48e27874SAdam Thomson DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, 556*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 557*48e27874SAdam Thomson SOC_SINGLE_TLV("DAC1 EQ Band 5 Volume", DA732X_REG_DAC1_EQ5, 558*48e27874SAdam Thomson DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, 559*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 560*48e27874SAdam Thomson 561*48e27874SAdam Thomson SOC_SINGLE("DAC2 EQ Switch", DA732X_REG_DAC2_EQ5, 562*48e27874SAdam Thomson DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), 563*48e27874SAdam Thomson SOC_SINGLE_TLV("DAC2 EQ Band 1 Volume", DA732X_REG_DAC2_EQ12, 564*48e27874SAdam Thomson DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, 565*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 566*48e27874SAdam Thomson SOC_SINGLE_TLV("DAC2 EQ Band 2 Volume", DA732X_REG_DAC2_EQ12, 567*48e27874SAdam Thomson DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, 568*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 569*48e27874SAdam Thomson SOC_SINGLE_TLV("DAC2 EQ Band 3 Volume", DA732X_REG_DAC2_EQ34, 570*48e27874SAdam Thomson DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, 571*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 572*48e27874SAdam Thomson SOC_SINGLE_TLV("DAC2 EQ Band 4 Volume", DA732X_REG_DAC2_EQ34, 573*48e27874SAdam Thomson DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, 574*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 575*48e27874SAdam Thomson SOC_SINGLE_TLV("DAC2 EQ Band 5 Volume", DA732X_REG_DAC2_EQ5, 576*48e27874SAdam Thomson DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, 577*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 578*48e27874SAdam Thomson 579*48e27874SAdam Thomson SOC_SINGLE("DAC3 EQ Switch", DA732X_REG_DAC3_EQ5, 580*48e27874SAdam Thomson DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), 581*48e27874SAdam Thomson SOC_SINGLE_TLV("DAC3 EQ Band 1 Volume", DA732X_REG_DAC3_EQ12, 582*48e27874SAdam Thomson DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, 583*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 584*48e27874SAdam Thomson SOC_SINGLE_TLV("DAC3 EQ Band 2 Volume", DA732X_REG_DAC3_EQ12, 585*48e27874SAdam Thomson DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, 586*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 587*48e27874SAdam Thomson SOC_SINGLE_TLV("DAC3 EQ Band 3 Volume", DA732X_REG_DAC3_EQ34, 588*48e27874SAdam Thomson DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, 589*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 590*48e27874SAdam Thomson SOC_SINGLE_TLV("DAC3 EQ Band 4 Volume", DA732X_REG_DAC3_EQ34, 591*48e27874SAdam Thomson DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, 592*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 593*48e27874SAdam Thomson SOC_SINGLE_TLV("DAC3 EQ Band 5 Volume", DA732X_REG_DAC3_EQ5, 594*48e27874SAdam Thomson DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, 595*48e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 596*48e27874SAdam Thomson 597*48e27874SAdam Thomson /* Lineout 2 Reciever*/ 598*48e27874SAdam Thomson SOC_SINGLE("Lineout 2 Switch", DA732X_REG_LIN2, DA732X_LOUT_MUTE_SHIFT, 599*48e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 600*48e27874SAdam Thomson SOC_SINGLE_TLV("Lineout 2 Volume", DA732X_REG_LIN2, 601*48e27874SAdam Thomson DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX, 602*48e27874SAdam Thomson DA732X_NO_INVERT, lin2_pga_tlv), 603*48e27874SAdam Thomson 604*48e27874SAdam Thomson /* Lineout 3 SPEAKER*/ 605*48e27874SAdam Thomson SOC_SINGLE("Lineout 3 Switch", DA732X_REG_LIN3, DA732X_LOUT_MUTE_SHIFT, 606*48e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 607*48e27874SAdam Thomson SOC_SINGLE_TLV("Lineout 3 Volume", DA732X_REG_LIN3, 608*48e27874SAdam Thomson DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX, 609*48e27874SAdam Thomson DA732X_NO_INVERT, lin3_pga_tlv), 610*48e27874SAdam Thomson 611*48e27874SAdam Thomson /* Lineout 4 */ 612*48e27874SAdam Thomson SOC_SINGLE("Lineout 4 Switch", DA732X_REG_LIN4, DA732X_LOUT_MUTE_SHIFT, 613*48e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 614*48e27874SAdam Thomson SOC_SINGLE_TLV("Lineout 4 Volume", DA732X_REG_LIN4, 615*48e27874SAdam Thomson DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX, 616*48e27874SAdam Thomson DA732X_NO_INVERT, lin4_pga_tlv), 617*48e27874SAdam Thomson 618*48e27874SAdam Thomson /* Headphones */ 619*48e27874SAdam Thomson SOC_DOUBLE_R("Headphone Switch", DA732X_REG_HPR, DA732X_REG_HPL, 620*48e27874SAdam Thomson DA732X_HP_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), 621*48e27874SAdam Thomson SOC_DOUBLE_R_TLV("Headphone Volume", DA732X_REG_HPL_VOL, 622*48e27874SAdam Thomson DA732X_REG_HPR_VOL, DA732X_HP_VOL_SHIFT, 623*48e27874SAdam Thomson DA732X_HP_VOL_VAL_MAX, DA732X_NO_INVERT, hp_pga_tlv), 624*48e27874SAdam Thomson }; 625*48e27874SAdam Thomson 626*48e27874SAdam Thomson static int da732x_adc_event(struct snd_soc_dapm_widget *w, 627*48e27874SAdam Thomson struct snd_kcontrol *kcontrol, int event) 628*48e27874SAdam Thomson { 629*48e27874SAdam Thomson struct snd_soc_codec *codec = w->codec; 630*48e27874SAdam Thomson 631*48e27874SAdam Thomson switch (event) { 632*48e27874SAdam Thomson case SND_SOC_DAPM_POST_PMU: 633*48e27874SAdam Thomson switch (w->reg) { 634*48e27874SAdam Thomson case DA732X_REG_ADC1_PD: 635*48e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, 636*48e27874SAdam Thomson DA732X_ADCA_BB_CLK_EN, 637*48e27874SAdam Thomson DA732X_ADCA_BB_CLK_EN); 638*48e27874SAdam Thomson break; 639*48e27874SAdam Thomson case DA732X_REG_ADC2_PD: 640*48e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, 641*48e27874SAdam Thomson DA732X_ADCC_BB_CLK_EN, 642*48e27874SAdam Thomson DA732X_ADCC_BB_CLK_EN); 643*48e27874SAdam Thomson break; 644*48e27874SAdam Thomson default: 645*48e27874SAdam Thomson return -EINVAL; 646*48e27874SAdam Thomson } 647*48e27874SAdam Thomson 648*48e27874SAdam Thomson snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK, 649*48e27874SAdam Thomson DA732X_ADC_SET_ACT); 650*48e27874SAdam Thomson snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK, 651*48e27874SAdam Thomson DA732X_ADC_ON); 652*48e27874SAdam Thomson break; 653*48e27874SAdam Thomson case SND_SOC_DAPM_POST_PMD: 654*48e27874SAdam Thomson snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK, 655*48e27874SAdam Thomson DA732X_ADC_OFF); 656*48e27874SAdam Thomson snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK, 657*48e27874SAdam Thomson DA732X_ADC_SET_RST); 658*48e27874SAdam Thomson 659*48e27874SAdam Thomson switch (w->reg) { 660*48e27874SAdam Thomson case DA732X_REG_ADC1_PD: 661*48e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, 662*48e27874SAdam Thomson DA732X_ADCA_BB_CLK_EN, 0); 663*48e27874SAdam Thomson break; 664*48e27874SAdam Thomson case DA732X_REG_ADC2_PD: 665*48e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, 666*48e27874SAdam Thomson DA732X_ADCC_BB_CLK_EN, 0); 667*48e27874SAdam Thomson break; 668*48e27874SAdam Thomson default: 669*48e27874SAdam Thomson return -EINVAL; 670*48e27874SAdam Thomson } 671*48e27874SAdam Thomson 672*48e27874SAdam Thomson break; 673*48e27874SAdam Thomson default: 674*48e27874SAdam Thomson return -EINVAL; 675*48e27874SAdam Thomson } 676*48e27874SAdam Thomson 677*48e27874SAdam Thomson return 0; 678*48e27874SAdam Thomson } 679*48e27874SAdam Thomson 680*48e27874SAdam Thomson static int da732x_out_pga_event(struct snd_soc_dapm_widget *w, 681*48e27874SAdam Thomson struct snd_kcontrol *kcontrol, int event) 682*48e27874SAdam Thomson { 683*48e27874SAdam Thomson struct snd_soc_codec *codec = w->codec; 684*48e27874SAdam Thomson 685*48e27874SAdam Thomson switch (event) { 686*48e27874SAdam Thomson case SND_SOC_DAPM_POST_PMU: 687*48e27874SAdam Thomson snd_soc_update_bits(codec, w->reg, 688*48e27874SAdam Thomson (1 << w->shift) | DA732X_OUT_HIZ_EN, 689*48e27874SAdam Thomson (1 << w->shift) | DA732X_OUT_HIZ_EN); 690*48e27874SAdam Thomson break; 691*48e27874SAdam Thomson case SND_SOC_DAPM_POST_PMD: 692*48e27874SAdam Thomson snd_soc_update_bits(codec, w->reg, 693*48e27874SAdam Thomson (1 << w->shift) | DA732X_OUT_HIZ_EN, 694*48e27874SAdam Thomson (1 << w->shift) | DA732X_OUT_HIZ_DIS); 695*48e27874SAdam Thomson break; 696*48e27874SAdam Thomson default: 697*48e27874SAdam Thomson return -EINVAL; 698*48e27874SAdam Thomson } 699*48e27874SAdam Thomson 700*48e27874SAdam Thomson return 0; 701*48e27874SAdam Thomson } 702*48e27874SAdam Thomson 703*48e27874SAdam Thomson static const char *adcl_text[] = { 704*48e27874SAdam Thomson "AUX1L", "MIC1" 705*48e27874SAdam Thomson }; 706*48e27874SAdam Thomson 707*48e27874SAdam Thomson static const char *adcr_text[] = { 708*48e27874SAdam Thomson "AUX1R", "MIC2", "MIC3" 709*48e27874SAdam Thomson }; 710*48e27874SAdam Thomson 711*48e27874SAdam Thomson static const char *enable_text[] = { 712*48e27874SAdam Thomson "Disabled", 713*48e27874SAdam Thomson "Enabled" 714*48e27874SAdam Thomson }; 715*48e27874SAdam Thomson 716*48e27874SAdam Thomson /* ADC1LMUX */ 717*48e27874SAdam Thomson static const struct soc_enum adc1l_enum = 718*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1L_MUX_SEL_SHIFT, 719*48e27874SAdam Thomson DA732X_ADCL_MUX_MAX, adcl_text); 720*48e27874SAdam Thomson static const struct snd_kcontrol_new adc1l_mux = 721*48e27874SAdam Thomson SOC_DAPM_ENUM("ADC Route", adc1l_enum); 722*48e27874SAdam Thomson 723*48e27874SAdam Thomson /* ADC1RMUX */ 724*48e27874SAdam Thomson static const struct soc_enum adc1r_enum = 725*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1R_MUX_SEL_SHIFT, 726*48e27874SAdam Thomson DA732X_ADCR_MUX_MAX, adcr_text); 727*48e27874SAdam Thomson static const struct snd_kcontrol_new adc1r_mux = 728*48e27874SAdam Thomson SOC_DAPM_ENUM("ADC Route", adc1r_enum); 729*48e27874SAdam Thomson 730*48e27874SAdam Thomson /* ADC2LMUX */ 731*48e27874SAdam Thomson static const struct soc_enum adc2l_enum = 732*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2L_MUX_SEL_SHIFT, 733*48e27874SAdam Thomson DA732X_ADCL_MUX_MAX, adcl_text); 734*48e27874SAdam Thomson static const struct snd_kcontrol_new adc2l_mux = 735*48e27874SAdam Thomson SOC_DAPM_ENUM("ADC Route", adc2l_enum); 736*48e27874SAdam Thomson 737*48e27874SAdam Thomson /* ADC2RMUX */ 738*48e27874SAdam Thomson static const struct soc_enum adc2r_enum = 739*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2R_MUX_SEL_SHIFT, 740*48e27874SAdam Thomson DA732X_ADCR_MUX_MAX, adcr_text); 741*48e27874SAdam Thomson 742*48e27874SAdam Thomson static const struct snd_kcontrol_new adc2r_mux = 743*48e27874SAdam Thomson SOC_DAPM_ENUM("ADC Route", adc2r_enum); 744*48e27874SAdam Thomson 745*48e27874SAdam Thomson static const struct soc_enum da732x_hp_left_output = 746*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN_SHIFT, 747*48e27874SAdam Thomson DA732X_DAC_EN_MAX, enable_text); 748*48e27874SAdam Thomson 749*48e27874SAdam Thomson static const struct snd_kcontrol_new hpl_mux = 750*48e27874SAdam Thomson SOC_DAPM_ENUM("HPL Switch", da732x_hp_left_output); 751*48e27874SAdam Thomson 752*48e27874SAdam Thomson static const struct soc_enum da732x_hp_right_output = 753*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_HPR, DA732X_HP_OUT_DAC_EN_SHIFT, 754*48e27874SAdam Thomson DA732X_DAC_EN_MAX, enable_text); 755*48e27874SAdam Thomson 756*48e27874SAdam Thomson static const struct snd_kcontrol_new hpr_mux = 757*48e27874SAdam Thomson SOC_DAPM_ENUM("HPR Switch", da732x_hp_right_output); 758*48e27874SAdam Thomson 759*48e27874SAdam Thomson static const struct soc_enum da732x_speaker_output = 760*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_LIN3, DA732X_LOUT_DAC_EN_SHIFT, 761*48e27874SAdam Thomson DA732X_DAC_EN_MAX, enable_text); 762*48e27874SAdam Thomson 763*48e27874SAdam Thomson static const struct snd_kcontrol_new spk_mux = 764*48e27874SAdam Thomson SOC_DAPM_ENUM("SPK Switch", da732x_speaker_output); 765*48e27874SAdam Thomson 766*48e27874SAdam Thomson static const struct soc_enum da732x_lout4_output = 767*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_LIN4, DA732X_LOUT_DAC_EN_SHIFT, 768*48e27874SAdam Thomson DA732X_DAC_EN_MAX, enable_text); 769*48e27874SAdam Thomson 770*48e27874SAdam Thomson static const struct snd_kcontrol_new lout4_mux = 771*48e27874SAdam Thomson SOC_DAPM_ENUM("LOUT4 Switch", da732x_lout4_output); 772*48e27874SAdam Thomson 773*48e27874SAdam Thomson static const struct soc_enum da732x_lout2_output = 774*48e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_LIN2, DA732X_LOUT_DAC_EN_SHIFT, 775*48e27874SAdam Thomson DA732X_DAC_EN_MAX, enable_text); 776*48e27874SAdam Thomson 777*48e27874SAdam Thomson static const struct snd_kcontrol_new lout2_mux = 778*48e27874SAdam Thomson SOC_DAPM_ENUM("LOUT2 Switch", da732x_lout2_output); 779*48e27874SAdam Thomson 780*48e27874SAdam Thomson static const struct snd_soc_dapm_widget da732x_dapm_widgets[] = { 781*48e27874SAdam Thomson /* Supplies */ 782*48e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("ADC1 Supply", DA732X_REG_ADC1_PD, 0, 783*48e27874SAdam Thomson DA732X_NO_INVERT, da732x_adc_event, 784*48e27874SAdam Thomson SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 785*48e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("ADC2 Supply", DA732X_REG_ADC2_PD, 0, 786*48e27874SAdam Thomson DA732X_NO_INVERT, da732x_adc_event, 787*48e27874SAdam Thomson SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 788*48e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("DAC1 CLK", DA732X_REG_CLK_EN4, 789*48e27874SAdam Thomson DA732X_DACA_BB_CLK_SHIFT, DA732X_NO_INVERT, 790*48e27874SAdam Thomson NULL, 0), 791*48e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("DAC2 CLK", DA732X_REG_CLK_EN4, 792*48e27874SAdam Thomson DA732X_DACC_BB_CLK_SHIFT, DA732X_NO_INVERT, 793*48e27874SAdam Thomson NULL, 0), 794*48e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("DAC3 CLK", DA732X_REG_CLK_EN5, 795*48e27874SAdam Thomson DA732X_DACE_BB_CLK_SHIFT, DA732X_NO_INVERT, 796*48e27874SAdam Thomson NULL, 0), 797*48e27874SAdam Thomson 798*48e27874SAdam Thomson /* Micbias */ 799*48e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("MICBIAS1", DA732X_REG_MICBIAS1, 800*48e27874SAdam Thomson DA732X_MICBIAS_EN_SHIFT, 801*48e27874SAdam Thomson DA732X_NO_INVERT, NULL, 0), 802*48e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("MICBIAS2", DA732X_REG_MICBIAS2, 803*48e27874SAdam Thomson DA732X_MICBIAS_EN_SHIFT, 804*48e27874SAdam Thomson DA732X_NO_INVERT, NULL, 0), 805*48e27874SAdam Thomson 806*48e27874SAdam Thomson /* Inputs */ 807*48e27874SAdam Thomson SND_SOC_DAPM_INPUT("MIC1"), 808*48e27874SAdam Thomson SND_SOC_DAPM_INPUT("MIC2"), 809*48e27874SAdam Thomson SND_SOC_DAPM_INPUT("MIC3"), 810*48e27874SAdam Thomson SND_SOC_DAPM_INPUT("AUX1L"), 811*48e27874SAdam Thomson SND_SOC_DAPM_INPUT("AUX1R"), 812*48e27874SAdam Thomson 813*48e27874SAdam Thomson /* Outputs */ 814*48e27874SAdam Thomson SND_SOC_DAPM_OUTPUT("HPL"), 815*48e27874SAdam Thomson SND_SOC_DAPM_OUTPUT("HPR"), 816*48e27874SAdam Thomson SND_SOC_DAPM_OUTPUT("LOUTL"), 817*48e27874SAdam Thomson SND_SOC_DAPM_OUTPUT("LOUTR"), 818*48e27874SAdam Thomson SND_SOC_DAPM_OUTPUT("ClassD"), 819*48e27874SAdam Thomson 820*48e27874SAdam Thomson /* ADCs */ 821*48e27874SAdam Thomson SND_SOC_DAPM_ADC("ADC1L", NULL, DA732X_REG_ADC1_SEL, 822*48e27874SAdam Thomson DA732X_ADCL_EN_SHIFT, DA732X_NO_INVERT), 823*48e27874SAdam Thomson SND_SOC_DAPM_ADC("ADC1R", NULL, DA732X_REG_ADC1_SEL, 824*48e27874SAdam Thomson DA732X_ADCR_EN_SHIFT, DA732X_NO_INVERT), 825*48e27874SAdam Thomson SND_SOC_DAPM_ADC("ADC2L", NULL, DA732X_REG_ADC2_SEL, 826*48e27874SAdam Thomson DA732X_ADCL_EN_SHIFT, DA732X_NO_INVERT), 827*48e27874SAdam Thomson SND_SOC_DAPM_ADC("ADC2R", NULL, DA732X_REG_ADC2_SEL, 828*48e27874SAdam Thomson DA732X_ADCR_EN_SHIFT, DA732X_NO_INVERT), 829*48e27874SAdam Thomson 830*48e27874SAdam Thomson /* DACs */ 831*48e27874SAdam Thomson SND_SOC_DAPM_DAC("DAC1L", NULL, DA732X_REG_DAC1_SEL, 832*48e27874SAdam Thomson DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT), 833*48e27874SAdam Thomson SND_SOC_DAPM_DAC("DAC1R", NULL, DA732X_REG_DAC1_SEL, 834*48e27874SAdam Thomson DA732X_DACR_EN_SHIFT, DA732X_NO_INVERT), 835*48e27874SAdam Thomson SND_SOC_DAPM_DAC("DAC2L", NULL, DA732X_REG_DAC2_SEL, 836*48e27874SAdam Thomson DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT), 837*48e27874SAdam Thomson SND_SOC_DAPM_DAC("DAC2R", NULL, DA732X_REG_DAC2_SEL, 838*48e27874SAdam Thomson DA732X_DACR_EN_SHIFT, DA732X_NO_INVERT), 839*48e27874SAdam Thomson SND_SOC_DAPM_DAC("DAC3", NULL, DA732X_REG_DAC3_SEL, 840*48e27874SAdam Thomson DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT), 841*48e27874SAdam Thomson 842*48e27874SAdam Thomson /* Input Pgas */ 843*48e27874SAdam Thomson SND_SOC_DAPM_PGA("MIC1 PGA", DA732X_REG_MIC1, DA732X_MIC_EN_SHIFT, 844*48e27874SAdam Thomson 0, NULL, 0), 845*48e27874SAdam Thomson SND_SOC_DAPM_PGA("MIC2 PGA", DA732X_REG_MIC2, DA732X_MIC_EN_SHIFT, 846*48e27874SAdam Thomson 0, NULL, 0), 847*48e27874SAdam Thomson SND_SOC_DAPM_PGA("MIC3 PGA", DA732X_REG_MIC3, DA732X_MIC_EN_SHIFT, 848*48e27874SAdam Thomson 0, NULL, 0), 849*48e27874SAdam Thomson SND_SOC_DAPM_PGA("AUX1L PGA", DA732X_REG_AUX1L, DA732X_AUX_EN_SHIFT, 850*48e27874SAdam Thomson 0, NULL, 0), 851*48e27874SAdam Thomson SND_SOC_DAPM_PGA("AUX1R PGA", DA732X_REG_AUX1R, DA732X_AUX_EN_SHIFT, 852*48e27874SAdam Thomson 0, NULL, 0), 853*48e27874SAdam Thomson 854*48e27874SAdam Thomson SND_SOC_DAPM_PGA_E("HP Left", DA732X_REG_HPL, DA732X_HP_OUT_EN_SHIFT, 855*48e27874SAdam Thomson 0, NULL, 0, da732x_out_pga_event, 856*48e27874SAdam Thomson SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 857*48e27874SAdam Thomson SND_SOC_DAPM_PGA_E("HP Right", DA732X_REG_HPR, DA732X_HP_OUT_EN_SHIFT, 858*48e27874SAdam Thomson 0, NULL, 0, da732x_out_pga_event, 859*48e27874SAdam Thomson SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 860*48e27874SAdam Thomson SND_SOC_DAPM_PGA_E("LIN2", DA732X_REG_LIN2, DA732X_LIN_OUT_EN_SHIFT, 861*48e27874SAdam Thomson 0, NULL, 0, da732x_out_pga_event, 862*48e27874SAdam Thomson SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 863*48e27874SAdam Thomson SND_SOC_DAPM_PGA_E("LIN3", DA732X_REG_LIN3, DA732X_LIN_OUT_EN_SHIFT, 864*48e27874SAdam Thomson 0, NULL, 0, da732x_out_pga_event, 865*48e27874SAdam Thomson SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 866*48e27874SAdam Thomson SND_SOC_DAPM_PGA_E("LIN4", DA732X_REG_LIN4, DA732X_LIN_OUT_EN_SHIFT, 867*48e27874SAdam Thomson 0, NULL, 0, da732x_out_pga_event, 868*48e27874SAdam Thomson SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 869*48e27874SAdam Thomson 870*48e27874SAdam Thomson /* MUXs */ 871*48e27874SAdam Thomson SND_SOC_DAPM_MUX("ADC1 Left MUX", SND_SOC_NOPM, 0, 0, &adc1l_mux), 872*48e27874SAdam Thomson SND_SOC_DAPM_MUX("ADC1 Right MUX", SND_SOC_NOPM, 0, 0, &adc1r_mux), 873*48e27874SAdam Thomson SND_SOC_DAPM_MUX("ADC2 Left MUX", SND_SOC_NOPM, 0, 0, &adc2l_mux), 874*48e27874SAdam Thomson SND_SOC_DAPM_MUX("ADC2 Right MUX", SND_SOC_NOPM, 0, 0, &adc2r_mux), 875*48e27874SAdam Thomson 876*48e27874SAdam Thomson SND_SOC_DAPM_MUX("HP Left MUX", SND_SOC_NOPM, 0, 0, &hpl_mux), 877*48e27874SAdam Thomson SND_SOC_DAPM_MUX("HP Right MUX", SND_SOC_NOPM, 0, 0, &hpr_mux), 878*48e27874SAdam Thomson SND_SOC_DAPM_MUX("Speaker MUX", SND_SOC_NOPM, 0, 0, &spk_mux), 879*48e27874SAdam Thomson SND_SOC_DAPM_MUX("LOUT2 MUX", SND_SOC_NOPM, 0, 0, &lout2_mux), 880*48e27874SAdam Thomson SND_SOC_DAPM_MUX("LOUT4 MUX", SND_SOC_NOPM, 0, 0, &lout4_mux), 881*48e27874SAdam Thomson 882*48e27874SAdam Thomson /* AIF interfaces */ 883*48e27874SAdam Thomson SND_SOC_DAPM_AIF_OUT("AIFA Output", "AIFA Capture", 0, DA732X_REG_AIFA3, 884*48e27874SAdam Thomson DA732X_AIF_EN_SHIFT, 0), 885*48e27874SAdam Thomson SND_SOC_DAPM_AIF_IN("AIFA Input", "AIFA Playback", 0, DA732X_REG_AIFA3, 886*48e27874SAdam Thomson DA732X_AIF_EN_SHIFT, 0), 887*48e27874SAdam Thomson 888*48e27874SAdam Thomson SND_SOC_DAPM_AIF_OUT("AIFB Output", "AIFB Capture", 0, DA732X_REG_AIFB3, 889*48e27874SAdam Thomson DA732X_AIF_EN_SHIFT, 0), 890*48e27874SAdam Thomson SND_SOC_DAPM_AIF_IN("AIFB Input", "AIFB Playback", 0, DA732X_REG_AIFB3, 891*48e27874SAdam Thomson DA732X_AIF_EN_SHIFT, 0), 892*48e27874SAdam Thomson }; 893*48e27874SAdam Thomson 894*48e27874SAdam Thomson static const struct snd_soc_dapm_route da732x_dapm_routes[] = { 895*48e27874SAdam Thomson /* Inputs */ 896*48e27874SAdam Thomson {"AUX1L PGA", "NULL", "AUX1L"}, 897*48e27874SAdam Thomson {"AUX1R PGA", "NULL", "AUX1R"}, 898*48e27874SAdam Thomson {"MIC1 PGA", NULL, "MIC1"}, 899*48e27874SAdam Thomson {"MIC2 PGA", "NULL", "MIC2"}, 900*48e27874SAdam Thomson {"MIC3 PGA", "NULL", "MIC3"}, 901*48e27874SAdam Thomson 902*48e27874SAdam Thomson /* Capture Path */ 903*48e27874SAdam Thomson {"ADC1 Left MUX", "MIC1", "MIC1 PGA"}, 904*48e27874SAdam Thomson {"ADC1 Left MUX", "AUX1L", "AUX1L PGA"}, 905*48e27874SAdam Thomson 906*48e27874SAdam Thomson {"ADC1 Right MUX", "AUX1R", "AUX1R PGA"}, 907*48e27874SAdam Thomson {"ADC1 Right MUX", "MIC2", "MIC2 PGA"}, 908*48e27874SAdam Thomson {"ADC1 Right MUX", "MIC3", "MIC3 PGA"}, 909*48e27874SAdam Thomson 910*48e27874SAdam Thomson {"ADC2 Left MUX", "AUX1L", "AUX1L PGA"}, 911*48e27874SAdam Thomson {"ADC2 Left MUX", "MIC1", "MIC1 PGA"}, 912*48e27874SAdam Thomson 913*48e27874SAdam Thomson {"ADC2 Right MUX", "AUX1R", "AUX1R PGA"}, 914*48e27874SAdam Thomson {"ADC2 Right MUX", "MIC2", "MIC2 PGA"}, 915*48e27874SAdam Thomson {"ADC2 Right MUX", "MIC3", "MIC3 PGA"}, 916*48e27874SAdam Thomson 917*48e27874SAdam Thomson {"ADC1L", NULL, "ADC1 Supply"}, 918*48e27874SAdam Thomson {"ADC1R", NULL, "ADC1 Supply"}, 919*48e27874SAdam Thomson {"ADC2L", NULL, "ADC2 Supply"}, 920*48e27874SAdam Thomson {"ADC2R", NULL, "ADC2 Supply"}, 921*48e27874SAdam Thomson 922*48e27874SAdam Thomson {"ADC1L", NULL, "ADC1 Left MUX"}, 923*48e27874SAdam Thomson {"ADC1R", NULL, "ADC1 Right MUX"}, 924*48e27874SAdam Thomson {"ADC2L", NULL, "ADC2 Left MUX"}, 925*48e27874SAdam Thomson {"ADC2R", NULL, "ADC2 Right MUX"}, 926*48e27874SAdam Thomson 927*48e27874SAdam Thomson {"AIFA Output", NULL, "ADC1L"}, 928*48e27874SAdam Thomson {"AIFA Output", NULL, "ADC1R"}, 929*48e27874SAdam Thomson {"AIFB Output", NULL, "ADC2L"}, 930*48e27874SAdam Thomson {"AIFB Output", NULL, "ADC2R"}, 931*48e27874SAdam Thomson 932*48e27874SAdam Thomson {"HP Left MUX", "Enabled", "AIFA Input"}, 933*48e27874SAdam Thomson {"HP Right MUX", "Enabled", "AIFA Input"}, 934*48e27874SAdam Thomson {"Speaker MUX", "Enabled", "AIFB Input"}, 935*48e27874SAdam Thomson {"LOUT2 MUX", "Enabled", "AIFB Input"}, 936*48e27874SAdam Thomson {"LOUT4 MUX", "Enabled", "AIFB Input"}, 937*48e27874SAdam Thomson 938*48e27874SAdam Thomson {"DAC1L", NULL, "DAC1 CLK"}, 939*48e27874SAdam Thomson {"DAC1R", NULL, "DAC1 CLK"}, 940*48e27874SAdam Thomson {"DAC2L", NULL, "DAC2 CLK"}, 941*48e27874SAdam Thomson {"DAC2R", NULL, "DAC2 CLK"}, 942*48e27874SAdam Thomson {"DAC3", NULL, "DAC3 CLK"}, 943*48e27874SAdam Thomson 944*48e27874SAdam Thomson {"DAC1L", NULL, "HP Left MUX"}, 945*48e27874SAdam Thomson {"DAC1R", NULL, "HP Right MUX"}, 946*48e27874SAdam Thomson {"DAC2L", NULL, "Speaker MUX"}, 947*48e27874SAdam Thomson {"DAC2R", NULL, "LOUT4 MUX"}, 948*48e27874SAdam Thomson {"DAC3", NULL, "LOUT2 MUX"}, 949*48e27874SAdam Thomson 950*48e27874SAdam Thomson /* Output Pgas */ 951*48e27874SAdam Thomson {"HP Left", NULL, "DAC1L"}, 952*48e27874SAdam Thomson {"HP Right", NULL, "DAC1R"}, 953*48e27874SAdam Thomson {"LIN3", NULL, "DAC2L"}, 954*48e27874SAdam Thomson {"LIN4", NULL, "DAC2R"}, 955*48e27874SAdam Thomson {"LIN2", NULL, "DAC3"}, 956*48e27874SAdam Thomson 957*48e27874SAdam Thomson /* Outputs */ 958*48e27874SAdam Thomson {"ClassD", NULL, "LIN3"}, 959*48e27874SAdam Thomson {"LOUTL", NULL, "LIN2"}, 960*48e27874SAdam Thomson {"LOUTR", NULL, "LIN4"}, 961*48e27874SAdam Thomson {"HPL", NULL, "HP Left"}, 962*48e27874SAdam Thomson {"HPR", NULL, "HP Right"}, 963*48e27874SAdam Thomson }; 964*48e27874SAdam Thomson 965*48e27874SAdam Thomson static int da732x_hw_params(struct snd_pcm_substream *substream, 966*48e27874SAdam Thomson struct snd_pcm_hw_params *params, 967*48e27874SAdam Thomson struct snd_soc_dai *dai) 968*48e27874SAdam Thomson { 969*48e27874SAdam Thomson struct snd_soc_codec *codec = dai->codec; 970*48e27874SAdam Thomson u32 aif = 0; 971*48e27874SAdam Thomson u32 reg_aif; 972*48e27874SAdam Thomson u32 fs; 973*48e27874SAdam Thomson 974*48e27874SAdam Thomson reg_aif = dai->driver->base; 975*48e27874SAdam Thomson 976*48e27874SAdam Thomson switch (params_format(params)) { 977*48e27874SAdam Thomson case SNDRV_PCM_FORMAT_S16_LE: 978*48e27874SAdam Thomson aif |= DA732X_AIF_WORD_16; 979*48e27874SAdam Thomson break; 980*48e27874SAdam Thomson case SNDRV_PCM_FORMAT_S20_3LE: 981*48e27874SAdam Thomson aif |= DA732X_AIF_WORD_20; 982*48e27874SAdam Thomson break; 983*48e27874SAdam Thomson case SNDRV_PCM_FORMAT_S24_LE: 984*48e27874SAdam Thomson aif |= DA732X_AIF_WORD_24; 985*48e27874SAdam Thomson break; 986*48e27874SAdam Thomson case SNDRV_PCM_FORMAT_S32_LE: 987*48e27874SAdam Thomson aif |= DA732X_AIF_WORD_32; 988*48e27874SAdam Thomson break; 989*48e27874SAdam Thomson default: 990*48e27874SAdam Thomson return -EINVAL; 991*48e27874SAdam Thomson } 992*48e27874SAdam Thomson 993*48e27874SAdam Thomson switch (params_rate(params)) { 994*48e27874SAdam Thomson case 8000: 995*48e27874SAdam Thomson fs = DA732X_SR_8KHZ; 996*48e27874SAdam Thomson break; 997*48e27874SAdam Thomson case 11025: 998*48e27874SAdam Thomson fs = DA732X_SR_11_025KHZ; 999*48e27874SAdam Thomson break; 1000*48e27874SAdam Thomson case 12000: 1001*48e27874SAdam Thomson fs = DA732X_SR_12KHZ; 1002*48e27874SAdam Thomson break; 1003*48e27874SAdam Thomson case 16000: 1004*48e27874SAdam Thomson fs = DA732X_SR_16KHZ; 1005*48e27874SAdam Thomson break; 1006*48e27874SAdam Thomson case 22050: 1007*48e27874SAdam Thomson fs = DA732X_SR_22_05KHZ; 1008*48e27874SAdam Thomson break; 1009*48e27874SAdam Thomson case 24000: 1010*48e27874SAdam Thomson fs = DA732X_SR_24KHZ; 1011*48e27874SAdam Thomson break; 1012*48e27874SAdam Thomson case 32000: 1013*48e27874SAdam Thomson fs = DA732X_SR_32KHZ; 1014*48e27874SAdam Thomson break; 1015*48e27874SAdam Thomson case 44100: 1016*48e27874SAdam Thomson fs = DA732X_SR_44_1KHZ; 1017*48e27874SAdam Thomson break; 1018*48e27874SAdam Thomson case 48000: 1019*48e27874SAdam Thomson fs = DA732X_SR_48KHZ; 1020*48e27874SAdam Thomson break; 1021*48e27874SAdam Thomson case 88100: 1022*48e27874SAdam Thomson fs = DA732X_SR_88_1KHZ; 1023*48e27874SAdam Thomson break; 1024*48e27874SAdam Thomson case 96000: 1025*48e27874SAdam Thomson fs = DA732X_SR_96KHZ; 1026*48e27874SAdam Thomson break; 1027*48e27874SAdam Thomson default: 1028*48e27874SAdam Thomson return -EINVAL; 1029*48e27874SAdam Thomson } 1030*48e27874SAdam Thomson 1031*48e27874SAdam Thomson snd_soc_update_bits(codec, reg_aif, DA732X_AIF_WORD_MASK, aif); 1032*48e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_CLK_CTRL, DA732X_SR1_MASK, fs); 1033*48e27874SAdam Thomson 1034*48e27874SAdam Thomson return 0; 1035*48e27874SAdam Thomson } 1036*48e27874SAdam Thomson 1037*48e27874SAdam Thomson static int da732x_set_dai_fmt(struct snd_soc_dai *dai, u32 fmt) 1038*48e27874SAdam Thomson { 1039*48e27874SAdam Thomson struct snd_soc_codec *codec = dai->codec; 1040*48e27874SAdam Thomson u32 aif_mclk, pc_count; 1041*48e27874SAdam Thomson u32 reg_aif1, aif1; 1042*48e27874SAdam Thomson u32 reg_aif3, aif3; 1043*48e27874SAdam Thomson 1044*48e27874SAdam Thomson switch (dai->id) { 1045*48e27874SAdam Thomson case DA732X_DAI_ID1: 1046*48e27874SAdam Thomson reg_aif1 = DA732X_REG_AIFA1; 1047*48e27874SAdam Thomson reg_aif3 = DA732X_REG_AIFA3; 1048*48e27874SAdam Thomson pc_count = DA732X_PC_PULSE_AIFA | DA732X_PC_RESYNC_NOT_AUT | 1049*48e27874SAdam Thomson DA732X_PC_SAME; 1050*48e27874SAdam Thomson break; 1051*48e27874SAdam Thomson case DA732X_DAI_ID2: 1052*48e27874SAdam Thomson reg_aif1 = DA732X_REG_AIFB1; 1053*48e27874SAdam Thomson reg_aif3 = DA732X_REG_AIFB3; 1054*48e27874SAdam Thomson pc_count = DA732X_PC_PULSE_AIFB | DA732X_PC_RESYNC_NOT_AUT | 1055*48e27874SAdam Thomson DA732X_PC_SAME; 1056*48e27874SAdam Thomson break; 1057*48e27874SAdam Thomson default: 1058*48e27874SAdam Thomson return -EINVAL; 1059*48e27874SAdam Thomson } 1060*48e27874SAdam Thomson 1061*48e27874SAdam Thomson switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1062*48e27874SAdam Thomson case SND_SOC_DAIFMT_CBS_CFS: 1063*48e27874SAdam Thomson aif1 = DA732X_AIF_SLAVE; 1064*48e27874SAdam Thomson aif_mclk = DA732X_AIFM_FRAME_64 | DA732X_AIFM_SRC_SEL_AIFA; 1065*48e27874SAdam Thomson break; 1066*48e27874SAdam Thomson case SND_SOC_DAIFMT_CBM_CFM: 1067*48e27874SAdam Thomson aif1 = DA732X_AIF_CLK_FROM_SRC; 1068*48e27874SAdam Thomson aif_mclk = DA732X_CLK_GENERATION_AIF_A; 1069*48e27874SAdam Thomson break; 1070*48e27874SAdam Thomson default: 1071*48e27874SAdam Thomson return -EINVAL; 1072*48e27874SAdam Thomson } 1073*48e27874SAdam Thomson 1074*48e27874SAdam Thomson switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 1075*48e27874SAdam Thomson case SND_SOC_DAIFMT_I2S: 1076*48e27874SAdam Thomson aif3 = DA732X_AIF_I2S_MODE; 1077*48e27874SAdam Thomson break; 1078*48e27874SAdam Thomson case SND_SOC_DAIFMT_RIGHT_J: 1079*48e27874SAdam Thomson aif3 = DA732X_AIF_RIGHT_J_MODE; 1080*48e27874SAdam Thomson break; 1081*48e27874SAdam Thomson case SND_SOC_DAIFMT_LEFT_J: 1082*48e27874SAdam Thomson aif3 = DA732X_AIF_LEFT_J_MODE; 1083*48e27874SAdam Thomson break; 1084*48e27874SAdam Thomson case SND_SOC_DAIFMT_DSP_B: 1085*48e27874SAdam Thomson aif3 = DA732X_AIF_DSP_MODE; 1086*48e27874SAdam Thomson break; 1087*48e27874SAdam Thomson default: 1088*48e27874SAdam Thomson return -EINVAL; 1089*48e27874SAdam Thomson } 1090*48e27874SAdam Thomson 1091*48e27874SAdam Thomson /* Clock inversion */ 1092*48e27874SAdam Thomson switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 1093*48e27874SAdam Thomson case SND_SOC_DAIFMT_DSP_B: 1094*48e27874SAdam Thomson switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 1095*48e27874SAdam Thomson case SND_SOC_DAIFMT_NB_NF: 1096*48e27874SAdam Thomson break; 1097*48e27874SAdam Thomson case SND_SOC_DAIFMT_IB_NF: 1098*48e27874SAdam Thomson aif3 |= DA732X_AIF_BCLK_INV; 1099*48e27874SAdam Thomson break; 1100*48e27874SAdam Thomson default: 1101*48e27874SAdam Thomson return -EINVAL; 1102*48e27874SAdam Thomson } 1103*48e27874SAdam Thomson break; 1104*48e27874SAdam Thomson case SND_SOC_DAIFMT_I2S: 1105*48e27874SAdam Thomson case SND_SOC_DAIFMT_RIGHT_J: 1106*48e27874SAdam Thomson case SND_SOC_DAIFMT_LEFT_J: 1107*48e27874SAdam Thomson switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 1108*48e27874SAdam Thomson case SND_SOC_DAIFMT_NB_NF: 1109*48e27874SAdam Thomson break; 1110*48e27874SAdam Thomson case SND_SOC_DAIFMT_IB_IF: 1111*48e27874SAdam Thomson aif3 |= DA732X_AIF_BCLK_INV | DA732X_AIF_WCLK_INV; 1112*48e27874SAdam Thomson break; 1113*48e27874SAdam Thomson case SND_SOC_DAIFMT_IB_NF: 1114*48e27874SAdam Thomson aif3 |= DA732X_AIF_BCLK_INV; 1115*48e27874SAdam Thomson break; 1116*48e27874SAdam Thomson case SND_SOC_DAIFMT_NB_IF: 1117*48e27874SAdam Thomson aif3 |= DA732X_AIF_WCLK_INV; 1118*48e27874SAdam Thomson break; 1119*48e27874SAdam Thomson default: 1120*48e27874SAdam Thomson return -EINVAL; 1121*48e27874SAdam Thomson } 1122*48e27874SAdam Thomson break; 1123*48e27874SAdam Thomson default: 1124*48e27874SAdam Thomson return -EINVAL; 1125*48e27874SAdam Thomson } 1126*48e27874SAdam Thomson 1127*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_AIF_MCLK, aif_mclk); 1128*48e27874SAdam Thomson snd_soc_update_bits(codec, reg_aif1, DA732X_AIF1_CLK_MASK, aif1); 1129*48e27874SAdam Thomson snd_soc_update_bits(codec, reg_aif3, DA732X_AIF_BCLK_INV | 1130*48e27874SAdam Thomson DA732X_AIF_WCLK_INV | DA732X_AIF_MODE_MASK, aif3); 1131*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_PC_CTRL, pc_count); 1132*48e27874SAdam Thomson 1133*48e27874SAdam Thomson return 0; 1134*48e27874SAdam Thomson } 1135*48e27874SAdam Thomson 1136*48e27874SAdam Thomson 1137*48e27874SAdam Thomson 1138*48e27874SAdam Thomson static int da732x_set_dai_pll(struct snd_soc_codec *codec, int pll_id, 1139*48e27874SAdam Thomson int source, unsigned int freq_in, 1140*48e27874SAdam Thomson unsigned int freq_out) 1141*48e27874SAdam Thomson { 1142*48e27874SAdam Thomson struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); 1143*48e27874SAdam Thomson int fref, indiv; 1144*48e27874SAdam Thomson u8 div_lo, div_mid, div_hi; 1145*48e27874SAdam Thomson u64 frac_div; 1146*48e27874SAdam Thomson 1147*48e27874SAdam Thomson /* Disable PLL */ 1148*48e27874SAdam Thomson if (freq_out == 0) { 1149*48e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, 1150*48e27874SAdam Thomson DA732X_PLL_EN, 0); 1151*48e27874SAdam Thomson da732x->pll_en = false; 1152*48e27874SAdam Thomson return 0; 1153*48e27874SAdam Thomson } 1154*48e27874SAdam Thomson 1155*48e27874SAdam Thomson if (da732x->pll_en) 1156*48e27874SAdam Thomson return -EBUSY; 1157*48e27874SAdam Thomson 1158*48e27874SAdam Thomson if (source == DA732X_SRCCLK_MCLK) { 1159*48e27874SAdam Thomson /* Validate Sysclk rate */ 1160*48e27874SAdam Thomson switch (da732x->sysclk) { 1161*48e27874SAdam Thomson case 11290000: 1162*48e27874SAdam Thomson case 12288000: 1163*48e27874SAdam Thomson case 22580000: 1164*48e27874SAdam Thomson case 24576000: 1165*48e27874SAdam Thomson case 45160000: 1166*48e27874SAdam Thomson case 49152000: 1167*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_PLL_CTRL, 1168*48e27874SAdam Thomson DA732X_PLL_BYPASS); 1169*48e27874SAdam Thomson return 0; 1170*48e27874SAdam Thomson default: 1171*48e27874SAdam Thomson dev_err(codec->dev, 1172*48e27874SAdam Thomson "Cannot use PLL Bypass, invalid SYSCLK rate\n"); 1173*48e27874SAdam Thomson return -EINVAL; 1174*48e27874SAdam Thomson } 1175*48e27874SAdam Thomson } 1176*48e27874SAdam Thomson 1177*48e27874SAdam Thomson indiv = da732x_get_input_div(codec, da732x->sysclk); 1178*48e27874SAdam Thomson if (indiv < 0) 1179*48e27874SAdam Thomson return indiv; 1180*48e27874SAdam Thomson 1181*48e27874SAdam Thomson fref = (da732x->sysclk / indiv); 1182*48e27874SAdam Thomson div_hi = freq_out / fref; 1183*48e27874SAdam Thomson frac_div = (u64)(freq_out % fref) * 8192ULL; 1184*48e27874SAdam Thomson do_div(frac_div, fref); 1185*48e27874SAdam Thomson div_mid = (frac_div >> DA732X_1BYTE_SHIFT) & DA732X_U8_MASK; 1186*48e27874SAdam Thomson div_lo = (frac_div) & DA732X_U8_MASK; 1187*48e27874SAdam Thomson 1188*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_PLL_DIV_LO, div_lo); 1189*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_PLL_DIV_MID, div_mid); 1190*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_PLL_DIV_HI, div_hi); 1191*48e27874SAdam Thomson 1192*48e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, DA732X_PLL_EN, 1193*48e27874SAdam Thomson DA732X_PLL_EN); 1194*48e27874SAdam Thomson 1195*48e27874SAdam Thomson da732x->pll_en = true; 1196*48e27874SAdam Thomson 1197*48e27874SAdam Thomson return 0; 1198*48e27874SAdam Thomson } 1199*48e27874SAdam Thomson 1200*48e27874SAdam Thomson static int da732x_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, 1201*48e27874SAdam Thomson unsigned int freq, int dir) 1202*48e27874SAdam Thomson { 1203*48e27874SAdam Thomson struct snd_soc_codec *codec = dai->codec; 1204*48e27874SAdam Thomson struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); 1205*48e27874SAdam Thomson 1206*48e27874SAdam Thomson da732x->sysclk = freq; 1207*48e27874SAdam Thomson 1208*48e27874SAdam Thomson return 0; 1209*48e27874SAdam Thomson } 1210*48e27874SAdam Thomson 1211*48e27874SAdam Thomson #define DA732X_RATES SNDRV_PCM_RATE_8000_96000 1212*48e27874SAdam Thomson 1213*48e27874SAdam Thomson #define DA732X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 1214*48e27874SAdam Thomson SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 1215*48e27874SAdam Thomson 1216*48e27874SAdam Thomson static struct snd_soc_dai_ops da732x_dai1_ops = { 1217*48e27874SAdam Thomson .hw_params = da732x_hw_params, 1218*48e27874SAdam Thomson .set_fmt = da732x_set_dai_fmt, 1219*48e27874SAdam Thomson .set_sysclk = da732x_set_dai_sysclk, 1220*48e27874SAdam Thomson }; 1221*48e27874SAdam Thomson 1222*48e27874SAdam Thomson static struct snd_soc_dai_ops da732x_dai2_ops = { 1223*48e27874SAdam Thomson .hw_params = da732x_hw_params, 1224*48e27874SAdam Thomson .set_fmt = da732x_set_dai_fmt, 1225*48e27874SAdam Thomson .set_sysclk = da732x_set_dai_sysclk, 1226*48e27874SAdam Thomson }; 1227*48e27874SAdam Thomson 1228*48e27874SAdam Thomson static struct snd_soc_dai_driver da732x_dai[] = { 1229*48e27874SAdam Thomson { 1230*48e27874SAdam Thomson .name = "DA732X_AIFA", 1231*48e27874SAdam Thomson .id = DA732X_DAI_ID1, 1232*48e27874SAdam Thomson .base = DA732X_REG_AIFA1, 1233*48e27874SAdam Thomson .playback = { 1234*48e27874SAdam Thomson .stream_name = "AIFA Playback", 1235*48e27874SAdam Thomson .channels_min = 1, 1236*48e27874SAdam Thomson .channels_max = 2, 1237*48e27874SAdam Thomson .rates = DA732X_RATES, 1238*48e27874SAdam Thomson .formats = DA732X_FORMATS, 1239*48e27874SAdam Thomson }, 1240*48e27874SAdam Thomson .capture = { 1241*48e27874SAdam Thomson .stream_name = "AIFA Capture", 1242*48e27874SAdam Thomson .channels_min = 1, 1243*48e27874SAdam Thomson .channels_max = 2, 1244*48e27874SAdam Thomson .rates = DA732X_RATES, 1245*48e27874SAdam Thomson .formats = DA732X_FORMATS, 1246*48e27874SAdam Thomson }, 1247*48e27874SAdam Thomson .ops = &da732x_dai1_ops, 1248*48e27874SAdam Thomson }, 1249*48e27874SAdam Thomson { 1250*48e27874SAdam Thomson .name = "DA732X_AIFB", 1251*48e27874SAdam Thomson .id = DA732X_DAI_ID2, 1252*48e27874SAdam Thomson .base = DA732X_REG_AIFB1, 1253*48e27874SAdam Thomson .playback = { 1254*48e27874SAdam Thomson .stream_name = "AIFB Playback", 1255*48e27874SAdam Thomson .channels_min = 1, 1256*48e27874SAdam Thomson .channels_max = 2, 1257*48e27874SAdam Thomson .rates = DA732X_RATES, 1258*48e27874SAdam Thomson .formats = DA732X_FORMATS, 1259*48e27874SAdam Thomson }, 1260*48e27874SAdam Thomson .capture = { 1261*48e27874SAdam Thomson .stream_name = "AIFB Capture", 1262*48e27874SAdam Thomson .channels_min = 1, 1263*48e27874SAdam Thomson .channels_max = 2, 1264*48e27874SAdam Thomson .rates = DA732X_RATES, 1265*48e27874SAdam Thomson .formats = DA732X_FORMATS, 1266*48e27874SAdam Thomson }, 1267*48e27874SAdam Thomson .ops = &da732x_dai2_ops, 1268*48e27874SAdam Thomson }, 1269*48e27874SAdam Thomson }; 1270*48e27874SAdam Thomson 1271*48e27874SAdam Thomson static const struct regmap_config da732x_regmap = { 1272*48e27874SAdam Thomson .reg_bits = 8, 1273*48e27874SAdam Thomson .val_bits = 8, 1274*48e27874SAdam Thomson 1275*48e27874SAdam Thomson .max_register = DA732X_MAX_REG, 1276*48e27874SAdam Thomson .reg_defaults = da732x_reg_cache, 1277*48e27874SAdam Thomson .num_reg_defaults = ARRAY_SIZE(da732x_reg_cache), 1278*48e27874SAdam Thomson .cache_type = REGCACHE_RBTREE, 1279*48e27874SAdam Thomson }; 1280*48e27874SAdam Thomson 1281*48e27874SAdam Thomson 1282*48e27874SAdam Thomson static void da732x_dac_offset_adjust(struct snd_soc_codec *codec) 1283*48e27874SAdam Thomson { 1284*48e27874SAdam Thomson u8 offset[DA732X_HP_DACS]; 1285*48e27874SAdam Thomson u8 sign[DA732X_HP_DACS]; 1286*48e27874SAdam Thomson u8 step = DA732X_DAC_OFFSET_STEP; 1287*48e27874SAdam Thomson 1288*48e27874SAdam Thomson /* Initialize DAC offset calibration circuits and registers */ 1289*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET, 1290*48e27874SAdam Thomson DA732X_HP_DAC_OFFSET_TRIM_VAL); 1291*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET, 1292*48e27874SAdam Thomson DA732X_HP_DAC_OFFSET_TRIM_VAL); 1293*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL, 1294*48e27874SAdam Thomson DA732X_HP_DAC_OFF_CALIBRATION | 1295*48e27874SAdam Thomson DA732X_HP_DAC_OFF_SCALE_STEPS); 1296*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL, 1297*48e27874SAdam Thomson DA732X_HP_DAC_OFF_CALIBRATION | 1298*48e27874SAdam Thomson DA732X_HP_DAC_OFF_SCALE_STEPS); 1299*48e27874SAdam Thomson 1300*48e27874SAdam Thomson /* Wait for voltage stabilization */ 1301*48e27874SAdam Thomson msleep(DA732X_WAIT_FOR_STABILIZATION); 1302*48e27874SAdam Thomson 1303*48e27874SAdam Thomson /* Check DAC offset sign */ 1304*48e27874SAdam Thomson sign[DA732X_HPL_DAC] = (codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) & 1305*48e27874SAdam Thomson DA732X_HP_DAC_OFF_CNTL_COMPO); 1306*48e27874SAdam Thomson sign[DA732X_HPR_DAC] = (codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) & 1307*48e27874SAdam Thomson DA732X_HP_DAC_OFF_CNTL_COMPO); 1308*48e27874SAdam Thomson 1309*48e27874SAdam Thomson /* Binary search DAC offset values (both channels at once) */ 1310*48e27874SAdam Thomson offset[DA732X_HPL_DAC] = sign[DA732X_HPL_DAC] << DA732X_HP_DAC_COMPO_SHIFT; 1311*48e27874SAdam Thomson offset[DA732X_HPR_DAC] = sign[DA732X_HPR_DAC] << DA732X_HP_DAC_COMPO_SHIFT; 1312*48e27874SAdam Thomson 1313*48e27874SAdam Thomson do { 1314*48e27874SAdam Thomson offset[DA732X_HPL_DAC] |= step; 1315*48e27874SAdam Thomson offset[DA732X_HPR_DAC] |= step; 1316*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET, 1317*48e27874SAdam Thomson ~offset[DA732X_HPL_DAC] & DA732X_HP_DAC_OFF_MASK); 1318*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET, 1319*48e27874SAdam Thomson ~offset[DA732X_HPR_DAC] & DA732X_HP_DAC_OFF_MASK); 1320*48e27874SAdam Thomson 1321*48e27874SAdam Thomson msleep(DA732X_WAIT_FOR_STABILIZATION); 1322*48e27874SAdam Thomson 1323*48e27874SAdam Thomson if ((codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) & 1324*48e27874SAdam Thomson DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPL_DAC]) 1325*48e27874SAdam Thomson offset[DA732X_HPL_DAC] &= ~step; 1326*48e27874SAdam Thomson if ((codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) & 1327*48e27874SAdam Thomson DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPR_DAC]) 1328*48e27874SAdam Thomson offset[DA732X_HPR_DAC] &= ~step; 1329*48e27874SAdam Thomson 1330*48e27874SAdam Thomson step >>= 1; 1331*48e27874SAdam Thomson } while (step); 1332*48e27874SAdam Thomson 1333*48e27874SAdam Thomson /* Write final DAC offsets to registers */ 1334*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET, 1335*48e27874SAdam Thomson ~offset[DA732X_HPL_DAC] & DA732X_HP_DAC_OFF_MASK); 1336*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET, 1337*48e27874SAdam Thomson ~offset[DA732X_HPR_DAC] & DA732X_HP_DAC_OFF_MASK); 1338*48e27874SAdam Thomson 1339*48e27874SAdam Thomson /* End DAC calibration mode */ 1340*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL, 1341*48e27874SAdam Thomson DA732X_HP_DAC_OFF_SCALE_STEPS); 1342*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL, 1343*48e27874SAdam Thomson DA732X_HP_DAC_OFF_SCALE_STEPS); 1344*48e27874SAdam Thomson } 1345*48e27874SAdam Thomson 1346*48e27874SAdam Thomson static void da732x_output_offset_adjust(struct snd_soc_codec *codec) 1347*48e27874SAdam Thomson { 1348*48e27874SAdam Thomson u8 offset[DA732X_HP_AMPS]; 1349*48e27874SAdam Thomson u8 sign[DA732X_HP_AMPS]; 1350*48e27874SAdam Thomson u8 step = DA732X_OUTPUT_OFFSET_STEP; 1351*48e27874SAdam Thomson 1352*48e27874SAdam Thomson offset[DA732X_HPL_AMP] = DA732X_HP_OUT_TRIM_VAL; 1353*48e27874SAdam Thomson offset[DA732X_HPR_AMP] = DA732X_HP_OUT_TRIM_VAL; 1354*48e27874SAdam Thomson 1355*48e27874SAdam Thomson /* Initialize output offset calibration circuits and registers */ 1356*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL); 1357*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL); 1358*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL, 1359*48e27874SAdam Thomson DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN); 1360*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR, 1361*48e27874SAdam Thomson DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN); 1362*48e27874SAdam Thomson 1363*48e27874SAdam Thomson /* Wait for voltage stabilization */ 1364*48e27874SAdam Thomson msleep(DA732X_WAIT_FOR_STABILIZATION); 1365*48e27874SAdam Thomson 1366*48e27874SAdam Thomson /* Check output offset sign */ 1367*48e27874SAdam Thomson sign[DA732X_HPL_AMP] = codec->hw_read(codec, DA732X_REG_HPL) & 1368*48e27874SAdam Thomson DA732X_HP_OUT_COMPO; 1369*48e27874SAdam Thomson sign[DA732X_HPR_AMP] = codec->hw_read(codec, DA732X_REG_HPR) & 1370*48e27874SAdam Thomson DA732X_HP_OUT_COMPO; 1371*48e27874SAdam Thomson 1372*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_COMP | 1373*48e27874SAdam Thomson (sign[DA732X_HPL_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) | 1374*48e27874SAdam Thomson DA732X_HP_OUT_EN); 1375*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_COMP | 1376*48e27874SAdam Thomson (sign[DA732X_HPR_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) | 1377*48e27874SAdam Thomson DA732X_HP_OUT_EN); 1378*48e27874SAdam Thomson 1379*48e27874SAdam Thomson /* Binary search output offset values (both channels at once) */ 1380*48e27874SAdam Thomson do { 1381*48e27874SAdam Thomson offset[DA732X_HPL_AMP] |= step; 1382*48e27874SAdam Thomson offset[DA732X_HPR_AMP] |= step; 1383*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, 1384*48e27874SAdam Thomson offset[DA732X_HPL_AMP]); 1385*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, 1386*48e27874SAdam Thomson offset[DA732X_HPR_AMP]); 1387*48e27874SAdam Thomson 1388*48e27874SAdam Thomson msleep(DA732X_WAIT_FOR_STABILIZATION); 1389*48e27874SAdam Thomson 1390*48e27874SAdam Thomson if ((codec->hw_read(codec, DA732X_REG_HPL) & 1391*48e27874SAdam Thomson DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPL_AMP]) 1392*48e27874SAdam Thomson offset[DA732X_HPL_AMP] &= ~step; 1393*48e27874SAdam Thomson if ((codec->hw_read(codec, DA732X_REG_HPR) & 1394*48e27874SAdam Thomson DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPR_AMP]) 1395*48e27874SAdam Thomson offset[DA732X_HPR_AMP] &= ~step; 1396*48e27874SAdam Thomson 1397*48e27874SAdam Thomson step >>= 1; 1398*48e27874SAdam Thomson } while (step); 1399*48e27874SAdam Thomson 1400*48e27874SAdam Thomson /* Write final DAC offsets to registers */ 1401*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, offset[DA732X_HPL_AMP]); 1402*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, offset[DA732X_HPR_AMP]); 1403*48e27874SAdam Thomson } 1404*48e27874SAdam Thomson 1405*48e27874SAdam Thomson static void da732x_hp_dc_offset_cancellation(struct snd_soc_codec *codec) 1406*48e27874SAdam Thomson { 1407*48e27874SAdam Thomson /* Make sure that we have Soft Mute enabled */ 1408*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_DAC1_SOFTMUTE, DA732X_SOFTMUTE_EN | 1409*48e27874SAdam Thomson DA732X_GAIN_RAMPED | DA732X_16_SAMPLES); 1410*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACL_EN | 1411*48e27874SAdam Thomson DA732X_DACR_EN | DA732X_DACL_SDM | DA732X_DACR_SDM | 1412*48e27874SAdam Thomson DA732X_DACL_MUTE | DA732X_DACR_MUTE); 1413*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN | 1414*48e27874SAdam Thomson DA732X_HP_OUT_MUTE | DA732X_HP_OUT_EN); 1415*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_EN | 1416*48e27874SAdam Thomson DA732X_HP_OUT_MUTE | DA732X_HP_OUT_DAC_EN); 1417*48e27874SAdam Thomson 1418*48e27874SAdam Thomson da732x_dac_offset_adjust(codec); 1419*48e27874SAdam Thomson da732x_output_offset_adjust(codec); 1420*48e27874SAdam Thomson 1421*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACS_DIS); 1422*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_DIS); 1423*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_DIS); 1424*48e27874SAdam Thomson } 1425*48e27874SAdam Thomson 1426*48e27874SAdam Thomson static int da732x_set_bias_level(struct snd_soc_codec *codec, 1427*48e27874SAdam Thomson enum snd_soc_bias_level level) 1428*48e27874SAdam Thomson { 1429*48e27874SAdam Thomson struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); 1430*48e27874SAdam Thomson 1431*48e27874SAdam Thomson switch (level) { 1432*48e27874SAdam Thomson case SND_SOC_BIAS_ON: 1433*48e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, 1434*48e27874SAdam Thomson DA732X_BIAS_BOOST_MASK, 1435*48e27874SAdam Thomson DA732X_BIAS_BOOST_100PC); 1436*48e27874SAdam Thomson break; 1437*48e27874SAdam Thomson case SND_SOC_BIAS_PREPARE: 1438*48e27874SAdam Thomson break; 1439*48e27874SAdam Thomson case SND_SOC_BIAS_STANDBY: 1440*48e27874SAdam Thomson if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 1441*48e27874SAdam Thomson /* Init Codec */ 1442*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_REF1, 1443*48e27874SAdam Thomson DA732X_VMID_FASTCHG); 1444*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_BIAS_EN, 1445*48e27874SAdam Thomson DA732X_BIAS_EN); 1446*48e27874SAdam Thomson 1447*48e27874SAdam Thomson mdelay(DA732X_STARTUP_DELAY); 1448*48e27874SAdam Thomson 1449*48e27874SAdam Thomson /* Disable Fast Charge and enable DAC ref voltage */ 1450*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_REF1, 1451*48e27874SAdam Thomson DA732X_REFBUFX2_EN); 1452*48e27874SAdam Thomson 1453*48e27874SAdam Thomson /* Enable bypass DSP routing */ 1454*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_DATA_ROUTE, 1455*48e27874SAdam Thomson DA732X_BYPASS_DSP); 1456*48e27874SAdam Thomson 1457*48e27874SAdam Thomson /* Enable Digital subsystem */ 1458*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_DSP_CTRL, 1459*48e27874SAdam Thomson DA732X_DIGITAL_EN); 1460*48e27874SAdam Thomson 1461*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_SPARE1_OUT, 1462*48e27874SAdam Thomson DA732X_HP_DRIVER_EN | 1463*48e27874SAdam Thomson DA732X_HP_GATE_LOW | 1464*48e27874SAdam Thomson DA732X_HP_LOOP_GAIN_CTRL); 1465*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HP_LIN1_GNDSEL, 1466*48e27874SAdam Thomson DA732X_HP_OUT_GNDSEL); 1467*48e27874SAdam Thomson 1468*48e27874SAdam Thomson da732x_set_charge_pump(codec, DA732X_ENABLE_CP); 1469*48e27874SAdam Thomson 1470*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_CLK_EN1, 1471*48e27874SAdam Thomson DA732X_SYS3_CLK_EN | DA732X_PC_CLK_EN); 1472*48e27874SAdam Thomson 1473*48e27874SAdam Thomson /* Enable Zero Crossing */ 1474*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_INP_ZC_EN, 1475*48e27874SAdam Thomson DA732X_MIC1_PRE_ZC_EN | 1476*48e27874SAdam Thomson DA732X_MIC1_ZC_EN | 1477*48e27874SAdam Thomson DA732X_MIC2_PRE_ZC_EN | 1478*48e27874SAdam Thomson DA732X_MIC2_ZC_EN | 1479*48e27874SAdam Thomson DA732X_AUXL_ZC_EN | 1480*48e27874SAdam Thomson DA732X_AUXR_ZC_EN | 1481*48e27874SAdam Thomson DA732X_MIC3_PRE_ZC_EN | 1482*48e27874SAdam Thomson DA732X_MIC3_ZC_EN); 1483*48e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_OUT_ZC_EN, 1484*48e27874SAdam Thomson DA732X_HPL_ZC_EN | DA732X_HPR_ZC_EN | 1485*48e27874SAdam Thomson DA732X_LIN2_ZC_EN | DA732X_LIN3_ZC_EN | 1486*48e27874SAdam Thomson DA732X_LIN4_ZC_EN); 1487*48e27874SAdam Thomson 1488*48e27874SAdam Thomson da732x_hp_dc_offset_cancellation(codec); 1489*48e27874SAdam Thomson 1490*48e27874SAdam Thomson regcache_cache_only(codec->control_data, false); 1491*48e27874SAdam Thomson regcache_sync(codec->control_data); 1492*48e27874SAdam Thomson } else { 1493*48e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, 1494*48e27874SAdam Thomson DA732X_BIAS_BOOST_MASK, 1495*48e27874SAdam Thomson DA732X_BIAS_BOOST_50PC); 1496*48e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, 1497*48e27874SAdam Thomson DA732X_PLL_EN, 0); 1498*48e27874SAdam Thomson da732x->pll_en = false; 1499*48e27874SAdam Thomson } 1500*48e27874SAdam Thomson break; 1501*48e27874SAdam Thomson case SND_SOC_BIAS_OFF: 1502*48e27874SAdam Thomson regcache_cache_only(codec->control_data, true); 1503*48e27874SAdam Thomson da732x_set_charge_pump(codec, DA732X_DISABLE_CP); 1504*48e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, DA732X_BIAS_EN, 1505*48e27874SAdam Thomson DA732X_BIAS_DIS); 1506*48e27874SAdam Thomson da732x->pll_en = false; 1507*48e27874SAdam Thomson break; 1508*48e27874SAdam Thomson } 1509*48e27874SAdam Thomson 1510*48e27874SAdam Thomson codec->dapm.bias_level = level; 1511*48e27874SAdam Thomson 1512*48e27874SAdam Thomson return 0; 1513*48e27874SAdam Thomson } 1514*48e27874SAdam Thomson 1515*48e27874SAdam Thomson static int da732x_probe(struct snd_soc_codec *codec) 1516*48e27874SAdam Thomson { 1517*48e27874SAdam Thomson struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); 1518*48e27874SAdam Thomson struct snd_soc_dapm_context *dapm = &codec->dapm; 1519*48e27874SAdam Thomson int ret = 0; 1520*48e27874SAdam Thomson 1521*48e27874SAdam Thomson da732x->codec = codec; 1522*48e27874SAdam Thomson 1523*48e27874SAdam Thomson dapm->idle_bias_off = false; 1524*48e27874SAdam Thomson 1525*48e27874SAdam Thomson codec->control_data = da732x->regmap; 1526*48e27874SAdam Thomson 1527*48e27874SAdam Thomson ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); 1528*48e27874SAdam Thomson if (ret != 0) { 1529*48e27874SAdam Thomson dev_err(codec->dev, "Failed to register codec.\n"); 1530*48e27874SAdam Thomson goto err; 1531*48e27874SAdam Thomson } 1532*48e27874SAdam Thomson 1533*48e27874SAdam Thomson da732x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1534*48e27874SAdam Thomson err: 1535*48e27874SAdam Thomson return ret; 1536*48e27874SAdam Thomson } 1537*48e27874SAdam Thomson 1538*48e27874SAdam Thomson static int da732x_remove(struct snd_soc_codec *codec) 1539*48e27874SAdam Thomson { 1540*48e27874SAdam Thomson 1541*48e27874SAdam Thomson da732x_set_bias_level(codec, SND_SOC_BIAS_OFF); 1542*48e27874SAdam Thomson 1543*48e27874SAdam Thomson return 0; 1544*48e27874SAdam Thomson } 1545*48e27874SAdam Thomson 1546*48e27874SAdam Thomson struct snd_soc_codec_driver soc_codec_dev_da732x = { 1547*48e27874SAdam Thomson .probe = da732x_probe, 1548*48e27874SAdam Thomson .remove = da732x_remove, 1549*48e27874SAdam Thomson .set_bias_level = da732x_set_bias_level, 1550*48e27874SAdam Thomson .controls = da732x_snd_controls, 1551*48e27874SAdam Thomson .num_controls = ARRAY_SIZE(da732x_snd_controls), 1552*48e27874SAdam Thomson .dapm_widgets = da732x_dapm_widgets, 1553*48e27874SAdam Thomson .num_dapm_widgets = ARRAY_SIZE(da732x_dapm_widgets), 1554*48e27874SAdam Thomson .dapm_routes = da732x_dapm_routes, 1555*48e27874SAdam Thomson .num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes), 1556*48e27874SAdam Thomson .set_pll = da732x_set_dai_pll, 1557*48e27874SAdam Thomson .reg_cache_size = ARRAY_SIZE(da732x_reg_cache), 1558*48e27874SAdam Thomson }; 1559*48e27874SAdam Thomson 1560*48e27874SAdam Thomson static __devinit int da732x_i2c_probe(struct i2c_client *i2c, 1561*48e27874SAdam Thomson const struct i2c_device_id *id) 1562*48e27874SAdam Thomson { 1563*48e27874SAdam Thomson struct da732x_priv *da732x; 1564*48e27874SAdam Thomson unsigned int reg; 1565*48e27874SAdam Thomson int ret; 1566*48e27874SAdam Thomson 1567*48e27874SAdam Thomson da732x = devm_kzalloc(&i2c->dev, sizeof(struct da732x_priv), 1568*48e27874SAdam Thomson GFP_KERNEL); 1569*48e27874SAdam Thomson if (!da732x) 1570*48e27874SAdam Thomson return -ENOMEM; 1571*48e27874SAdam Thomson 1572*48e27874SAdam Thomson i2c_set_clientdata(i2c, da732x); 1573*48e27874SAdam Thomson 1574*48e27874SAdam Thomson da732x->regmap = devm_regmap_init_i2c(i2c, &da732x_regmap); 1575*48e27874SAdam Thomson if (IS_ERR(da732x->regmap)) { 1576*48e27874SAdam Thomson ret = PTR_ERR(da732x->regmap); 1577*48e27874SAdam Thomson dev_err(&i2c->dev, "Failed to initialize regmap\n"); 1578*48e27874SAdam Thomson goto err; 1579*48e27874SAdam Thomson } 1580*48e27874SAdam Thomson 1581*48e27874SAdam Thomson ret = regmap_read(da732x->regmap, DA732X_REG_ID, ®); 1582*48e27874SAdam Thomson if (ret < 0) { 1583*48e27874SAdam Thomson dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret); 1584*48e27874SAdam Thomson goto err; 1585*48e27874SAdam Thomson } 1586*48e27874SAdam Thomson 1587*48e27874SAdam Thomson dev_info(&i2c->dev, "Revision: %d.%d\n", 1588*48e27874SAdam Thomson (reg & DA732X_ID_MAJOR_MASK), (reg & DA732X_ID_MINOR_MASK)); 1589*48e27874SAdam Thomson 1590*48e27874SAdam Thomson ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da732x, 1591*48e27874SAdam Thomson da732x_dai, ARRAY_SIZE(da732x_dai)); 1592*48e27874SAdam Thomson if (ret != 0) 1593*48e27874SAdam Thomson dev_err(&i2c->dev, "Failed to register codec.\n"); 1594*48e27874SAdam Thomson 1595*48e27874SAdam Thomson err: 1596*48e27874SAdam Thomson return ret; 1597*48e27874SAdam Thomson } 1598*48e27874SAdam Thomson 1599*48e27874SAdam Thomson static __devexit int da732x_i2c_remove(struct i2c_client *client) 1600*48e27874SAdam Thomson { 1601*48e27874SAdam Thomson snd_soc_unregister_codec(&client->dev); 1602*48e27874SAdam Thomson 1603*48e27874SAdam Thomson return 0; 1604*48e27874SAdam Thomson } 1605*48e27874SAdam Thomson 1606*48e27874SAdam Thomson static const struct i2c_device_id da732x_i2c_id[] = { 1607*48e27874SAdam Thomson { "da7320", 0}, 1608*48e27874SAdam Thomson { } 1609*48e27874SAdam Thomson }; 1610*48e27874SAdam Thomson MODULE_DEVICE_TABLE(i2c, da732x_i2c_id); 1611*48e27874SAdam Thomson 1612*48e27874SAdam Thomson static struct i2c_driver da732x_i2c_driver = { 1613*48e27874SAdam Thomson .driver = { 1614*48e27874SAdam Thomson .name = "da7320", 1615*48e27874SAdam Thomson .owner = THIS_MODULE, 1616*48e27874SAdam Thomson }, 1617*48e27874SAdam Thomson .probe = da732x_i2c_probe, 1618*48e27874SAdam Thomson .remove = __devexit_p(da732x_i2c_remove), 1619*48e27874SAdam Thomson .id_table = da732x_i2c_id, 1620*48e27874SAdam Thomson }; 1621*48e27874SAdam Thomson 1622*48e27874SAdam Thomson module_i2c_driver(da732x_i2c_driver); 1623*48e27874SAdam Thomson 1624*48e27874SAdam Thomson 1625*48e27874SAdam Thomson MODULE_DESCRIPTION("ASoC DA732X driver"); 1626*48e27874SAdam Thomson MODULE_AUTHOR("Michal Hajduk <michal.hajduk@diasemi.com>"); 1627*48e27874SAdam Thomson MODULE_LICENSE("GPL"); 1628