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