148e27874SAdam Thomson /* 248e27874SAdam Thomson * da732x.c --- Dialog DA732X ALSA SoC Audio Driver 348e27874SAdam Thomson * 448e27874SAdam Thomson * Copyright (C) 2012 Dialog Semiconductor GmbH 548e27874SAdam Thomson * 648e27874SAdam Thomson * Author: Michal Hajduk <Michal.Hajduk@diasemi.com> 748e27874SAdam Thomson * 848e27874SAdam Thomson * This program is free software; you can redistribute it and/or modify 948e27874SAdam Thomson * it under the terms of the GNU General Public License version 2 as 1048e27874SAdam Thomson * published by the Free Software Foundation. 1148e27874SAdam Thomson */ 1248e27874SAdam Thomson 1348e27874SAdam Thomson #include <linux/module.h> 1448e27874SAdam Thomson #include <linux/moduleparam.h> 1548e27874SAdam Thomson #include <linux/init.h> 1648e27874SAdam Thomson #include <linux/delay.h> 1748e27874SAdam Thomson #include <linux/pm.h> 1848e27874SAdam Thomson #include <linux/i2c.h> 1948e27874SAdam Thomson #include <linux/regmap.h> 2048e27874SAdam Thomson #include <linux/platform_device.h> 2148e27874SAdam Thomson #include <linux/slab.h> 2248e27874SAdam Thomson #include <linux/sysfs.h> 2348e27874SAdam Thomson #include <sound/core.h> 2448e27874SAdam Thomson #include <sound/pcm.h> 2548e27874SAdam Thomson #include <sound/pcm_params.h> 2648e27874SAdam Thomson #include <sound/soc.h> 2748e27874SAdam Thomson #include <sound/soc-dapm.h> 2848e27874SAdam Thomson #include <sound/initval.h> 2948e27874SAdam Thomson #include <sound/tlv.h> 3048e27874SAdam Thomson #include <asm/div64.h> 3148e27874SAdam Thomson 3248e27874SAdam Thomson #include "da732x.h" 3348e27874SAdam Thomson #include "da732x_reg.h" 3448e27874SAdam Thomson 3548e27874SAdam Thomson 3648e27874SAdam Thomson struct da732x_priv { 3748e27874SAdam Thomson struct regmap *regmap; 3848e27874SAdam Thomson struct snd_soc_codec *codec; 3948e27874SAdam Thomson 4048e27874SAdam Thomson unsigned int sysclk; 4148e27874SAdam Thomson bool pll_en; 4248e27874SAdam Thomson }; 4348e27874SAdam Thomson 4448e27874SAdam Thomson /* 4548e27874SAdam Thomson * da732x register cache - default settings 4648e27874SAdam Thomson */ 4748e27874SAdam Thomson static struct reg_default da732x_reg_cache[] = { 4848e27874SAdam Thomson { DA732X_REG_REF1 , 0x02 }, 4948e27874SAdam Thomson { DA732X_REG_BIAS_EN , 0x80 }, 5048e27874SAdam Thomson { DA732X_REG_BIAS1 , 0x00 }, 5148e27874SAdam Thomson { DA732X_REG_BIAS2 , 0x00 }, 5248e27874SAdam Thomson { DA732X_REG_BIAS3 , 0x00 }, 5348e27874SAdam Thomson { DA732X_REG_BIAS4 , 0x00 }, 5448e27874SAdam Thomson { DA732X_REG_MICBIAS2 , 0x00 }, 5548e27874SAdam Thomson { DA732X_REG_MICBIAS1 , 0x00 }, 5648e27874SAdam Thomson { DA732X_REG_MICDET , 0x00 }, 5748e27874SAdam Thomson { DA732X_REG_MIC1_PRE , 0x01 }, 5848e27874SAdam Thomson { DA732X_REG_MIC1 , 0x40 }, 5948e27874SAdam Thomson { DA732X_REG_MIC2_PRE , 0x01 }, 6048e27874SAdam Thomson { DA732X_REG_MIC2 , 0x40 }, 6148e27874SAdam Thomson { DA732X_REG_AUX1L , 0x75 }, 6248e27874SAdam Thomson { DA732X_REG_AUX1R , 0x75 }, 6348e27874SAdam Thomson { DA732X_REG_MIC3_PRE , 0x01 }, 6448e27874SAdam Thomson { DA732X_REG_MIC3 , 0x40 }, 6548e27874SAdam Thomson { DA732X_REG_INP_PINBIAS , 0x00 }, 6648e27874SAdam Thomson { DA732X_REG_INP_ZC_EN , 0x00 }, 6748e27874SAdam Thomson { DA732X_REG_INP_MUX , 0x50 }, 6848e27874SAdam Thomson { DA732X_REG_HP_DET , 0x00 }, 6948e27874SAdam Thomson { DA732X_REG_HPL_DAC_OFFSET , 0x00 }, 7048e27874SAdam Thomson { DA732X_REG_HPL_DAC_OFF_CNTL , 0x00 }, 7148e27874SAdam Thomson { DA732X_REG_HPL_OUT_OFFSET , 0x00 }, 7248e27874SAdam Thomson { DA732X_REG_HPL , 0x40 }, 7348e27874SAdam Thomson { DA732X_REG_HPL_VOL , 0x0F }, 7448e27874SAdam Thomson { DA732X_REG_HPR_DAC_OFFSET , 0x00 }, 7548e27874SAdam Thomson { DA732X_REG_HPR_DAC_OFF_CNTL , 0x00 }, 7648e27874SAdam Thomson { DA732X_REG_HPR_OUT_OFFSET , 0x00 }, 7748e27874SAdam Thomson { DA732X_REG_HPR , 0x40 }, 7848e27874SAdam Thomson { DA732X_REG_HPR_VOL , 0x0F }, 7948e27874SAdam Thomson { DA732X_REG_LIN2 , 0x4F }, 8048e27874SAdam Thomson { DA732X_REG_LIN3 , 0x4F }, 8148e27874SAdam Thomson { DA732X_REG_LIN4 , 0x4F }, 8248e27874SAdam Thomson { DA732X_REG_OUT_ZC_EN , 0x00 }, 8348e27874SAdam Thomson { DA732X_REG_HP_LIN1_GNDSEL , 0x00 }, 8448e27874SAdam Thomson { DA732X_REG_CP_HP1 , 0x0C }, 8548e27874SAdam Thomson { DA732X_REG_CP_HP2 , 0x03 }, 8648e27874SAdam Thomson { DA732X_REG_CP_CTRL1 , 0x00 }, 8748e27874SAdam Thomson { DA732X_REG_CP_CTRL2 , 0x99 }, 8848e27874SAdam Thomson { DA732X_REG_CP_CTRL3 , 0x25 }, 8948e27874SAdam Thomson { DA732X_REG_CP_LEVEL_MASK , 0x3F }, 9048e27874SAdam Thomson { DA732X_REG_CP_DET , 0x00 }, 9148e27874SAdam Thomson { DA732X_REG_CP_STATUS , 0x00 }, 9248e27874SAdam Thomson { DA732X_REG_CP_THRESH1 , 0x00 }, 9348e27874SAdam Thomson { DA732X_REG_CP_THRESH2 , 0x00 }, 9448e27874SAdam Thomson { DA732X_REG_CP_THRESH3 , 0x00 }, 9548e27874SAdam Thomson { DA732X_REG_CP_THRESH4 , 0x00 }, 9648e27874SAdam Thomson { DA732X_REG_CP_THRESH5 , 0x00 }, 9748e27874SAdam Thomson { DA732X_REG_CP_THRESH6 , 0x00 }, 9848e27874SAdam Thomson { DA732X_REG_CP_THRESH7 , 0x00 }, 9948e27874SAdam Thomson { DA732X_REG_CP_THRESH8 , 0x00 }, 10048e27874SAdam Thomson { DA732X_REG_PLL_DIV_LO , 0x00 }, 10148e27874SAdam Thomson { DA732X_REG_PLL_DIV_MID , 0x00 }, 10248e27874SAdam Thomson { DA732X_REG_PLL_DIV_HI , 0x00 }, 10348e27874SAdam Thomson { DA732X_REG_PLL_CTRL , 0x02 }, 10448e27874SAdam Thomson { DA732X_REG_CLK_CTRL , 0xaa }, 10548e27874SAdam Thomson { DA732X_REG_CLK_DSP , 0x07 }, 10648e27874SAdam Thomson { DA732X_REG_CLK_EN1 , 0x00 }, 10748e27874SAdam Thomson { DA732X_REG_CLK_EN2 , 0x00 }, 10848e27874SAdam Thomson { DA732X_REG_CLK_EN3 , 0x00 }, 10948e27874SAdam Thomson { DA732X_REG_CLK_EN4 , 0x00 }, 11048e27874SAdam Thomson { DA732X_REG_CLK_EN5 , 0x00 }, 11148e27874SAdam Thomson { DA732X_REG_AIF_MCLK , 0x00 }, 11248e27874SAdam Thomson { DA732X_REG_AIFA1 , 0x02 }, 11348e27874SAdam Thomson { DA732X_REG_AIFA2 , 0x00 }, 11448e27874SAdam Thomson { DA732X_REG_AIFA3 , 0x08 }, 11548e27874SAdam Thomson { DA732X_REG_AIFB1 , 0x02 }, 11648e27874SAdam Thomson { DA732X_REG_AIFB2 , 0x00 }, 11748e27874SAdam Thomson { DA732X_REG_AIFB3 , 0x08 }, 11848e27874SAdam Thomson { DA732X_REG_PC_CTRL , 0xC0 }, 11948e27874SAdam Thomson { DA732X_REG_DATA_ROUTE , 0x00 }, 12048e27874SAdam Thomson { DA732X_REG_DSP_CTRL , 0x00 }, 12148e27874SAdam Thomson { DA732X_REG_CIF_CTRL2 , 0x00 }, 12248e27874SAdam Thomson { DA732X_REG_HANDSHAKE , 0x00 }, 12348e27874SAdam Thomson { DA732X_REG_SPARE1_OUT , 0x00 }, 12448e27874SAdam Thomson { DA732X_REG_SPARE2_OUT , 0x00 }, 12548e27874SAdam Thomson { DA732X_REG_SPARE1_IN , 0x00 }, 12648e27874SAdam Thomson { DA732X_REG_ADC1_PD , 0x00 }, 12748e27874SAdam Thomson { DA732X_REG_ADC1_HPF , 0x00 }, 12848e27874SAdam Thomson { DA732X_REG_ADC1_SEL , 0x00 }, 12948e27874SAdam Thomson { DA732X_REG_ADC1_EQ12 , 0x00 }, 13048e27874SAdam Thomson { DA732X_REG_ADC1_EQ34 , 0x00 }, 13148e27874SAdam Thomson { DA732X_REG_ADC1_EQ5 , 0x00 }, 13248e27874SAdam Thomson { DA732X_REG_ADC2_PD , 0x00 }, 13348e27874SAdam Thomson { DA732X_REG_ADC2_HPF , 0x00 }, 13448e27874SAdam Thomson { DA732X_REG_ADC2_SEL , 0x00 }, 13548e27874SAdam Thomson { DA732X_REG_ADC2_EQ12 , 0x00 }, 13648e27874SAdam Thomson { DA732X_REG_ADC2_EQ34 , 0x00 }, 13748e27874SAdam Thomson { DA732X_REG_ADC2_EQ5 , 0x00 }, 13848e27874SAdam Thomson { DA732X_REG_DAC1_HPF , 0x00 }, 13948e27874SAdam Thomson { DA732X_REG_DAC1_L_VOL , 0x00 }, 14048e27874SAdam Thomson { DA732X_REG_DAC1_R_VOL , 0x00 }, 14148e27874SAdam Thomson { DA732X_REG_DAC1_SEL , 0x00 }, 14248e27874SAdam Thomson { DA732X_REG_DAC1_SOFTMUTE , 0x00 }, 14348e27874SAdam Thomson { DA732X_REG_DAC1_EQ12 , 0x00 }, 14448e27874SAdam Thomson { DA732X_REG_DAC1_EQ34 , 0x00 }, 14548e27874SAdam Thomson { DA732X_REG_DAC1_EQ5 , 0x00 }, 14648e27874SAdam Thomson { DA732X_REG_DAC2_HPF , 0x00 }, 14748e27874SAdam Thomson { DA732X_REG_DAC2_L_VOL , 0x00 }, 14848e27874SAdam Thomson { DA732X_REG_DAC2_R_VOL , 0x00 }, 14948e27874SAdam Thomson { DA732X_REG_DAC2_SEL , 0x00 }, 15048e27874SAdam Thomson { DA732X_REG_DAC2_SOFTMUTE , 0x00 }, 15148e27874SAdam Thomson { DA732X_REG_DAC2_EQ12 , 0x00 }, 15248e27874SAdam Thomson { DA732X_REG_DAC2_EQ34 , 0x00 }, 15348e27874SAdam Thomson { DA732X_REG_DAC2_EQ5 , 0x00 }, 15448e27874SAdam Thomson { DA732X_REG_DAC3_HPF , 0x00 }, 15548e27874SAdam Thomson { DA732X_REG_DAC3_VOL , 0x00 }, 15648e27874SAdam Thomson { DA732X_REG_DAC3_SEL , 0x00 }, 15748e27874SAdam Thomson { DA732X_REG_DAC3_SOFTMUTE , 0x00 }, 15848e27874SAdam Thomson { DA732X_REG_DAC3_EQ12 , 0x00 }, 15948e27874SAdam Thomson { DA732X_REG_DAC3_EQ34 , 0x00 }, 16048e27874SAdam Thomson { DA732X_REG_DAC3_EQ5 , 0x00 }, 16148e27874SAdam Thomson { DA732X_REG_BIQ_BYP , 0x00 }, 16248e27874SAdam Thomson { DA732X_REG_DMA_CMD , 0x00 }, 16348e27874SAdam Thomson { DA732X_REG_DMA_ADDR0 , 0x00 }, 16448e27874SAdam Thomson { DA732X_REG_DMA_ADDR1 , 0x00 }, 16548e27874SAdam Thomson { DA732X_REG_DMA_DATA0 , 0x00 }, 16648e27874SAdam Thomson { DA732X_REG_DMA_DATA1 , 0x00 }, 16748e27874SAdam Thomson { DA732X_REG_DMA_DATA2 , 0x00 }, 16848e27874SAdam Thomson { DA732X_REG_DMA_DATA3 , 0x00 }, 16948e27874SAdam Thomson { DA732X_REG_UNLOCK , 0x00 }, 17048e27874SAdam Thomson }; 17148e27874SAdam Thomson 17248e27874SAdam Thomson static inline int da732x_get_input_div(struct snd_soc_codec *codec, int sysclk) 17348e27874SAdam Thomson { 17448e27874SAdam Thomson int val; 17548e27874SAdam Thomson int ret; 17648e27874SAdam Thomson 17748e27874SAdam Thomson if (sysclk < DA732X_MCLK_10MHZ) { 17848e27874SAdam Thomson val = DA732X_MCLK_RET_0_10MHZ; 17948e27874SAdam Thomson ret = DA732X_MCLK_VAL_0_10MHZ; 18048e27874SAdam Thomson } else if ((sysclk >= DA732X_MCLK_10MHZ) && 18148e27874SAdam Thomson (sysclk < DA732X_MCLK_20MHZ)) { 18248e27874SAdam Thomson val = DA732X_MCLK_RET_10_20MHZ; 18348e27874SAdam Thomson ret = DA732X_MCLK_VAL_10_20MHZ; 18448e27874SAdam Thomson } else if ((sysclk >= DA732X_MCLK_20MHZ) && 18548e27874SAdam Thomson (sysclk < DA732X_MCLK_40MHZ)) { 18648e27874SAdam Thomson val = DA732X_MCLK_RET_20_40MHZ; 18748e27874SAdam Thomson ret = DA732X_MCLK_VAL_20_40MHZ; 18848e27874SAdam Thomson } else if ((sysclk >= DA732X_MCLK_40MHZ) && 18948e27874SAdam Thomson (sysclk <= DA732X_MCLK_54MHZ)) { 19048e27874SAdam Thomson val = DA732X_MCLK_RET_40_54MHZ; 19148e27874SAdam Thomson ret = DA732X_MCLK_VAL_40_54MHZ; 19248e27874SAdam Thomson } else { 19348e27874SAdam Thomson return -EINVAL; 19448e27874SAdam Thomson } 19548e27874SAdam Thomson 19648e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_PLL_CTRL, val); 19748e27874SAdam Thomson 19848e27874SAdam Thomson return ret; 19948e27874SAdam Thomson } 20048e27874SAdam Thomson 20148e27874SAdam Thomson static void da732x_set_charge_pump(struct snd_soc_codec *codec, int state) 20248e27874SAdam Thomson { 20348e27874SAdam Thomson switch (state) { 20448e27874SAdam Thomson case DA732X_ENABLE_CP: 20548e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_CLK_EN2, DA732X_CP_CLK_EN); 20648e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_CP_HP2, DA732X_HP_CP_EN | 20748e27874SAdam Thomson DA732X_HP_CP_REG | DA732X_HP_CP_PULSESKIP); 20848e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA732X_CP_EN | 20948e27874SAdam Thomson DA732X_CP_CTRL_CPVDD1); 21048e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_CP_CTRL2, 21148e27874SAdam Thomson DA732X_CP_MANAGE_MAGNITUDE | DA732X_CP_BOOST); 21248e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_CP_CTRL3, DA732X_CP_1MHZ); 21348e27874SAdam Thomson break; 21448e27874SAdam Thomson case DA732X_DISABLE_CP: 21548e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_CLK_EN2, DA732X_CP_CLK_DIS); 21648e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_CP_HP2, DA732X_HP_CP_DIS); 21748e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA723X_CP_DIS); 21848e27874SAdam Thomson break; 21948e27874SAdam Thomson default: 22048e27874SAdam Thomson pr_err(KERN_ERR "Wrong charge pump state\n"); 22148e27874SAdam Thomson break; 22248e27874SAdam Thomson } 22348e27874SAdam Thomson } 22448e27874SAdam Thomson 22548e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(mic_boost_tlv, DA732X_MIC_PRE_VOL_DB_MIN, 22648e27874SAdam Thomson DA732X_MIC_PRE_VOL_DB_INC, 0); 22748e27874SAdam Thomson 22848e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(mic_pga_tlv, DA732X_MIC_VOL_DB_MIN, 22948e27874SAdam Thomson DA732X_MIC_VOL_DB_INC, 0); 23048e27874SAdam Thomson 23148e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(aux_pga_tlv, DA732X_AUX_VOL_DB_MIN, 23248e27874SAdam Thomson DA732X_AUX_VOL_DB_INC, 0); 23348e27874SAdam Thomson 23448e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(hp_pga_tlv, DA732X_HP_VOL_DB_MIN, 23548e27874SAdam Thomson DA732X_AUX_VOL_DB_INC, 0); 23648e27874SAdam Thomson 23748e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(lin2_pga_tlv, DA732X_LIN2_VOL_DB_MIN, 23848e27874SAdam Thomson DA732X_LIN2_VOL_DB_INC, 0); 23948e27874SAdam Thomson 24048e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(lin3_pga_tlv, DA732X_LIN3_VOL_DB_MIN, 24148e27874SAdam Thomson DA732X_LIN3_VOL_DB_INC, 0); 24248e27874SAdam Thomson 24348e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(lin4_pga_tlv, DA732X_LIN4_VOL_DB_MIN, 24448e27874SAdam Thomson DA732X_LIN4_VOL_DB_INC, 0); 24548e27874SAdam Thomson 24648e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(adc_pga_tlv, DA732X_ADC_VOL_DB_MIN, 24748e27874SAdam Thomson DA732X_ADC_VOL_DB_INC, 0); 24848e27874SAdam Thomson 24948e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(dac_pga_tlv, DA732X_DAC_VOL_DB_MIN, 25048e27874SAdam Thomson DA732X_DAC_VOL_DB_INC, 0); 25148e27874SAdam Thomson 25248e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(eq_band_pga_tlv, DA732X_EQ_BAND_VOL_DB_MIN, 25348e27874SAdam Thomson DA732X_EQ_BAND_VOL_DB_INC, 0); 25448e27874SAdam Thomson 25548e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(eq_overall_tlv, DA732X_EQ_OVERALL_VOL_DB_MIN, 25648e27874SAdam Thomson DA732X_EQ_OVERALL_VOL_DB_INC, 0); 25748e27874SAdam Thomson 25848e27874SAdam Thomson /* High Pass Filter */ 25948e27874SAdam Thomson static const char *da732x_hpf_mode[] = { 26048e27874SAdam Thomson "Disable", "Music", "Voice", 26148e27874SAdam Thomson }; 26248e27874SAdam Thomson 26348e27874SAdam Thomson static const char *da732x_hpf_music[] = { 26448e27874SAdam Thomson "1.8Hz", "3.75Hz", "7.5Hz", "15Hz", 26548e27874SAdam Thomson }; 26648e27874SAdam Thomson 26748e27874SAdam Thomson static const char *da732x_hpf_voice[] = { 26848e27874SAdam Thomson "2.5Hz", "25Hz", "50Hz", "100Hz", 26948e27874SAdam Thomson "150Hz", "200Hz", "300Hz", "400Hz" 27048e27874SAdam Thomson }; 27148e27874SAdam Thomson 27248e27874SAdam Thomson static const struct soc_enum da732x_dac1_hpf_mode_enum[] = { 27348e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MODE_SHIFT, 27448e27874SAdam Thomson DA732X_HPF_MODE_MAX, da732x_hpf_mode) 27548e27874SAdam Thomson }; 27648e27874SAdam Thomson 27748e27874SAdam Thomson static const struct soc_enum da732x_dac2_hpf_mode_enum[] = { 27848e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MODE_SHIFT, 27948e27874SAdam Thomson DA732X_HPF_MODE_MAX, da732x_hpf_mode) 28048e27874SAdam Thomson }; 28148e27874SAdam Thomson 28248e27874SAdam Thomson static const struct soc_enum da732x_dac3_hpf_mode_enum[] = { 28348e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MODE_SHIFT, 28448e27874SAdam Thomson DA732X_HPF_MODE_MAX, da732x_hpf_mode) 28548e27874SAdam Thomson }; 28648e27874SAdam Thomson 28748e27874SAdam Thomson static const struct soc_enum da732x_adc1_hpf_mode_enum[] = { 28848e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MODE_SHIFT, 28948e27874SAdam Thomson DA732X_HPF_MODE_MAX, da732x_hpf_mode) 29048e27874SAdam Thomson }; 29148e27874SAdam Thomson 29248e27874SAdam Thomson static const struct soc_enum da732x_adc2_hpf_mode_enum[] = { 29348e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MODE_SHIFT, 29448e27874SAdam Thomson DA732X_HPF_MODE_MAX, da732x_hpf_mode) 29548e27874SAdam Thomson }; 29648e27874SAdam Thomson 29748e27874SAdam Thomson static const struct soc_enum da732x_dac1_hp_filter_enum[] = { 29848e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MUSIC_SHIFT, 29948e27874SAdam Thomson DA732X_HPF_MUSIC_MAX, da732x_hpf_music) 30048e27874SAdam Thomson }; 30148e27874SAdam Thomson 30248e27874SAdam Thomson static const struct soc_enum da732x_dac2_hp_filter_enum[] = { 30348e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MUSIC_SHIFT, 30448e27874SAdam Thomson DA732X_HPF_MUSIC_MAX, da732x_hpf_music) 30548e27874SAdam Thomson }; 30648e27874SAdam Thomson 30748e27874SAdam Thomson static const struct soc_enum da732x_dac3_hp_filter_enum[] = { 30848e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MUSIC_SHIFT, 30948e27874SAdam Thomson DA732X_HPF_MUSIC_MAX, da732x_hpf_music) 31048e27874SAdam Thomson }; 31148e27874SAdam Thomson 31248e27874SAdam Thomson static const struct soc_enum da732x_adc1_hp_filter_enum[] = { 31348e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MUSIC_SHIFT, 31448e27874SAdam Thomson DA732X_HPF_MUSIC_MAX, da732x_hpf_music) 31548e27874SAdam Thomson }; 31648e27874SAdam Thomson 31748e27874SAdam Thomson static const struct soc_enum da732x_adc2_hp_filter_enum[] = { 31848e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MUSIC_SHIFT, 31948e27874SAdam Thomson DA732X_HPF_MUSIC_MAX, da732x_hpf_music) 32048e27874SAdam Thomson }; 32148e27874SAdam Thomson 32248e27874SAdam Thomson static const struct soc_enum da732x_dac1_voice_filter_enum[] = { 32348e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_VOICE_SHIFT, 32448e27874SAdam Thomson DA732X_HPF_VOICE_MAX, da732x_hpf_voice) 32548e27874SAdam Thomson }; 32648e27874SAdam Thomson 32748e27874SAdam Thomson static const struct soc_enum da732x_dac2_voice_filter_enum[] = { 32848e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_VOICE_SHIFT, 32948e27874SAdam Thomson DA732X_HPF_VOICE_MAX, da732x_hpf_voice) 33048e27874SAdam Thomson }; 33148e27874SAdam Thomson 33248e27874SAdam Thomson static const struct soc_enum da732x_dac3_voice_filter_enum[] = { 33348e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_VOICE_SHIFT, 33448e27874SAdam Thomson DA732X_HPF_VOICE_MAX, da732x_hpf_voice) 33548e27874SAdam Thomson }; 33648e27874SAdam Thomson 33748e27874SAdam Thomson static const struct soc_enum da732x_adc1_voice_filter_enum[] = { 33848e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_VOICE_SHIFT, 33948e27874SAdam Thomson DA732X_HPF_VOICE_MAX, da732x_hpf_voice) 34048e27874SAdam Thomson }; 34148e27874SAdam Thomson 34248e27874SAdam Thomson static const struct soc_enum da732x_adc2_voice_filter_enum[] = { 34348e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_VOICE_SHIFT, 34448e27874SAdam Thomson DA732X_HPF_VOICE_MAX, da732x_hpf_voice) 34548e27874SAdam Thomson }; 34648e27874SAdam Thomson 34748e27874SAdam Thomson 34848e27874SAdam Thomson static int da732x_hpf_set(struct snd_kcontrol *kcontrol, 34948e27874SAdam Thomson struct snd_ctl_elem_value *ucontrol) 35048e27874SAdam Thomson { 35148e27874SAdam Thomson struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 35248e27874SAdam Thomson struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value; 35348e27874SAdam Thomson unsigned int reg = enum_ctrl->reg; 35448e27874SAdam Thomson unsigned int sel = ucontrol->value.integer.value[0]; 35548e27874SAdam Thomson unsigned int bits; 35648e27874SAdam Thomson 35748e27874SAdam Thomson switch (sel) { 35848e27874SAdam Thomson case DA732X_HPF_DISABLED: 35948e27874SAdam Thomson bits = DA732X_HPF_DIS; 36048e27874SAdam Thomson break; 36148e27874SAdam Thomson case DA732X_HPF_VOICE: 36248e27874SAdam Thomson bits = DA732X_HPF_VOICE_EN; 36348e27874SAdam Thomson break; 36448e27874SAdam Thomson case DA732X_HPF_MUSIC: 36548e27874SAdam Thomson bits = DA732X_HPF_MUSIC_EN; 36648e27874SAdam Thomson break; 36748e27874SAdam Thomson default: 36848e27874SAdam Thomson return -EINVAL; 36948e27874SAdam Thomson } 37048e27874SAdam Thomson 37148e27874SAdam Thomson snd_soc_update_bits(codec, reg, DA732X_HPF_MASK, bits); 37248e27874SAdam Thomson 37348e27874SAdam Thomson return 0; 37448e27874SAdam Thomson } 37548e27874SAdam Thomson 37648e27874SAdam Thomson static int da732x_hpf_get(struct snd_kcontrol *kcontrol, 37748e27874SAdam Thomson struct snd_ctl_elem_value *ucontrol) 37848e27874SAdam Thomson { 37948e27874SAdam Thomson struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 38048e27874SAdam Thomson struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value; 38148e27874SAdam Thomson unsigned int reg = enum_ctrl->reg; 38248e27874SAdam Thomson int val; 38348e27874SAdam Thomson 38448e27874SAdam Thomson val = snd_soc_read(codec, reg) & DA732X_HPF_MASK; 38548e27874SAdam Thomson 38648e27874SAdam Thomson switch (val) { 38748e27874SAdam Thomson case DA732X_HPF_VOICE_EN: 38848e27874SAdam Thomson ucontrol->value.integer.value[0] = DA732X_HPF_VOICE; 38948e27874SAdam Thomson break; 39048e27874SAdam Thomson case DA732X_HPF_MUSIC_EN: 39148e27874SAdam Thomson ucontrol->value.integer.value[0] = DA732X_HPF_MUSIC; 39248e27874SAdam Thomson break; 39348e27874SAdam Thomson default: 39448e27874SAdam Thomson ucontrol->value.integer.value[0] = DA732X_HPF_DISABLED; 39548e27874SAdam Thomson break; 39648e27874SAdam Thomson } 39748e27874SAdam Thomson 39848e27874SAdam Thomson return 0; 39948e27874SAdam Thomson } 40048e27874SAdam Thomson 40148e27874SAdam Thomson static const struct snd_kcontrol_new da732x_snd_controls[] = { 40248e27874SAdam Thomson /* Input PGAs */ 40348e27874SAdam Thomson SOC_SINGLE_RANGE_TLV("MIC1 Boost Volume", DA732X_REG_MIC1_PRE, 40448e27874SAdam Thomson DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN, 40548e27874SAdam Thomson DA732X_MICBOOST_MAX, 0, mic_boost_tlv), 40648e27874SAdam Thomson SOC_SINGLE_RANGE_TLV("MIC2 Boost Volume", DA732X_REG_MIC2_PRE, 40748e27874SAdam Thomson DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN, 40848e27874SAdam Thomson DA732X_MICBOOST_MAX, 0, mic_boost_tlv), 40948e27874SAdam Thomson SOC_SINGLE_RANGE_TLV("MIC3 Boost Volume", DA732X_REG_MIC3_PRE, 41048e27874SAdam Thomson DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN, 41148e27874SAdam Thomson DA732X_MICBOOST_MAX, 0, mic_boost_tlv), 41248e27874SAdam Thomson 41348e27874SAdam Thomson /* MICs */ 41448e27874SAdam Thomson SOC_SINGLE("MIC1 Switch", DA732X_REG_MIC1, DA732X_MIC_MUTE_SHIFT, 41548e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 41648e27874SAdam Thomson SOC_SINGLE_RANGE_TLV("MIC1 Volume", DA732X_REG_MIC1, 41748e27874SAdam Thomson DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN, 41848e27874SAdam Thomson DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv), 41948e27874SAdam Thomson SOC_SINGLE("MIC2 Switch", DA732X_REG_MIC2, DA732X_MIC_MUTE_SHIFT, 42048e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 42148e27874SAdam Thomson SOC_SINGLE_RANGE_TLV("MIC2 Volume", DA732X_REG_MIC2, 42248e27874SAdam Thomson DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN, 42348e27874SAdam Thomson DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv), 42448e27874SAdam Thomson SOC_SINGLE("MIC3 Switch", DA732X_REG_MIC3, DA732X_MIC_MUTE_SHIFT, 42548e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 42648e27874SAdam Thomson SOC_SINGLE_RANGE_TLV("MIC3 Volume", DA732X_REG_MIC3, 42748e27874SAdam Thomson DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN, 42848e27874SAdam Thomson DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv), 42948e27874SAdam Thomson 43048e27874SAdam Thomson /* AUXs */ 43148e27874SAdam Thomson SOC_SINGLE("AUX1L Switch", DA732X_REG_AUX1L, DA732X_AUX_MUTE_SHIFT, 43248e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 43348e27874SAdam Thomson SOC_SINGLE_TLV("AUX1L Volume", DA732X_REG_AUX1L, 43448e27874SAdam Thomson DA732X_AUX_VOL_SHIFT, DA732X_AUX_VOL_VAL_MAX, 43548e27874SAdam Thomson DA732X_NO_INVERT, aux_pga_tlv), 43648e27874SAdam Thomson SOC_SINGLE("AUX1R Switch", DA732X_REG_AUX1R, DA732X_AUX_MUTE_SHIFT, 43748e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 43848e27874SAdam Thomson SOC_SINGLE_TLV("AUX1R Volume", DA732X_REG_AUX1R, 43948e27874SAdam Thomson DA732X_AUX_VOL_SHIFT, DA732X_AUX_VOL_VAL_MAX, 44048e27874SAdam Thomson DA732X_NO_INVERT, aux_pga_tlv), 44148e27874SAdam Thomson 44248e27874SAdam Thomson /* ADCs */ 44348e27874SAdam Thomson SOC_DOUBLE_TLV("ADC1 Volume", DA732X_REG_ADC1_SEL, 44448e27874SAdam Thomson DA732X_ADCL_VOL_SHIFT, DA732X_ADCR_VOL_SHIFT, 44548e27874SAdam Thomson DA732X_ADC_VOL_VAL_MAX, DA732X_INVERT, adc_pga_tlv), 44648e27874SAdam Thomson 44748e27874SAdam Thomson SOC_DOUBLE_TLV("ADC2 Volume", DA732X_REG_ADC2_SEL, 44848e27874SAdam Thomson DA732X_ADCL_VOL_SHIFT, DA732X_ADCR_VOL_SHIFT, 44948e27874SAdam Thomson DA732X_ADC_VOL_VAL_MAX, DA732X_INVERT, adc_pga_tlv), 45048e27874SAdam Thomson 45148e27874SAdam Thomson /* DACs */ 45248e27874SAdam Thomson SOC_DOUBLE("Digital Playback DAC12 Switch", DA732X_REG_DAC1_SEL, 45348e27874SAdam Thomson DA732X_DACL_MUTE_SHIFT, DA732X_DACR_MUTE_SHIFT, 45448e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 45548e27874SAdam Thomson SOC_DOUBLE_R_TLV("Digital Playback DAC12 Volume", DA732X_REG_DAC1_L_VOL, 45648e27874SAdam Thomson DA732X_REG_DAC1_R_VOL, DA732X_DAC_VOL_SHIFT, 45748e27874SAdam Thomson DA732X_DAC_VOL_VAL_MAX, DA732X_INVERT, dac_pga_tlv), 45848e27874SAdam Thomson SOC_SINGLE("Digital Playback DAC3 Switch", DA732X_REG_DAC2_SEL, 45948e27874SAdam Thomson DA732X_DACL_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), 46048e27874SAdam Thomson SOC_SINGLE_TLV("Digital Playback DAC3 Volume", DA732X_REG_DAC2_L_VOL, 46148e27874SAdam Thomson DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX, 46248e27874SAdam Thomson DA732X_INVERT, dac_pga_tlv), 46348e27874SAdam Thomson SOC_SINGLE("Digital Playback DAC4 Switch", DA732X_REG_DAC2_SEL, 46448e27874SAdam Thomson DA732X_DACR_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), 46548e27874SAdam Thomson SOC_SINGLE_TLV("Digital Playback DAC4 Volume", DA732X_REG_DAC2_R_VOL, 46648e27874SAdam Thomson DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX, 46748e27874SAdam Thomson DA732X_INVERT, dac_pga_tlv), 46848e27874SAdam Thomson SOC_SINGLE("Digital Playback DAC5 Switch", DA732X_REG_DAC3_SEL, 46948e27874SAdam Thomson DA732X_DACL_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), 47048e27874SAdam Thomson SOC_SINGLE_TLV("Digital Playback DAC5 Volume", DA732X_REG_DAC3_VOL, 47148e27874SAdam Thomson DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX, 47248e27874SAdam Thomson DA732X_INVERT, dac_pga_tlv), 47348e27874SAdam Thomson 47448e27874SAdam Thomson /* High Pass Filters */ 47548e27874SAdam Thomson SOC_ENUM_EXT("DAC1 High Pass Filter Mode", 47648e27874SAdam Thomson da732x_dac1_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), 47748e27874SAdam Thomson SOC_ENUM("DAC1 High Pass Filter", da732x_dac1_hp_filter_enum), 47848e27874SAdam Thomson SOC_ENUM("DAC1 Voice Filter", da732x_dac1_voice_filter_enum), 47948e27874SAdam Thomson 48048e27874SAdam Thomson SOC_ENUM_EXT("DAC2 High Pass Filter Mode", 48148e27874SAdam Thomson da732x_dac2_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), 48248e27874SAdam Thomson SOC_ENUM("DAC2 High Pass Filter", da732x_dac2_hp_filter_enum), 48348e27874SAdam Thomson SOC_ENUM("DAC2 Voice Filter", da732x_dac2_voice_filter_enum), 48448e27874SAdam Thomson 48548e27874SAdam Thomson SOC_ENUM_EXT("DAC3 High Pass Filter Mode", 48648e27874SAdam Thomson da732x_dac3_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), 48748e27874SAdam Thomson SOC_ENUM("DAC3 High Pass Filter", da732x_dac3_hp_filter_enum), 48848e27874SAdam Thomson SOC_ENUM("DAC3 Filter Mode", da732x_dac3_voice_filter_enum), 48948e27874SAdam Thomson 49048e27874SAdam Thomson SOC_ENUM_EXT("ADC1 High Pass Filter Mode", 49148e27874SAdam Thomson da732x_adc1_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), 49248e27874SAdam Thomson SOC_ENUM("ADC1 High Pass Filter", da732x_adc1_hp_filter_enum), 49348e27874SAdam Thomson SOC_ENUM("ADC1 Voice Filter", da732x_adc1_voice_filter_enum), 49448e27874SAdam Thomson 49548e27874SAdam Thomson SOC_ENUM_EXT("ADC2 High Pass Filter Mode", 49648e27874SAdam Thomson da732x_adc2_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), 49748e27874SAdam Thomson SOC_ENUM("ADC2 High Pass Filter", da732x_adc2_hp_filter_enum), 49848e27874SAdam Thomson SOC_ENUM("ADC2 Voice Filter", da732x_adc2_voice_filter_enum), 49948e27874SAdam Thomson 50048e27874SAdam Thomson /* Equalizers */ 50148e27874SAdam Thomson SOC_SINGLE("ADC1 EQ Switch", DA732X_REG_ADC1_EQ5, 50248e27874SAdam Thomson DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), 50348e27874SAdam Thomson SOC_SINGLE_TLV("ADC1 EQ Band 1 Volume", DA732X_REG_ADC1_EQ12, 50448e27874SAdam Thomson DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, 50548e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 50648e27874SAdam Thomson SOC_SINGLE_TLV("ADC1 EQ Band 2 Volume", DA732X_REG_ADC1_EQ12, 50748e27874SAdam Thomson DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, 50848e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 50948e27874SAdam Thomson SOC_SINGLE_TLV("ADC1 EQ Band 3 Volume", DA732X_REG_ADC1_EQ34, 51048e27874SAdam Thomson DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, 51148e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 51248e27874SAdam Thomson SOC_SINGLE_TLV("ADC1 EQ Band 4 Volume", DA732X_REG_ADC1_EQ34, 51348e27874SAdam Thomson DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, 51448e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 51548e27874SAdam Thomson SOC_SINGLE_TLV("ADC1 EQ Band 5 Volume", DA732X_REG_ADC1_EQ5, 51648e27874SAdam Thomson DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, 51748e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 51848e27874SAdam Thomson SOC_SINGLE_TLV("ADC1 EQ Overall Volume", DA732X_REG_ADC1_EQ5, 51948e27874SAdam Thomson DA732X_EQ_OVERALL_SHIFT, DA732X_EQ_OVERALL_VOL_VAL_MAX, 52048e27874SAdam Thomson DA732X_INVERT, eq_overall_tlv), 52148e27874SAdam Thomson 52248e27874SAdam Thomson SOC_SINGLE("ADC2 EQ Switch", DA732X_REG_ADC2_EQ5, 52348e27874SAdam Thomson DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), 52448e27874SAdam Thomson SOC_SINGLE_TLV("ADC2 EQ Band 1 Volume", DA732X_REG_ADC2_EQ12, 52548e27874SAdam Thomson DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, 52648e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 52748e27874SAdam Thomson SOC_SINGLE_TLV("ADC2 EQ Band 2 Volume", DA732X_REG_ADC2_EQ12, 52848e27874SAdam Thomson DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, 52948e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 53048e27874SAdam Thomson SOC_SINGLE_TLV("ADC2 EQ Band 3 Volume", DA732X_REG_ADC2_EQ34, 53148e27874SAdam Thomson DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, 53248e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 53348e27874SAdam Thomson SOC_SINGLE_TLV("ACD2 EQ Band 4 Volume", DA732X_REG_ADC2_EQ34, 53448e27874SAdam Thomson DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, 53548e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 53648e27874SAdam Thomson SOC_SINGLE_TLV("ACD2 EQ Band 5 Volume", DA732X_REG_ADC2_EQ5, 53748e27874SAdam Thomson DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, 53848e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 53948e27874SAdam Thomson SOC_SINGLE_TLV("ADC2 EQ Overall Volume", DA732X_REG_ADC1_EQ5, 54048e27874SAdam Thomson DA732X_EQ_OVERALL_SHIFT, DA732X_EQ_OVERALL_VOL_VAL_MAX, 54148e27874SAdam Thomson DA732X_INVERT, eq_overall_tlv), 54248e27874SAdam Thomson 54348e27874SAdam Thomson SOC_SINGLE("DAC1 EQ Switch", DA732X_REG_DAC1_EQ5, 54448e27874SAdam Thomson DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), 54548e27874SAdam Thomson SOC_SINGLE_TLV("DAC1 EQ Band 1 Volume", DA732X_REG_DAC1_EQ12, 54648e27874SAdam Thomson DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, 54748e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 54848e27874SAdam Thomson SOC_SINGLE_TLV("DAC1 EQ Band 2 Volume", DA732X_REG_DAC1_EQ12, 54948e27874SAdam Thomson DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, 55048e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 55148e27874SAdam Thomson SOC_SINGLE_TLV("DAC1 EQ Band 3 Volume", DA732X_REG_DAC1_EQ34, 55248e27874SAdam Thomson DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, 55348e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 55448e27874SAdam Thomson SOC_SINGLE_TLV("DAC1 EQ Band 4 Volume", DA732X_REG_DAC1_EQ34, 55548e27874SAdam Thomson DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, 55648e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 55748e27874SAdam Thomson SOC_SINGLE_TLV("DAC1 EQ Band 5 Volume", DA732X_REG_DAC1_EQ5, 55848e27874SAdam Thomson DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, 55948e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 56048e27874SAdam Thomson 56148e27874SAdam Thomson SOC_SINGLE("DAC2 EQ Switch", DA732X_REG_DAC2_EQ5, 56248e27874SAdam Thomson DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), 56348e27874SAdam Thomson SOC_SINGLE_TLV("DAC2 EQ Band 1 Volume", DA732X_REG_DAC2_EQ12, 56448e27874SAdam Thomson DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, 56548e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 56648e27874SAdam Thomson SOC_SINGLE_TLV("DAC2 EQ Band 2 Volume", DA732X_REG_DAC2_EQ12, 56748e27874SAdam Thomson DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, 56848e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 56948e27874SAdam Thomson SOC_SINGLE_TLV("DAC2 EQ Band 3 Volume", DA732X_REG_DAC2_EQ34, 57048e27874SAdam Thomson DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, 57148e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 57248e27874SAdam Thomson SOC_SINGLE_TLV("DAC2 EQ Band 4 Volume", DA732X_REG_DAC2_EQ34, 57348e27874SAdam Thomson DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, 57448e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 57548e27874SAdam Thomson SOC_SINGLE_TLV("DAC2 EQ Band 5 Volume", DA732X_REG_DAC2_EQ5, 57648e27874SAdam Thomson DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, 57748e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 57848e27874SAdam Thomson 57948e27874SAdam Thomson SOC_SINGLE("DAC3 EQ Switch", DA732X_REG_DAC3_EQ5, 58048e27874SAdam Thomson DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), 58148e27874SAdam Thomson SOC_SINGLE_TLV("DAC3 EQ Band 1 Volume", DA732X_REG_DAC3_EQ12, 58248e27874SAdam Thomson DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, 58348e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 58448e27874SAdam Thomson SOC_SINGLE_TLV("DAC3 EQ Band 2 Volume", DA732X_REG_DAC3_EQ12, 58548e27874SAdam Thomson DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, 58648e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 58748e27874SAdam Thomson SOC_SINGLE_TLV("DAC3 EQ Band 3 Volume", DA732X_REG_DAC3_EQ34, 58848e27874SAdam Thomson DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, 58948e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 59048e27874SAdam Thomson SOC_SINGLE_TLV("DAC3 EQ Band 4 Volume", DA732X_REG_DAC3_EQ34, 59148e27874SAdam Thomson DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, 59248e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 59348e27874SAdam Thomson SOC_SINGLE_TLV("DAC3 EQ Band 5 Volume", DA732X_REG_DAC3_EQ5, 59448e27874SAdam Thomson DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, 59548e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 59648e27874SAdam Thomson 59748e27874SAdam Thomson /* Lineout 2 Reciever*/ 59848e27874SAdam Thomson SOC_SINGLE("Lineout 2 Switch", DA732X_REG_LIN2, DA732X_LOUT_MUTE_SHIFT, 59948e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 60048e27874SAdam Thomson SOC_SINGLE_TLV("Lineout 2 Volume", DA732X_REG_LIN2, 60148e27874SAdam Thomson DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX, 60248e27874SAdam Thomson DA732X_NO_INVERT, lin2_pga_tlv), 60348e27874SAdam Thomson 60448e27874SAdam Thomson /* Lineout 3 SPEAKER*/ 60548e27874SAdam Thomson SOC_SINGLE("Lineout 3 Switch", DA732X_REG_LIN3, DA732X_LOUT_MUTE_SHIFT, 60648e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 60748e27874SAdam Thomson SOC_SINGLE_TLV("Lineout 3 Volume", DA732X_REG_LIN3, 60848e27874SAdam Thomson DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX, 60948e27874SAdam Thomson DA732X_NO_INVERT, lin3_pga_tlv), 61048e27874SAdam Thomson 61148e27874SAdam Thomson /* Lineout 4 */ 61248e27874SAdam Thomson SOC_SINGLE("Lineout 4 Switch", DA732X_REG_LIN4, DA732X_LOUT_MUTE_SHIFT, 61348e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 61448e27874SAdam Thomson SOC_SINGLE_TLV("Lineout 4 Volume", DA732X_REG_LIN4, 61548e27874SAdam Thomson DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX, 61648e27874SAdam Thomson DA732X_NO_INVERT, lin4_pga_tlv), 61748e27874SAdam Thomson 61848e27874SAdam Thomson /* Headphones */ 61948e27874SAdam Thomson SOC_DOUBLE_R("Headphone Switch", DA732X_REG_HPR, DA732X_REG_HPL, 62048e27874SAdam Thomson DA732X_HP_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), 62148e27874SAdam Thomson SOC_DOUBLE_R_TLV("Headphone Volume", DA732X_REG_HPL_VOL, 62248e27874SAdam Thomson DA732X_REG_HPR_VOL, DA732X_HP_VOL_SHIFT, 62348e27874SAdam Thomson DA732X_HP_VOL_VAL_MAX, DA732X_NO_INVERT, hp_pga_tlv), 62448e27874SAdam Thomson }; 62548e27874SAdam Thomson 62648e27874SAdam Thomson static int da732x_adc_event(struct snd_soc_dapm_widget *w, 62748e27874SAdam Thomson struct snd_kcontrol *kcontrol, int event) 62848e27874SAdam Thomson { 62948e27874SAdam Thomson struct snd_soc_codec *codec = w->codec; 63048e27874SAdam Thomson 63148e27874SAdam Thomson switch (event) { 63248e27874SAdam Thomson case SND_SOC_DAPM_POST_PMU: 63348e27874SAdam Thomson switch (w->reg) { 63448e27874SAdam Thomson case DA732X_REG_ADC1_PD: 63548e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, 63648e27874SAdam Thomson DA732X_ADCA_BB_CLK_EN, 63748e27874SAdam Thomson DA732X_ADCA_BB_CLK_EN); 63848e27874SAdam Thomson break; 63948e27874SAdam Thomson case DA732X_REG_ADC2_PD: 64048e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, 64148e27874SAdam Thomson DA732X_ADCC_BB_CLK_EN, 64248e27874SAdam Thomson DA732X_ADCC_BB_CLK_EN); 64348e27874SAdam Thomson break; 64448e27874SAdam Thomson default: 64548e27874SAdam Thomson return -EINVAL; 64648e27874SAdam Thomson } 64748e27874SAdam Thomson 64848e27874SAdam Thomson snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK, 64948e27874SAdam Thomson DA732X_ADC_SET_ACT); 65048e27874SAdam Thomson snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK, 65148e27874SAdam Thomson DA732X_ADC_ON); 65248e27874SAdam Thomson break; 65348e27874SAdam Thomson case SND_SOC_DAPM_POST_PMD: 65448e27874SAdam Thomson snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK, 65548e27874SAdam Thomson DA732X_ADC_OFF); 65648e27874SAdam Thomson snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK, 65748e27874SAdam Thomson DA732X_ADC_SET_RST); 65848e27874SAdam Thomson 65948e27874SAdam Thomson switch (w->reg) { 66048e27874SAdam Thomson case DA732X_REG_ADC1_PD: 66148e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, 66248e27874SAdam Thomson DA732X_ADCA_BB_CLK_EN, 0); 66348e27874SAdam Thomson break; 66448e27874SAdam Thomson case DA732X_REG_ADC2_PD: 66548e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, 66648e27874SAdam Thomson DA732X_ADCC_BB_CLK_EN, 0); 66748e27874SAdam Thomson break; 66848e27874SAdam Thomson default: 66948e27874SAdam Thomson return -EINVAL; 67048e27874SAdam Thomson } 67148e27874SAdam Thomson 67248e27874SAdam Thomson break; 67348e27874SAdam Thomson default: 67448e27874SAdam Thomson return -EINVAL; 67548e27874SAdam Thomson } 67648e27874SAdam Thomson 67748e27874SAdam Thomson return 0; 67848e27874SAdam Thomson } 67948e27874SAdam Thomson 68048e27874SAdam Thomson static int da732x_out_pga_event(struct snd_soc_dapm_widget *w, 68148e27874SAdam Thomson struct snd_kcontrol *kcontrol, int event) 68248e27874SAdam Thomson { 68348e27874SAdam Thomson struct snd_soc_codec *codec = w->codec; 68448e27874SAdam Thomson 68548e27874SAdam Thomson switch (event) { 68648e27874SAdam Thomson case SND_SOC_DAPM_POST_PMU: 68748e27874SAdam Thomson snd_soc_update_bits(codec, w->reg, 68848e27874SAdam Thomson (1 << w->shift) | DA732X_OUT_HIZ_EN, 68948e27874SAdam Thomson (1 << w->shift) | DA732X_OUT_HIZ_EN); 69048e27874SAdam Thomson break; 69148e27874SAdam Thomson case SND_SOC_DAPM_POST_PMD: 69248e27874SAdam Thomson snd_soc_update_bits(codec, w->reg, 69348e27874SAdam Thomson (1 << w->shift) | DA732X_OUT_HIZ_EN, 69448e27874SAdam Thomson (1 << w->shift) | DA732X_OUT_HIZ_DIS); 69548e27874SAdam Thomson break; 69648e27874SAdam Thomson default: 69748e27874SAdam Thomson return -EINVAL; 69848e27874SAdam Thomson } 69948e27874SAdam Thomson 70048e27874SAdam Thomson return 0; 70148e27874SAdam Thomson } 70248e27874SAdam Thomson 70348e27874SAdam Thomson static const char *adcl_text[] = { 70448e27874SAdam Thomson "AUX1L", "MIC1" 70548e27874SAdam Thomson }; 70648e27874SAdam Thomson 70748e27874SAdam Thomson static const char *adcr_text[] = { 70848e27874SAdam Thomson "AUX1R", "MIC2", "MIC3" 70948e27874SAdam Thomson }; 71048e27874SAdam Thomson 71148e27874SAdam Thomson static const char *enable_text[] = { 71248e27874SAdam Thomson "Disabled", 71348e27874SAdam Thomson "Enabled" 71448e27874SAdam Thomson }; 71548e27874SAdam Thomson 71648e27874SAdam Thomson /* ADC1LMUX */ 71748e27874SAdam Thomson static const struct soc_enum adc1l_enum = 71848e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1L_MUX_SEL_SHIFT, 71948e27874SAdam Thomson DA732X_ADCL_MUX_MAX, adcl_text); 72048e27874SAdam Thomson static const struct snd_kcontrol_new adc1l_mux = 72148e27874SAdam Thomson SOC_DAPM_ENUM("ADC Route", adc1l_enum); 72248e27874SAdam Thomson 72348e27874SAdam Thomson /* ADC1RMUX */ 72448e27874SAdam Thomson static const struct soc_enum adc1r_enum = 72548e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1R_MUX_SEL_SHIFT, 72648e27874SAdam Thomson DA732X_ADCR_MUX_MAX, adcr_text); 72748e27874SAdam Thomson static const struct snd_kcontrol_new adc1r_mux = 72848e27874SAdam Thomson SOC_DAPM_ENUM("ADC Route", adc1r_enum); 72948e27874SAdam Thomson 73048e27874SAdam Thomson /* ADC2LMUX */ 73148e27874SAdam Thomson static const struct soc_enum adc2l_enum = 73248e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2L_MUX_SEL_SHIFT, 73348e27874SAdam Thomson DA732X_ADCL_MUX_MAX, adcl_text); 73448e27874SAdam Thomson static const struct snd_kcontrol_new adc2l_mux = 73548e27874SAdam Thomson SOC_DAPM_ENUM("ADC Route", adc2l_enum); 73648e27874SAdam Thomson 73748e27874SAdam Thomson /* ADC2RMUX */ 73848e27874SAdam Thomson static const struct soc_enum adc2r_enum = 73948e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2R_MUX_SEL_SHIFT, 74048e27874SAdam Thomson DA732X_ADCR_MUX_MAX, adcr_text); 74148e27874SAdam Thomson 74248e27874SAdam Thomson static const struct snd_kcontrol_new adc2r_mux = 74348e27874SAdam Thomson SOC_DAPM_ENUM("ADC Route", adc2r_enum); 74448e27874SAdam Thomson 74548e27874SAdam Thomson static const struct soc_enum da732x_hp_left_output = 74648e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN_SHIFT, 74748e27874SAdam Thomson DA732X_DAC_EN_MAX, enable_text); 74848e27874SAdam Thomson 74948e27874SAdam Thomson static const struct snd_kcontrol_new hpl_mux = 75048e27874SAdam Thomson SOC_DAPM_ENUM("HPL Switch", da732x_hp_left_output); 75148e27874SAdam Thomson 75248e27874SAdam Thomson static const struct soc_enum da732x_hp_right_output = 75348e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_HPR, DA732X_HP_OUT_DAC_EN_SHIFT, 75448e27874SAdam Thomson DA732X_DAC_EN_MAX, enable_text); 75548e27874SAdam Thomson 75648e27874SAdam Thomson static const struct snd_kcontrol_new hpr_mux = 75748e27874SAdam Thomson SOC_DAPM_ENUM("HPR Switch", da732x_hp_right_output); 75848e27874SAdam Thomson 75948e27874SAdam Thomson static const struct soc_enum da732x_speaker_output = 76048e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_LIN3, DA732X_LOUT_DAC_EN_SHIFT, 76148e27874SAdam Thomson DA732X_DAC_EN_MAX, enable_text); 76248e27874SAdam Thomson 76348e27874SAdam Thomson static const struct snd_kcontrol_new spk_mux = 76448e27874SAdam Thomson SOC_DAPM_ENUM("SPK Switch", da732x_speaker_output); 76548e27874SAdam Thomson 76648e27874SAdam Thomson static const struct soc_enum da732x_lout4_output = 76748e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_LIN4, DA732X_LOUT_DAC_EN_SHIFT, 76848e27874SAdam Thomson DA732X_DAC_EN_MAX, enable_text); 76948e27874SAdam Thomson 77048e27874SAdam Thomson static const struct snd_kcontrol_new lout4_mux = 77148e27874SAdam Thomson SOC_DAPM_ENUM("LOUT4 Switch", da732x_lout4_output); 77248e27874SAdam Thomson 77348e27874SAdam Thomson static const struct soc_enum da732x_lout2_output = 77448e27874SAdam Thomson SOC_ENUM_SINGLE(DA732X_REG_LIN2, DA732X_LOUT_DAC_EN_SHIFT, 77548e27874SAdam Thomson DA732X_DAC_EN_MAX, enable_text); 77648e27874SAdam Thomson 77748e27874SAdam Thomson static const struct snd_kcontrol_new lout2_mux = 77848e27874SAdam Thomson SOC_DAPM_ENUM("LOUT2 Switch", da732x_lout2_output); 77948e27874SAdam Thomson 78048e27874SAdam Thomson static const struct snd_soc_dapm_widget da732x_dapm_widgets[] = { 78148e27874SAdam Thomson /* Supplies */ 78248e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("ADC1 Supply", DA732X_REG_ADC1_PD, 0, 78348e27874SAdam Thomson DA732X_NO_INVERT, da732x_adc_event, 78448e27874SAdam Thomson SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 78548e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("ADC2 Supply", DA732X_REG_ADC2_PD, 0, 78648e27874SAdam Thomson DA732X_NO_INVERT, da732x_adc_event, 78748e27874SAdam Thomson SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 78848e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("DAC1 CLK", DA732X_REG_CLK_EN4, 78948e27874SAdam Thomson DA732X_DACA_BB_CLK_SHIFT, DA732X_NO_INVERT, 79048e27874SAdam Thomson NULL, 0), 79148e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("DAC2 CLK", DA732X_REG_CLK_EN4, 79248e27874SAdam Thomson DA732X_DACC_BB_CLK_SHIFT, DA732X_NO_INVERT, 79348e27874SAdam Thomson NULL, 0), 79448e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("DAC3 CLK", DA732X_REG_CLK_EN5, 79548e27874SAdam Thomson DA732X_DACE_BB_CLK_SHIFT, DA732X_NO_INVERT, 79648e27874SAdam Thomson NULL, 0), 79748e27874SAdam Thomson 79848e27874SAdam Thomson /* Micbias */ 79948e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("MICBIAS1", DA732X_REG_MICBIAS1, 80048e27874SAdam Thomson DA732X_MICBIAS_EN_SHIFT, 80148e27874SAdam Thomson DA732X_NO_INVERT, NULL, 0), 80248e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("MICBIAS2", DA732X_REG_MICBIAS2, 80348e27874SAdam Thomson DA732X_MICBIAS_EN_SHIFT, 80448e27874SAdam Thomson DA732X_NO_INVERT, NULL, 0), 80548e27874SAdam Thomson 80648e27874SAdam Thomson /* Inputs */ 80748e27874SAdam Thomson SND_SOC_DAPM_INPUT("MIC1"), 80848e27874SAdam Thomson SND_SOC_DAPM_INPUT("MIC2"), 80948e27874SAdam Thomson SND_SOC_DAPM_INPUT("MIC3"), 81048e27874SAdam Thomson SND_SOC_DAPM_INPUT("AUX1L"), 81148e27874SAdam Thomson SND_SOC_DAPM_INPUT("AUX1R"), 81248e27874SAdam Thomson 81348e27874SAdam Thomson /* Outputs */ 81448e27874SAdam Thomson SND_SOC_DAPM_OUTPUT("HPL"), 81548e27874SAdam Thomson SND_SOC_DAPM_OUTPUT("HPR"), 81648e27874SAdam Thomson SND_SOC_DAPM_OUTPUT("LOUTL"), 81748e27874SAdam Thomson SND_SOC_DAPM_OUTPUT("LOUTR"), 81848e27874SAdam Thomson SND_SOC_DAPM_OUTPUT("ClassD"), 81948e27874SAdam Thomson 82048e27874SAdam Thomson /* ADCs */ 82148e27874SAdam Thomson SND_SOC_DAPM_ADC("ADC1L", NULL, DA732X_REG_ADC1_SEL, 82248e27874SAdam Thomson DA732X_ADCL_EN_SHIFT, DA732X_NO_INVERT), 82348e27874SAdam Thomson SND_SOC_DAPM_ADC("ADC1R", NULL, DA732X_REG_ADC1_SEL, 82448e27874SAdam Thomson DA732X_ADCR_EN_SHIFT, DA732X_NO_INVERT), 82548e27874SAdam Thomson SND_SOC_DAPM_ADC("ADC2L", NULL, DA732X_REG_ADC2_SEL, 82648e27874SAdam Thomson DA732X_ADCL_EN_SHIFT, DA732X_NO_INVERT), 82748e27874SAdam Thomson SND_SOC_DAPM_ADC("ADC2R", NULL, DA732X_REG_ADC2_SEL, 82848e27874SAdam Thomson DA732X_ADCR_EN_SHIFT, DA732X_NO_INVERT), 82948e27874SAdam Thomson 83048e27874SAdam Thomson /* DACs */ 83148e27874SAdam Thomson SND_SOC_DAPM_DAC("DAC1L", NULL, DA732X_REG_DAC1_SEL, 83248e27874SAdam Thomson DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT), 83348e27874SAdam Thomson SND_SOC_DAPM_DAC("DAC1R", NULL, DA732X_REG_DAC1_SEL, 83448e27874SAdam Thomson DA732X_DACR_EN_SHIFT, DA732X_NO_INVERT), 83548e27874SAdam Thomson SND_SOC_DAPM_DAC("DAC2L", NULL, DA732X_REG_DAC2_SEL, 83648e27874SAdam Thomson DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT), 83748e27874SAdam Thomson SND_SOC_DAPM_DAC("DAC2R", NULL, DA732X_REG_DAC2_SEL, 83848e27874SAdam Thomson DA732X_DACR_EN_SHIFT, DA732X_NO_INVERT), 83948e27874SAdam Thomson SND_SOC_DAPM_DAC("DAC3", NULL, DA732X_REG_DAC3_SEL, 84048e27874SAdam Thomson DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT), 84148e27874SAdam Thomson 84248e27874SAdam Thomson /* Input Pgas */ 84348e27874SAdam Thomson SND_SOC_DAPM_PGA("MIC1 PGA", DA732X_REG_MIC1, DA732X_MIC_EN_SHIFT, 84448e27874SAdam Thomson 0, NULL, 0), 84548e27874SAdam Thomson SND_SOC_DAPM_PGA("MIC2 PGA", DA732X_REG_MIC2, DA732X_MIC_EN_SHIFT, 84648e27874SAdam Thomson 0, NULL, 0), 84748e27874SAdam Thomson SND_SOC_DAPM_PGA("MIC3 PGA", DA732X_REG_MIC3, DA732X_MIC_EN_SHIFT, 84848e27874SAdam Thomson 0, NULL, 0), 84948e27874SAdam Thomson SND_SOC_DAPM_PGA("AUX1L PGA", DA732X_REG_AUX1L, DA732X_AUX_EN_SHIFT, 85048e27874SAdam Thomson 0, NULL, 0), 85148e27874SAdam Thomson SND_SOC_DAPM_PGA("AUX1R PGA", DA732X_REG_AUX1R, DA732X_AUX_EN_SHIFT, 85248e27874SAdam Thomson 0, NULL, 0), 85348e27874SAdam Thomson 85448e27874SAdam Thomson SND_SOC_DAPM_PGA_E("HP Left", DA732X_REG_HPL, DA732X_HP_OUT_EN_SHIFT, 85548e27874SAdam Thomson 0, NULL, 0, da732x_out_pga_event, 85648e27874SAdam Thomson SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 85748e27874SAdam Thomson SND_SOC_DAPM_PGA_E("HP Right", DA732X_REG_HPR, DA732X_HP_OUT_EN_SHIFT, 85848e27874SAdam Thomson 0, NULL, 0, da732x_out_pga_event, 85948e27874SAdam Thomson SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 86048e27874SAdam Thomson SND_SOC_DAPM_PGA_E("LIN2", DA732X_REG_LIN2, DA732X_LIN_OUT_EN_SHIFT, 86148e27874SAdam Thomson 0, NULL, 0, da732x_out_pga_event, 86248e27874SAdam Thomson SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 86348e27874SAdam Thomson SND_SOC_DAPM_PGA_E("LIN3", DA732X_REG_LIN3, DA732X_LIN_OUT_EN_SHIFT, 86448e27874SAdam Thomson 0, NULL, 0, da732x_out_pga_event, 86548e27874SAdam Thomson SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 86648e27874SAdam Thomson SND_SOC_DAPM_PGA_E("LIN4", DA732X_REG_LIN4, DA732X_LIN_OUT_EN_SHIFT, 86748e27874SAdam Thomson 0, NULL, 0, da732x_out_pga_event, 86848e27874SAdam Thomson SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 86948e27874SAdam Thomson 87048e27874SAdam Thomson /* MUXs */ 87148e27874SAdam Thomson SND_SOC_DAPM_MUX("ADC1 Left MUX", SND_SOC_NOPM, 0, 0, &adc1l_mux), 87248e27874SAdam Thomson SND_SOC_DAPM_MUX("ADC1 Right MUX", SND_SOC_NOPM, 0, 0, &adc1r_mux), 87348e27874SAdam Thomson SND_SOC_DAPM_MUX("ADC2 Left MUX", SND_SOC_NOPM, 0, 0, &adc2l_mux), 87448e27874SAdam Thomson SND_SOC_DAPM_MUX("ADC2 Right MUX", SND_SOC_NOPM, 0, 0, &adc2r_mux), 87548e27874SAdam Thomson 87648e27874SAdam Thomson SND_SOC_DAPM_MUX("HP Left MUX", SND_SOC_NOPM, 0, 0, &hpl_mux), 87748e27874SAdam Thomson SND_SOC_DAPM_MUX("HP Right MUX", SND_SOC_NOPM, 0, 0, &hpr_mux), 87848e27874SAdam Thomson SND_SOC_DAPM_MUX("Speaker MUX", SND_SOC_NOPM, 0, 0, &spk_mux), 87948e27874SAdam Thomson SND_SOC_DAPM_MUX("LOUT2 MUX", SND_SOC_NOPM, 0, 0, &lout2_mux), 88048e27874SAdam Thomson SND_SOC_DAPM_MUX("LOUT4 MUX", SND_SOC_NOPM, 0, 0, &lout4_mux), 88148e27874SAdam Thomson 88248e27874SAdam Thomson /* AIF interfaces */ 88348e27874SAdam Thomson SND_SOC_DAPM_AIF_OUT("AIFA Output", "AIFA Capture", 0, DA732X_REG_AIFA3, 88448e27874SAdam Thomson DA732X_AIF_EN_SHIFT, 0), 88548e27874SAdam Thomson SND_SOC_DAPM_AIF_IN("AIFA Input", "AIFA Playback", 0, DA732X_REG_AIFA3, 88648e27874SAdam Thomson DA732X_AIF_EN_SHIFT, 0), 88748e27874SAdam Thomson 88848e27874SAdam Thomson SND_SOC_DAPM_AIF_OUT("AIFB Output", "AIFB Capture", 0, DA732X_REG_AIFB3, 88948e27874SAdam Thomson DA732X_AIF_EN_SHIFT, 0), 89048e27874SAdam Thomson SND_SOC_DAPM_AIF_IN("AIFB Input", "AIFB Playback", 0, DA732X_REG_AIFB3, 89148e27874SAdam Thomson DA732X_AIF_EN_SHIFT, 0), 89248e27874SAdam Thomson }; 89348e27874SAdam Thomson 89448e27874SAdam Thomson static const struct snd_soc_dapm_route da732x_dapm_routes[] = { 89548e27874SAdam Thomson /* Inputs */ 89648e27874SAdam Thomson {"AUX1L PGA", "NULL", "AUX1L"}, 89748e27874SAdam Thomson {"AUX1R PGA", "NULL", "AUX1R"}, 89848e27874SAdam Thomson {"MIC1 PGA", NULL, "MIC1"}, 89948e27874SAdam Thomson {"MIC2 PGA", "NULL", "MIC2"}, 90048e27874SAdam Thomson {"MIC3 PGA", "NULL", "MIC3"}, 90148e27874SAdam Thomson 90248e27874SAdam Thomson /* Capture Path */ 90348e27874SAdam Thomson {"ADC1 Left MUX", "MIC1", "MIC1 PGA"}, 90448e27874SAdam Thomson {"ADC1 Left MUX", "AUX1L", "AUX1L PGA"}, 90548e27874SAdam Thomson 90648e27874SAdam Thomson {"ADC1 Right MUX", "AUX1R", "AUX1R PGA"}, 90748e27874SAdam Thomson {"ADC1 Right MUX", "MIC2", "MIC2 PGA"}, 90848e27874SAdam Thomson {"ADC1 Right MUX", "MIC3", "MIC3 PGA"}, 90948e27874SAdam Thomson 91048e27874SAdam Thomson {"ADC2 Left MUX", "AUX1L", "AUX1L PGA"}, 91148e27874SAdam Thomson {"ADC2 Left MUX", "MIC1", "MIC1 PGA"}, 91248e27874SAdam Thomson 91348e27874SAdam Thomson {"ADC2 Right MUX", "AUX1R", "AUX1R PGA"}, 91448e27874SAdam Thomson {"ADC2 Right MUX", "MIC2", "MIC2 PGA"}, 91548e27874SAdam Thomson {"ADC2 Right MUX", "MIC3", "MIC3 PGA"}, 91648e27874SAdam Thomson 91748e27874SAdam Thomson {"ADC1L", NULL, "ADC1 Supply"}, 91848e27874SAdam Thomson {"ADC1R", NULL, "ADC1 Supply"}, 91948e27874SAdam Thomson {"ADC2L", NULL, "ADC2 Supply"}, 92048e27874SAdam Thomson {"ADC2R", NULL, "ADC2 Supply"}, 92148e27874SAdam Thomson 92248e27874SAdam Thomson {"ADC1L", NULL, "ADC1 Left MUX"}, 92348e27874SAdam Thomson {"ADC1R", NULL, "ADC1 Right MUX"}, 92448e27874SAdam Thomson {"ADC2L", NULL, "ADC2 Left MUX"}, 92548e27874SAdam Thomson {"ADC2R", NULL, "ADC2 Right MUX"}, 92648e27874SAdam Thomson 92748e27874SAdam Thomson {"AIFA Output", NULL, "ADC1L"}, 92848e27874SAdam Thomson {"AIFA Output", NULL, "ADC1R"}, 92948e27874SAdam Thomson {"AIFB Output", NULL, "ADC2L"}, 93048e27874SAdam Thomson {"AIFB Output", NULL, "ADC2R"}, 93148e27874SAdam Thomson 93248e27874SAdam Thomson {"HP Left MUX", "Enabled", "AIFA Input"}, 93348e27874SAdam Thomson {"HP Right MUX", "Enabled", "AIFA Input"}, 93448e27874SAdam Thomson {"Speaker MUX", "Enabled", "AIFB Input"}, 93548e27874SAdam Thomson {"LOUT2 MUX", "Enabled", "AIFB Input"}, 93648e27874SAdam Thomson {"LOUT4 MUX", "Enabled", "AIFB Input"}, 93748e27874SAdam Thomson 93848e27874SAdam Thomson {"DAC1L", NULL, "DAC1 CLK"}, 93948e27874SAdam Thomson {"DAC1R", NULL, "DAC1 CLK"}, 94048e27874SAdam Thomson {"DAC2L", NULL, "DAC2 CLK"}, 94148e27874SAdam Thomson {"DAC2R", NULL, "DAC2 CLK"}, 94248e27874SAdam Thomson {"DAC3", NULL, "DAC3 CLK"}, 94348e27874SAdam Thomson 94448e27874SAdam Thomson {"DAC1L", NULL, "HP Left MUX"}, 94548e27874SAdam Thomson {"DAC1R", NULL, "HP Right MUX"}, 94648e27874SAdam Thomson {"DAC2L", NULL, "Speaker MUX"}, 94748e27874SAdam Thomson {"DAC2R", NULL, "LOUT4 MUX"}, 94848e27874SAdam Thomson {"DAC3", NULL, "LOUT2 MUX"}, 94948e27874SAdam Thomson 95048e27874SAdam Thomson /* Output Pgas */ 95148e27874SAdam Thomson {"HP Left", NULL, "DAC1L"}, 95248e27874SAdam Thomson {"HP Right", NULL, "DAC1R"}, 95348e27874SAdam Thomson {"LIN3", NULL, "DAC2L"}, 95448e27874SAdam Thomson {"LIN4", NULL, "DAC2R"}, 95548e27874SAdam Thomson {"LIN2", NULL, "DAC3"}, 95648e27874SAdam Thomson 95748e27874SAdam Thomson /* Outputs */ 95848e27874SAdam Thomson {"ClassD", NULL, "LIN3"}, 95948e27874SAdam Thomson {"LOUTL", NULL, "LIN2"}, 96048e27874SAdam Thomson {"LOUTR", NULL, "LIN4"}, 96148e27874SAdam Thomson {"HPL", NULL, "HP Left"}, 96248e27874SAdam Thomson {"HPR", NULL, "HP Right"}, 96348e27874SAdam Thomson }; 96448e27874SAdam Thomson 96548e27874SAdam Thomson static int da732x_hw_params(struct snd_pcm_substream *substream, 96648e27874SAdam Thomson struct snd_pcm_hw_params *params, 96748e27874SAdam Thomson struct snd_soc_dai *dai) 96848e27874SAdam Thomson { 96948e27874SAdam Thomson struct snd_soc_codec *codec = dai->codec; 97048e27874SAdam Thomson u32 aif = 0; 97148e27874SAdam Thomson u32 reg_aif; 97248e27874SAdam Thomson u32 fs; 97348e27874SAdam Thomson 97448e27874SAdam Thomson reg_aif = dai->driver->base; 97548e27874SAdam Thomson 97648e27874SAdam Thomson switch (params_format(params)) { 97748e27874SAdam Thomson case SNDRV_PCM_FORMAT_S16_LE: 97848e27874SAdam Thomson aif |= DA732X_AIF_WORD_16; 97948e27874SAdam Thomson break; 98048e27874SAdam Thomson case SNDRV_PCM_FORMAT_S20_3LE: 98148e27874SAdam Thomson aif |= DA732X_AIF_WORD_20; 98248e27874SAdam Thomson break; 98348e27874SAdam Thomson case SNDRV_PCM_FORMAT_S24_LE: 98448e27874SAdam Thomson aif |= DA732X_AIF_WORD_24; 98548e27874SAdam Thomson break; 98648e27874SAdam Thomson case SNDRV_PCM_FORMAT_S32_LE: 98748e27874SAdam Thomson aif |= DA732X_AIF_WORD_32; 98848e27874SAdam Thomson break; 98948e27874SAdam Thomson default: 99048e27874SAdam Thomson return -EINVAL; 99148e27874SAdam Thomson } 99248e27874SAdam Thomson 99348e27874SAdam Thomson switch (params_rate(params)) { 99448e27874SAdam Thomson case 8000: 99548e27874SAdam Thomson fs = DA732X_SR_8KHZ; 99648e27874SAdam Thomson break; 99748e27874SAdam Thomson case 11025: 99848e27874SAdam Thomson fs = DA732X_SR_11_025KHZ; 99948e27874SAdam Thomson break; 100048e27874SAdam Thomson case 12000: 100148e27874SAdam Thomson fs = DA732X_SR_12KHZ; 100248e27874SAdam Thomson break; 100348e27874SAdam Thomson case 16000: 100448e27874SAdam Thomson fs = DA732X_SR_16KHZ; 100548e27874SAdam Thomson break; 100648e27874SAdam Thomson case 22050: 100748e27874SAdam Thomson fs = DA732X_SR_22_05KHZ; 100848e27874SAdam Thomson break; 100948e27874SAdam Thomson case 24000: 101048e27874SAdam Thomson fs = DA732X_SR_24KHZ; 101148e27874SAdam Thomson break; 101248e27874SAdam Thomson case 32000: 101348e27874SAdam Thomson fs = DA732X_SR_32KHZ; 101448e27874SAdam Thomson break; 101548e27874SAdam Thomson case 44100: 101648e27874SAdam Thomson fs = DA732X_SR_44_1KHZ; 101748e27874SAdam Thomson break; 101848e27874SAdam Thomson case 48000: 101948e27874SAdam Thomson fs = DA732X_SR_48KHZ; 102048e27874SAdam Thomson break; 102148e27874SAdam Thomson case 88100: 102248e27874SAdam Thomson fs = DA732X_SR_88_1KHZ; 102348e27874SAdam Thomson break; 102448e27874SAdam Thomson case 96000: 102548e27874SAdam Thomson fs = DA732X_SR_96KHZ; 102648e27874SAdam Thomson break; 102748e27874SAdam Thomson default: 102848e27874SAdam Thomson return -EINVAL; 102948e27874SAdam Thomson } 103048e27874SAdam Thomson 103148e27874SAdam Thomson snd_soc_update_bits(codec, reg_aif, DA732X_AIF_WORD_MASK, aif); 103248e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_CLK_CTRL, DA732X_SR1_MASK, fs); 103348e27874SAdam Thomson 103448e27874SAdam Thomson return 0; 103548e27874SAdam Thomson } 103648e27874SAdam Thomson 103748e27874SAdam Thomson static int da732x_set_dai_fmt(struct snd_soc_dai *dai, u32 fmt) 103848e27874SAdam Thomson { 103948e27874SAdam Thomson struct snd_soc_codec *codec = dai->codec; 104048e27874SAdam Thomson u32 aif_mclk, pc_count; 104148e27874SAdam Thomson u32 reg_aif1, aif1; 104248e27874SAdam Thomson u32 reg_aif3, aif3; 104348e27874SAdam Thomson 104448e27874SAdam Thomson switch (dai->id) { 104548e27874SAdam Thomson case DA732X_DAI_ID1: 104648e27874SAdam Thomson reg_aif1 = DA732X_REG_AIFA1; 104748e27874SAdam Thomson reg_aif3 = DA732X_REG_AIFA3; 104848e27874SAdam Thomson pc_count = DA732X_PC_PULSE_AIFA | DA732X_PC_RESYNC_NOT_AUT | 104948e27874SAdam Thomson DA732X_PC_SAME; 105048e27874SAdam Thomson break; 105148e27874SAdam Thomson case DA732X_DAI_ID2: 105248e27874SAdam Thomson reg_aif1 = DA732X_REG_AIFB1; 105348e27874SAdam Thomson reg_aif3 = DA732X_REG_AIFB3; 105448e27874SAdam Thomson pc_count = DA732X_PC_PULSE_AIFB | DA732X_PC_RESYNC_NOT_AUT | 105548e27874SAdam Thomson DA732X_PC_SAME; 105648e27874SAdam Thomson break; 105748e27874SAdam Thomson default: 105848e27874SAdam Thomson return -EINVAL; 105948e27874SAdam Thomson } 106048e27874SAdam Thomson 106148e27874SAdam Thomson switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 106248e27874SAdam Thomson case SND_SOC_DAIFMT_CBS_CFS: 106348e27874SAdam Thomson aif1 = DA732X_AIF_SLAVE; 106448e27874SAdam Thomson aif_mclk = DA732X_AIFM_FRAME_64 | DA732X_AIFM_SRC_SEL_AIFA; 106548e27874SAdam Thomson break; 106648e27874SAdam Thomson case SND_SOC_DAIFMT_CBM_CFM: 106748e27874SAdam Thomson aif1 = DA732X_AIF_CLK_FROM_SRC; 106848e27874SAdam Thomson aif_mclk = DA732X_CLK_GENERATION_AIF_A; 106948e27874SAdam Thomson break; 107048e27874SAdam Thomson default: 107148e27874SAdam Thomson return -EINVAL; 107248e27874SAdam Thomson } 107348e27874SAdam Thomson 107448e27874SAdam Thomson switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 107548e27874SAdam Thomson case SND_SOC_DAIFMT_I2S: 107648e27874SAdam Thomson aif3 = DA732X_AIF_I2S_MODE; 107748e27874SAdam Thomson break; 107848e27874SAdam Thomson case SND_SOC_DAIFMT_RIGHT_J: 107948e27874SAdam Thomson aif3 = DA732X_AIF_RIGHT_J_MODE; 108048e27874SAdam Thomson break; 108148e27874SAdam Thomson case SND_SOC_DAIFMT_LEFT_J: 108248e27874SAdam Thomson aif3 = DA732X_AIF_LEFT_J_MODE; 108348e27874SAdam Thomson break; 108448e27874SAdam Thomson case SND_SOC_DAIFMT_DSP_B: 108548e27874SAdam Thomson aif3 = DA732X_AIF_DSP_MODE; 108648e27874SAdam Thomson break; 108748e27874SAdam Thomson default: 108848e27874SAdam Thomson return -EINVAL; 108948e27874SAdam Thomson } 109048e27874SAdam Thomson 109148e27874SAdam Thomson /* Clock inversion */ 109248e27874SAdam Thomson switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 109348e27874SAdam Thomson case SND_SOC_DAIFMT_DSP_B: 109448e27874SAdam Thomson switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 109548e27874SAdam Thomson case SND_SOC_DAIFMT_NB_NF: 109648e27874SAdam Thomson break; 109748e27874SAdam Thomson case SND_SOC_DAIFMT_IB_NF: 109848e27874SAdam Thomson aif3 |= DA732X_AIF_BCLK_INV; 109948e27874SAdam Thomson break; 110048e27874SAdam Thomson default: 110148e27874SAdam Thomson return -EINVAL; 110248e27874SAdam Thomson } 110348e27874SAdam Thomson break; 110448e27874SAdam Thomson case SND_SOC_DAIFMT_I2S: 110548e27874SAdam Thomson case SND_SOC_DAIFMT_RIGHT_J: 110648e27874SAdam Thomson case SND_SOC_DAIFMT_LEFT_J: 110748e27874SAdam Thomson switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 110848e27874SAdam Thomson case SND_SOC_DAIFMT_NB_NF: 110948e27874SAdam Thomson break; 111048e27874SAdam Thomson case SND_SOC_DAIFMT_IB_IF: 111148e27874SAdam Thomson aif3 |= DA732X_AIF_BCLK_INV | DA732X_AIF_WCLK_INV; 111248e27874SAdam Thomson break; 111348e27874SAdam Thomson case SND_SOC_DAIFMT_IB_NF: 111448e27874SAdam Thomson aif3 |= DA732X_AIF_BCLK_INV; 111548e27874SAdam Thomson break; 111648e27874SAdam Thomson case SND_SOC_DAIFMT_NB_IF: 111748e27874SAdam Thomson aif3 |= DA732X_AIF_WCLK_INV; 111848e27874SAdam Thomson break; 111948e27874SAdam Thomson default: 112048e27874SAdam Thomson return -EINVAL; 112148e27874SAdam Thomson } 112248e27874SAdam Thomson break; 112348e27874SAdam Thomson default: 112448e27874SAdam Thomson return -EINVAL; 112548e27874SAdam Thomson } 112648e27874SAdam Thomson 112748e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_AIF_MCLK, aif_mclk); 112848e27874SAdam Thomson snd_soc_update_bits(codec, reg_aif1, DA732X_AIF1_CLK_MASK, aif1); 112948e27874SAdam Thomson snd_soc_update_bits(codec, reg_aif3, DA732X_AIF_BCLK_INV | 113048e27874SAdam Thomson DA732X_AIF_WCLK_INV | DA732X_AIF_MODE_MASK, aif3); 113148e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_PC_CTRL, pc_count); 113248e27874SAdam Thomson 113348e27874SAdam Thomson return 0; 113448e27874SAdam Thomson } 113548e27874SAdam Thomson 113648e27874SAdam Thomson 113748e27874SAdam Thomson 113848e27874SAdam Thomson static int da732x_set_dai_pll(struct snd_soc_codec *codec, int pll_id, 113948e27874SAdam Thomson int source, unsigned int freq_in, 114048e27874SAdam Thomson unsigned int freq_out) 114148e27874SAdam Thomson { 114248e27874SAdam Thomson struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); 114348e27874SAdam Thomson int fref, indiv; 114448e27874SAdam Thomson u8 div_lo, div_mid, div_hi; 114548e27874SAdam Thomson u64 frac_div; 114648e27874SAdam Thomson 114748e27874SAdam Thomson /* Disable PLL */ 114848e27874SAdam Thomson if (freq_out == 0) { 114948e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, 115048e27874SAdam Thomson DA732X_PLL_EN, 0); 115148e27874SAdam Thomson da732x->pll_en = false; 115248e27874SAdam Thomson return 0; 115348e27874SAdam Thomson } 115448e27874SAdam Thomson 115548e27874SAdam Thomson if (da732x->pll_en) 115648e27874SAdam Thomson return -EBUSY; 115748e27874SAdam Thomson 115848e27874SAdam Thomson if (source == DA732X_SRCCLK_MCLK) { 115948e27874SAdam Thomson /* Validate Sysclk rate */ 116048e27874SAdam Thomson switch (da732x->sysclk) { 116148e27874SAdam Thomson case 11290000: 116248e27874SAdam Thomson case 12288000: 116348e27874SAdam Thomson case 22580000: 116448e27874SAdam Thomson case 24576000: 116548e27874SAdam Thomson case 45160000: 116648e27874SAdam Thomson case 49152000: 116748e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_PLL_CTRL, 116848e27874SAdam Thomson DA732X_PLL_BYPASS); 116948e27874SAdam Thomson return 0; 117048e27874SAdam Thomson default: 117148e27874SAdam Thomson dev_err(codec->dev, 117248e27874SAdam Thomson "Cannot use PLL Bypass, invalid SYSCLK rate\n"); 117348e27874SAdam Thomson return -EINVAL; 117448e27874SAdam Thomson } 117548e27874SAdam Thomson } 117648e27874SAdam Thomson 117748e27874SAdam Thomson indiv = da732x_get_input_div(codec, da732x->sysclk); 117848e27874SAdam Thomson if (indiv < 0) 117948e27874SAdam Thomson return indiv; 118048e27874SAdam Thomson 118148e27874SAdam Thomson fref = (da732x->sysclk / indiv); 118248e27874SAdam Thomson div_hi = freq_out / fref; 118348e27874SAdam Thomson frac_div = (u64)(freq_out % fref) * 8192ULL; 118448e27874SAdam Thomson do_div(frac_div, fref); 118548e27874SAdam Thomson div_mid = (frac_div >> DA732X_1BYTE_SHIFT) & DA732X_U8_MASK; 118648e27874SAdam Thomson div_lo = (frac_div) & DA732X_U8_MASK; 118748e27874SAdam Thomson 118848e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_PLL_DIV_LO, div_lo); 118948e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_PLL_DIV_MID, div_mid); 119048e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_PLL_DIV_HI, div_hi); 119148e27874SAdam Thomson 119248e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, DA732X_PLL_EN, 119348e27874SAdam Thomson DA732X_PLL_EN); 119448e27874SAdam Thomson 119548e27874SAdam Thomson da732x->pll_en = true; 119648e27874SAdam Thomson 119748e27874SAdam Thomson return 0; 119848e27874SAdam Thomson } 119948e27874SAdam Thomson 120048e27874SAdam Thomson static int da732x_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, 120148e27874SAdam Thomson unsigned int freq, int dir) 120248e27874SAdam Thomson { 120348e27874SAdam Thomson struct snd_soc_codec *codec = dai->codec; 120448e27874SAdam Thomson struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); 120548e27874SAdam Thomson 120648e27874SAdam Thomson da732x->sysclk = freq; 120748e27874SAdam Thomson 120848e27874SAdam Thomson return 0; 120948e27874SAdam Thomson } 121048e27874SAdam Thomson 121148e27874SAdam Thomson #define DA732X_RATES SNDRV_PCM_RATE_8000_96000 121248e27874SAdam Thomson 121348e27874SAdam Thomson #define DA732X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 121448e27874SAdam Thomson SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 121548e27874SAdam Thomson 121648e27874SAdam Thomson static struct snd_soc_dai_ops da732x_dai1_ops = { 121748e27874SAdam Thomson .hw_params = da732x_hw_params, 121848e27874SAdam Thomson .set_fmt = da732x_set_dai_fmt, 121948e27874SAdam Thomson .set_sysclk = da732x_set_dai_sysclk, 122048e27874SAdam Thomson }; 122148e27874SAdam Thomson 122248e27874SAdam Thomson static struct snd_soc_dai_ops da732x_dai2_ops = { 122348e27874SAdam Thomson .hw_params = da732x_hw_params, 122448e27874SAdam Thomson .set_fmt = da732x_set_dai_fmt, 122548e27874SAdam Thomson .set_sysclk = da732x_set_dai_sysclk, 122648e27874SAdam Thomson }; 122748e27874SAdam Thomson 122848e27874SAdam Thomson static struct snd_soc_dai_driver da732x_dai[] = { 122948e27874SAdam Thomson { 123048e27874SAdam Thomson .name = "DA732X_AIFA", 123148e27874SAdam Thomson .id = DA732X_DAI_ID1, 123248e27874SAdam Thomson .base = DA732X_REG_AIFA1, 123348e27874SAdam Thomson .playback = { 123448e27874SAdam Thomson .stream_name = "AIFA Playback", 123548e27874SAdam Thomson .channels_min = 1, 123648e27874SAdam Thomson .channels_max = 2, 123748e27874SAdam Thomson .rates = DA732X_RATES, 123848e27874SAdam Thomson .formats = DA732X_FORMATS, 123948e27874SAdam Thomson }, 124048e27874SAdam Thomson .capture = { 124148e27874SAdam Thomson .stream_name = "AIFA Capture", 124248e27874SAdam Thomson .channels_min = 1, 124348e27874SAdam Thomson .channels_max = 2, 124448e27874SAdam Thomson .rates = DA732X_RATES, 124548e27874SAdam Thomson .formats = DA732X_FORMATS, 124648e27874SAdam Thomson }, 124748e27874SAdam Thomson .ops = &da732x_dai1_ops, 124848e27874SAdam Thomson }, 124948e27874SAdam Thomson { 125048e27874SAdam Thomson .name = "DA732X_AIFB", 125148e27874SAdam Thomson .id = DA732X_DAI_ID2, 125248e27874SAdam Thomson .base = DA732X_REG_AIFB1, 125348e27874SAdam Thomson .playback = { 125448e27874SAdam Thomson .stream_name = "AIFB Playback", 125548e27874SAdam Thomson .channels_min = 1, 125648e27874SAdam Thomson .channels_max = 2, 125748e27874SAdam Thomson .rates = DA732X_RATES, 125848e27874SAdam Thomson .formats = DA732X_FORMATS, 125948e27874SAdam Thomson }, 126048e27874SAdam Thomson .capture = { 126148e27874SAdam Thomson .stream_name = "AIFB Capture", 126248e27874SAdam Thomson .channels_min = 1, 126348e27874SAdam Thomson .channels_max = 2, 126448e27874SAdam Thomson .rates = DA732X_RATES, 126548e27874SAdam Thomson .formats = DA732X_FORMATS, 126648e27874SAdam Thomson }, 126748e27874SAdam Thomson .ops = &da732x_dai2_ops, 126848e27874SAdam Thomson }, 126948e27874SAdam Thomson }; 127048e27874SAdam Thomson 127148e27874SAdam Thomson static const struct regmap_config da732x_regmap = { 127248e27874SAdam Thomson .reg_bits = 8, 127348e27874SAdam Thomson .val_bits = 8, 127448e27874SAdam Thomson 127548e27874SAdam Thomson .max_register = DA732X_MAX_REG, 127648e27874SAdam Thomson .reg_defaults = da732x_reg_cache, 127748e27874SAdam Thomson .num_reg_defaults = ARRAY_SIZE(da732x_reg_cache), 127848e27874SAdam Thomson .cache_type = REGCACHE_RBTREE, 127948e27874SAdam Thomson }; 128048e27874SAdam Thomson 128148e27874SAdam Thomson 128248e27874SAdam Thomson static void da732x_dac_offset_adjust(struct snd_soc_codec *codec) 128348e27874SAdam Thomson { 128448e27874SAdam Thomson u8 offset[DA732X_HP_DACS]; 128548e27874SAdam Thomson u8 sign[DA732X_HP_DACS]; 128648e27874SAdam Thomson u8 step = DA732X_DAC_OFFSET_STEP; 128748e27874SAdam Thomson 128848e27874SAdam Thomson /* Initialize DAC offset calibration circuits and registers */ 128948e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET, 129048e27874SAdam Thomson DA732X_HP_DAC_OFFSET_TRIM_VAL); 129148e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET, 129248e27874SAdam Thomson DA732X_HP_DAC_OFFSET_TRIM_VAL); 129348e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL, 129448e27874SAdam Thomson DA732X_HP_DAC_OFF_CALIBRATION | 129548e27874SAdam Thomson DA732X_HP_DAC_OFF_SCALE_STEPS); 129648e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL, 129748e27874SAdam Thomson DA732X_HP_DAC_OFF_CALIBRATION | 129848e27874SAdam Thomson DA732X_HP_DAC_OFF_SCALE_STEPS); 129948e27874SAdam Thomson 130048e27874SAdam Thomson /* Wait for voltage stabilization */ 130148e27874SAdam Thomson msleep(DA732X_WAIT_FOR_STABILIZATION); 130248e27874SAdam Thomson 130348e27874SAdam Thomson /* Check DAC offset sign */ 130448e27874SAdam Thomson sign[DA732X_HPL_DAC] = (codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) & 130548e27874SAdam Thomson DA732X_HP_DAC_OFF_CNTL_COMPO); 130648e27874SAdam Thomson sign[DA732X_HPR_DAC] = (codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) & 130748e27874SAdam Thomson DA732X_HP_DAC_OFF_CNTL_COMPO); 130848e27874SAdam Thomson 130948e27874SAdam Thomson /* Binary search DAC offset values (both channels at once) */ 131048e27874SAdam Thomson offset[DA732X_HPL_DAC] = sign[DA732X_HPL_DAC] << DA732X_HP_DAC_COMPO_SHIFT; 131148e27874SAdam Thomson offset[DA732X_HPR_DAC] = sign[DA732X_HPR_DAC] << DA732X_HP_DAC_COMPO_SHIFT; 131248e27874SAdam Thomson 131348e27874SAdam Thomson do { 131448e27874SAdam Thomson offset[DA732X_HPL_DAC] |= step; 131548e27874SAdam Thomson offset[DA732X_HPR_DAC] |= step; 131648e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET, 131748e27874SAdam Thomson ~offset[DA732X_HPL_DAC] & DA732X_HP_DAC_OFF_MASK); 131848e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET, 131948e27874SAdam Thomson ~offset[DA732X_HPR_DAC] & DA732X_HP_DAC_OFF_MASK); 132048e27874SAdam Thomson 132148e27874SAdam Thomson msleep(DA732X_WAIT_FOR_STABILIZATION); 132248e27874SAdam Thomson 132348e27874SAdam Thomson if ((codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) & 132448e27874SAdam Thomson DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPL_DAC]) 132548e27874SAdam Thomson offset[DA732X_HPL_DAC] &= ~step; 132648e27874SAdam Thomson if ((codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) & 132748e27874SAdam Thomson DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPR_DAC]) 132848e27874SAdam Thomson offset[DA732X_HPR_DAC] &= ~step; 132948e27874SAdam Thomson 133048e27874SAdam Thomson step >>= 1; 133148e27874SAdam Thomson } while (step); 133248e27874SAdam Thomson 133348e27874SAdam Thomson /* Write final DAC offsets to registers */ 133448e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET, 133548e27874SAdam Thomson ~offset[DA732X_HPL_DAC] & DA732X_HP_DAC_OFF_MASK); 133648e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET, 133748e27874SAdam Thomson ~offset[DA732X_HPR_DAC] & DA732X_HP_DAC_OFF_MASK); 133848e27874SAdam Thomson 133948e27874SAdam Thomson /* End DAC calibration mode */ 134048e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL, 134148e27874SAdam Thomson DA732X_HP_DAC_OFF_SCALE_STEPS); 134248e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL, 134348e27874SAdam Thomson DA732X_HP_DAC_OFF_SCALE_STEPS); 134448e27874SAdam Thomson } 134548e27874SAdam Thomson 134648e27874SAdam Thomson static void da732x_output_offset_adjust(struct snd_soc_codec *codec) 134748e27874SAdam Thomson { 134848e27874SAdam Thomson u8 offset[DA732X_HP_AMPS]; 134948e27874SAdam Thomson u8 sign[DA732X_HP_AMPS]; 135048e27874SAdam Thomson u8 step = DA732X_OUTPUT_OFFSET_STEP; 135148e27874SAdam Thomson 135248e27874SAdam Thomson offset[DA732X_HPL_AMP] = DA732X_HP_OUT_TRIM_VAL; 135348e27874SAdam Thomson offset[DA732X_HPR_AMP] = DA732X_HP_OUT_TRIM_VAL; 135448e27874SAdam Thomson 135548e27874SAdam Thomson /* Initialize output offset calibration circuits and registers */ 135648e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL); 135748e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL); 135848e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL, 135948e27874SAdam Thomson DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN); 136048e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR, 136148e27874SAdam Thomson DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN); 136248e27874SAdam Thomson 136348e27874SAdam Thomson /* Wait for voltage stabilization */ 136448e27874SAdam Thomson msleep(DA732X_WAIT_FOR_STABILIZATION); 136548e27874SAdam Thomson 136648e27874SAdam Thomson /* Check output offset sign */ 136748e27874SAdam Thomson sign[DA732X_HPL_AMP] = codec->hw_read(codec, DA732X_REG_HPL) & 136848e27874SAdam Thomson DA732X_HP_OUT_COMPO; 136948e27874SAdam Thomson sign[DA732X_HPR_AMP] = codec->hw_read(codec, DA732X_REG_HPR) & 137048e27874SAdam Thomson DA732X_HP_OUT_COMPO; 137148e27874SAdam Thomson 137248e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_COMP | 137348e27874SAdam Thomson (sign[DA732X_HPL_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) | 137448e27874SAdam Thomson DA732X_HP_OUT_EN); 137548e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_COMP | 137648e27874SAdam Thomson (sign[DA732X_HPR_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) | 137748e27874SAdam Thomson DA732X_HP_OUT_EN); 137848e27874SAdam Thomson 137948e27874SAdam Thomson /* Binary search output offset values (both channels at once) */ 138048e27874SAdam Thomson do { 138148e27874SAdam Thomson offset[DA732X_HPL_AMP] |= step; 138248e27874SAdam Thomson offset[DA732X_HPR_AMP] |= step; 138348e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, 138448e27874SAdam Thomson offset[DA732X_HPL_AMP]); 138548e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, 138648e27874SAdam Thomson offset[DA732X_HPR_AMP]); 138748e27874SAdam Thomson 138848e27874SAdam Thomson msleep(DA732X_WAIT_FOR_STABILIZATION); 138948e27874SAdam Thomson 139048e27874SAdam Thomson if ((codec->hw_read(codec, DA732X_REG_HPL) & 139148e27874SAdam Thomson DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPL_AMP]) 139248e27874SAdam Thomson offset[DA732X_HPL_AMP] &= ~step; 139348e27874SAdam Thomson if ((codec->hw_read(codec, DA732X_REG_HPR) & 139448e27874SAdam Thomson DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPR_AMP]) 139548e27874SAdam Thomson offset[DA732X_HPR_AMP] &= ~step; 139648e27874SAdam Thomson 139748e27874SAdam Thomson step >>= 1; 139848e27874SAdam Thomson } while (step); 139948e27874SAdam Thomson 140048e27874SAdam Thomson /* Write final DAC offsets to registers */ 140148e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, offset[DA732X_HPL_AMP]); 140248e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, offset[DA732X_HPR_AMP]); 140348e27874SAdam Thomson } 140448e27874SAdam Thomson 140548e27874SAdam Thomson static void da732x_hp_dc_offset_cancellation(struct snd_soc_codec *codec) 140648e27874SAdam Thomson { 140748e27874SAdam Thomson /* Make sure that we have Soft Mute enabled */ 140848e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_DAC1_SOFTMUTE, DA732X_SOFTMUTE_EN | 140948e27874SAdam Thomson DA732X_GAIN_RAMPED | DA732X_16_SAMPLES); 141048e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACL_EN | 141148e27874SAdam Thomson DA732X_DACR_EN | DA732X_DACL_SDM | DA732X_DACR_SDM | 141248e27874SAdam Thomson DA732X_DACL_MUTE | DA732X_DACR_MUTE); 141348e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN | 141448e27874SAdam Thomson DA732X_HP_OUT_MUTE | DA732X_HP_OUT_EN); 141548e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_EN | 141648e27874SAdam Thomson DA732X_HP_OUT_MUTE | DA732X_HP_OUT_DAC_EN); 141748e27874SAdam Thomson 141848e27874SAdam Thomson da732x_dac_offset_adjust(codec); 141948e27874SAdam Thomson da732x_output_offset_adjust(codec); 142048e27874SAdam Thomson 142148e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACS_DIS); 142248e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_DIS); 142348e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_DIS); 142448e27874SAdam Thomson } 142548e27874SAdam Thomson 142648e27874SAdam Thomson static int da732x_set_bias_level(struct snd_soc_codec *codec, 142748e27874SAdam Thomson enum snd_soc_bias_level level) 142848e27874SAdam Thomson { 142948e27874SAdam Thomson struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); 143048e27874SAdam Thomson 143148e27874SAdam Thomson switch (level) { 143248e27874SAdam Thomson case SND_SOC_BIAS_ON: 143348e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, 143448e27874SAdam Thomson DA732X_BIAS_BOOST_MASK, 143548e27874SAdam Thomson DA732X_BIAS_BOOST_100PC); 143648e27874SAdam Thomson break; 143748e27874SAdam Thomson case SND_SOC_BIAS_PREPARE: 143848e27874SAdam Thomson break; 143948e27874SAdam Thomson case SND_SOC_BIAS_STANDBY: 144048e27874SAdam Thomson if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 144148e27874SAdam Thomson /* Init Codec */ 144248e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_REF1, 144348e27874SAdam Thomson DA732X_VMID_FASTCHG); 144448e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_BIAS_EN, 144548e27874SAdam Thomson DA732X_BIAS_EN); 144648e27874SAdam Thomson 144748e27874SAdam Thomson mdelay(DA732X_STARTUP_DELAY); 144848e27874SAdam Thomson 144948e27874SAdam Thomson /* Disable Fast Charge and enable DAC ref voltage */ 145048e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_REF1, 145148e27874SAdam Thomson DA732X_REFBUFX2_EN); 145248e27874SAdam Thomson 145348e27874SAdam Thomson /* Enable bypass DSP routing */ 145448e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_DATA_ROUTE, 145548e27874SAdam Thomson DA732X_BYPASS_DSP); 145648e27874SAdam Thomson 145748e27874SAdam Thomson /* Enable Digital subsystem */ 145848e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_DSP_CTRL, 145948e27874SAdam Thomson DA732X_DIGITAL_EN); 146048e27874SAdam Thomson 146148e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_SPARE1_OUT, 146248e27874SAdam Thomson DA732X_HP_DRIVER_EN | 146348e27874SAdam Thomson DA732X_HP_GATE_LOW | 146448e27874SAdam Thomson DA732X_HP_LOOP_GAIN_CTRL); 146548e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HP_LIN1_GNDSEL, 146648e27874SAdam Thomson DA732X_HP_OUT_GNDSEL); 146748e27874SAdam Thomson 146848e27874SAdam Thomson da732x_set_charge_pump(codec, DA732X_ENABLE_CP); 146948e27874SAdam Thomson 147048e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_CLK_EN1, 147148e27874SAdam Thomson DA732X_SYS3_CLK_EN | DA732X_PC_CLK_EN); 147248e27874SAdam Thomson 147348e27874SAdam Thomson /* Enable Zero Crossing */ 147448e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_INP_ZC_EN, 147548e27874SAdam Thomson DA732X_MIC1_PRE_ZC_EN | 147648e27874SAdam Thomson DA732X_MIC1_ZC_EN | 147748e27874SAdam Thomson DA732X_MIC2_PRE_ZC_EN | 147848e27874SAdam Thomson DA732X_MIC2_ZC_EN | 147948e27874SAdam Thomson DA732X_AUXL_ZC_EN | 148048e27874SAdam Thomson DA732X_AUXR_ZC_EN | 148148e27874SAdam Thomson DA732X_MIC3_PRE_ZC_EN | 148248e27874SAdam Thomson DA732X_MIC3_ZC_EN); 148348e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_OUT_ZC_EN, 148448e27874SAdam Thomson DA732X_HPL_ZC_EN | DA732X_HPR_ZC_EN | 148548e27874SAdam Thomson DA732X_LIN2_ZC_EN | DA732X_LIN3_ZC_EN | 148648e27874SAdam Thomson DA732X_LIN4_ZC_EN); 148748e27874SAdam Thomson 148848e27874SAdam Thomson da732x_hp_dc_offset_cancellation(codec); 148948e27874SAdam Thomson 149048e27874SAdam Thomson regcache_cache_only(codec->control_data, false); 149148e27874SAdam Thomson regcache_sync(codec->control_data); 149248e27874SAdam Thomson } else { 149348e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, 149448e27874SAdam Thomson DA732X_BIAS_BOOST_MASK, 149548e27874SAdam Thomson DA732X_BIAS_BOOST_50PC); 149648e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, 149748e27874SAdam Thomson DA732X_PLL_EN, 0); 149848e27874SAdam Thomson da732x->pll_en = false; 149948e27874SAdam Thomson } 150048e27874SAdam Thomson break; 150148e27874SAdam Thomson case SND_SOC_BIAS_OFF: 150248e27874SAdam Thomson regcache_cache_only(codec->control_data, true); 150348e27874SAdam Thomson da732x_set_charge_pump(codec, DA732X_DISABLE_CP); 150448e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, DA732X_BIAS_EN, 150548e27874SAdam Thomson DA732X_BIAS_DIS); 150648e27874SAdam Thomson da732x->pll_en = false; 150748e27874SAdam Thomson break; 150848e27874SAdam Thomson } 150948e27874SAdam Thomson 151048e27874SAdam Thomson codec->dapm.bias_level = level; 151148e27874SAdam Thomson 151248e27874SAdam Thomson return 0; 151348e27874SAdam Thomson } 151448e27874SAdam Thomson 151548e27874SAdam Thomson static int da732x_probe(struct snd_soc_codec *codec) 151648e27874SAdam Thomson { 151748e27874SAdam Thomson struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); 151848e27874SAdam Thomson struct snd_soc_dapm_context *dapm = &codec->dapm; 151948e27874SAdam Thomson int ret = 0; 152048e27874SAdam Thomson 152148e27874SAdam Thomson da732x->codec = codec; 152248e27874SAdam Thomson 152348e27874SAdam Thomson dapm->idle_bias_off = false; 152448e27874SAdam Thomson 152548e27874SAdam Thomson codec->control_data = da732x->regmap; 152648e27874SAdam Thomson 152748e27874SAdam Thomson ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); 152848e27874SAdam Thomson if (ret != 0) { 152948e27874SAdam Thomson dev_err(codec->dev, "Failed to register codec.\n"); 153048e27874SAdam Thomson goto err; 153148e27874SAdam Thomson } 153248e27874SAdam Thomson 153348e27874SAdam Thomson da732x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 153448e27874SAdam Thomson err: 153548e27874SAdam Thomson return ret; 153648e27874SAdam Thomson } 153748e27874SAdam Thomson 153848e27874SAdam Thomson static int da732x_remove(struct snd_soc_codec *codec) 153948e27874SAdam Thomson { 154048e27874SAdam Thomson 154148e27874SAdam Thomson da732x_set_bias_level(codec, SND_SOC_BIAS_OFF); 154248e27874SAdam Thomson 154348e27874SAdam Thomson return 0; 154448e27874SAdam Thomson } 154548e27874SAdam Thomson 1546b2a4ec3dSMark Brown static struct snd_soc_codec_driver soc_codec_dev_da732x = { 154748e27874SAdam Thomson .probe = da732x_probe, 154848e27874SAdam Thomson .remove = da732x_remove, 154948e27874SAdam Thomson .set_bias_level = da732x_set_bias_level, 155048e27874SAdam Thomson .controls = da732x_snd_controls, 155148e27874SAdam Thomson .num_controls = ARRAY_SIZE(da732x_snd_controls), 155248e27874SAdam Thomson .dapm_widgets = da732x_dapm_widgets, 155348e27874SAdam Thomson .num_dapm_widgets = ARRAY_SIZE(da732x_dapm_widgets), 155448e27874SAdam Thomson .dapm_routes = da732x_dapm_routes, 155548e27874SAdam Thomson .num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes), 155648e27874SAdam Thomson .set_pll = da732x_set_dai_pll, 155748e27874SAdam Thomson .reg_cache_size = ARRAY_SIZE(da732x_reg_cache), 155848e27874SAdam Thomson }; 155948e27874SAdam Thomson 15607a79e94eSBill Pemberton static int da732x_i2c_probe(struct i2c_client *i2c, 156148e27874SAdam Thomson const struct i2c_device_id *id) 156248e27874SAdam Thomson { 156348e27874SAdam Thomson struct da732x_priv *da732x; 156448e27874SAdam Thomson unsigned int reg; 156548e27874SAdam Thomson int ret; 156648e27874SAdam Thomson 156748e27874SAdam Thomson da732x = devm_kzalloc(&i2c->dev, sizeof(struct da732x_priv), 156848e27874SAdam Thomson GFP_KERNEL); 156948e27874SAdam Thomson if (!da732x) 157048e27874SAdam Thomson return -ENOMEM; 157148e27874SAdam Thomson 157248e27874SAdam Thomson i2c_set_clientdata(i2c, da732x); 157348e27874SAdam Thomson 157448e27874SAdam Thomson da732x->regmap = devm_regmap_init_i2c(i2c, &da732x_regmap); 157548e27874SAdam Thomson if (IS_ERR(da732x->regmap)) { 157648e27874SAdam Thomson ret = PTR_ERR(da732x->regmap); 157748e27874SAdam Thomson dev_err(&i2c->dev, "Failed to initialize regmap\n"); 157848e27874SAdam Thomson goto err; 157948e27874SAdam Thomson } 158048e27874SAdam Thomson 158148e27874SAdam Thomson ret = regmap_read(da732x->regmap, DA732X_REG_ID, ®); 158248e27874SAdam Thomson if (ret < 0) { 158348e27874SAdam Thomson dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret); 158448e27874SAdam Thomson goto err; 158548e27874SAdam Thomson } 158648e27874SAdam Thomson 158748e27874SAdam Thomson dev_info(&i2c->dev, "Revision: %d.%d\n", 158848e27874SAdam Thomson (reg & DA732X_ID_MAJOR_MASK), (reg & DA732X_ID_MINOR_MASK)); 158948e27874SAdam Thomson 159048e27874SAdam Thomson ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da732x, 159148e27874SAdam Thomson da732x_dai, ARRAY_SIZE(da732x_dai)); 159248e27874SAdam Thomson if (ret != 0) 159348e27874SAdam Thomson dev_err(&i2c->dev, "Failed to register codec.\n"); 159448e27874SAdam Thomson 159548e27874SAdam Thomson err: 159648e27874SAdam Thomson return ret; 159748e27874SAdam Thomson } 159848e27874SAdam Thomson 15997a79e94eSBill Pemberton static int da732x_i2c_remove(struct i2c_client *client) 160048e27874SAdam Thomson { 160148e27874SAdam Thomson snd_soc_unregister_codec(&client->dev); 160248e27874SAdam Thomson 160348e27874SAdam Thomson return 0; 160448e27874SAdam Thomson } 160548e27874SAdam Thomson 160648e27874SAdam Thomson static const struct i2c_device_id da732x_i2c_id[] = { 160748e27874SAdam Thomson { "da7320", 0}, 160848e27874SAdam Thomson { } 160948e27874SAdam Thomson }; 161048e27874SAdam Thomson MODULE_DEVICE_TABLE(i2c, da732x_i2c_id); 161148e27874SAdam Thomson 161248e27874SAdam Thomson static struct i2c_driver da732x_i2c_driver = { 161348e27874SAdam Thomson .driver = { 161448e27874SAdam Thomson .name = "da7320", 161548e27874SAdam Thomson .owner = THIS_MODULE, 161648e27874SAdam Thomson }, 161748e27874SAdam Thomson .probe = da732x_i2c_probe, 16187a79e94eSBill Pemberton .remove = da732x_i2c_remove, 161948e27874SAdam Thomson .id_table = da732x_i2c_id, 162048e27874SAdam Thomson }; 162148e27874SAdam Thomson 162248e27874SAdam Thomson module_i2c_driver(da732x_i2c_driver); 162348e27874SAdam Thomson 162448e27874SAdam Thomson 162548e27874SAdam Thomson MODULE_DESCRIPTION("ASoC DA732X driver"); 162648e27874SAdam Thomson MODULE_AUTHOR("Michal Hajduk <michal.hajduk@diasemi.com>"); 162748e27874SAdam Thomson MODULE_LICENSE("GPL"); 1628