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: 220*cd9241e4SMasanari Iida pr_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 2727e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_dac1_hpf_mode_enum, 2737e509108STakashi Iwai DA732X_REG_DAC1_HPF, DA732X_HPF_MODE_SHIFT, 2747e509108STakashi Iwai da732x_hpf_mode); 27548e27874SAdam Thomson 2767e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_dac2_hpf_mode_enum, 2777e509108STakashi Iwai DA732X_REG_DAC2_HPF, DA732X_HPF_MODE_SHIFT, 2787e509108STakashi Iwai da732x_hpf_mode); 27948e27874SAdam Thomson 2807e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_dac3_hpf_mode_enum, 2817e509108STakashi Iwai DA732X_REG_DAC3_HPF, DA732X_HPF_MODE_SHIFT, 2827e509108STakashi Iwai da732x_hpf_mode); 28348e27874SAdam Thomson 2847e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_adc1_hpf_mode_enum, 2857e509108STakashi Iwai DA732X_REG_ADC1_HPF, DA732X_HPF_MODE_SHIFT, 2867e509108STakashi Iwai da732x_hpf_mode); 28748e27874SAdam Thomson 2887e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_adc2_hpf_mode_enum, 2897e509108STakashi Iwai DA732X_REG_ADC2_HPF, DA732X_HPF_MODE_SHIFT, 2907e509108STakashi Iwai da732x_hpf_mode); 29148e27874SAdam Thomson 2927e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_dac1_hp_filter_enum, 2937e509108STakashi Iwai DA732X_REG_DAC1_HPF, DA732X_HPF_MUSIC_SHIFT, 2947e509108STakashi Iwai da732x_hpf_music); 29548e27874SAdam Thomson 2967e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_dac2_hp_filter_enum, 2977e509108STakashi Iwai DA732X_REG_DAC2_HPF, DA732X_HPF_MUSIC_SHIFT, 2987e509108STakashi Iwai da732x_hpf_music); 29948e27874SAdam Thomson 3007e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_dac3_hp_filter_enum, 3017e509108STakashi Iwai DA732X_REG_DAC3_HPF, DA732X_HPF_MUSIC_SHIFT, 3027e509108STakashi Iwai da732x_hpf_music); 30348e27874SAdam Thomson 3047e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_adc1_hp_filter_enum, 3057e509108STakashi Iwai DA732X_REG_ADC1_HPF, DA732X_HPF_MUSIC_SHIFT, 3067e509108STakashi Iwai da732x_hpf_music); 30748e27874SAdam Thomson 3087e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_adc2_hp_filter_enum, 3097e509108STakashi Iwai DA732X_REG_ADC2_HPF, DA732X_HPF_MUSIC_SHIFT, 3107e509108STakashi Iwai da732x_hpf_music); 31148e27874SAdam Thomson 3127e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_dac1_voice_filter_enum, 3137e509108STakashi Iwai DA732X_REG_DAC1_HPF, DA732X_HPF_VOICE_SHIFT, 3147e509108STakashi Iwai da732x_hpf_voice); 31548e27874SAdam Thomson 3167e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_dac2_voice_filter_enum, 3177e509108STakashi Iwai DA732X_REG_DAC2_HPF, DA732X_HPF_VOICE_SHIFT, 3187e509108STakashi Iwai da732x_hpf_voice); 31948e27874SAdam Thomson 3207e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_dac3_voice_filter_enum, 3217e509108STakashi Iwai DA732X_REG_DAC3_HPF, DA732X_HPF_VOICE_SHIFT, 3227e509108STakashi Iwai da732x_hpf_voice); 32348e27874SAdam Thomson 3247e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_adc1_voice_filter_enum, 3257e509108STakashi Iwai DA732X_REG_ADC1_HPF, DA732X_HPF_VOICE_SHIFT, 3267e509108STakashi Iwai da732x_hpf_voice); 32748e27874SAdam Thomson 3287e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_adc2_voice_filter_enum, 3297e509108STakashi Iwai DA732X_REG_ADC2_HPF, DA732X_HPF_VOICE_SHIFT, 3307e509108STakashi Iwai da732x_hpf_voice); 33148e27874SAdam Thomson 33248e27874SAdam Thomson static int da732x_hpf_set(struct snd_kcontrol *kcontrol, 33348e27874SAdam Thomson struct snd_ctl_elem_value *ucontrol) 33448e27874SAdam Thomson { 335ea53bf77SLars-Peter Clausen struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 33648e27874SAdam Thomson struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value; 33748e27874SAdam Thomson unsigned int reg = enum_ctrl->reg; 33848e27874SAdam Thomson unsigned int sel = ucontrol->value.integer.value[0]; 33948e27874SAdam Thomson unsigned int bits; 34048e27874SAdam Thomson 34148e27874SAdam Thomson switch (sel) { 34248e27874SAdam Thomson case DA732X_HPF_DISABLED: 34348e27874SAdam Thomson bits = DA732X_HPF_DIS; 34448e27874SAdam Thomson break; 34548e27874SAdam Thomson case DA732X_HPF_VOICE: 34648e27874SAdam Thomson bits = DA732X_HPF_VOICE_EN; 34748e27874SAdam Thomson break; 34848e27874SAdam Thomson case DA732X_HPF_MUSIC: 34948e27874SAdam Thomson bits = DA732X_HPF_MUSIC_EN; 35048e27874SAdam Thomson break; 35148e27874SAdam Thomson default: 35248e27874SAdam Thomson return -EINVAL; 35348e27874SAdam Thomson } 35448e27874SAdam Thomson 35548e27874SAdam Thomson snd_soc_update_bits(codec, reg, DA732X_HPF_MASK, bits); 35648e27874SAdam Thomson 35748e27874SAdam Thomson return 0; 35848e27874SAdam Thomson } 35948e27874SAdam Thomson 36048e27874SAdam Thomson static int da732x_hpf_get(struct snd_kcontrol *kcontrol, 36148e27874SAdam Thomson struct snd_ctl_elem_value *ucontrol) 36248e27874SAdam Thomson { 363ea53bf77SLars-Peter Clausen struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 36448e27874SAdam Thomson struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value; 36548e27874SAdam Thomson unsigned int reg = enum_ctrl->reg; 36648e27874SAdam Thomson int val; 36748e27874SAdam Thomson 36848e27874SAdam Thomson val = snd_soc_read(codec, reg) & DA732X_HPF_MASK; 36948e27874SAdam Thomson 37048e27874SAdam Thomson switch (val) { 37148e27874SAdam Thomson case DA732X_HPF_VOICE_EN: 37248e27874SAdam Thomson ucontrol->value.integer.value[0] = DA732X_HPF_VOICE; 37348e27874SAdam Thomson break; 37448e27874SAdam Thomson case DA732X_HPF_MUSIC_EN: 37548e27874SAdam Thomson ucontrol->value.integer.value[0] = DA732X_HPF_MUSIC; 37648e27874SAdam Thomson break; 37748e27874SAdam Thomson default: 37848e27874SAdam Thomson ucontrol->value.integer.value[0] = DA732X_HPF_DISABLED; 37948e27874SAdam Thomson break; 38048e27874SAdam Thomson } 38148e27874SAdam Thomson 38248e27874SAdam Thomson return 0; 38348e27874SAdam Thomson } 38448e27874SAdam Thomson 38548e27874SAdam Thomson static const struct snd_kcontrol_new da732x_snd_controls[] = { 38648e27874SAdam Thomson /* Input PGAs */ 38748e27874SAdam Thomson SOC_SINGLE_RANGE_TLV("MIC1 Boost Volume", DA732X_REG_MIC1_PRE, 38848e27874SAdam Thomson DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN, 38948e27874SAdam Thomson DA732X_MICBOOST_MAX, 0, mic_boost_tlv), 39048e27874SAdam Thomson SOC_SINGLE_RANGE_TLV("MIC2 Boost Volume", DA732X_REG_MIC2_PRE, 39148e27874SAdam Thomson DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN, 39248e27874SAdam Thomson DA732X_MICBOOST_MAX, 0, mic_boost_tlv), 39348e27874SAdam Thomson SOC_SINGLE_RANGE_TLV("MIC3 Boost Volume", DA732X_REG_MIC3_PRE, 39448e27874SAdam Thomson DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN, 39548e27874SAdam Thomson DA732X_MICBOOST_MAX, 0, mic_boost_tlv), 39648e27874SAdam Thomson 39748e27874SAdam Thomson /* MICs */ 39848e27874SAdam Thomson SOC_SINGLE("MIC1 Switch", DA732X_REG_MIC1, DA732X_MIC_MUTE_SHIFT, 39948e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 40048e27874SAdam Thomson SOC_SINGLE_RANGE_TLV("MIC1 Volume", DA732X_REG_MIC1, 40148e27874SAdam Thomson DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN, 40248e27874SAdam Thomson DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv), 40348e27874SAdam Thomson SOC_SINGLE("MIC2 Switch", DA732X_REG_MIC2, DA732X_MIC_MUTE_SHIFT, 40448e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 40548e27874SAdam Thomson SOC_SINGLE_RANGE_TLV("MIC2 Volume", DA732X_REG_MIC2, 40648e27874SAdam Thomson DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN, 40748e27874SAdam Thomson DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv), 40848e27874SAdam Thomson SOC_SINGLE("MIC3 Switch", DA732X_REG_MIC3, DA732X_MIC_MUTE_SHIFT, 40948e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 41048e27874SAdam Thomson SOC_SINGLE_RANGE_TLV("MIC3 Volume", DA732X_REG_MIC3, 41148e27874SAdam Thomson DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN, 41248e27874SAdam Thomson DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv), 41348e27874SAdam Thomson 41448e27874SAdam Thomson /* AUXs */ 41548e27874SAdam Thomson SOC_SINGLE("AUX1L Switch", DA732X_REG_AUX1L, DA732X_AUX_MUTE_SHIFT, 41648e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 41748e27874SAdam Thomson SOC_SINGLE_TLV("AUX1L Volume", DA732X_REG_AUX1L, 41848e27874SAdam Thomson DA732X_AUX_VOL_SHIFT, DA732X_AUX_VOL_VAL_MAX, 41948e27874SAdam Thomson DA732X_NO_INVERT, aux_pga_tlv), 42048e27874SAdam Thomson SOC_SINGLE("AUX1R Switch", DA732X_REG_AUX1R, DA732X_AUX_MUTE_SHIFT, 42148e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 42248e27874SAdam Thomson SOC_SINGLE_TLV("AUX1R Volume", DA732X_REG_AUX1R, 42348e27874SAdam Thomson DA732X_AUX_VOL_SHIFT, DA732X_AUX_VOL_VAL_MAX, 42448e27874SAdam Thomson DA732X_NO_INVERT, aux_pga_tlv), 42548e27874SAdam Thomson 42648e27874SAdam Thomson /* ADCs */ 42748e27874SAdam Thomson SOC_DOUBLE_TLV("ADC1 Volume", DA732X_REG_ADC1_SEL, 42848e27874SAdam Thomson DA732X_ADCL_VOL_SHIFT, DA732X_ADCR_VOL_SHIFT, 42948e27874SAdam Thomson DA732X_ADC_VOL_VAL_MAX, DA732X_INVERT, adc_pga_tlv), 43048e27874SAdam Thomson 43148e27874SAdam Thomson SOC_DOUBLE_TLV("ADC2 Volume", DA732X_REG_ADC2_SEL, 43248e27874SAdam Thomson DA732X_ADCL_VOL_SHIFT, DA732X_ADCR_VOL_SHIFT, 43348e27874SAdam Thomson DA732X_ADC_VOL_VAL_MAX, DA732X_INVERT, adc_pga_tlv), 43448e27874SAdam Thomson 43548e27874SAdam Thomson /* DACs */ 43648e27874SAdam Thomson SOC_DOUBLE("Digital Playback DAC12 Switch", DA732X_REG_DAC1_SEL, 43748e27874SAdam Thomson DA732X_DACL_MUTE_SHIFT, DA732X_DACR_MUTE_SHIFT, 43848e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 43948e27874SAdam Thomson SOC_DOUBLE_R_TLV("Digital Playback DAC12 Volume", DA732X_REG_DAC1_L_VOL, 44048e27874SAdam Thomson DA732X_REG_DAC1_R_VOL, DA732X_DAC_VOL_SHIFT, 44148e27874SAdam Thomson DA732X_DAC_VOL_VAL_MAX, DA732X_INVERT, dac_pga_tlv), 44248e27874SAdam Thomson SOC_SINGLE("Digital Playback DAC3 Switch", DA732X_REG_DAC2_SEL, 44348e27874SAdam Thomson DA732X_DACL_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), 44448e27874SAdam Thomson SOC_SINGLE_TLV("Digital Playback DAC3 Volume", DA732X_REG_DAC2_L_VOL, 44548e27874SAdam Thomson DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX, 44648e27874SAdam Thomson DA732X_INVERT, dac_pga_tlv), 44748e27874SAdam Thomson SOC_SINGLE("Digital Playback DAC4 Switch", DA732X_REG_DAC2_SEL, 44848e27874SAdam Thomson DA732X_DACR_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), 44948e27874SAdam Thomson SOC_SINGLE_TLV("Digital Playback DAC4 Volume", DA732X_REG_DAC2_R_VOL, 45048e27874SAdam Thomson DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX, 45148e27874SAdam Thomson DA732X_INVERT, dac_pga_tlv), 45248e27874SAdam Thomson SOC_SINGLE("Digital Playback DAC5 Switch", DA732X_REG_DAC3_SEL, 45348e27874SAdam Thomson DA732X_DACL_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), 45448e27874SAdam Thomson SOC_SINGLE_TLV("Digital Playback DAC5 Volume", DA732X_REG_DAC3_VOL, 45548e27874SAdam Thomson DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX, 45648e27874SAdam Thomson DA732X_INVERT, dac_pga_tlv), 45748e27874SAdam Thomson 45848e27874SAdam Thomson /* High Pass Filters */ 45948e27874SAdam Thomson SOC_ENUM_EXT("DAC1 High Pass Filter Mode", 46048e27874SAdam Thomson da732x_dac1_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), 46148e27874SAdam Thomson SOC_ENUM("DAC1 High Pass Filter", da732x_dac1_hp_filter_enum), 46248e27874SAdam Thomson SOC_ENUM("DAC1 Voice Filter", da732x_dac1_voice_filter_enum), 46348e27874SAdam Thomson 46448e27874SAdam Thomson SOC_ENUM_EXT("DAC2 High Pass Filter Mode", 46548e27874SAdam Thomson da732x_dac2_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), 46648e27874SAdam Thomson SOC_ENUM("DAC2 High Pass Filter", da732x_dac2_hp_filter_enum), 46748e27874SAdam Thomson SOC_ENUM("DAC2 Voice Filter", da732x_dac2_voice_filter_enum), 46848e27874SAdam Thomson 46948e27874SAdam Thomson SOC_ENUM_EXT("DAC3 High Pass Filter Mode", 47048e27874SAdam Thomson da732x_dac3_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), 47148e27874SAdam Thomson SOC_ENUM("DAC3 High Pass Filter", da732x_dac3_hp_filter_enum), 47248e27874SAdam Thomson SOC_ENUM("DAC3 Filter Mode", da732x_dac3_voice_filter_enum), 47348e27874SAdam Thomson 47448e27874SAdam Thomson SOC_ENUM_EXT("ADC1 High Pass Filter Mode", 47548e27874SAdam Thomson da732x_adc1_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), 47648e27874SAdam Thomson SOC_ENUM("ADC1 High Pass Filter", da732x_adc1_hp_filter_enum), 47748e27874SAdam Thomson SOC_ENUM("ADC1 Voice Filter", da732x_adc1_voice_filter_enum), 47848e27874SAdam Thomson 47948e27874SAdam Thomson SOC_ENUM_EXT("ADC2 High Pass Filter Mode", 48048e27874SAdam Thomson da732x_adc2_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), 48148e27874SAdam Thomson SOC_ENUM("ADC2 High Pass Filter", da732x_adc2_hp_filter_enum), 48248e27874SAdam Thomson SOC_ENUM("ADC2 Voice Filter", da732x_adc2_voice_filter_enum), 48348e27874SAdam Thomson 48448e27874SAdam Thomson /* Equalizers */ 48548e27874SAdam Thomson SOC_SINGLE("ADC1 EQ Switch", DA732X_REG_ADC1_EQ5, 48648e27874SAdam Thomson DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), 48748e27874SAdam Thomson SOC_SINGLE_TLV("ADC1 EQ Band 1 Volume", DA732X_REG_ADC1_EQ12, 48848e27874SAdam Thomson DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, 48948e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 49048e27874SAdam Thomson SOC_SINGLE_TLV("ADC1 EQ Band 2 Volume", DA732X_REG_ADC1_EQ12, 49148e27874SAdam Thomson DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, 49248e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 49348e27874SAdam Thomson SOC_SINGLE_TLV("ADC1 EQ Band 3 Volume", DA732X_REG_ADC1_EQ34, 49448e27874SAdam Thomson DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, 49548e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 49648e27874SAdam Thomson SOC_SINGLE_TLV("ADC1 EQ Band 4 Volume", DA732X_REG_ADC1_EQ34, 49748e27874SAdam Thomson DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, 49848e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 49948e27874SAdam Thomson SOC_SINGLE_TLV("ADC1 EQ Band 5 Volume", DA732X_REG_ADC1_EQ5, 50048e27874SAdam Thomson DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, 50148e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 50248e27874SAdam Thomson SOC_SINGLE_TLV("ADC1 EQ Overall Volume", DA732X_REG_ADC1_EQ5, 50348e27874SAdam Thomson DA732X_EQ_OVERALL_SHIFT, DA732X_EQ_OVERALL_VOL_VAL_MAX, 50448e27874SAdam Thomson DA732X_INVERT, eq_overall_tlv), 50548e27874SAdam Thomson 50648e27874SAdam Thomson SOC_SINGLE("ADC2 EQ Switch", DA732X_REG_ADC2_EQ5, 50748e27874SAdam Thomson DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), 50848e27874SAdam Thomson SOC_SINGLE_TLV("ADC2 EQ Band 1 Volume", DA732X_REG_ADC2_EQ12, 50948e27874SAdam Thomson DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, 51048e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 51148e27874SAdam Thomson SOC_SINGLE_TLV("ADC2 EQ Band 2 Volume", DA732X_REG_ADC2_EQ12, 51248e27874SAdam Thomson DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, 51348e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 51448e27874SAdam Thomson SOC_SINGLE_TLV("ADC2 EQ Band 3 Volume", DA732X_REG_ADC2_EQ34, 51548e27874SAdam Thomson DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, 51648e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 51748e27874SAdam Thomson SOC_SINGLE_TLV("ACD2 EQ Band 4 Volume", DA732X_REG_ADC2_EQ34, 51848e27874SAdam Thomson DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, 51948e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 52048e27874SAdam Thomson SOC_SINGLE_TLV("ACD2 EQ Band 5 Volume", DA732X_REG_ADC2_EQ5, 52148e27874SAdam Thomson DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, 52248e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 52348e27874SAdam Thomson SOC_SINGLE_TLV("ADC2 EQ Overall Volume", DA732X_REG_ADC1_EQ5, 52448e27874SAdam Thomson DA732X_EQ_OVERALL_SHIFT, DA732X_EQ_OVERALL_VOL_VAL_MAX, 52548e27874SAdam Thomson DA732X_INVERT, eq_overall_tlv), 52648e27874SAdam Thomson 52748e27874SAdam Thomson SOC_SINGLE("DAC1 EQ Switch", DA732X_REG_DAC1_EQ5, 52848e27874SAdam Thomson DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), 52948e27874SAdam Thomson SOC_SINGLE_TLV("DAC1 EQ Band 1 Volume", DA732X_REG_DAC1_EQ12, 53048e27874SAdam Thomson DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, 53148e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 53248e27874SAdam Thomson SOC_SINGLE_TLV("DAC1 EQ Band 2 Volume", DA732X_REG_DAC1_EQ12, 53348e27874SAdam Thomson DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, 53448e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 53548e27874SAdam Thomson SOC_SINGLE_TLV("DAC1 EQ Band 3 Volume", DA732X_REG_DAC1_EQ34, 53648e27874SAdam Thomson DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, 53748e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 53848e27874SAdam Thomson SOC_SINGLE_TLV("DAC1 EQ Band 4 Volume", DA732X_REG_DAC1_EQ34, 53948e27874SAdam Thomson DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, 54048e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 54148e27874SAdam Thomson SOC_SINGLE_TLV("DAC1 EQ Band 5 Volume", DA732X_REG_DAC1_EQ5, 54248e27874SAdam Thomson DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, 54348e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 54448e27874SAdam Thomson 54548e27874SAdam Thomson SOC_SINGLE("DAC2 EQ Switch", DA732X_REG_DAC2_EQ5, 54648e27874SAdam Thomson DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), 54748e27874SAdam Thomson SOC_SINGLE_TLV("DAC2 EQ Band 1 Volume", DA732X_REG_DAC2_EQ12, 54848e27874SAdam Thomson DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, 54948e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 55048e27874SAdam Thomson SOC_SINGLE_TLV("DAC2 EQ Band 2 Volume", DA732X_REG_DAC2_EQ12, 55148e27874SAdam Thomson DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, 55248e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 55348e27874SAdam Thomson SOC_SINGLE_TLV("DAC2 EQ Band 3 Volume", DA732X_REG_DAC2_EQ34, 55448e27874SAdam Thomson DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, 55548e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 55648e27874SAdam Thomson SOC_SINGLE_TLV("DAC2 EQ Band 4 Volume", DA732X_REG_DAC2_EQ34, 55748e27874SAdam Thomson DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, 55848e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 55948e27874SAdam Thomson SOC_SINGLE_TLV("DAC2 EQ Band 5 Volume", DA732X_REG_DAC2_EQ5, 56048e27874SAdam Thomson DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, 56148e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 56248e27874SAdam Thomson 56348e27874SAdam Thomson SOC_SINGLE("DAC3 EQ Switch", DA732X_REG_DAC3_EQ5, 56448e27874SAdam Thomson DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), 56548e27874SAdam Thomson SOC_SINGLE_TLV("DAC3 EQ Band 1 Volume", DA732X_REG_DAC3_EQ12, 56648e27874SAdam Thomson DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, 56748e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 56848e27874SAdam Thomson SOC_SINGLE_TLV("DAC3 EQ Band 2 Volume", DA732X_REG_DAC3_EQ12, 56948e27874SAdam Thomson DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, 57048e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 57148e27874SAdam Thomson SOC_SINGLE_TLV("DAC3 EQ Band 3 Volume", DA732X_REG_DAC3_EQ34, 57248e27874SAdam Thomson DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, 57348e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 57448e27874SAdam Thomson SOC_SINGLE_TLV("DAC3 EQ Band 4 Volume", DA732X_REG_DAC3_EQ34, 57548e27874SAdam Thomson DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, 57648e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 57748e27874SAdam Thomson SOC_SINGLE_TLV("DAC3 EQ Band 5 Volume", DA732X_REG_DAC3_EQ5, 57848e27874SAdam Thomson DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, 57948e27874SAdam Thomson DA732X_INVERT, eq_band_pga_tlv), 58048e27874SAdam Thomson 58148e27874SAdam Thomson /* Lineout 2 Reciever*/ 58248e27874SAdam Thomson SOC_SINGLE("Lineout 2 Switch", DA732X_REG_LIN2, DA732X_LOUT_MUTE_SHIFT, 58348e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 58448e27874SAdam Thomson SOC_SINGLE_TLV("Lineout 2 Volume", DA732X_REG_LIN2, 58548e27874SAdam Thomson DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX, 58648e27874SAdam Thomson DA732X_NO_INVERT, lin2_pga_tlv), 58748e27874SAdam Thomson 58848e27874SAdam Thomson /* Lineout 3 SPEAKER*/ 58948e27874SAdam Thomson SOC_SINGLE("Lineout 3 Switch", DA732X_REG_LIN3, DA732X_LOUT_MUTE_SHIFT, 59048e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 59148e27874SAdam Thomson SOC_SINGLE_TLV("Lineout 3 Volume", DA732X_REG_LIN3, 59248e27874SAdam Thomson DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX, 59348e27874SAdam Thomson DA732X_NO_INVERT, lin3_pga_tlv), 59448e27874SAdam Thomson 59548e27874SAdam Thomson /* Lineout 4 */ 59648e27874SAdam Thomson SOC_SINGLE("Lineout 4 Switch", DA732X_REG_LIN4, DA732X_LOUT_MUTE_SHIFT, 59748e27874SAdam Thomson DA732X_SWITCH_MAX, DA732X_INVERT), 59848e27874SAdam Thomson SOC_SINGLE_TLV("Lineout 4 Volume", DA732X_REG_LIN4, 59948e27874SAdam Thomson DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX, 60048e27874SAdam Thomson DA732X_NO_INVERT, lin4_pga_tlv), 60148e27874SAdam Thomson 60248e27874SAdam Thomson /* Headphones */ 60348e27874SAdam Thomson SOC_DOUBLE_R("Headphone Switch", DA732X_REG_HPR, DA732X_REG_HPL, 60448e27874SAdam Thomson DA732X_HP_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), 60548e27874SAdam Thomson SOC_DOUBLE_R_TLV("Headphone Volume", DA732X_REG_HPL_VOL, 60648e27874SAdam Thomson DA732X_REG_HPR_VOL, DA732X_HP_VOL_SHIFT, 60748e27874SAdam Thomson DA732X_HP_VOL_VAL_MAX, DA732X_NO_INVERT, hp_pga_tlv), 60848e27874SAdam Thomson }; 60948e27874SAdam Thomson 61048e27874SAdam Thomson static int da732x_adc_event(struct snd_soc_dapm_widget *w, 61148e27874SAdam Thomson struct snd_kcontrol *kcontrol, int event) 61248e27874SAdam Thomson { 61348e27874SAdam Thomson struct snd_soc_codec *codec = w->codec; 61448e27874SAdam Thomson 61548e27874SAdam Thomson switch (event) { 61648e27874SAdam Thomson case SND_SOC_DAPM_POST_PMU: 61748e27874SAdam Thomson switch (w->reg) { 61848e27874SAdam Thomson case DA732X_REG_ADC1_PD: 61948e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, 62048e27874SAdam Thomson DA732X_ADCA_BB_CLK_EN, 62148e27874SAdam Thomson DA732X_ADCA_BB_CLK_EN); 62248e27874SAdam Thomson break; 62348e27874SAdam Thomson case DA732X_REG_ADC2_PD: 62448e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, 62548e27874SAdam Thomson DA732X_ADCC_BB_CLK_EN, 62648e27874SAdam Thomson DA732X_ADCC_BB_CLK_EN); 62748e27874SAdam Thomson break; 62848e27874SAdam Thomson default: 62948e27874SAdam Thomson return -EINVAL; 63048e27874SAdam Thomson } 63148e27874SAdam Thomson 63248e27874SAdam Thomson snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK, 63348e27874SAdam Thomson DA732X_ADC_SET_ACT); 63448e27874SAdam Thomson snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK, 63548e27874SAdam Thomson DA732X_ADC_ON); 63648e27874SAdam Thomson break; 63748e27874SAdam Thomson case SND_SOC_DAPM_POST_PMD: 63848e27874SAdam Thomson snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK, 63948e27874SAdam Thomson DA732X_ADC_OFF); 64048e27874SAdam Thomson snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK, 64148e27874SAdam Thomson DA732X_ADC_SET_RST); 64248e27874SAdam Thomson 64348e27874SAdam Thomson switch (w->reg) { 64448e27874SAdam Thomson case DA732X_REG_ADC1_PD: 64548e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, 64648e27874SAdam Thomson DA732X_ADCA_BB_CLK_EN, 0); 64748e27874SAdam Thomson break; 64848e27874SAdam Thomson case DA732X_REG_ADC2_PD: 64948e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, 65048e27874SAdam Thomson DA732X_ADCC_BB_CLK_EN, 0); 65148e27874SAdam Thomson break; 65248e27874SAdam Thomson default: 65348e27874SAdam Thomson return -EINVAL; 65448e27874SAdam Thomson } 65548e27874SAdam Thomson 65648e27874SAdam Thomson break; 65748e27874SAdam Thomson default: 65848e27874SAdam Thomson return -EINVAL; 65948e27874SAdam Thomson } 66048e27874SAdam Thomson 66148e27874SAdam Thomson return 0; 66248e27874SAdam Thomson } 66348e27874SAdam Thomson 66448e27874SAdam Thomson static int da732x_out_pga_event(struct snd_soc_dapm_widget *w, 66548e27874SAdam Thomson struct snd_kcontrol *kcontrol, int event) 66648e27874SAdam Thomson { 66748e27874SAdam Thomson struct snd_soc_codec *codec = w->codec; 66848e27874SAdam Thomson 66948e27874SAdam Thomson switch (event) { 67048e27874SAdam Thomson case SND_SOC_DAPM_POST_PMU: 67148e27874SAdam Thomson snd_soc_update_bits(codec, w->reg, 67248e27874SAdam Thomson (1 << w->shift) | DA732X_OUT_HIZ_EN, 67348e27874SAdam Thomson (1 << w->shift) | DA732X_OUT_HIZ_EN); 67448e27874SAdam Thomson break; 67548e27874SAdam Thomson case SND_SOC_DAPM_POST_PMD: 67648e27874SAdam Thomson snd_soc_update_bits(codec, w->reg, 67748e27874SAdam Thomson (1 << w->shift) | DA732X_OUT_HIZ_EN, 67848e27874SAdam Thomson (1 << w->shift) | DA732X_OUT_HIZ_DIS); 67948e27874SAdam Thomson break; 68048e27874SAdam Thomson default: 68148e27874SAdam Thomson return -EINVAL; 68248e27874SAdam Thomson } 68348e27874SAdam Thomson 68448e27874SAdam Thomson return 0; 68548e27874SAdam Thomson } 68648e27874SAdam Thomson 68748e27874SAdam Thomson static const char *adcl_text[] = { 68848e27874SAdam Thomson "AUX1L", "MIC1" 68948e27874SAdam Thomson }; 69048e27874SAdam Thomson 69148e27874SAdam Thomson static const char *adcr_text[] = { 69248e27874SAdam Thomson "AUX1R", "MIC2", "MIC3" 69348e27874SAdam Thomson }; 69448e27874SAdam Thomson 69548e27874SAdam Thomson static const char *enable_text[] = { 69648e27874SAdam Thomson "Disabled", 69748e27874SAdam Thomson "Enabled" 69848e27874SAdam Thomson }; 69948e27874SAdam Thomson 70048e27874SAdam Thomson /* ADC1LMUX */ 7017e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(adc1l_enum, 7027e509108STakashi Iwai DA732X_REG_INP_MUX, DA732X_ADC1L_MUX_SEL_SHIFT, 7037e509108STakashi Iwai adcl_text); 70448e27874SAdam Thomson static const struct snd_kcontrol_new adc1l_mux = 70548e27874SAdam Thomson SOC_DAPM_ENUM("ADC Route", adc1l_enum); 70648e27874SAdam Thomson 70748e27874SAdam Thomson /* ADC1RMUX */ 7087e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(adc1r_enum, 7097e509108STakashi Iwai DA732X_REG_INP_MUX, DA732X_ADC1R_MUX_SEL_SHIFT, 7107e509108STakashi Iwai adcr_text); 71148e27874SAdam Thomson static const struct snd_kcontrol_new adc1r_mux = 71248e27874SAdam Thomson SOC_DAPM_ENUM("ADC Route", adc1r_enum); 71348e27874SAdam Thomson 71448e27874SAdam Thomson /* ADC2LMUX */ 7157e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(adc2l_enum, 7167e509108STakashi Iwai DA732X_REG_INP_MUX, DA732X_ADC2L_MUX_SEL_SHIFT, 7177e509108STakashi Iwai adcl_text); 71848e27874SAdam Thomson static const struct snd_kcontrol_new adc2l_mux = 71948e27874SAdam Thomson SOC_DAPM_ENUM("ADC Route", adc2l_enum); 72048e27874SAdam Thomson 72148e27874SAdam Thomson /* ADC2RMUX */ 7227e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(adc2r_enum, 7237e509108STakashi Iwai DA732X_REG_INP_MUX, DA732X_ADC2R_MUX_SEL_SHIFT, 7247e509108STakashi Iwai adcr_text); 72548e27874SAdam Thomson 72648e27874SAdam Thomson static const struct snd_kcontrol_new adc2r_mux = 72748e27874SAdam Thomson SOC_DAPM_ENUM("ADC Route", adc2r_enum); 72848e27874SAdam Thomson 7297e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_hp_left_output, 7307e509108STakashi Iwai DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN_SHIFT, 7317e509108STakashi Iwai enable_text); 73248e27874SAdam Thomson 73348e27874SAdam Thomson static const struct snd_kcontrol_new hpl_mux = 73448e27874SAdam Thomson SOC_DAPM_ENUM("HPL Switch", da732x_hp_left_output); 73548e27874SAdam Thomson 7367e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_hp_right_output, 7377e509108STakashi Iwai DA732X_REG_HPR, DA732X_HP_OUT_DAC_EN_SHIFT, 7387e509108STakashi Iwai enable_text); 73948e27874SAdam Thomson 74048e27874SAdam Thomson static const struct snd_kcontrol_new hpr_mux = 74148e27874SAdam Thomson SOC_DAPM_ENUM("HPR Switch", da732x_hp_right_output); 74248e27874SAdam Thomson 7437e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_speaker_output, 7447e509108STakashi Iwai DA732X_REG_LIN3, DA732X_LOUT_DAC_EN_SHIFT, 7457e509108STakashi Iwai enable_text); 74648e27874SAdam Thomson 74748e27874SAdam Thomson static const struct snd_kcontrol_new spk_mux = 74848e27874SAdam Thomson SOC_DAPM_ENUM("SPK Switch", da732x_speaker_output); 74948e27874SAdam Thomson 7507e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_lout4_output, 7517e509108STakashi Iwai DA732X_REG_LIN4, DA732X_LOUT_DAC_EN_SHIFT, 7527e509108STakashi Iwai enable_text); 75348e27874SAdam Thomson 75448e27874SAdam Thomson static const struct snd_kcontrol_new lout4_mux = 75548e27874SAdam Thomson SOC_DAPM_ENUM("LOUT4 Switch", da732x_lout4_output); 75648e27874SAdam Thomson 7577e509108STakashi Iwai static SOC_ENUM_SINGLE_DECL(da732x_lout2_output, 7587e509108STakashi Iwai DA732X_REG_LIN2, DA732X_LOUT_DAC_EN_SHIFT, 7597e509108STakashi Iwai enable_text); 76048e27874SAdam Thomson 76148e27874SAdam Thomson static const struct snd_kcontrol_new lout2_mux = 76248e27874SAdam Thomson SOC_DAPM_ENUM("LOUT2 Switch", da732x_lout2_output); 76348e27874SAdam Thomson 76448e27874SAdam Thomson static const struct snd_soc_dapm_widget da732x_dapm_widgets[] = { 76548e27874SAdam Thomson /* Supplies */ 76648e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("ADC1 Supply", DA732X_REG_ADC1_PD, 0, 76748e27874SAdam Thomson DA732X_NO_INVERT, da732x_adc_event, 76848e27874SAdam Thomson SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 76948e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("ADC2 Supply", DA732X_REG_ADC2_PD, 0, 77048e27874SAdam Thomson DA732X_NO_INVERT, da732x_adc_event, 77148e27874SAdam Thomson SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 77248e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("DAC1 CLK", DA732X_REG_CLK_EN4, 77348e27874SAdam Thomson DA732X_DACA_BB_CLK_SHIFT, DA732X_NO_INVERT, 77448e27874SAdam Thomson NULL, 0), 77548e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("DAC2 CLK", DA732X_REG_CLK_EN4, 77648e27874SAdam Thomson DA732X_DACC_BB_CLK_SHIFT, DA732X_NO_INVERT, 77748e27874SAdam Thomson NULL, 0), 77848e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("DAC3 CLK", DA732X_REG_CLK_EN5, 77948e27874SAdam Thomson DA732X_DACE_BB_CLK_SHIFT, DA732X_NO_INVERT, 78048e27874SAdam Thomson NULL, 0), 78148e27874SAdam Thomson 78248e27874SAdam Thomson /* Micbias */ 78348e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("MICBIAS1", DA732X_REG_MICBIAS1, 78448e27874SAdam Thomson DA732X_MICBIAS_EN_SHIFT, 78548e27874SAdam Thomson DA732X_NO_INVERT, NULL, 0), 78648e27874SAdam Thomson SND_SOC_DAPM_SUPPLY("MICBIAS2", DA732X_REG_MICBIAS2, 78748e27874SAdam Thomson DA732X_MICBIAS_EN_SHIFT, 78848e27874SAdam Thomson DA732X_NO_INVERT, NULL, 0), 78948e27874SAdam Thomson 79048e27874SAdam Thomson /* Inputs */ 79148e27874SAdam Thomson SND_SOC_DAPM_INPUT("MIC1"), 79248e27874SAdam Thomson SND_SOC_DAPM_INPUT("MIC2"), 79348e27874SAdam Thomson SND_SOC_DAPM_INPUT("MIC3"), 79448e27874SAdam Thomson SND_SOC_DAPM_INPUT("AUX1L"), 79548e27874SAdam Thomson SND_SOC_DAPM_INPUT("AUX1R"), 79648e27874SAdam Thomson 79748e27874SAdam Thomson /* Outputs */ 79848e27874SAdam Thomson SND_SOC_DAPM_OUTPUT("HPL"), 79948e27874SAdam Thomson SND_SOC_DAPM_OUTPUT("HPR"), 80048e27874SAdam Thomson SND_SOC_DAPM_OUTPUT("LOUTL"), 80148e27874SAdam Thomson SND_SOC_DAPM_OUTPUT("LOUTR"), 80248e27874SAdam Thomson SND_SOC_DAPM_OUTPUT("ClassD"), 80348e27874SAdam Thomson 80448e27874SAdam Thomson /* ADCs */ 80548e27874SAdam Thomson SND_SOC_DAPM_ADC("ADC1L", NULL, DA732X_REG_ADC1_SEL, 80648e27874SAdam Thomson DA732X_ADCL_EN_SHIFT, DA732X_NO_INVERT), 80748e27874SAdam Thomson SND_SOC_DAPM_ADC("ADC1R", NULL, DA732X_REG_ADC1_SEL, 80848e27874SAdam Thomson DA732X_ADCR_EN_SHIFT, DA732X_NO_INVERT), 80948e27874SAdam Thomson SND_SOC_DAPM_ADC("ADC2L", NULL, DA732X_REG_ADC2_SEL, 81048e27874SAdam Thomson DA732X_ADCL_EN_SHIFT, DA732X_NO_INVERT), 81148e27874SAdam Thomson SND_SOC_DAPM_ADC("ADC2R", NULL, DA732X_REG_ADC2_SEL, 81248e27874SAdam Thomson DA732X_ADCR_EN_SHIFT, DA732X_NO_INVERT), 81348e27874SAdam Thomson 81448e27874SAdam Thomson /* DACs */ 81548e27874SAdam Thomson SND_SOC_DAPM_DAC("DAC1L", NULL, DA732X_REG_DAC1_SEL, 81648e27874SAdam Thomson DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT), 81748e27874SAdam Thomson SND_SOC_DAPM_DAC("DAC1R", NULL, DA732X_REG_DAC1_SEL, 81848e27874SAdam Thomson DA732X_DACR_EN_SHIFT, DA732X_NO_INVERT), 81948e27874SAdam Thomson SND_SOC_DAPM_DAC("DAC2L", NULL, DA732X_REG_DAC2_SEL, 82048e27874SAdam Thomson DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT), 82148e27874SAdam Thomson SND_SOC_DAPM_DAC("DAC2R", NULL, DA732X_REG_DAC2_SEL, 82248e27874SAdam Thomson DA732X_DACR_EN_SHIFT, DA732X_NO_INVERT), 82348e27874SAdam Thomson SND_SOC_DAPM_DAC("DAC3", NULL, DA732X_REG_DAC3_SEL, 82448e27874SAdam Thomson DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT), 82548e27874SAdam Thomson 82648e27874SAdam Thomson /* Input Pgas */ 82748e27874SAdam Thomson SND_SOC_DAPM_PGA("MIC1 PGA", DA732X_REG_MIC1, DA732X_MIC_EN_SHIFT, 82848e27874SAdam Thomson 0, NULL, 0), 82948e27874SAdam Thomson SND_SOC_DAPM_PGA("MIC2 PGA", DA732X_REG_MIC2, DA732X_MIC_EN_SHIFT, 83048e27874SAdam Thomson 0, NULL, 0), 83148e27874SAdam Thomson SND_SOC_DAPM_PGA("MIC3 PGA", DA732X_REG_MIC3, DA732X_MIC_EN_SHIFT, 83248e27874SAdam Thomson 0, NULL, 0), 83348e27874SAdam Thomson SND_SOC_DAPM_PGA("AUX1L PGA", DA732X_REG_AUX1L, DA732X_AUX_EN_SHIFT, 83448e27874SAdam Thomson 0, NULL, 0), 83548e27874SAdam Thomson SND_SOC_DAPM_PGA("AUX1R PGA", DA732X_REG_AUX1R, DA732X_AUX_EN_SHIFT, 83648e27874SAdam Thomson 0, NULL, 0), 83748e27874SAdam Thomson 83848e27874SAdam Thomson SND_SOC_DAPM_PGA_E("HP Left", DA732X_REG_HPL, DA732X_HP_OUT_EN_SHIFT, 83948e27874SAdam Thomson 0, NULL, 0, da732x_out_pga_event, 84048e27874SAdam Thomson SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 84148e27874SAdam Thomson SND_SOC_DAPM_PGA_E("HP Right", DA732X_REG_HPR, DA732X_HP_OUT_EN_SHIFT, 84248e27874SAdam Thomson 0, NULL, 0, da732x_out_pga_event, 84348e27874SAdam Thomson SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 84448e27874SAdam Thomson SND_SOC_DAPM_PGA_E("LIN2", DA732X_REG_LIN2, DA732X_LIN_OUT_EN_SHIFT, 84548e27874SAdam Thomson 0, NULL, 0, da732x_out_pga_event, 84648e27874SAdam Thomson SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 84748e27874SAdam Thomson SND_SOC_DAPM_PGA_E("LIN3", DA732X_REG_LIN3, DA732X_LIN_OUT_EN_SHIFT, 84848e27874SAdam Thomson 0, NULL, 0, da732x_out_pga_event, 84948e27874SAdam Thomson SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 85048e27874SAdam Thomson SND_SOC_DAPM_PGA_E("LIN4", DA732X_REG_LIN4, DA732X_LIN_OUT_EN_SHIFT, 85148e27874SAdam Thomson 0, NULL, 0, da732x_out_pga_event, 85248e27874SAdam Thomson SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 85348e27874SAdam Thomson 85448e27874SAdam Thomson /* MUXs */ 85548e27874SAdam Thomson SND_SOC_DAPM_MUX("ADC1 Left MUX", SND_SOC_NOPM, 0, 0, &adc1l_mux), 85648e27874SAdam Thomson SND_SOC_DAPM_MUX("ADC1 Right MUX", SND_SOC_NOPM, 0, 0, &adc1r_mux), 85748e27874SAdam Thomson SND_SOC_DAPM_MUX("ADC2 Left MUX", SND_SOC_NOPM, 0, 0, &adc2l_mux), 85848e27874SAdam Thomson SND_SOC_DAPM_MUX("ADC2 Right MUX", SND_SOC_NOPM, 0, 0, &adc2r_mux), 85948e27874SAdam Thomson 86048e27874SAdam Thomson SND_SOC_DAPM_MUX("HP Left MUX", SND_SOC_NOPM, 0, 0, &hpl_mux), 86148e27874SAdam Thomson SND_SOC_DAPM_MUX("HP Right MUX", SND_SOC_NOPM, 0, 0, &hpr_mux), 86248e27874SAdam Thomson SND_SOC_DAPM_MUX("Speaker MUX", SND_SOC_NOPM, 0, 0, &spk_mux), 86348e27874SAdam Thomson SND_SOC_DAPM_MUX("LOUT2 MUX", SND_SOC_NOPM, 0, 0, &lout2_mux), 86448e27874SAdam Thomson SND_SOC_DAPM_MUX("LOUT4 MUX", SND_SOC_NOPM, 0, 0, &lout4_mux), 86548e27874SAdam Thomson 86648e27874SAdam Thomson /* AIF interfaces */ 86748e27874SAdam Thomson SND_SOC_DAPM_AIF_OUT("AIFA Output", "AIFA Capture", 0, DA732X_REG_AIFA3, 86848e27874SAdam Thomson DA732X_AIF_EN_SHIFT, 0), 86948e27874SAdam Thomson SND_SOC_DAPM_AIF_IN("AIFA Input", "AIFA Playback", 0, DA732X_REG_AIFA3, 87048e27874SAdam Thomson DA732X_AIF_EN_SHIFT, 0), 87148e27874SAdam Thomson 87248e27874SAdam Thomson SND_SOC_DAPM_AIF_OUT("AIFB Output", "AIFB Capture", 0, DA732X_REG_AIFB3, 87348e27874SAdam Thomson DA732X_AIF_EN_SHIFT, 0), 87448e27874SAdam Thomson SND_SOC_DAPM_AIF_IN("AIFB Input", "AIFB Playback", 0, DA732X_REG_AIFB3, 87548e27874SAdam Thomson DA732X_AIF_EN_SHIFT, 0), 87648e27874SAdam Thomson }; 87748e27874SAdam Thomson 87848e27874SAdam Thomson static const struct snd_soc_dapm_route da732x_dapm_routes[] = { 87948e27874SAdam Thomson /* Inputs */ 88048e27874SAdam Thomson {"AUX1L PGA", "NULL", "AUX1L"}, 88148e27874SAdam Thomson {"AUX1R PGA", "NULL", "AUX1R"}, 88248e27874SAdam Thomson {"MIC1 PGA", NULL, "MIC1"}, 88348e27874SAdam Thomson {"MIC2 PGA", "NULL", "MIC2"}, 88448e27874SAdam Thomson {"MIC3 PGA", "NULL", "MIC3"}, 88548e27874SAdam Thomson 88648e27874SAdam Thomson /* Capture Path */ 88748e27874SAdam Thomson {"ADC1 Left MUX", "MIC1", "MIC1 PGA"}, 88848e27874SAdam Thomson {"ADC1 Left MUX", "AUX1L", "AUX1L PGA"}, 88948e27874SAdam Thomson 89048e27874SAdam Thomson {"ADC1 Right MUX", "AUX1R", "AUX1R PGA"}, 89148e27874SAdam Thomson {"ADC1 Right MUX", "MIC2", "MIC2 PGA"}, 89248e27874SAdam Thomson {"ADC1 Right MUX", "MIC3", "MIC3 PGA"}, 89348e27874SAdam Thomson 89448e27874SAdam Thomson {"ADC2 Left MUX", "AUX1L", "AUX1L PGA"}, 89548e27874SAdam Thomson {"ADC2 Left MUX", "MIC1", "MIC1 PGA"}, 89648e27874SAdam Thomson 89748e27874SAdam Thomson {"ADC2 Right MUX", "AUX1R", "AUX1R PGA"}, 89848e27874SAdam Thomson {"ADC2 Right MUX", "MIC2", "MIC2 PGA"}, 89948e27874SAdam Thomson {"ADC2 Right MUX", "MIC3", "MIC3 PGA"}, 90048e27874SAdam Thomson 90148e27874SAdam Thomson {"ADC1L", NULL, "ADC1 Supply"}, 90248e27874SAdam Thomson {"ADC1R", NULL, "ADC1 Supply"}, 90348e27874SAdam Thomson {"ADC2L", NULL, "ADC2 Supply"}, 90448e27874SAdam Thomson {"ADC2R", NULL, "ADC2 Supply"}, 90548e27874SAdam Thomson 90648e27874SAdam Thomson {"ADC1L", NULL, "ADC1 Left MUX"}, 90748e27874SAdam Thomson {"ADC1R", NULL, "ADC1 Right MUX"}, 90848e27874SAdam Thomson {"ADC2L", NULL, "ADC2 Left MUX"}, 90948e27874SAdam Thomson {"ADC2R", NULL, "ADC2 Right MUX"}, 91048e27874SAdam Thomson 91148e27874SAdam Thomson {"AIFA Output", NULL, "ADC1L"}, 91248e27874SAdam Thomson {"AIFA Output", NULL, "ADC1R"}, 91348e27874SAdam Thomson {"AIFB Output", NULL, "ADC2L"}, 91448e27874SAdam Thomson {"AIFB Output", NULL, "ADC2R"}, 91548e27874SAdam Thomson 91648e27874SAdam Thomson {"HP Left MUX", "Enabled", "AIFA Input"}, 91748e27874SAdam Thomson {"HP Right MUX", "Enabled", "AIFA Input"}, 91848e27874SAdam Thomson {"Speaker MUX", "Enabled", "AIFB Input"}, 91948e27874SAdam Thomson {"LOUT2 MUX", "Enabled", "AIFB Input"}, 92048e27874SAdam Thomson {"LOUT4 MUX", "Enabled", "AIFB Input"}, 92148e27874SAdam Thomson 92248e27874SAdam Thomson {"DAC1L", NULL, "DAC1 CLK"}, 92348e27874SAdam Thomson {"DAC1R", NULL, "DAC1 CLK"}, 92448e27874SAdam Thomson {"DAC2L", NULL, "DAC2 CLK"}, 92548e27874SAdam Thomson {"DAC2R", NULL, "DAC2 CLK"}, 92648e27874SAdam Thomson {"DAC3", NULL, "DAC3 CLK"}, 92748e27874SAdam Thomson 92848e27874SAdam Thomson {"DAC1L", NULL, "HP Left MUX"}, 92948e27874SAdam Thomson {"DAC1R", NULL, "HP Right MUX"}, 93048e27874SAdam Thomson {"DAC2L", NULL, "Speaker MUX"}, 93148e27874SAdam Thomson {"DAC2R", NULL, "LOUT4 MUX"}, 93248e27874SAdam Thomson {"DAC3", NULL, "LOUT2 MUX"}, 93348e27874SAdam Thomson 93448e27874SAdam Thomson /* Output Pgas */ 93548e27874SAdam Thomson {"HP Left", NULL, "DAC1L"}, 93648e27874SAdam Thomson {"HP Right", NULL, "DAC1R"}, 93748e27874SAdam Thomson {"LIN3", NULL, "DAC2L"}, 93848e27874SAdam Thomson {"LIN4", NULL, "DAC2R"}, 93948e27874SAdam Thomson {"LIN2", NULL, "DAC3"}, 94048e27874SAdam Thomson 94148e27874SAdam Thomson /* Outputs */ 94248e27874SAdam Thomson {"ClassD", NULL, "LIN3"}, 94348e27874SAdam Thomson {"LOUTL", NULL, "LIN2"}, 94448e27874SAdam Thomson {"LOUTR", NULL, "LIN4"}, 94548e27874SAdam Thomson {"HPL", NULL, "HP Left"}, 94648e27874SAdam Thomson {"HPR", NULL, "HP Right"}, 94748e27874SAdam Thomson }; 94848e27874SAdam Thomson 94948e27874SAdam Thomson static int da732x_hw_params(struct snd_pcm_substream *substream, 95048e27874SAdam Thomson struct snd_pcm_hw_params *params, 95148e27874SAdam Thomson struct snd_soc_dai *dai) 95248e27874SAdam Thomson { 95348e27874SAdam Thomson struct snd_soc_codec *codec = dai->codec; 95448e27874SAdam Thomson u32 aif = 0; 95548e27874SAdam Thomson u32 reg_aif; 95648e27874SAdam Thomson u32 fs; 95748e27874SAdam Thomson 95848e27874SAdam Thomson reg_aif = dai->driver->base; 95948e27874SAdam Thomson 960abf82ae6SMark Brown switch (params_width(params)) { 961abf82ae6SMark Brown case 16: 96248e27874SAdam Thomson aif |= DA732X_AIF_WORD_16; 96348e27874SAdam Thomson break; 964abf82ae6SMark Brown case 20: 96548e27874SAdam Thomson aif |= DA732X_AIF_WORD_20; 96648e27874SAdam Thomson break; 967abf82ae6SMark Brown case 24: 96848e27874SAdam Thomson aif |= DA732X_AIF_WORD_24; 96948e27874SAdam Thomson break; 970abf82ae6SMark Brown case 32: 97148e27874SAdam Thomson aif |= DA732X_AIF_WORD_32; 97248e27874SAdam Thomson break; 97348e27874SAdam Thomson default: 97448e27874SAdam Thomson return -EINVAL; 97548e27874SAdam Thomson } 97648e27874SAdam Thomson 97748e27874SAdam Thomson switch (params_rate(params)) { 97848e27874SAdam Thomson case 8000: 97948e27874SAdam Thomson fs = DA732X_SR_8KHZ; 98048e27874SAdam Thomson break; 98148e27874SAdam Thomson case 11025: 98248e27874SAdam Thomson fs = DA732X_SR_11_025KHZ; 98348e27874SAdam Thomson break; 98448e27874SAdam Thomson case 12000: 98548e27874SAdam Thomson fs = DA732X_SR_12KHZ; 98648e27874SAdam Thomson break; 98748e27874SAdam Thomson case 16000: 98848e27874SAdam Thomson fs = DA732X_SR_16KHZ; 98948e27874SAdam Thomson break; 99048e27874SAdam Thomson case 22050: 99148e27874SAdam Thomson fs = DA732X_SR_22_05KHZ; 99248e27874SAdam Thomson break; 99348e27874SAdam Thomson case 24000: 99448e27874SAdam Thomson fs = DA732X_SR_24KHZ; 99548e27874SAdam Thomson break; 99648e27874SAdam Thomson case 32000: 99748e27874SAdam Thomson fs = DA732X_SR_32KHZ; 99848e27874SAdam Thomson break; 99948e27874SAdam Thomson case 44100: 100048e27874SAdam Thomson fs = DA732X_SR_44_1KHZ; 100148e27874SAdam Thomson break; 100248e27874SAdam Thomson case 48000: 100348e27874SAdam Thomson fs = DA732X_SR_48KHZ; 100448e27874SAdam Thomson break; 100548e27874SAdam Thomson case 88100: 100648e27874SAdam Thomson fs = DA732X_SR_88_1KHZ; 100748e27874SAdam Thomson break; 100848e27874SAdam Thomson case 96000: 100948e27874SAdam Thomson fs = DA732X_SR_96KHZ; 101048e27874SAdam Thomson break; 101148e27874SAdam Thomson default: 101248e27874SAdam Thomson return -EINVAL; 101348e27874SAdam Thomson } 101448e27874SAdam Thomson 101548e27874SAdam Thomson snd_soc_update_bits(codec, reg_aif, DA732X_AIF_WORD_MASK, aif); 101648e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_CLK_CTRL, DA732X_SR1_MASK, fs); 101748e27874SAdam Thomson 101848e27874SAdam Thomson return 0; 101948e27874SAdam Thomson } 102048e27874SAdam Thomson 102148e27874SAdam Thomson static int da732x_set_dai_fmt(struct snd_soc_dai *dai, u32 fmt) 102248e27874SAdam Thomson { 102348e27874SAdam Thomson struct snd_soc_codec *codec = dai->codec; 102448e27874SAdam Thomson u32 aif_mclk, pc_count; 102548e27874SAdam Thomson u32 reg_aif1, aif1; 102648e27874SAdam Thomson u32 reg_aif3, aif3; 102748e27874SAdam Thomson 102848e27874SAdam Thomson switch (dai->id) { 102948e27874SAdam Thomson case DA732X_DAI_ID1: 103048e27874SAdam Thomson reg_aif1 = DA732X_REG_AIFA1; 103148e27874SAdam Thomson reg_aif3 = DA732X_REG_AIFA3; 103248e27874SAdam Thomson pc_count = DA732X_PC_PULSE_AIFA | DA732X_PC_RESYNC_NOT_AUT | 103348e27874SAdam Thomson DA732X_PC_SAME; 103448e27874SAdam Thomson break; 103548e27874SAdam Thomson case DA732X_DAI_ID2: 103648e27874SAdam Thomson reg_aif1 = DA732X_REG_AIFB1; 103748e27874SAdam Thomson reg_aif3 = DA732X_REG_AIFB3; 103848e27874SAdam Thomson pc_count = DA732X_PC_PULSE_AIFB | DA732X_PC_RESYNC_NOT_AUT | 103948e27874SAdam Thomson DA732X_PC_SAME; 104048e27874SAdam Thomson break; 104148e27874SAdam Thomson default: 104248e27874SAdam Thomson return -EINVAL; 104348e27874SAdam Thomson } 104448e27874SAdam Thomson 104548e27874SAdam Thomson switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 104648e27874SAdam Thomson case SND_SOC_DAIFMT_CBS_CFS: 104748e27874SAdam Thomson aif1 = DA732X_AIF_SLAVE; 104848e27874SAdam Thomson aif_mclk = DA732X_AIFM_FRAME_64 | DA732X_AIFM_SRC_SEL_AIFA; 104948e27874SAdam Thomson break; 105048e27874SAdam Thomson case SND_SOC_DAIFMT_CBM_CFM: 105148e27874SAdam Thomson aif1 = DA732X_AIF_CLK_FROM_SRC; 105248e27874SAdam Thomson aif_mclk = DA732X_CLK_GENERATION_AIF_A; 105348e27874SAdam Thomson break; 105448e27874SAdam Thomson default: 105548e27874SAdam Thomson return -EINVAL; 105648e27874SAdam Thomson } 105748e27874SAdam Thomson 105848e27874SAdam Thomson switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 105948e27874SAdam Thomson case SND_SOC_DAIFMT_I2S: 106048e27874SAdam Thomson aif3 = DA732X_AIF_I2S_MODE; 106148e27874SAdam Thomson break; 106248e27874SAdam Thomson case SND_SOC_DAIFMT_RIGHT_J: 106348e27874SAdam Thomson aif3 = DA732X_AIF_RIGHT_J_MODE; 106448e27874SAdam Thomson break; 106548e27874SAdam Thomson case SND_SOC_DAIFMT_LEFT_J: 106648e27874SAdam Thomson aif3 = DA732X_AIF_LEFT_J_MODE; 106748e27874SAdam Thomson break; 106848e27874SAdam Thomson case SND_SOC_DAIFMT_DSP_B: 106948e27874SAdam Thomson aif3 = DA732X_AIF_DSP_MODE; 107048e27874SAdam Thomson break; 107148e27874SAdam Thomson default: 107248e27874SAdam Thomson return -EINVAL; 107348e27874SAdam Thomson } 107448e27874SAdam Thomson 107548e27874SAdam Thomson /* Clock inversion */ 107648e27874SAdam Thomson switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 107748e27874SAdam Thomson case SND_SOC_DAIFMT_DSP_B: 107848e27874SAdam Thomson switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 107948e27874SAdam Thomson case SND_SOC_DAIFMT_NB_NF: 108048e27874SAdam Thomson break; 108148e27874SAdam Thomson case SND_SOC_DAIFMT_IB_NF: 108248e27874SAdam Thomson aif3 |= DA732X_AIF_BCLK_INV; 108348e27874SAdam Thomson break; 108448e27874SAdam Thomson default: 108548e27874SAdam Thomson return -EINVAL; 108648e27874SAdam Thomson } 108748e27874SAdam Thomson break; 108848e27874SAdam Thomson case SND_SOC_DAIFMT_I2S: 108948e27874SAdam Thomson case SND_SOC_DAIFMT_RIGHT_J: 109048e27874SAdam Thomson case SND_SOC_DAIFMT_LEFT_J: 109148e27874SAdam Thomson switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 109248e27874SAdam Thomson case SND_SOC_DAIFMT_NB_NF: 109348e27874SAdam Thomson break; 109448e27874SAdam Thomson case SND_SOC_DAIFMT_IB_IF: 109548e27874SAdam Thomson aif3 |= DA732X_AIF_BCLK_INV | DA732X_AIF_WCLK_INV; 109648e27874SAdam Thomson break; 109748e27874SAdam Thomson case SND_SOC_DAIFMT_IB_NF: 109848e27874SAdam Thomson aif3 |= DA732X_AIF_BCLK_INV; 109948e27874SAdam Thomson break; 110048e27874SAdam Thomson case SND_SOC_DAIFMT_NB_IF: 110148e27874SAdam Thomson aif3 |= DA732X_AIF_WCLK_INV; 110248e27874SAdam Thomson break; 110348e27874SAdam Thomson default: 110448e27874SAdam Thomson return -EINVAL; 110548e27874SAdam Thomson } 110648e27874SAdam Thomson break; 110748e27874SAdam Thomson default: 110848e27874SAdam Thomson return -EINVAL; 110948e27874SAdam Thomson } 111048e27874SAdam Thomson 111148e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_AIF_MCLK, aif_mclk); 111248e27874SAdam Thomson snd_soc_update_bits(codec, reg_aif1, DA732X_AIF1_CLK_MASK, aif1); 111348e27874SAdam Thomson snd_soc_update_bits(codec, reg_aif3, DA732X_AIF_BCLK_INV | 111448e27874SAdam Thomson DA732X_AIF_WCLK_INV | DA732X_AIF_MODE_MASK, aif3); 111548e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_PC_CTRL, pc_count); 111648e27874SAdam Thomson 111748e27874SAdam Thomson return 0; 111848e27874SAdam Thomson } 111948e27874SAdam Thomson 112048e27874SAdam Thomson 112148e27874SAdam Thomson 112248e27874SAdam Thomson static int da732x_set_dai_pll(struct snd_soc_codec *codec, int pll_id, 112348e27874SAdam Thomson int source, unsigned int freq_in, 112448e27874SAdam Thomson unsigned int freq_out) 112548e27874SAdam Thomson { 112648e27874SAdam Thomson struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); 112748e27874SAdam Thomson int fref, indiv; 112848e27874SAdam Thomson u8 div_lo, div_mid, div_hi; 112948e27874SAdam Thomson u64 frac_div; 113048e27874SAdam Thomson 113148e27874SAdam Thomson /* Disable PLL */ 113248e27874SAdam Thomson if (freq_out == 0) { 113348e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, 113448e27874SAdam Thomson DA732X_PLL_EN, 0); 113548e27874SAdam Thomson da732x->pll_en = false; 113648e27874SAdam Thomson return 0; 113748e27874SAdam Thomson } 113848e27874SAdam Thomson 113948e27874SAdam Thomson if (da732x->pll_en) 114048e27874SAdam Thomson return -EBUSY; 114148e27874SAdam Thomson 114248e27874SAdam Thomson if (source == DA732X_SRCCLK_MCLK) { 114348e27874SAdam Thomson /* Validate Sysclk rate */ 114448e27874SAdam Thomson switch (da732x->sysclk) { 114548e27874SAdam Thomson case 11290000: 114648e27874SAdam Thomson case 12288000: 114748e27874SAdam Thomson case 22580000: 114848e27874SAdam Thomson case 24576000: 114948e27874SAdam Thomson case 45160000: 115048e27874SAdam Thomson case 49152000: 115148e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_PLL_CTRL, 115248e27874SAdam Thomson DA732X_PLL_BYPASS); 115348e27874SAdam Thomson return 0; 115448e27874SAdam Thomson default: 115548e27874SAdam Thomson dev_err(codec->dev, 115648e27874SAdam Thomson "Cannot use PLL Bypass, invalid SYSCLK rate\n"); 115748e27874SAdam Thomson return -EINVAL; 115848e27874SAdam Thomson } 115948e27874SAdam Thomson } 116048e27874SAdam Thomson 116148e27874SAdam Thomson indiv = da732x_get_input_div(codec, da732x->sysclk); 116248e27874SAdam Thomson if (indiv < 0) 116348e27874SAdam Thomson return indiv; 116448e27874SAdam Thomson 116548e27874SAdam Thomson fref = (da732x->sysclk / indiv); 116648e27874SAdam Thomson div_hi = freq_out / fref; 116748e27874SAdam Thomson frac_div = (u64)(freq_out % fref) * 8192ULL; 116848e27874SAdam Thomson do_div(frac_div, fref); 116948e27874SAdam Thomson div_mid = (frac_div >> DA732X_1BYTE_SHIFT) & DA732X_U8_MASK; 117048e27874SAdam Thomson div_lo = (frac_div) & DA732X_U8_MASK; 117148e27874SAdam Thomson 117248e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_PLL_DIV_LO, div_lo); 117348e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_PLL_DIV_MID, div_mid); 117448e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_PLL_DIV_HI, div_hi); 117548e27874SAdam Thomson 117648e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, DA732X_PLL_EN, 117748e27874SAdam Thomson DA732X_PLL_EN); 117848e27874SAdam Thomson 117948e27874SAdam Thomson da732x->pll_en = true; 118048e27874SAdam Thomson 118148e27874SAdam Thomson return 0; 118248e27874SAdam Thomson } 118348e27874SAdam Thomson 118448e27874SAdam Thomson static int da732x_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, 118548e27874SAdam Thomson unsigned int freq, int dir) 118648e27874SAdam Thomson { 118748e27874SAdam Thomson struct snd_soc_codec *codec = dai->codec; 118848e27874SAdam Thomson struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); 118948e27874SAdam Thomson 119048e27874SAdam Thomson da732x->sysclk = freq; 119148e27874SAdam Thomson 119248e27874SAdam Thomson return 0; 119348e27874SAdam Thomson } 119448e27874SAdam Thomson 119548e27874SAdam Thomson #define DA732X_RATES SNDRV_PCM_RATE_8000_96000 119648e27874SAdam Thomson 119748e27874SAdam Thomson #define DA732X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 119848e27874SAdam Thomson SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 119948e27874SAdam Thomson 120048e27874SAdam Thomson static struct snd_soc_dai_ops da732x_dai1_ops = { 120148e27874SAdam Thomson .hw_params = da732x_hw_params, 120248e27874SAdam Thomson .set_fmt = da732x_set_dai_fmt, 120348e27874SAdam Thomson .set_sysclk = da732x_set_dai_sysclk, 120448e27874SAdam Thomson }; 120548e27874SAdam Thomson 120648e27874SAdam Thomson static struct snd_soc_dai_ops da732x_dai2_ops = { 120748e27874SAdam Thomson .hw_params = da732x_hw_params, 120848e27874SAdam Thomson .set_fmt = da732x_set_dai_fmt, 120948e27874SAdam Thomson .set_sysclk = da732x_set_dai_sysclk, 121048e27874SAdam Thomson }; 121148e27874SAdam Thomson 121248e27874SAdam Thomson static struct snd_soc_dai_driver da732x_dai[] = { 121348e27874SAdam Thomson { 121448e27874SAdam Thomson .name = "DA732X_AIFA", 121548e27874SAdam Thomson .id = DA732X_DAI_ID1, 121648e27874SAdam Thomson .base = DA732X_REG_AIFA1, 121748e27874SAdam Thomson .playback = { 121848e27874SAdam Thomson .stream_name = "AIFA Playback", 121948e27874SAdam Thomson .channels_min = 1, 122048e27874SAdam Thomson .channels_max = 2, 122148e27874SAdam Thomson .rates = DA732X_RATES, 122248e27874SAdam Thomson .formats = DA732X_FORMATS, 122348e27874SAdam Thomson }, 122448e27874SAdam Thomson .capture = { 122548e27874SAdam Thomson .stream_name = "AIFA Capture", 122648e27874SAdam Thomson .channels_min = 1, 122748e27874SAdam Thomson .channels_max = 2, 122848e27874SAdam Thomson .rates = DA732X_RATES, 122948e27874SAdam Thomson .formats = DA732X_FORMATS, 123048e27874SAdam Thomson }, 123148e27874SAdam Thomson .ops = &da732x_dai1_ops, 123248e27874SAdam Thomson }, 123348e27874SAdam Thomson { 123448e27874SAdam Thomson .name = "DA732X_AIFB", 123548e27874SAdam Thomson .id = DA732X_DAI_ID2, 123648e27874SAdam Thomson .base = DA732X_REG_AIFB1, 123748e27874SAdam Thomson .playback = { 123848e27874SAdam Thomson .stream_name = "AIFB Playback", 123948e27874SAdam Thomson .channels_min = 1, 124048e27874SAdam Thomson .channels_max = 2, 124148e27874SAdam Thomson .rates = DA732X_RATES, 124248e27874SAdam Thomson .formats = DA732X_FORMATS, 124348e27874SAdam Thomson }, 124448e27874SAdam Thomson .capture = { 124548e27874SAdam Thomson .stream_name = "AIFB Capture", 124648e27874SAdam Thomson .channels_min = 1, 124748e27874SAdam Thomson .channels_max = 2, 124848e27874SAdam Thomson .rates = DA732X_RATES, 124948e27874SAdam Thomson .formats = DA732X_FORMATS, 125048e27874SAdam Thomson }, 125148e27874SAdam Thomson .ops = &da732x_dai2_ops, 125248e27874SAdam Thomson }, 125348e27874SAdam Thomson }; 125448e27874SAdam Thomson 125575306820SMark Brown static bool da732x_volatile(struct device *dev, unsigned int reg) 125675306820SMark Brown { 125775306820SMark Brown switch (reg) { 125875306820SMark Brown case DA732X_REG_HPL_DAC_OFF_CNTL: 125975306820SMark Brown case DA732X_REG_HPR_DAC_OFF_CNTL: 126075306820SMark Brown return true; 126175306820SMark Brown default: 126275306820SMark Brown return false; 126375306820SMark Brown } 126475306820SMark Brown } 126575306820SMark Brown 126648e27874SAdam Thomson static const struct regmap_config da732x_regmap = { 126748e27874SAdam Thomson .reg_bits = 8, 126848e27874SAdam Thomson .val_bits = 8, 126948e27874SAdam Thomson 127048e27874SAdam Thomson .max_register = DA732X_MAX_REG, 127175306820SMark Brown .volatile_reg = da732x_volatile, 127248e27874SAdam Thomson .reg_defaults = da732x_reg_cache, 127348e27874SAdam Thomson .num_reg_defaults = ARRAY_SIZE(da732x_reg_cache), 127448e27874SAdam Thomson .cache_type = REGCACHE_RBTREE, 127548e27874SAdam Thomson }; 127648e27874SAdam Thomson 127748e27874SAdam Thomson 127848e27874SAdam Thomson static void da732x_dac_offset_adjust(struct snd_soc_codec *codec) 127948e27874SAdam Thomson { 128048e27874SAdam Thomson u8 offset[DA732X_HP_DACS]; 128148e27874SAdam Thomson u8 sign[DA732X_HP_DACS]; 128248e27874SAdam Thomson u8 step = DA732X_DAC_OFFSET_STEP; 128348e27874SAdam Thomson 128448e27874SAdam Thomson /* Initialize DAC offset calibration circuits and registers */ 128548e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET, 128648e27874SAdam Thomson DA732X_HP_DAC_OFFSET_TRIM_VAL); 128748e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET, 128848e27874SAdam Thomson DA732X_HP_DAC_OFFSET_TRIM_VAL); 128948e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL, 129048e27874SAdam Thomson DA732X_HP_DAC_OFF_CALIBRATION | 129148e27874SAdam Thomson DA732X_HP_DAC_OFF_SCALE_STEPS); 129248e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL, 129348e27874SAdam Thomson DA732X_HP_DAC_OFF_CALIBRATION | 129448e27874SAdam Thomson DA732X_HP_DAC_OFF_SCALE_STEPS); 129548e27874SAdam Thomson 129648e27874SAdam Thomson /* Wait for voltage stabilization */ 129748e27874SAdam Thomson msleep(DA732X_WAIT_FOR_STABILIZATION); 129848e27874SAdam Thomson 129948e27874SAdam Thomson /* Check DAC offset sign */ 1300d4179c1dSMark Brown sign[DA732X_HPL_DAC] = (snd_soc_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) & 130148e27874SAdam Thomson DA732X_HP_DAC_OFF_CNTL_COMPO); 1302d4179c1dSMark Brown sign[DA732X_HPR_DAC] = (snd_soc_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) & 130348e27874SAdam Thomson DA732X_HP_DAC_OFF_CNTL_COMPO); 130448e27874SAdam Thomson 130548e27874SAdam Thomson /* Binary search DAC offset values (both channels at once) */ 130648e27874SAdam Thomson offset[DA732X_HPL_DAC] = sign[DA732X_HPL_DAC] << DA732X_HP_DAC_COMPO_SHIFT; 130748e27874SAdam Thomson offset[DA732X_HPR_DAC] = sign[DA732X_HPR_DAC] << DA732X_HP_DAC_COMPO_SHIFT; 130848e27874SAdam Thomson 130948e27874SAdam Thomson do { 131048e27874SAdam Thomson offset[DA732X_HPL_DAC] |= step; 131148e27874SAdam Thomson offset[DA732X_HPR_DAC] |= step; 131248e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET, 131348e27874SAdam Thomson ~offset[DA732X_HPL_DAC] & DA732X_HP_DAC_OFF_MASK); 131448e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET, 131548e27874SAdam Thomson ~offset[DA732X_HPR_DAC] & DA732X_HP_DAC_OFF_MASK); 131648e27874SAdam Thomson 131748e27874SAdam Thomson msleep(DA732X_WAIT_FOR_STABILIZATION); 131848e27874SAdam Thomson 1319d4179c1dSMark Brown if ((snd_soc_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) & 132048e27874SAdam Thomson DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPL_DAC]) 132148e27874SAdam Thomson offset[DA732X_HPL_DAC] &= ~step; 1322d4179c1dSMark Brown if ((snd_soc_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) & 132348e27874SAdam Thomson DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPR_DAC]) 132448e27874SAdam Thomson offset[DA732X_HPR_DAC] &= ~step; 132548e27874SAdam Thomson 132648e27874SAdam Thomson step >>= 1; 132748e27874SAdam Thomson } while (step); 132848e27874SAdam Thomson 132948e27874SAdam Thomson /* Write final DAC offsets to registers */ 133048e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET, 133148e27874SAdam Thomson ~offset[DA732X_HPL_DAC] & DA732X_HP_DAC_OFF_MASK); 133248e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET, 133348e27874SAdam Thomson ~offset[DA732X_HPR_DAC] & DA732X_HP_DAC_OFF_MASK); 133448e27874SAdam Thomson 133548e27874SAdam Thomson /* End DAC calibration mode */ 133648e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL, 133748e27874SAdam Thomson DA732X_HP_DAC_OFF_SCALE_STEPS); 133848e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL, 133948e27874SAdam Thomson DA732X_HP_DAC_OFF_SCALE_STEPS); 134048e27874SAdam Thomson } 134148e27874SAdam Thomson 134248e27874SAdam Thomson static void da732x_output_offset_adjust(struct snd_soc_codec *codec) 134348e27874SAdam Thomson { 134448e27874SAdam Thomson u8 offset[DA732X_HP_AMPS]; 134548e27874SAdam Thomson u8 sign[DA732X_HP_AMPS]; 134648e27874SAdam Thomson u8 step = DA732X_OUTPUT_OFFSET_STEP; 134748e27874SAdam Thomson 134848e27874SAdam Thomson offset[DA732X_HPL_AMP] = DA732X_HP_OUT_TRIM_VAL; 134948e27874SAdam Thomson offset[DA732X_HPR_AMP] = DA732X_HP_OUT_TRIM_VAL; 135048e27874SAdam Thomson 135148e27874SAdam Thomson /* Initialize output offset calibration circuits and registers */ 135248e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL); 135348e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL); 135448e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL, 135548e27874SAdam Thomson DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN); 135648e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR, 135748e27874SAdam Thomson DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN); 135848e27874SAdam Thomson 135948e27874SAdam Thomson /* Wait for voltage stabilization */ 136048e27874SAdam Thomson msleep(DA732X_WAIT_FOR_STABILIZATION); 136148e27874SAdam Thomson 136248e27874SAdam Thomson /* Check output offset sign */ 1363d4179c1dSMark Brown sign[DA732X_HPL_AMP] = snd_soc_read(codec, DA732X_REG_HPL) & 136448e27874SAdam Thomson DA732X_HP_OUT_COMPO; 1365d4179c1dSMark Brown sign[DA732X_HPR_AMP] = snd_soc_read(codec, DA732X_REG_HPR) & 136648e27874SAdam Thomson DA732X_HP_OUT_COMPO; 136748e27874SAdam Thomson 136848e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_COMP | 136948e27874SAdam Thomson (sign[DA732X_HPL_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) | 137048e27874SAdam Thomson DA732X_HP_OUT_EN); 137148e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_COMP | 137248e27874SAdam Thomson (sign[DA732X_HPR_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) | 137348e27874SAdam Thomson DA732X_HP_OUT_EN); 137448e27874SAdam Thomson 137548e27874SAdam Thomson /* Binary search output offset values (both channels at once) */ 137648e27874SAdam Thomson do { 137748e27874SAdam Thomson offset[DA732X_HPL_AMP] |= step; 137848e27874SAdam Thomson offset[DA732X_HPR_AMP] |= step; 137948e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, 138048e27874SAdam Thomson offset[DA732X_HPL_AMP]); 138148e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, 138248e27874SAdam Thomson offset[DA732X_HPR_AMP]); 138348e27874SAdam Thomson 138448e27874SAdam Thomson msleep(DA732X_WAIT_FOR_STABILIZATION); 138548e27874SAdam Thomson 1386d4179c1dSMark Brown if ((snd_soc_read(codec, DA732X_REG_HPL) & 138748e27874SAdam Thomson DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPL_AMP]) 138848e27874SAdam Thomson offset[DA732X_HPL_AMP] &= ~step; 1389d4179c1dSMark Brown if ((snd_soc_read(codec, DA732X_REG_HPR) & 139048e27874SAdam Thomson DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPR_AMP]) 139148e27874SAdam Thomson offset[DA732X_HPR_AMP] &= ~step; 139248e27874SAdam Thomson 139348e27874SAdam Thomson step >>= 1; 139448e27874SAdam Thomson } while (step); 139548e27874SAdam Thomson 139648e27874SAdam Thomson /* Write final DAC offsets to registers */ 139748e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, offset[DA732X_HPL_AMP]); 139848e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, offset[DA732X_HPR_AMP]); 139948e27874SAdam Thomson } 140048e27874SAdam Thomson 140148e27874SAdam Thomson static void da732x_hp_dc_offset_cancellation(struct snd_soc_codec *codec) 140248e27874SAdam Thomson { 140348e27874SAdam Thomson /* Make sure that we have Soft Mute enabled */ 140448e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_DAC1_SOFTMUTE, DA732X_SOFTMUTE_EN | 140548e27874SAdam Thomson DA732X_GAIN_RAMPED | DA732X_16_SAMPLES); 140648e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACL_EN | 140748e27874SAdam Thomson DA732X_DACR_EN | DA732X_DACL_SDM | DA732X_DACR_SDM | 140848e27874SAdam Thomson DA732X_DACL_MUTE | DA732X_DACR_MUTE); 140948e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN | 141048e27874SAdam Thomson DA732X_HP_OUT_MUTE | DA732X_HP_OUT_EN); 141148e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_EN | 141248e27874SAdam Thomson DA732X_HP_OUT_MUTE | DA732X_HP_OUT_DAC_EN); 141348e27874SAdam Thomson 141448e27874SAdam Thomson da732x_dac_offset_adjust(codec); 141548e27874SAdam Thomson da732x_output_offset_adjust(codec); 141648e27874SAdam Thomson 141748e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACS_DIS); 141848e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_DIS); 141948e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_DIS); 142048e27874SAdam Thomson } 142148e27874SAdam Thomson 142248e27874SAdam Thomson static int da732x_set_bias_level(struct snd_soc_codec *codec, 142348e27874SAdam Thomson enum snd_soc_bias_level level) 142448e27874SAdam Thomson { 142548e27874SAdam Thomson struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); 142648e27874SAdam Thomson 142748e27874SAdam Thomson switch (level) { 142848e27874SAdam Thomson case SND_SOC_BIAS_ON: 142948e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, 143048e27874SAdam Thomson DA732X_BIAS_BOOST_MASK, 143148e27874SAdam Thomson DA732X_BIAS_BOOST_100PC); 143248e27874SAdam Thomson break; 143348e27874SAdam Thomson case SND_SOC_BIAS_PREPARE: 143448e27874SAdam Thomson break; 143548e27874SAdam Thomson case SND_SOC_BIAS_STANDBY: 143648e27874SAdam Thomson if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 143748e27874SAdam Thomson /* Init Codec */ 143848e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_REF1, 143948e27874SAdam Thomson DA732X_VMID_FASTCHG); 144048e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_BIAS_EN, 144148e27874SAdam Thomson DA732X_BIAS_EN); 144248e27874SAdam Thomson 144348e27874SAdam Thomson mdelay(DA732X_STARTUP_DELAY); 144448e27874SAdam Thomson 144548e27874SAdam Thomson /* Disable Fast Charge and enable DAC ref voltage */ 144648e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_REF1, 144748e27874SAdam Thomson DA732X_REFBUFX2_EN); 144848e27874SAdam Thomson 144948e27874SAdam Thomson /* Enable bypass DSP routing */ 145048e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_DATA_ROUTE, 145148e27874SAdam Thomson DA732X_BYPASS_DSP); 145248e27874SAdam Thomson 145348e27874SAdam Thomson /* Enable Digital subsystem */ 145448e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_DSP_CTRL, 145548e27874SAdam Thomson DA732X_DIGITAL_EN); 145648e27874SAdam Thomson 145748e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_SPARE1_OUT, 145848e27874SAdam Thomson DA732X_HP_DRIVER_EN | 145948e27874SAdam Thomson DA732X_HP_GATE_LOW | 146048e27874SAdam Thomson DA732X_HP_LOOP_GAIN_CTRL); 146148e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_HP_LIN1_GNDSEL, 146248e27874SAdam Thomson DA732X_HP_OUT_GNDSEL); 146348e27874SAdam Thomson 146448e27874SAdam Thomson da732x_set_charge_pump(codec, DA732X_ENABLE_CP); 146548e27874SAdam Thomson 146648e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_CLK_EN1, 146748e27874SAdam Thomson DA732X_SYS3_CLK_EN | DA732X_PC_CLK_EN); 146848e27874SAdam Thomson 146948e27874SAdam Thomson /* Enable Zero Crossing */ 147048e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_INP_ZC_EN, 147148e27874SAdam Thomson DA732X_MIC1_PRE_ZC_EN | 147248e27874SAdam Thomson DA732X_MIC1_ZC_EN | 147348e27874SAdam Thomson DA732X_MIC2_PRE_ZC_EN | 147448e27874SAdam Thomson DA732X_MIC2_ZC_EN | 147548e27874SAdam Thomson DA732X_AUXL_ZC_EN | 147648e27874SAdam Thomson DA732X_AUXR_ZC_EN | 147748e27874SAdam Thomson DA732X_MIC3_PRE_ZC_EN | 147848e27874SAdam Thomson DA732X_MIC3_ZC_EN); 147948e27874SAdam Thomson snd_soc_write(codec, DA732X_REG_OUT_ZC_EN, 148048e27874SAdam Thomson DA732X_HPL_ZC_EN | DA732X_HPR_ZC_EN | 148148e27874SAdam Thomson DA732X_LIN2_ZC_EN | DA732X_LIN3_ZC_EN | 148248e27874SAdam Thomson DA732X_LIN4_ZC_EN); 148348e27874SAdam Thomson 148448e27874SAdam Thomson da732x_hp_dc_offset_cancellation(codec); 148548e27874SAdam Thomson 148630812ccaSLars-Peter Clausen regcache_cache_only(da732x->regmap, false); 148730812ccaSLars-Peter Clausen regcache_sync(da732x->regmap); 148848e27874SAdam Thomson } else { 148948e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, 149048e27874SAdam Thomson DA732X_BIAS_BOOST_MASK, 149148e27874SAdam Thomson DA732X_BIAS_BOOST_50PC); 149248e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, 149348e27874SAdam Thomson DA732X_PLL_EN, 0); 149448e27874SAdam Thomson da732x->pll_en = false; 149548e27874SAdam Thomson } 149648e27874SAdam Thomson break; 149748e27874SAdam Thomson case SND_SOC_BIAS_OFF: 149830812ccaSLars-Peter Clausen regcache_cache_only(da732x->regmap, true); 149948e27874SAdam Thomson da732x_set_charge_pump(codec, DA732X_DISABLE_CP); 150048e27874SAdam Thomson snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, DA732X_BIAS_EN, 150148e27874SAdam Thomson DA732X_BIAS_DIS); 150248e27874SAdam Thomson da732x->pll_en = false; 150348e27874SAdam Thomson break; 150448e27874SAdam Thomson } 150548e27874SAdam Thomson 150648e27874SAdam Thomson codec->dapm.bias_level = level; 150748e27874SAdam Thomson 150848e27874SAdam Thomson return 0; 150948e27874SAdam Thomson } 151048e27874SAdam Thomson 151148e27874SAdam Thomson static int da732x_probe(struct snd_soc_codec *codec) 151248e27874SAdam Thomson { 151348e27874SAdam Thomson struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); 151448e27874SAdam Thomson struct snd_soc_dapm_context *dapm = &codec->dapm; 151548e27874SAdam Thomson 151648e27874SAdam Thomson da732x->codec = codec; 151748e27874SAdam Thomson 151848e27874SAdam Thomson dapm->idle_bias_off = false; 151948e27874SAdam Thomson 152048e27874SAdam Thomson da732x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 15215d6be5aaSXiubo Li 15225d6be5aaSXiubo Li return 0; 152348e27874SAdam Thomson } 152448e27874SAdam Thomson 152548e27874SAdam Thomson static int da732x_remove(struct snd_soc_codec *codec) 152648e27874SAdam Thomson { 152748e27874SAdam Thomson 152848e27874SAdam Thomson da732x_set_bias_level(codec, SND_SOC_BIAS_OFF); 152948e27874SAdam Thomson 153048e27874SAdam Thomson return 0; 153148e27874SAdam Thomson } 153248e27874SAdam Thomson 1533b2a4ec3dSMark Brown static struct snd_soc_codec_driver soc_codec_dev_da732x = { 153448e27874SAdam Thomson .probe = da732x_probe, 153548e27874SAdam Thomson .remove = da732x_remove, 153648e27874SAdam Thomson .set_bias_level = da732x_set_bias_level, 153748e27874SAdam Thomson .controls = da732x_snd_controls, 153848e27874SAdam Thomson .num_controls = ARRAY_SIZE(da732x_snd_controls), 153948e27874SAdam Thomson .dapm_widgets = da732x_dapm_widgets, 154048e27874SAdam Thomson .num_dapm_widgets = ARRAY_SIZE(da732x_dapm_widgets), 154148e27874SAdam Thomson .dapm_routes = da732x_dapm_routes, 154248e27874SAdam Thomson .num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes), 154348e27874SAdam Thomson .set_pll = da732x_set_dai_pll, 154448e27874SAdam Thomson }; 154548e27874SAdam Thomson 15467a79e94eSBill Pemberton static int da732x_i2c_probe(struct i2c_client *i2c, 154748e27874SAdam Thomson const struct i2c_device_id *id) 154848e27874SAdam Thomson { 154948e27874SAdam Thomson struct da732x_priv *da732x; 155048e27874SAdam Thomson unsigned int reg; 155148e27874SAdam Thomson int ret; 155248e27874SAdam Thomson 155348e27874SAdam Thomson da732x = devm_kzalloc(&i2c->dev, sizeof(struct da732x_priv), 155448e27874SAdam Thomson GFP_KERNEL); 155548e27874SAdam Thomson if (!da732x) 155648e27874SAdam Thomson return -ENOMEM; 155748e27874SAdam Thomson 155848e27874SAdam Thomson i2c_set_clientdata(i2c, da732x); 155948e27874SAdam Thomson 156048e27874SAdam Thomson da732x->regmap = devm_regmap_init_i2c(i2c, &da732x_regmap); 156148e27874SAdam Thomson if (IS_ERR(da732x->regmap)) { 156248e27874SAdam Thomson ret = PTR_ERR(da732x->regmap); 156348e27874SAdam Thomson dev_err(&i2c->dev, "Failed to initialize regmap\n"); 156448e27874SAdam Thomson goto err; 156548e27874SAdam Thomson } 156648e27874SAdam Thomson 156748e27874SAdam Thomson ret = regmap_read(da732x->regmap, DA732X_REG_ID, ®); 156848e27874SAdam Thomson if (ret < 0) { 156948e27874SAdam Thomson dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret); 157048e27874SAdam Thomson goto err; 157148e27874SAdam Thomson } 157248e27874SAdam Thomson 157348e27874SAdam Thomson dev_info(&i2c->dev, "Revision: %d.%d\n", 157405b00067SAxel Lin (reg & DA732X_ID_MAJOR_MASK) >> 4, 157505b00067SAxel Lin (reg & DA732X_ID_MINOR_MASK)); 157648e27874SAdam Thomson 157748e27874SAdam Thomson ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da732x, 157848e27874SAdam Thomson da732x_dai, ARRAY_SIZE(da732x_dai)); 157948e27874SAdam Thomson if (ret != 0) 158048e27874SAdam Thomson dev_err(&i2c->dev, "Failed to register codec.\n"); 158148e27874SAdam Thomson 158248e27874SAdam Thomson err: 158348e27874SAdam Thomson return ret; 158448e27874SAdam Thomson } 158548e27874SAdam Thomson 15867a79e94eSBill Pemberton static int da732x_i2c_remove(struct i2c_client *client) 158748e27874SAdam Thomson { 158848e27874SAdam Thomson snd_soc_unregister_codec(&client->dev); 158948e27874SAdam Thomson 159048e27874SAdam Thomson return 0; 159148e27874SAdam Thomson } 159248e27874SAdam Thomson 159348e27874SAdam Thomson static const struct i2c_device_id da732x_i2c_id[] = { 159448e27874SAdam Thomson { "da7320", 0}, 159548e27874SAdam Thomson { } 159648e27874SAdam Thomson }; 159748e27874SAdam Thomson MODULE_DEVICE_TABLE(i2c, da732x_i2c_id); 159848e27874SAdam Thomson 159948e27874SAdam Thomson static struct i2c_driver da732x_i2c_driver = { 160048e27874SAdam Thomson .driver = { 160148e27874SAdam Thomson .name = "da7320", 160248e27874SAdam Thomson .owner = THIS_MODULE, 160348e27874SAdam Thomson }, 160448e27874SAdam Thomson .probe = da732x_i2c_probe, 16057a79e94eSBill Pemberton .remove = da732x_i2c_remove, 160648e27874SAdam Thomson .id_table = da732x_i2c_id, 160748e27874SAdam Thomson }; 160848e27874SAdam Thomson 160948e27874SAdam Thomson module_i2c_driver(da732x_i2c_driver); 161048e27874SAdam Thomson 161148e27874SAdam Thomson 161248e27874SAdam Thomson MODULE_DESCRIPTION("ASoC DA732X driver"); 161348e27874SAdam Thomson MODULE_AUTHOR("Michal Hajduk <michal.hajduk@diasemi.com>"); 161448e27874SAdam Thomson MODULE_LICENSE("GPL"); 1615