From e7f8f22c7ad86fec9a78dad166d53cfdf059e556 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=99=88=E9=87=91=E6=B3=89?= Date: Tue, 22 Nov 2011 19:39:01 +0800 Subject: [PATCH] delete old driver of rt5621 --- sound/soc/codecs/alc5621.c | 1932 ---------------------------------- sound/soc/codecs/alc5621.h | 516 --------- sound/soc/rk29/rk29_rt5621.c | 229 ---- 3 files changed, 2677 deletions(-) delete mode 100644 sound/soc/codecs/alc5621.c delete mode 100644 sound/soc/codecs/alc5621.h delete mode 100644 sound/soc/rk29/rk29_rt5621.c diff --git a/sound/soc/codecs/alc5621.c b/sound/soc/codecs/alc5621.c deleted file mode 100644 index ab04ab7dedf9..000000000000 --- a/sound/soc/codecs/alc5621.c +++ /dev/null @@ -1,1932 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include "alc5621.h" - -#if REALTEK_HWDEP - -#include -#include - -#endif - -#define AUDIO_NAME "rt5621" -#define RT5621_VERSION "alsa 1.0.21 0.05" - -#ifdef RT5621_DEBUG -#define dbg(format, arg...) \ - printk(KERN_DEBUG AUDIO_NAME ": " format "\n" , ## arg) -#else -#define dbg(format, arg...) do {} while (0) -#endif -#define err(format, arg...) \ - printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg) -#define info(format, arg...) \ - printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg) -#define warn(format, arg...) \ - printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg) - -static int caps_charge = 500; -module_param(caps_charge, int, 0); -MODULE_PARM_DESC(caps_charge, "RT5621 cap charge time (msecs)"); - -/* codec private data */ -struct rt5621_priv { - unsigned int sysclk; -}; - -static struct snd_soc_device *rt5621_socdev; - -struct rt5621_reg{ - - u8 reg_index; - u16 reg_value; -}; - -static struct rt5621_reg init_data[] = { - {RT5621_AUDIO_INTERFACE, 0x8000}, //set I2S codec to slave mode - {RT5621_STEREO_DAC_VOL, 0x0808}, //default stereo DAC volume to 0db - {RT5621_OUTPUT_MIXER_CTRL, 0x0740}, //default output mixer control - {RT5621_ADC_REC_MIXER, 0x3f3f}, //set record source is Mic1 by default - {RT5621_MIC_CTRL, 0x0500}, //set Mic1,Mic2 boost 20db - {RT5621_SPK_OUT_VOL, 0x8080}, //default speaker volume to 0db - {RT5621_HP_OUT_VOL, 0x8888}, //default HP volume to -12db - {RT5621_ADD_CTRL_REG, 0x5f00}, //Class AB/D speaker ratio is 1VDD - {RT5621_STEREO_AD_DA_CLK_CTRL, 0x066d}, //set Dac filter to 256fs - {RT5621_HID_CTRL_INDEX, 0x46}, //Class D setting - {RT5621_HID_CTRL_DATA, 0xFFFF}, //power on Class D Internal register -}; - -#define RT5621_INIT_REG_NUM ARRAY_SIZE(init_data) - -/* - * rt5621 register cache - * We can't read the RT5621 register space when we - * are using 2 wire for device control, so we cache them instead. - */ -static const u16 rt5621_reg[0x80/2]; - - -/* virtual HP mixers regs */ -#define HPL_MIXER 0x80 -#define HPR_MIXER 0x82 -/*reg84*/ -/*bit0,1:for hp pga power control - *bit2,3:for aux pga power control - */ -#define MISC_FUNC_REG 0x84 -static u16 reg80=0,reg82=0, reg84 = 0; - - -/* - * read rt5621 register cache - */ -static inline unsigned int rt5621_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - u16 *cache = codec->reg_cache; - if (reg < 1 || reg > (ARRAY_SIZE(rt5621_reg) + 1)) - return -1; - return cache[reg/2]; -} - - -/* - * write rt5621 register cache - */ - -static inline void rt5621_write_reg_cache(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value) -{ - u16 *cache = codec->reg_cache; - if (reg < 0 || reg > 0x7e) - return; - cache[reg/2] = value; -} - - - -static int rt5621_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - u8 data[3]; - - if(reg>0x7E) - { - if(reg==HPL_MIXER) - reg80=value; - else if(reg==HPR_MIXER) - reg82=value; - else if (reg == MISC_FUNC_REG) - reg84 = value; - else - return -EIO; - - return 0; - } - - - printk("rt5621 write reg=%x,value=%x\n",reg,value); - data[0] = reg; - data[1] = (0xFF00 & value) >> 8; - data[2] = 0x00FF & value; - - if (codec->hw_write(codec->control_data, data, 3) == 3) - { - rt5621_write_reg_cache (codec, reg, value); - printk(KERN_INFO "rt5621 write reg=%x,value=%x\n",reg,value); - return 0; - } - else - { - printk(KERN_ERR "rt5621 write faile\n"); - return -EIO; - } -} - - -static unsigned int rt5621_read(struct snd_soc_codec *codec, unsigned int reg) -{ - u8 data[2]={0}; - unsigned int value=0x0; - - if(reg>0x7E) - { - if(reg==HPL_MIXER) - return reg80; - else if(reg==HPR_MIXER) - return reg82; - else if (reg == MISC_FUNC_REG) - return reg84; - else - return -EIO; - - return -EIO; - } - - - data[0] = reg; -//flove031811_S -#if 0 - i2c_master_recv(codec->control_data, data, 2); - - value = (data[0]<<8) | data[1]; - printk("rt5621_read reg%x=%x\n",reg,value); -#elif 1 - - i2c_master_reg8_recv(codec->control_data,reg,data, 2,100 * 1000); - - value = (data[0]<<8) | data[1]; - printk("rt5621_read reg%x=%x\n",reg,value); - return value; - -#else - if(codec->hw_write(codec->control_data, data, 1) ==1) - { - i2c_master_recv(codec->control_data, data, 2); - - value = (data[0]<<8) | data[1]; - printk(KERN_DEBUG "rt5621 read reg%x=%x\n",reg,value); - - return value; - } - else - { - printk(KERN_ERR "rt5621 read faile\n"); - return -EIO; - } -#endif -//flove031811_E -} - -#define rt5621_write_mask(c, reg, value, mask) snd_soc_update_bits(c, reg, mask, value) - - -#define rt5621_reset(c) rt5621_write(c, 0x0, 0) - -static unsigned int rt5621_read_index(struct snd_soc_codec *codec, unsigned int index) -{ - unsigned int value; - - rt5621_write(codec, 0x6a, index); - mdelay(1); - value = rt5621_read(codec, 0x6c); - return value; -} - -static int rt5621_init_reg(struct snd_soc_codec *codec) -{ - int i; - - for (i = 0; i < RT5621_INIT_REG_NUM; i++) - { - rt5621_write(codec, init_data[i].reg_index, init_data[i].reg_value); - } - - return 0; -} - - -#if !USE_DAPM_CONTROL -//***************************************************************************** -// -//function:Change audio codec power status -// -//***************************************************************************** -static int rt5621_ChangeCodecPowerStatus(struct snd_soc_codec *codec,int power_state) -{ - unsigned short int PowerDownState=0; - - switch(power_state) - { - case POWER_STATE_D0: //FULL ON-----power on all power - - rt5621_write(codec,RT5621_PWR_MANAG_ADD1,~PowerDownState); - rt5621_write(codec,RT5621_PWR_MANAG_ADD2,~PowerDownState); - rt5621_write(codec,RT5621_PWR_MANAG_ADD3,~PowerDownState); - - break; - - case POWER_STATE_D1: //LOW ON----- - - - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD2 ,PWR_VREF |PWR_DAC_REF_CIR |PWR_L_DAC_CLK |PWR_R_DAC_CLK |PWR_L_HP_MIXER |PWR_R_HP_MIXER| - PWR_L_ADC_CLK_GAIN |PWR_R_ADC_CLK_GAIN |PWR_L_ADC_REC_MIXER |PWR_R_ADC_REC_MIXER|PWR_CLASS_AB - ,PWR_VREF |PWR_DAC_REF_CIR |PWR_L_DAC_CLK |PWR_R_DAC_CLK |PWR_L_HP_MIXER |PWR_R_HP_MIXER| - PWR_L_ADC_CLK_GAIN |PWR_R_ADC_CLK_GAIN |PWR_L_ADC_REC_MIXER |PWR_R_ADC_REC_MIXER|PWR_CLASS_AB); - - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD3 ,PWR_MAIN_BIAS|PWR_HP_R_OUT_VOL|PWR_HP_L_OUT_VOL|PWR_SPK_OUT| - PWR_MIC1_FUN_CTRL|PWR_MIC1_BOOST_MIXER - ,PWR_MAIN_BIAS|PWR_HP_R_OUT_VOL|PWR_HP_L_OUT_VOL|PWR_SPK_OUT| - PWR_MIC1_FUN_CTRL|PWR_MIC1_BOOST_MIXER); - - - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD1 ,PWR_MAIN_I2S_EN|PWR_HP_OUT_ENH_AMP|PWR_HP_OUT_AMP|PWR_MIC1_BIAS_EN - ,PWR_MAIN_I2S_EN|PWR_HP_OUT_ENH_AMP|PWR_HP_OUT_AMP|PWR_MIC1_BIAS_EN); - - break; - - case POWER_STATE_D1_PLAYBACK: //Low on of Playback - - - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD2,PWR_VREF|PWR_DAC_REF_CIR|PWR_L_DAC_CLK|PWR_R_DAC_CLK|PWR_L_HP_MIXER|PWR_R_HP_MIXER|PWR_CLASS_AB|PWR_CLASS_D - ,PWR_VREF|PWR_DAC_REF_CIR|PWR_L_DAC_CLK|PWR_R_DAC_CLK|PWR_L_HP_MIXER|PWR_R_HP_MIXER|PWR_CLASS_AB|PWR_CLASS_D); - - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD3,PWR_MAIN_BIAS|PWR_HP_R_OUT_VOL|PWR_HP_L_OUT_VOL|PWR_SPK_OUT - ,PWR_MAIN_BIAS|PWR_HP_R_OUT_VOL|PWR_HP_L_OUT_VOL|PWR_SPK_OUT); - - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD1,PWR_MAIN_I2S_EN|PWR_HP_OUT_ENH_AMP|PWR_HP_OUT_AMP - ,PWR_MAIN_I2S_EN|PWR_HP_OUT_ENH_AMP|PWR_HP_OUT_AMP); - - - break; - - case POWER_STATE_D1_RECORD: //Low on of Record - - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD1 ,PWR_MAIN_I2S_EN|PWR_MIC1_BIAS_EN - ,PWR_MAIN_I2S_EN|PWR_MIC1_BIAS_EN); - - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD2 ,PWR_VREF|PWR_L_ADC_CLK_GAIN|PWR_R_ADC_CLK_GAIN|PWR_L_ADC_REC_MIXER|PWR_R_ADC_REC_MIXER - ,PWR_VREF|PWR_L_ADC_CLK_GAIN|PWR_R_ADC_CLK_GAIN|PWR_L_ADC_REC_MIXER|PWR_R_ADC_REC_MIXER); - - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD3 ,PWR_MAIN_BIAS|PWR_MIC2_BOOST_MIXER|PWR_MIC1_BOOST_MIXER - ,PWR_MAIN_BIAS|PWR_MIC2_BOOST_MIXER|PWR_MIC1_BOOST_MIXER); - - break; - - case POWER_STATE_D2: //STANDBY---- - - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD1 ,0,PWR_MAIN_I2S_EN|PWR_HP_OUT_ENH_AMP|PWR_HP_OUT_AMP|PWR_MIC1_BIAS_EN); - - - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD3 ,0,PWR_HP_R_OUT_VOL|PWR_HP_L_OUT_VOL|PWR_SPK_OUT|PWR_MIC1_FUN_CTRL|PWR_MIC1_BOOST_MIXER); - - - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD2 ,0,PWR_DAC_REF_CIR |PWR_L_DAC_CLK |PWR_R_DAC_CLK |PWR_L_HP_MIXER |PWR_R_HP_MIXER| - PWR_L_ADC_CLK_GAIN |PWR_R_ADC_CLK_GAIN |PWR_L_ADC_REC_MIXER |PWR_R_ADC_REC_MIXER|PWR_CLASS_AB|PWR_CLASS_D); - - - break; - - case POWER_STATE_D2_PLAYBACK: //STANDBY of playback - - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD3 ,0,/*PWR_HP_R_OUT_VOL|PWR_HP_L_OUT_VOL|*/PWR_SPK_OUT); - - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD1 ,0,PWR_HP_OUT_ENH_AMP|PWR_HP_OUT_AMP); - - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD2 ,0,PWR_DAC_REF_CIR|PWR_L_DAC_CLK|PWR_R_DAC_CLK|PWR_L_HP_MIXER|PWR_R_HP_MIXER|PWR_CLASS_AB|PWR_CLASS_D); - - break; - - case POWER_STATE_D2_RECORD: //STANDBY of record - - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD1 ,0,PWR_MIC1_BIAS_EN); - - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD2 ,0,PWR_L_ADC_CLK_GAIN|PWR_R_ADC_CLK_GAIN|PWR_L_ADC_REC_MIXER|PWR_R_ADC_REC_MIXER); - - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD3 ,0,PWR_MIC2_BOOST_MIXER|PWR_MIC1_BOOST_MIXER); - - break; - - case POWER_STATE_D3: //SLEEP - case POWER_STATE_D4: //OFF----power off all power - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD1 ,0,PWR_HP_OUT_ENH_AMP|PWR_HP_OUT_AMP); - rt5621_write(codec,RT5621_PWR_MANAG_ADD3,0); - rt5621_write(codec,RT5621_PWR_MANAG_ADD1,0); - rt5621_write(codec,RT5621_PWR_MANAG_ADD2,0); - - break; - - default: - - break; - } - - return 0; -} - - -//***************************************************************************** -// -//function AudioOutEnable:Mute/Unmute audio out channel -// WavOutPath:output channel -// Mute :Mute/Unmute output channel -// -//***************************************************************************** -static int rt5621_AudioOutEnable(struct snd_soc_codec *codec,unsigned short int WavOutPath,int Mute) -{ - int RetVal=0; - - if(Mute) - { - switch(WavOutPath) - { - case RT_WAVOUT_ALL_ON: - - RetVal=rt5621_write_mask(codec,RT5621_SPK_OUT_VOL,RT_L_MUTE|RT_R_MUTE,RT_L_MUTE|RT_R_MUTE); //Mute Speaker right/left channel - RetVal=rt5621_write_mask(codec,RT5621_HP_OUT_VOL,RT_L_MUTE|RT_R_MUTE,RT_L_MUTE|RT_R_MUTE); //Mute headphone right/left channel - RetVal=rt5621_write_mask(codec,RT5621_MONO_AUX_OUT_VOL,RT_L_MUTE|RT_R_MUTE,RT_L_MUTE|RT_R_MUTE); //Mute Aux/Mono right/left channel - RetVal=rt5621_write_mask(codec,RT5621_STEREO_DAC_VOL,RT_M_HP_MIXER|RT_M_SPK_MIXER|RT_M_MONO_MIXER - ,RT_M_HP_MIXER|RT_M_SPK_MIXER|RT_M_MONO_MIXER); //Mute DAC to HP,Speaker,Mono Mixer - - break; - - case RT_WAVOUT_HP: - - RetVal=rt5621_write_mask(codec,RT5621_HP_OUT_VOL,RT_L_MUTE|RT_R_MUTE,RT_L_MUTE|RT_R_MUTE); //Mute headphone right/left channel - - break; - - case RT_WAVOUT_SPK: - - RetVal=rt5621_write_mask(codec,RT5621_SPK_OUT_VOL,RT_L_MUTE|RT_R_MUTE,RT_L_MUTE|RT_R_MUTE); //Mute Speaker right/left channel - - break; - - case RT_WAVOUT_AUXOUT: - - RetVal=rt5621_write_mask(codec,RT5621_MONO_AUX_OUT_VOL,RT_L_MUTE|RT_R_MUTE,RT_L_MUTE|RT_R_MUTE); //Mute AuxOut right/left channel - - break; - - case RT_WAVOUT_MONO: - - RetVal=rt5621_write_mask(codec,RT5621_MONO_AUX_OUT_VOL,RT_L_MUTE,RT_L_MUTE); //Mute MonoOut channel - - break; - - case RT_WAVOUT_DAC: - - RetVal=rt5621_write_mask(codec,RT5621_STEREO_DAC_VOL,RT_M_HP_MIXER|RT_M_SPK_MIXER|RT_M_MONO_MIXER - ,RT_M_HP_MIXER|RT_M_SPK_MIXER|RT_M_MONO_MIXER); //Mute DAC to HP,Speaker,Mono Mixer - break; - - default: - - return 0; - - } - } - else - { - switch(WavOutPath) - { - - case RT_WAVOUT_ALL_ON: - - RetVal=rt5621_write_mask(codec,RT5621_SPK_OUT_VOL ,0,RT_L_MUTE|RT_R_MUTE); //Mute Speaker right/left channel - RetVal=rt5621_write_mask(codec,RT5621_HP_OUT_VOL ,0,RT_L_MUTE|RT_R_MUTE); //Mute headphone right/left channel - RetVal=rt5621_write_mask(codec,RT5621_MONO_AUX_OUT_VOL ,0,RT_L_MUTE|RT_R_MUTE); //Mute Aux/Mono right/left channel - RetVal=rt5621_write_mask(codec,RT5621_STEREO_DAC_VOL ,0,RT_M_HP_MIXER|RT_M_SPK_MIXER|RT_M_MONO_MIXER); //Mute DAC to HP,Speaker,Mono Mixer - - break; - - case RT_WAVOUT_HP: - - RetVal=rt5621_write_mask(codec,RT5621_HP_OUT_VOL,0,RT_L_MUTE|RT_R_MUTE); //UnMute headphone right/left channel - - break; - - case RT_WAVOUT_SPK: - - RetVal=rt5621_write_mask(codec,RT5621_SPK_OUT_VOL,0,RT_L_MUTE|RT_R_MUTE); //unMute Speaker right/left channel - - break; - - case RT_WAVOUT_AUXOUT: - - RetVal=rt5621_write_mask(codec,RT5621_MONO_AUX_OUT_VOL,0,RT_L_MUTE|RT_R_MUTE);//unMute AuxOut right/left channel - - break; - - case RT_WAVOUT_MONO: - - RetVal=rt5621_write_mask(codec,RT5621_MONO_AUX_OUT_VOL,0,RT_L_MUTE); //unMute MonoOut channel - - break; - - case RT_WAVOUT_DAC: - - RetVal=rt5621_write_mask(codec,RT5621_STEREO_DAC_VOL,0,RT_M_HP_MIXER|RT_M_SPK_MIXER|RT_M_MONO_MIXER); //unMute DAC to HP,Speaker,Mono Mixer - - default: - return 0; - } - - } - - return RetVal; -} - - -//***************************************************************************** -// -//function:Enable/Disable ADC input source control -// -//***************************************************************************** -static int Enable_ADC_Input_Source(struct snd_soc_codec *codec,unsigned short int ADC_Input_Sour,int Enable) -{ - int bRetVal=0; - - if(Enable) - { - //Enable ADC source - bRetVal=rt5621_write_mask(codec,RT5621_ADC_REC_MIXER,0,ADC_Input_Sour); - } - else - { - //Disable ADC source - bRetVal=rt5621_write_mask(codec,RT5621_ADC_REC_MIXER,ADC_Input_Sour,ADC_Input_Sour); - } - - return bRetVal; -} -#endif - - -//static const char *rt5621_spkl_pga[] = {"Vmid","HPL mixer","SPK mixer","Mono Mixer"}; -static const char *rt5621_spkn_source_sel[] = {"RN", "RP", "LN"}; -static const char *rt5621_spk_pga[] = {"Vmid","HP mixer","SPK mixer","Mono Mixer"}; -static const char *rt5621_hpl_pga[] = {"Vmid","HPL mixer"}; -static const char *rt5621_hpr_pga[] = {"Vmid","HPR mixer"}; -static const char *rt5621_mono_pga[] = {"Vmid","HP mixer","SPK mixer","Mono Mixer"}; -static const char *rt5621_amp_type_sel[] = {"Class AB","Class D"}; -static const char *rt5621_mic_boost_sel[] = {"Bypass","20db","30db","40db"}; - -static const struct soc_enum rt5621_enum[] = { -SOC_ENUM_SINGLE(RT5621_OUTPUT_MIXER_CTRL, 14, 3, rt5621_spkn_source_sel), /* spkn source from hp mixer */ -SOC_ENUM_SINGLE(RT5621_OUTPUT_MIXER_CTRL, 10, 4, rt5621_spk_pga), /* spk input sel 1 */ -SOC_ENUM_SINGLE(RT5621_OUTPUT_MIXER_CTRL, 9, 2, rt5621_hpl_pga), /* hp left input sel 2 */ -SOC_ENUM_SINGLE(RT5621_OUTPUT_MIXER_CTRL, 8, 2, rt5621_hpr_pga), /* hp right input sel 3 */ -SOC_ENUM_SINGLE(RT5621_OUTPUT_MIXER_CTRL, 6, 4, rt5621_mono_pga), /* mono input sel 4 */ -SOC_ENUM_SINGLE(RT5621_MIC_CTRL , 10,4, rt5621_mic_boost_sel), /*Mic1 boost sel 5 */ -SOC_ENUM_SINGLE(RT5621_MIC_CTRL , 8,4,rt5621_mic_boost_sel), /*Mic2 boost sel 6 */ -SOC_ENUM_SINGLE(RT5621_OUTPUT_MIXER_CTRL,13,2,rt5621_amp_type_sel), /*Speaker AMP sel 7 */ -}; - -static int rt5621_amp_sel_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned short val; - unsigned short mask, bitmask; - - for (bitmask = 1; bitmask < e->max; bitmask <<= 1) - ; - if (ucontrol->value.enumerated.item[0] > e->max - 1) - return -EINVAL; - val = ucontrol->value.enumerated.item[0] << e->shift_l; - mask = (bitmask - 1) << e->shift_l; - if (e->shift_l != e->shift_r) { - if (ucontrol->value.enumerated.item[1] > e->max - 1) - return -EINVAL; - val |= ucontrol->value.enumerated.item[1] << e->shift_r; - mask |= (bitmask - 1) << e->shift_r; - } - - snd_soc_update_bits(codec, e->reg, mask, val); - val &= (0x1 << 13); - if (val == 0) - { - snd_soc_update_bits(codec, 0x3c, 0x0000, 0x4000); /*power off classd*/ - snd_soc_update_bits(codec, 0x3c, 0x8000, 0x8000); /*power on classab*/ - } - else - { - snd_soc_update_bits(codec, 0x3c, 0x0000, 0x8000); /*power off classab*/ - snd_soc_update_bits(codec, 0x3c, 0x4000, 0x4000); /*power on classd*/ - } - return 0; -} - - - -static const struct snd_kcontrol_new rt5621_snd_controls[] = { -SOC_DOUBLE("Speaker Playback Volume", RT5621_SPK_OUT_VOL, 8, 0, 31, 1), -SOC_DOUBLE("Speaker Playback Switch", RT5621_SPK_OUT_VOL, 15, 7, 1, 1), -SOC_DOUBLE("Headphone Playback Volume", RT5621_HP_OUT_VOL, 8, 0, 31, 1), -SOC_DOUBLE("Headphone Playback Switch", RT5621_HP_OUT_VOL,15, 7, 1, 1), -SOC_DOUBLE("AUX Playback Volume", RT5621_MONO_AUX_OUT_VOL, 8, 0, 31, 1), -SOC_DOUBLE("AUX Playback Switch", RT5621_MONO_AUX_OUT_VOL, 15, 7, 1, 1), -SOC_DOUBLE("PCM Playback Volume", RT5621_STEREO_DAC_VOL, 8, 0, 31, 1), -SOC_DOUBLE("Line In Volume", RT5621_LINE_IN_VOL, 8, 0, 31, 1), -SOC_SINGLE("Mic 1 Volume", RT5621_MIC_VOL, 8, 31, 1), -SOC_SINGLE("Mic 2 Volume", RT5621_MIC_VOL, 0, 31, 1), -SOC_ENUM("Mic 1 Boost", rt5621_enum[5]), -SOC_ENUM("Mic 2 Boost", rt5621_enum[6]), -SOC_ENUM_EXT("Speaker Amp Type", rt5621_enum[7], snd_soc_get_enum_double, rt5621_amp_sel_put), -SOC_DOUBLE("AUX In Volume", RT5621_AUXIN_VOL, 8, 0, 31, 1), -SOC_DOUBLE("Capture Volume", RT5621_ADC_REC_GAIN, 7, 0, 31, 0), -}; - - - -/* add non dapm controls */ -static int rt5621_add_controls(struct snd_soc_codec *codec) -{ - int err, i; - - for (i = 0; i < ARRAY_SIZE(rt5621_snd_controls); i++) { - err = snd_ctl_add(codec->card, - snd_soc_cnew(&rt5621_snd_controls[i],codec, NULL)); - if (err < 0) - return err; - } - return 0; -} - -void hp_depop_mode2(struct snd_soc_codec *codec) -{ - rt5621_write_mask(codec, 0x3e, 0x8000, 0x8000); - rt5621_write_mask(codec, 0x04, 0x8080, 0x8080); - rt5621_write_mask(codec, 0x3a, 0x0100, 0x0100); - rt5621_write_mask(codec, 0x3c, 0x2000, 0x2000); - rt5621_write_mask(codec, 0x3e, 0x0600, 0x0600); - rt5621_write_mask(codec, 0x5e, 0x0200, 0x0200); - schedule_timeout_uninterruptible(msecs_to_jiffies(300)); -} - -void aux_depop_mode2(struct snd_soc_codec *codec) -{ - rt5621_write_mask(codec, 0x3e, 0x8000, 0x8000); - rt5621_write_mask(codec, 0x06, 0x8080, 0x8080); - rt5621_write_mask(codec, 0x3a, 0x0100, 0x0100); - rt5621_write_mask(codec, 0x3c, 0x2000, 0x2000); - rt5621_write_mask(codec, 0x3e, 0x6000, 0x6000); - rt5621_write_mask(codec, 0x5e, 0x0020, 0x0200); - schedule_timeout_uninterruptible(msecs_to_jiffies(300)); - rt5621_write_mask(codec, 0x3a, 0x0002, 0x0002); - rt5621_write_mask(codec, 0x3a, 0x0001, 0x0001); -} -#if USE_DAPM_CONTROL - -/* - * _DAPM_ Controls - */ - -/* We have to create a fake left and right HP mixers because - * the codec only has a single control that is shared by both channels. - * This makes it impossible to determine the audio path using the current - * register map, thus we add a new (virtual) register to help determine the - * audio route within the device. - */ - static int mixer_event (struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - - u16 l, r, lineIn,mic1,mic2, aux, pcm; - - l = rt5621_read(w->codec, HPL_MIXER); - r = rt5621_read(w->codec, HPR_MIXER); - lineIn = rt5621_read(w->codec, RT5621_LINE_IN_VOL); - mic2 = rt5621_read(w->codec, RT5621_MIC_ROUTING_CTRL); - aux = rt5621_read(w->codec,RT5621_AUXIN_VOL); - pcm = rt5621_read(w->codec, RT5621_STEREO_DAC_VOL); - - - if (event & SND_SOC_DAPM_PRE_REG) - return 0; - - if (l & 0x1 || r & 0x1) - rt5621_write(w->codec, RT5621_STEREO_DAC_VOL, pcm & 0x7fff); - else - rt5621_write(w->codec, RT5621_STEREO_DAC_VOL, pcm | 0x8000); - - if (l & 0x2 || r & 0x2) - rt5621_write(w->codec, RT5621_MIC_ROUTING_CTRL, mic2 & 0xff7f); - else - rt5621_write(w->codec, RT5621_MIC_ROUTING_CTRL, mic2 | 0x0080); - - mic1 = rt5621_read(w->codec, RT5621_MIC_ROUTING_CTRL); - if (l & 0x4 || r & 0x4) - rt5621_write(w->codec, RT5621_MIC_ROUTING_CTRL, mic1 & 0x7fff); - else - rt5621_write(w->codec, RT5621_MIC_ROUTING_CTRL, mic1 | 0x8000); - - if (l & 0x8 || r & 0x8) - rt5621_write(w->codec, RT5621_AUXIN_VOL, aux & 0x7fff); - else - rt5621_write(w->codec, RT5621_AUXIN_VOL, aux | 0x8000); - - if (l & 0x10 || r & 0x10) - rt5621_write(w->codec, RT5621_LINE_IN_VOL, lineIn & 0x7fff); - else - rt5621_write(w->codec, RT5621_LINE_IN_VOL, lineIn | 0x8000); - - return 0; -} - - -static int hp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - unsigned int reg = rt5621_read(codec, MISC_FUNC_REG); - - if (((reg & 0x03) != 0x00) && ((reg & 0x03) != 0x03)) - return 0; - - switch (event) - { - case SND_SOC_DAPM_POST_PMU: - hp_depop_mode2(codec); - rt5621_write_mask(codec, 0x04, 0x0000, 0x8080); - rt5621_write_mask(codec, 0x3a, 0x0020, 0x0020); - break; - case SND_SOC_DAPM_POST_PMD: - rt5621_write_mask(codec, 0x04, 0x8080, 0x8080); - rt5621_write_mask(codec, 0x3a, 0x0000, 0x0010); - rt5621_write_mask(codec, 0x3a, 0x0000, 0x0020); - rt5621_write_mask(codec, 0x3e, 0x0000, 0x0600); - break; - } - return 0; -} - -static int aux_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - unsigned int reg = rt5621_read(codec, MISC_FUNC_REG); - - if (((reg & 0x0c) != 0x00) && ((reg & 0x0c) != 0x0c)) - return 0; - - switch (event) - { - case SND_SOC_DAPM_POST_PMU: - aux_depop_mode2(codec); - rt5621_write_mask(codec, 0x06, 0x0000, 0x8080); - break; - case SND_SOC_DAPM_POST_PMD: - rt5621_write_mask(codec, 0x06, 0x8080, 0x8080); - rt5621_write_mask(codec, 0x3a, 0x0000, 0x0001); - rt5621_write_mask(codec, 0x3a, 0x0000, 0x0002); - rt5621_write_mask(codec, 0x3e, 0x0000, 0x6000); - break; - } - return 0; -} - -/* Left Headphone Mixers */ -static const struct snd_kcontrol_new rt5621_hpl_mixer_controls[] = { -SOC_DAPM_SINGLE("LineIn Playback Switch", HPL_MIXER, 4, 1, 0), -SOC_DAPM_SINGLE("AUXIN Playback Switch", HPL_MIXER, 3, 1, 0), -SOC_DAPM_SINGLE("Mic1 Playback Switch", HPL_MIXER, 2, 1, 0), -SOC_DAPM_SINGLE("Mic2 Playback Switch", HPL_MIXER, 1, 1, 0), -SOC_DAPM_SINGLE("PCM Playback Switch", HPL_MIXER, 0, 1, 0), -SOC_DAPM_SINGLE("RecordL Playback Switch", RT5621_ADC_REC_GAIN, 15, 1,1), -}; - -/* Right Headphone Mixers */ -static const struct snd_kcontrol_new rt5621_hpr_mixer_controls[] = { -SOC_DAPM_SINGLE("LineIn Playback Switch", HPR_MIXER, 4, 1, 0), -SOC_DAPM_SINGLE("AUXIN Playback Switch", HPR_MIXER, 3, 1, 0), -SOC_DAPM_SINGLE("Mic1 Playback Switch", HPR_MIXER, 2, 1, 0), -SOC_DAPM_SINGLE("Mic2 Playback Switch", HPR_MIXER, 1, 1, 0), -SOC_DAPM_SINGLE("PCM Playback Switch", HPR_MIXER, 0, 1, 0), -SOC_DAPM_SINGLE("RecordR Playback Switch", RT5621_ADC_REC_GAIN, 14, 1,1), -}; - -//Left Record Mixer -static const struct snd_kcontrol_new rt5621_captureL_mixer_controls[] = { -SOC_DAPM_SINGLE("Mic1 Capture Switch", RT5621_ADC_REC_MIXER, 14, 1, 1), -SOC_DAPM_SINGLE("Mic2 Capture Switch", RT5621_ADC_REC_MIXER, 13, 1, 1), -SOC_DAPM_SINGLE("LineInL Capture Switch",RT5621_ADC_REC_MIXER,12, 1, 1), -SOC_DAPM_SINGLE("AUXIN Capture Switch", RT5621_ADC_REC_MIXER, 11, 1, 1), -SOC_DAPM_SINGLE("HPMixerL Capture Switch", RT5621_ADC_REC_MIXER,10, 1, 1), -SOC_DAPM_SINGLE("SPKMixer Capture Switch",RT5621_ADC_REC_MIXER,9, 1, 1), -SOC_DAPM_SINGLE("MonoMixer Capture Switch",RT5621_ADC_REC_MIXER,8, 1, 1), -}; - - -//Right Record Mixer -static const struct snd_kcontrol_new rt5621_captureR_mixer_controls[] = { -SOC_DAPM_SINGLE("Mic1 Capture Switch", RT5621_ADC_REC_MIXER, 6, 1, 1), -SOC_DAPM_SINGLE("Mic2 Capture Switch", RT5621_ADC_REC_MIXER, 5, 1, 1), -SOC_DAPM_SINGLE("LineInR Capture Switch",RT5621_ADC_REC_MIXER,4, 1, 1), -SOC_DAPM_SINGLE("AUXIN Capture Switch", RT5621_ADC_REC_MIXER, 3, 1, 1), -SOC_DAPM_SINGLE("HPMixerR Capture Switch", RT5621_ADC_REC_MIXER,2, 1, 1), -SOC_DAPM_SINGLE("SPKMixer Capture Switch",RT5621_ADC_REC_MIXER,1, 1, 1), -SOC_DAPM_SINGLE("MonoMixer Capture Switch",RT5621_ADC_REC_MIXER,0, 1, 1), -}; - -/* Speaker Mixer */ -static const struct snd_kcontrol_new rt5621_speaker_mixer_controls[] = { -SOC_DAPM_SINGLE("LineIn Playback Switch", RT5621_LINE_IN_VOL, 14, 1, 1), -SOC_DAPM_SINGLE("AUXIN Playback Switch", RT5621_AUXIN_VOL, 14, 1, 1), -SOC_DAPM_SINGLE("Mic1 Playback Switch", RT5621_MIC_ROUTING_CTRL, 14, 1, 1), -SOC_DAPM_SINGLE("Mic2 Playback Switch", RT5621_MIC_ROUTING_CTRL, 6, 1, 1), -SOC_DAPM_SINGLE("PCM Playback Switch", RT5621_STEREO_DAC_VOL, 14, 1, 1), -}; - - -/* Mono Mixer */ -static const struct snd_kcontrol_new rt5621_mono_mixer_controls[] = { -SOC_DAPM_SINGLE("LineIn Playback Switch", RT5621_LINE_IN_VOL, 13, 1, 1), -SOC_DAPM_SINGLE("Mic1 Playback Switch", RT5621_MIC_ROUTING_CTRL, 13, 1, 1), -SOC_DAPM_SINGLE("Mic2 Playback Switch", RT5621_MIC_ROUTING_CTRL, 5, 1, 1), -SOC_DAPM_SINGLE("AUXIN Playback Switch", RT5621_AUXIN_VOL, 13, 1, 1), -SOC_DAPM_SINGLE("PCM Playback Switch", RT5621_STEREO_DAC_VOL, 13, 1, 1), -SOC_DAPM_SINGLE("RecordL Playback Switch", RT5621_ADC_REC_GAIN, 13, 1,1), -SOC_DAPM_SINGLE("RecordR Playback Switch", RT5621_ADC_REC_GAIN, 12, 1,1), -}; - -/* mono output mux */ -static const struct snd_kcontrol_new rt5621_mono_mux_controls = -SOC_DAPM_ENUM("Route", rt5621_enum[4]); - -/* speaker left output mux */ -static const struct snd_kcontrol_new rt5621_hp_spk_mux_controls = -SOC_DAPM_ENUM("Route", rt5621_enum[1]); - - -/* headphone left output mux */ -static const struct snd_kcontrol_new rt5621_hpl_out_mux_controls = -SOC_DAPM_ENUM("Route", rt5621_enum[2]); - -/* headphone right output mux */ -static const struct snd_kcontrol_new rt5621_hpr_out_mux_controls = -SOC_DAPM_ENUM("Route", rt5621_enum[3]); - -static const struct snd_soc_dapm_widget rt5621_dapm_widgets[] = { -SND_SOC_DAPM_MUX("Mono Out Mux", SND_SOC_NOPM, 0, 0, - &rt5621_mono_mux_controls), -SND_SOC_DAPM_MUX("Speaker Out Mux", SND_SOC_NOPM, 0, 0, - &rt5621_hp_spk_mux_controls), -SND_SOC_DAPM_MUX("Left Headphone Out Mux", SND_SOC_NOPM, 0, 0, - &rt5621_hpl_out_mux_controls), -SND_SOC_DAPM_MUX("Right Headphone Out Mux", SND_SOC_NOPM, 0, 0, - &rt5621_hpr_out_mux_controls), - -SND_SOC_DAPM_MIXER_E("Left HP Mixer",RT5621_PWR_MANAG_ADD2, 5, 0, - &rt5621_hpl_mixer_controls[0], ARRAY_SIZE(rt5621_hpl_mixer_controls), - mixer_event, SND_SOC_DAPM_POST_REG), -SND_SOC_DAPM_MIXER_E("Right HP Mixer",RT5621_PWR_MANAG_ADD2, 4, 0, - &rt5621_hpr_mixer_controls[0], ARRAY_SIZE(rt5621_hpr_mixer_controls), - mixer_event, SND_SOC_DAPM_POST_REG), -SND_SOC_DAPM_MIXER("Mono Mixer", RT5621_PWR_MANAG_ADD2, 2, 0, - &rt5621_mono_mixer_controls[0], ARRAY_SIZE(rt5621_mono_mixer_controls)), - -SND_SOC_DAPM_MIXER("Speaker Mixer", RT5621_PWR_MANAG_ADD2,3,0, - &rt5621_speaker_mixer_controls[0], ARRAY_SIZE(rt5621_speaker_mixer_controls)), - -SND_SOC_DAPM_MIXER("Left Record Mixer", RT5621_PWR_MANAG_ADD2,1,0, - &rt5621_captureL_mixer_controls[0], ARRAY_SIZE(rt5621_captureL_mixer_controls)), -SND_SOC_DAPM_MIXER("Right Record Mixer", RT5621_PWR_MANAG_ADD2,0,0, - &rt5621_captureR_mixer_controls[0], ARRAY_SIZE(rt5621_captureR_mixer_controls)), - -SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", RT5621_PWR_MANAG_ADD2,9, 0), -SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", RT5621_PWR_MANAG_ADD2, 8, 0), - -SND_SOC_DAPM_MIXER("IIS Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), -SND_SOC_DAPM_MIXER("HP Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), - -SND_SOC_DAPM_MIXER("Line Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), -SND_SOC_DAPM_MIXER("AUXIN Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), - -SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture", RT5621_PWR_MANAG_ADD2, 7, 0), -SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture", RT5621_PWR_MANAG_ADD2, 6, 0), - -SND_SOC_DAPM_PGA_E("Left Headphone", MISC_FUNC_REG, 0, 0, NULL, 0, - hp_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), -SND_SOC_DAPM_PGA_E("Right Headphone", MISC_FUNC_REG, 1, 0, NULL, 0, - hp_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - -SND_SOC_DAPM_PGA("Speaker PGA", RT5621_PWR_MANAG_ADD3, 12, 0, NULL, 0), - -SND_SOC_DAPM_PGA_E("AUXL Out", MISC_FUNC_REG, 2, 0, NULL, 0, - aux_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), -SND_SOC_DAPM_PGA_E("AUXR Out", MISC_FUNC_REG, 3, 0, NULL, 0, - aux_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - -SND_SOC_DAPM_PGA("Left Line In", RT5621_PWR_MANAG_ADD3, 7, 0, NULL, 0), -SND_SOC_DAPM_PGA("Right Line In", RT5621_PWR_MANAG_ADD3, 6, 0, NULL, 0), -SND_SOC_DAPM_PGA("Left AUX In", RT5621_PWR_MANAG_ADD3, 5, 0, NULL, 0), -SND_SOC_DAPM_PGA("Right AUX In", RT5621_PWR_MANAG_ADD3, 4, 0, NULL, 0), - -SND_SOC_DAPM_PGA("Mic 1 PGA", RT5621_PWR_MANAG_ADD3, 3, 0, NULL, 0), -SND_SOC_DAPM_PGA("Mic 2 PGA", RT5621_PWR_MANAG_ADD3, 2, 0, NULL, 0), -SND_SOC_DAPM_PGA("Mic 1 Pre Amp", RT5621_PWR_MANAG_ADD3, 1, 0, NULL, 0), -SND_SOC_DAPM_PGA("Mic 2 Pre Amp", RT5621_PWR_MANAG_ADD3, 0, 0, NULL, 0), - -SND_SOC_DAPM_MICBIAS("Mic Bias1", RT5621_PWR_MANAG_ADD1, 11, 0), - -SND_SOC_DAPM_OUTPUT("AUXL"), -SND_SOC_DAPM_OUTPUT("AUXR"), -SND_SOC_DAPM_OUTPUT("HPL"), -SND_SOC_DAPM_OUTPUT("HPR"), -SND_SOC_DAPM_OUTPUT("SPK"), - -SND_SOC_DAPM_INPUT("LINEL"), -SND_SOC_DAPM_INPUT("LINER"), -SND_SOC_DAPM_INPUT("AUXINL"), -SND_SOC_DAPM_INPUT("AUXINR"), -SND_SOC_DAPM_INPUT("MIC1"), -SND_SOC_DAPM_INPUT("MIC2"), -SND_SOC_DAPM_VMID("VMID"), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - /* left HP mixer */ - {"Left HP Mixer" , "LineIn Playback Switch" , "Left Line In"}, - {"Left HP Mixer" , "AUXIN Playback Switch" , "Left AUX In"}, - {"Left HP Mixer" , "Mic1 Playback Switch" , "Mic 1 PGA"}, - {"Left HP Mixer" , "Mic2 Playback Switch" , "Mic 2 PGA"}, - {"Left HP Mixer" , "PCM Playback Switch" , "Left DAC"}, - {"Left HP Mixer" , "RecordL Playback Switch" , "Left Record Mixer"}, - - /* right HP mixer */ - {"Right HP Mixer" , "LineIn Playback Switch" , "Right Line In"}, - {"Right HP Mixer" , "AUXIN Playback Switch" , "Right AUX In"}, - {"Right HP Mixer" , "Mic1 Playback Switch" , "Mic 1 PGA"}, - {"Right HP Mixer" , "Mic2 Playback Switch" , "Mic 2 PGA"}, - {"Right HP Mixer" , "PCM Playback Switch" , "Right DAC"}, - {"Right HP Mixer" , "RecordR Playback Switch" , "Right Record Mixer"}, - - /* virtual mixer - mixes left & right channels for spk and mono */ - {"IIS Mixer" , NULL , "Left DAC"}, - {"IIS Mixer" , NULL , "Right DAC"}, - {"Line Mixer" , NULL , "Right Line In"}, - {"Line Mixer" , NULL , "Left Line In"}, - {"AUXIN Mixer" , NULL , "Left AUX In"}, - {"AUXIN Mixer" , NULL , "Right AUX In"}, - {"HP Mixer" , NULL , "Left HP Mixer"}, - {"HP Mixer" , NULL , "Right HP Mixer"}, - - /* speaker mixer */ - {"Speaker Mixer" , "LineIn Playback Switch" , "Line Mixer"}, - {"Speaker Mixer" , "AUXIN Playback Switch" , "AUXIN Mixer"}, - {"Speaker Mixer" , "Mic1 Playback Switch" , "Mic 1 PGA"}, - {"Speaker Mixer" , "Mic2 Playback Switch" , "Mic 2 PGA"}, - {"Speaker Mixer" , "PCM Playback Switch" , "IIS Mixer"}, - - - /* mono mixer */ - {"Mono Mixer" , "LineIn Playback Switch" , "Line Mixer"}, - {"Mono Mixer" , "Mic1 Playback Switch" , "Mic 1 PGA"}, - {"Mono Mixer" , "Mic2 Playback Switch" , "Mic 2 PGA"}, - {"Mono Mixer" , "PCM Playback Switch" , "IIS Mixer"}, - {"Mono Mixer" , "AUXIN Playback Switch" , "AUXIN Mixer"}, - {"Mono Mixer" , "RecordL Playback Switch" , "Left Record Mixer"}, - {"Mono Mixer" , "RecordR Playback Switch" , "Right Record Mixer"}, - - /*Left record mixer */ - {"Left Record Mixer" , "Mic1 Capture Switch" , "Mic 1 Pre Amp"}, - {"Left Record Mixer" , "Mic2 Capture Switch" , "Mic 2 Pre Amp"}, - {"Left Record Mixer" , "LineInL Capture Switch" , "LINEL"}, - {"Left Record Mixer" , "AUXIN Capture Switch" , "AUXINL"}, - {"Left Record Mixer" , "HPMixerL Capture Switch" , "Left HP Mixer"}, - {"Left Record Mixer" , "SPKMixer Capture Switch" , "Speaker Mixer"}, - {"Left Record Mixer" , "MonoMixer Capture Switch" , "Mono Mixer"}, - - /*Right record mixer */ - {"Right Record Mixer" , "Mic1 Capture Switch" , "Mic 1 Pre Amp"}, - {"Right Record Mixer" , "Mic2 Capture Switch" , "Mic 2 Pre Amp"}, - {"Right Record Mixer" , "LineInR Capture Switch" , "LINER"}, - {"Right Record Mixer" , "AUXIN Capture Switch" , "AUXINR"}, - {"Right Record Mixer" , "HPMixerR Capture Switch" , "Right HP Mixer"}, - {"Right Record Mixer" , "SPKMixer Capture Switch" , "Speaker Mixer"}, - {"Right Record Mixer" , "MonoMixer Capture Switch" , "Mono Mixer"}, - - /* headphone left mux */ - {"Left Headphone Out Mux" , "HPL mixer" , "Left HP Mixer"}, - - /* headphone right mux */ - {"Right Headphone Out Mux", "HPR mixer", "Right HP Mixer"}, - - /* speaker mux */ - {"Speaker Out Mux", "HP mixer", "HP Mixer"}, - {"Speaker Out Mux", "SPK mixer", "Speaker Mixer"}, - {"Speaker Out Mux", "Mono Mixer", "Mono Mixer"}, - - /* mono mux */ - {"Mono Out Mux", "HP mixer", "HP Mixer"}, - {"Mono Out Mux", "SPK mixer", "Speaker Mixer"}, - {"Mono Out Mux", "Mono Mixer", "Mono Mixer"}, - - /* output pga */ - {"HPL", NULL, "Left Headphone"}, - {"Left Headphone", NULL, "Left Headphone Out Mux"}, - - {"HPR", NULL, "Right Headphone"}, - {"Right Headphone", NULL, "Right Headphone Out Mux"}, - - {"SPK", NULL, "Speaker PGA"}, - {"Speaker PGA", NULL, "Speaker Out Mux"}, - - {"AUXL", NULL, "AUXL Out"}, - {"AUXL Out", NULL, "Mono Out Mux"}, - - {"AUXR", NULL, "AUXR Out"}, - {"AUXR Out", NULL, "Mono Out Mux"}, - - /* input pga */ - {"Left Line In", NULL, "LINEL"}, - {"Right Line In", NULL, "LINER"}, - - {"Left AUX In", NULL, "AUXINL"}, - {"Right AUX In", NULL, "AUXINR"}, - - {"Mic 1 Pre Amp", NULL, "MIC1"}, - {"Mic 2 Pre Amp", NULL, "MIC2"}, - {"Mic 1 PGA", NULL, "Mic 1 Pre Amp"}, - {"Mic 2 PGA", NULL, "Mic 2 Pre Amp"}, - - /* left ADC */ - {"Left ADC", NULL, "Left Record Mixer"}, - - /* right ADC */ - {"Right ADC", NULL, "Right Record Mixer"}, - -}; - -static int rt5621_add_widgets(struct snd_soc_codec *codec) -{ - snd_soc_dapm_new_controls(codec, rt5621_dapm_widgets, - ARRAY_SIZE(rt5621_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_new_widgets(codec); - - return 0; -} - -#else - -static int rt5621_pcm_hw_prepare(struct snd_pcm_substream *substream, - struct snd_soc_dai *codec_dai) -{ - - struct snd_soc_codec *codec = codec_dai->codec; - int stream = substream->stream; - - switch (stream) - { - case SNDRV_PCM_STREAM_PLAYBACK: - - rt5621_ChangeCodecPowerStatus(codec,POWER_STATE_D1_PLAYBACK); //power on dac to hp and speaker out - - rt5621_AudioOutEnable(codec,RT_WAVOUT_SPK,0); //unmute speaker out - - rt5621_AudioOutEnable(codec,RT_WAVOUT_HP,0); //unmute hp out - - break; - case SNDRV_PCM_STREAM_CAPTURE: - - rt5621_ChangeCodecPowerStatus(codec,POWER_STATE_D1_RECORD); //power on input to adc - - Enable_ADC_Input_Source(codec,RT_WAVIN_L_MIC1|RT_WAVIN_R_MIC1,1); //enable record source from mic1 - - break; - } - - return 0; -} - -#endif -/* PLL divisors */ -struct _pll_div { - u32 pll_in; - u32 pll_out; - u16 regvalue; -}; - -static const struct _pll_div codec_pll_div[] = { - - { 2048000, 8192000, 0x0ea0}, - { 3686400, 8192000, 0x4e27}, - { 12000000, 8192000, 0x456b}, - { 13000000, 8192000, 0x495f}, - { 13100000, 8192000, 0x0320}, - { 2048000, 11289600, 0xf637}, - { 3686400, 11289600, 0x2f22}, - { 12000000, 11289600, 0x3e2f}, - { 13000000, 11289600, 0x4d5b}, - { 13100000, 11289600, 0x363b}, - { 2048000, 16384000, 0x1ea0}, - { 3686400, 16384000, 0x9e27}, - { 12000000, 16384000, 0x452b}, - { 13000000, 16384000, 0x542f}, - { 13100000, 16384000, 0x03a0}, - { 2048000, 16934400, 0xe625}, - { 3686400, 16934400, 0x9126}, - { 12000000, 16934400, 0x4d2c}, - { 13000000, 16934400, 0x742f}, - { 13100000, 16934400, 0x3c27}, - { 2048000, 22579200, 0x2aa0}, - { 3686400, 22579200, 0x2f20}, - { 12000000, 22579200, 0x7e2f}, - { 13000000, 22579200, 0x742f}, - { 13100000, 22579200, 0x3c27}, - { 2048000, 24576000, 0x2ea0}, - { 3686400, 24576000, 0xee27}, - { 12000000, 24576000, 0x2915}, - { 13000000, 24576000, 0x772e}, - { 13100000, 24576000, 0x0d20}, -}; - -static const struct _pll_div codec_bclk_pll_div[] = { - - { 1536000, 24576000, 0x3ea0}, - { 3072000, 24576000, 0x1ea0}, - { 512000, 24576000, 0x8e90}, - { 256000, 24576000, 0xbe80}, - { 2822400, 11289600, 0x1ee0}, //flove040711 - { 3072000, 12288000, 0x1ee0}, //flove040711 -}; - - -static int rt5621_set_dai_pll(struct snd_soc_dai *codec_dai, - int pll_id, unsigned int freq_in, unsigned int freq_out) -{ - int i; - int ret = -EINVAL; - struct snd_soc_codec *codec = codec_dai->codec; - - if (pll_id < RT5621_PLL_FR_MCLK || pll_id > RT5621_PLL_FR_BCLK) - return -EINVAL; - - //rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD2, 0x0000,0x1000); //disable PLL power - - if (!freq_in || !freq_out) { - - return 0; - } - - if (RT5621_PLL_FR_MCLK == pll_id) { - for (i = 0; i < ARRAY_SIZE(codec_pll_div); i++) { - - if (codec_pll_div[i].pll_in == freq_in && codec_pll_div[i].pll_out == freq_out) - { - rt5621_write_mask(codec, RT5621_GLOBAL_CLK_CTRL_REG, 0x0000, 0x4000); - rt5621_write(codec,RT5621_PLL_CTRL,codec_pll_div[i].regvalue);//set PLL parameter - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD2, 0x1000,0x1000); //enable PLL power - ret = 0; - } - } - } - else if (RT5621_PLL_FR_BCLK == pll_id) - { - for (i = 0; i < ARRAY_SIZE(codec_bclk_pll_div); i++) - { - if ((freq_in == codec_bclk_pll_div[i].pll_in) && (freq_out == codec_bclk_pll_div[i].pll_out)) - { - rt5621_write_mask(codec, RT5621_GLOBAL_CLK_CTRL_REG, 0x4000, 0x4000); - rt5621_write(codec,RT5621_PLL_CTRL,codec_bclk_pll_div[i].regvalue);//set PLL parameter - rt5621_write_mask(codec,RT5621_PWR_MANAG_ADD2, 0x1000,0x1000); //enable PLL power - ret = 0; - } - } - } - - rt5621_write_mask(codec,RT5621_GLOBAL_CLK_CTRL_REG,0x8000,0x8000);//Codec sys-clock from PLL - return ret; -} - - -struct _coeff_div { - u32 mclk; - u32 rate; - u16 fs; - u16 regvalue; -}; - -/* codec hifi mclk (after PLL) clock divider coefficients */ -static const struct _coeff_div coeff_div[] = { - /* 8k */ - { 8192000, 8000, 256*4, 0x2a2d}, - {12288000, 8000, 384*4, 0x2c2f}, - - /* 11.025k */ - {11289600, 11025, 256*4, 0x2a2d}, - {16934400, 11025, 384*4, 0x2c2f}, - - /* 16k */ - {12288000, 16000, 384*2, 0x1c2f}, - {16384000, 16000, 256*4, 0x2a2d}, - {24576000, 16000, 384*4, 0x2c2f}, - - /* 22.05k */ - {11289600, 22050, 256*2, 0x1a2d}, - {16934400, 22050, 384*2, 0x1c2f}, - - /* 32k */ - {12288000, 32000, 384 , 0x0c2f}, - {16384000, 32000, 256*2, 0x1a2d}, - {24576000, 32000, 384*2, 0x1c2f}, - - /* 44.1k */ - {11289600, 44100, 256*1, 0x0a2d}, - {22579200, 44100, 256*2, 0x1a2d}, - {45158400, 44100, 256*4, 0x2a2d}, - - /* 48k */ - {12288000, 48000, 256*1, 0x0a2d}, - {24576000, 48000, 256*2, 0x1a2d}, - {49152000, 48000, 256*4, 0x2a2d}, - -}; - - - -static int get_coeff(int mclk, int rate) -{ - int i; - - printk("get_coeff mclk=%d,rate=%d\n",mclk,rate); - - for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { - if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) - return i; - } - return -EINVAL; -} - - - - -/* - * Clock after PLL and dividers - */ - /*in this driver, you have to set sysclk to be 24576000, - * but you don't need to give a clk to be 24576000, our - * internal pll will generate this clock! so it won't make - * you any difficult. - */ -static int rt5621_set_dai_sysclk(struct snd_soc_dai *codec_dai, - int clk_id, unsigned int freq, int dir) -{ - struct snd_soc_codec *codec = codec_dai->codec; - struct rt5621_priv *rt5621 = codec->private_data; - - switch (freq) { - case 24576000: - rt5621->sysclk = freq; - return 0; - } - return 0; -} - - -static int rt5621_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int fmt) -{ - struct snd_soc_codec *codec = codec_dai->codec; - u16 iface = 0; - - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - iface = 0x0000; - break; - case SND_SOC_DAIFMT_CBS_CFS: - iface = 0x8000; - break; - default: - return -EINVAL; - } - - /* interface format */ - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - iface |= 0x0000; - break; - case SND_SOC_DAIFMT_RIGHT_J: - iface |= 0x0001; - break; - case SND_SOC_DAIFMT_LEFT_J: - iface |= 0x0002; - break; - case SND_SOC_DAIFMT_DSP_A: - iface |= 0x0003; - break; - case SND_SOC_DAIFMT_DSP_B: - iface |= 0x4003; - break; - default: - return -EINVAL; - } - - /* clock inversion */ - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - iface |= 0x0000; - break; - case SND_SOC_DAIFMT_IB_NF: - iface |= 0x0100; - break; - default: - return -EINVAL; - } - - rt5621_write(codec,RT5621_AUDIO_INTERFACE,iface); - return 0; -} - - -static int rt5621_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *codec_dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev ->card->codec; - struct rt5621_priv *rt5621 = codec->private_data; - u16 iface=rt5621_read(codec,RT5621_AUDIO_INTERFACE)&0xfff3; - int coeff = get_coeff(rt5621->sysclk, params_rate(params)); - - printk("rt5621_pcm_hw_params\n"); - if (coeff < 0) - coeff = get_coeff(24576000, params_rate(params)); /*if not set sysclk, default to be 24.576MHz*/ - - /* bit size */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - iface |= 0x0000; - break; - case SNDRV_PCM_FORMAT_S20_3LE: - iface |= 0x0004; - break; - case SNDRV_PCM_FORMAT_S24_LE: - iface |= 0x0008; - break; - case SNDRV_PCM_FORMAT_S32_LE: - iface |= 0x000c; - break; - } - - /* set iface & srate */ - rt5621_write(codec, RT5621_AUDIO_INTERFACE, iface); - - if (coeff >= 0) - rt5621_write(codec, RT5621_STEREO_AD_DA_CLK_CTRL, coeff_div[coeff].regvalue); -// else -// { -// printk(KERN_ERR "cant find matched sysclk and rate config\n"); -// return -EINVAL; - -// } - return 0; -} - -#if !USE_DAPM_CONTROL -static int rt5621_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - switch (level) { - case SND_SOC_BIAS_ON: - break; - case SND_SOC_BIAS_PREPARE: - break; - case SND_SOC_BIAS_STANDBY: - break; - case SND_SOC_BIAS_OFF: - - rt5621_write_mask(codec, 0x02, 0x8080, 0x8080); - rt5621_write_mask(codec, 0x04, 0x8080, 0x8080); - rt5621_write(codec, 0x3e, 0x0000); - rt5621_write(codec, 0x3c, 0x0000); - rt5621_write(codec, 0x3a, 0x0000); - break; - } - codec->bias_level = level; - return 0; -} -#else -static int rt5621_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - switch (level) { - case SND_SOC_BIAS_ON: - break; - case SND_SOC_BIAS_PREPARE: - break; - case SND_SOC_BIAS_STANDBY: - - break; - case SND_SOC_BIAS_OFF: - - rt5621_write_mask(codec, 0x02, 0x8080, 0x8080); - rt5621_write_mask(codec, 0x04, 0x8080, 0x8080); - rt5621_write(codec, 0x3e, 0x0000); - rt5621_write(codec, 0x3c, 0x0000); - rt5621_write(codec, 0x3a, 0x0000); - break; - } - codec->bias_level = level; - return 0; -} -#endif - - - - - -#if !USE_DAPM_CONTROL - -static void rt5621_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *codec_dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; - int stream = substream->stream; - - switch (stream) - { - case SNDRV_PCM_STREAM_PLAYBACK: - - rt5621_AudioOutEnable(codec,RT_WAVOUT_SPK,1); //mute speaker out - - rt5621_AudioOutEnable(codec,RT_WAVOUT_HP,1); //mute hp out - - rt5621_ChangeCodecPowerStatus(codec,POWER_STATE_D2_PLAYBACK); //power off dac to hp and speaker out - - - - break; - case SNDRV_PCM_STREAM_CAPTURE: - - Enable_ADC_Input_Source(codec,RT_WAVIN_L_MIC1|RT_WAVIN_R_MIC1,0); //disable record source from mic1 - - rt5621_ChangeCodecPowerStatus(codec,POWER_STATE_D2_RECORD); - - - break; - } -} - -#endif - - -#define RT5621_HIFI_RATES SNDRV_PCM_RATE_8000_48000 - -#define RT5621_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ - SNDRV_PCM_FMTBIT_S24_LE) - -struct snd_soc_dai_ops rt5621_hifi_ops = { - .hw_params = rt5621_pcm_hw_params, - .set_fmt = rt5621_set_dai_fmt, - .set_sysclk = rt5621_set_dai_sysclk, - .set_pll = rt5621_set_dai_pll, -#if !USE_DAPM_CONTROL - .prepare = rt5621_pcm_hw_prepare, - .shutdown = rt5621_shutdown, -#endif - -}; - -struct snd_soc_dai rt5621_dai = { - - .name = "RT5621", - .playback = { - .stream_name = "HiFi Playback", - .channels_min = 1, - .channels_max = 2, - .rates = RT5621_HIFI_RATES, - .formats = RT5621_FORMATS,}, - .capture = { - .stream_name = "HiFi Capture", - .channels_min = 1, - .channels_max = 2, - .rates = RT5621_HIFI_RATES, - .formats = RT5621_FORMATS,}, - - .ops = &rt5621_hifi_ops, -}; - - -EXPORT_SYMBOL_GPL(rt5621_dai); - -static ssize_t rt5621_index_reg_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct snd_soc_device *socdev = dev_get_drvdata(dev); - struct snd_soc_codec *codec = socdev ->card->codec; - int count = 0; - int value; - int i; - - count += sprintf(buf, "%s index register\n", codec->name); - - for (i = 0; i < 0x60; i++) { - count += sprintf(buf + count, "index-%2x ", i); - if (count >= PAGE_SIZE - 1) - break; - value = rt5621_read_index(codec, i); - count += snprintf(buf + count, PAGE_SIZE - count, "0x%4x", value); - - if (count >= PAGE_SIZE - 1) - break; - - count += snprintf(buf + count, PAGE_SIZE - count, "\n"); - if (count >= PAGE_SIZE - 1) - break; - } - - if (count >= PAGE_SIZE) - count = PAGE_SIZE - 1; - - return count; - -} - -static DEVICE_ATTR(index_reg, 0444, rt5621_index_reg_show, NULL); - -#if defined(CONFIG_SND_HWDEP) -#if REALTEK_HWDEP - -#define RT_CE_CODEC_HWDEP_NAME "rt56xx hwdep " - -static int rt56xx_hwdep_open(struct snd_hwdep *hw, struct file *file) -{ - printk("enter %s\n", __func__); - return 0; -} - -static int rt56xx_hwdep_release(struct snd_hwdep *hw, struct file *file) -{ - printk("enter %s\n", __func__); - return 0; -} - - -static int rt56xx_hwdep_ioctl_common(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg) -{ - struct rt56xx_cmd rt56xx; - struct rt56xx_cmd __user *_rt56xx = arg; - struct rt56xx_reg_state *buf; - struct rt56xx_reg_state *p; - struct snd_soc_codec *codec = hw->private_data; - - if (copy_from_user(&rt56xx, _rt56xx, sizeof(rt56xx))) - return -EFAULT; - buf = kmalloc(sizeof(*buf) * rt56xx.number, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - if (copy_from_user(buf, rt56xx.buf, sizeof(*buf) * rt56xx.number)) { - goto err; - } - switch (cmd) { - case RT_READ_CODEC_REG_IOCTL: - for (p = buf; p < buf + rt56xx.number; p++) - { - p->reg_value = codec->read(codec, p->reg_index); - } - if (copy_to_user(rt56xx.buf, buf, sizeof(*buf) * rt56xx.number)) - goto err; - - break; - case RT_WRITE_CODEC_REG_IOCTL: - for (p = buf; p < buf + rt56xx.number; p++) - codec->write(codec, p->reg_index, p->reg_value); - break; - } - - kfree(buf); - return 0; - -err: - kfree(buf); - return -EFAULT; - -} - -static int rt56xx_codec_dump_reg(struct snd_hwdep *hw, struct file *file, unsigned long arg) -{ - struct rt56xx_cmd rt56xx; - struct rt56xx_cmd __user *_rt56xx = arg; - struct rt56xx_reg_state *buf; - struct snd_soc_codec *codec = hw->private_data; - int number = codec->reg_cache_size; - int i; - - printk(KERN_DEBUG "enter %s, number = %d\n", __func__, number); - if (copy_from_user(&rt56xx, _rt56xx, sizeof(rt56xx))) - return -EFAULT; - - buf = kmalloc(sizeof(*buf) * number, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - for (i = 0; i < number; i++) - { - buf[i].reg_index = i << 1; - buf[i].reg_value = codec->read(codec, buf[i].reg_index); - } - if (copy_to_user(rt56xx.buf, buf, sizeof(*buf) * i)) - goto err; - rt56xx.number = number; - if (copy_to_user(_rt56xx, &rt56xx, sizeof(rt56xx))) - goto err; - kfree(buf); - return 0; -err: - kfree(buf); - return -EFAULT; - -} - -static int rt56xx_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg) -{ - if (cmd == RT_READ_ALL_CODEC_REG_IOCTL) - { - return rt56xx_codec_dump_reg(hw, file, arg); - } - else - { - return rt56xx_hwdep_ioctl_common(hw, file, cmd, arg); - } -} - -static int realtek_ce_init_hwdep(struct snd_soc_codec *codec) -{ - struct snd_hwdep *hw; - struct snd_card *card = codec->card; - int err; - - if ((err = snd_hwdep_new(card, RT_CE_CODEC_HWDEP_NAME, 0, &hw)) < 0) - return err; - - strcpy(hw->name, RT_CE_CODEC_HWDEP_NAME); - hw->private_data = codec; - hw->ops.open = rt56xx_hwdep_open; - hw->ops.release = rt56xx_hwdep_release; - hw->ops.ioctl = rt56xx_hwdep_ioctl; - return 0; -} - -#endif -#endif - -static void rt5621_work(struct work_struct *work) -{ - struct snd_soc_codec *codec = - container_of(work, struct snd_soc_codec, delayed_work.work); - - rt5621_set_bias_level(codec, codec->bias_level); -} - - -static int rt5621_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev ->card->codec; - - /* we only need to suspend if we are a valid card */ - if(!codec->card) - return 0; - - rt5621_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} - -static int rt5621_resume(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev ->card->codec; - int i; - u8 data[3]; - u16 *cache = codec->reg_cache; - - /* we only need to resume if we are a valid card */ - if(!codec->card) - return 0; - - /* Sync reg_cache with the hardware */ - - for (i = 0; i < ARRAY_SIZE(rt5621_reg); i++) { - if (i == RT5621_RESET) - continue; - data[0] =i << 1; - data[1] = (0xFF00 & cache[i]) >> 8; - data[2] = 0x00FF & cache[i]; - codec->hw_write(codec->control_data, data, 3); - } - - rt5621_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - /* charge rt5621 caps */ - - if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { - rt5621_set_bias_level(codec, SND_SOC_BIAS_PREPARE); - codec->bias_level = SND_SOC_BIAS_ON; - schedule_delayed_work(&codec->delayed_work, - msecs_to_jiffies(caps_charge)); - } - return 0; -} - - -/* - * initialise the RT5621 driver - * register the mixer and dsp interfaces with the kernel - */ -static int rt5621_init(struct snd_soc_device *socdev) -{ - struct snd_soc_codec *codec = socdev ->card->codec; - int ret = 0; - - printk(KERN_INFO "alsa version is 1.0.21, codec driver version is 0.04\n"); - codec->name = "RT5621"; - codec->owner = THIS_MODULE; - codec->read = rt5621_read; - codec->write = rt5621_write; - codec->set_bias_level = rt5621_set_bias_level; - codec->dai = &rt5621_dai; - codec->num_dai = 1; - codec->reg_cache_step = 2; - codec->reg_cache_size = ARRAY_SIZE(rt5621_reg) * 2; - codec->reg_cache = kmemdup(rt5621_reg, sizeof(rt5621_reg), GFP_KERNEL); - - if (codec->reg_cache == NULL) - return -ENOMEM; - - /* register pcms */ - ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); - if (ret < 0) { - printk(KERN_ERR "rt5621: failed to create pcms\n"); - goto pcm_err; - } - - - rt5621_reset(codec); - rt5621_write(codec, RT5621_PWR_MANAG_ADD3, 0x8000);//enable Main bias - rt5621_write(codec, RT5621_PWR_MANAG_ADD2, 0x2000);//enable Vref - - hp_depop_mode2(codec); - - rt5621_init_reg(codec); - rt5621_set_bias_level(codec, SND_SOC_BIAS_PREPARE); - codec->bias_level = SND_SOC_BIAS_STANDBY; - schedule_delayed_work(&codec->delayed_work, - msecs_to_jiffies(caps_charge)); - - rt5621_add_controls(codec); - - #if USE_DAPM_CONTROL - - rt5621_add_widgets(codec); - - #endif - - #if defined(CONFIG_SND_HWDEP) - #if REALTEK_HWDEP - - realtek_ce_init_hwdep(codec); - - #endif - #endif - - ret = snd_soc_init_card(socdev); - - if (ret < 0) { - printk(KERN_ERR "rt5621: failed to register card\n"); - goto card_err; - } - return ret; - -card_err: - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); -pcm_err: - kfree(codec->reg_cache); - return ret; -} - -static int rt5621_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) -{ - struct snd_soc_device *socdev = rt5621_socdev; - struct snd_soc_codec *codec = socdev ->card->codec; - int ret; - - i2c_set_clientdata(i2c, codec); - codec->control_data = i2c; - - ret = rt5621_init(socdev); - if (ret < 0) - pr_err("failed to initialise rt5621\n"); - - return ret; -} - - -static int rt5621_i2c_remove(struct i2c_client *client) -{ - struct snd_soc_codec *codec = i2c_get_clientdata(client); - kfree(codec->reg_cache); - return 0; -} - -static const struct i2c_device_id rt5621_i2c_id[] = { - {"ALC5621", 0}, - {} -}; -MODULE_DEVICE_TABLE(i2c, rt5621_i2c_id); -static struct i2c_driver rt5621_i2c_driver = { - .driver = { - .name = "RT5621 I2C Codec", - .owner = THIS_MODULE, - }, - .probe = rt5621_i2c_probe, - .remove = rt5621_i2c_remove, - .id_table = rt5621_i2c_id, -}; - -static int rt5621_add_i2c_device(struct platform_device *pdev, - const struct rt5621_setup_data *setup) -{ -#if 0 - struct i2c_board_info info; - struct i2c_adapter *adapter; - struct i2c_client *client; -#endif - int ret; - ret = i2c_add_driver(&rt5621_i2c_driver); - if (ret != 0) { - dev_err(&pdev->dev, "can't add i2c driver\n"); - return ret; - } -#if 0 - memset(&info, 0, sizeof(struct i2c_board_info)); - info.addr = setup->i2c_address; - strlcpy(info.type, "rt5621", I2C_NAME_SIZE); - - adapter = i2c_get_adapter(setup->i2c_bus); - if (!adapter) { - dev_err(&pdev->dev, "can't get i2c adapter %d\n", - setup->i2c_bus); - goto err_driver; - } - - client = i2c_new_device(adapter, &info); - i2c_put_adapter(adapter); - if (!client) { - dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", - (unsigned int)info.addr); - goto err_driver; - } -#endif - return 0; - -#if 0 -err_driver: - i2c_del_driver(&rt5621_i2c_driver); - return -ENODEV; -#endif -} - - -static int rt5621_probe(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct rt5621_setup_data *setup = socdev->codec_data; - struct snd_soc_codec *codec; - struct rt5621_priv *rt5621; - int ret; - - pr_info("RT5621 Audio Codec %s\n", RT5621_VERSION); - - codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); - if (codec == NULL) - return -ENOMEM; - - rt5621 = kzalloc(sizeof(struct rt5621_priv), GFP_KERNEL); - if (rt5621 == NULL) { - kfree(codec); - return -ENOMEM; - } - codec->private_data = rt5621; - socdev ->card->codec = codec; - mutex_init(&codec->mutex); - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); - rt5621_socdev = socdev; - INIT_DELAYED_WORK(&codec->delayed_work, rt5621_work); - ret = device_create_file(&pdev->dev, &dev_attr_index_reg); - if (ret < 0) - printk(KERN_WARNING "asoc: failed to add index_reg sysfs files\n"); - - ret = -ENODEV; -// if (setup->i2c_address) { - codec->hw_write = (hw_write_t)i2c_master_send; - ret = rt5621_add_i2c_device(pdev, setup); -// } - if (ret != 0) { - kfree(codec->private_data); - kfree(codec); - } - return ret; -} - -static int run_delayed_work(struct delayed_work *dwork) -{ - int ret; - - /* cancel any work waiting to be queued. */ - ret = cancel_delayed_work(dwork); - - /* if there was any work waiting then we run it now and - * wait for it's completion */ - if (ret) { - schedule_delayed_work(dwork, 0); - flush_scheduled_work(); - } - return ret; -} - -static int rt5621_remove(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev ->card->codec; - - if (codec->control_data) - rt5621_set_bias_level(codec, SND_SOC_BIAS_OFF); - run_delayed_work(&codec->delayed_work); - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); - device_remove_file(&pdev->dev, &dev_attr_index_reg); - i2c_unregister_device(codec->control_data); - i2c_del_driver(&rt5621_i2c_driver); - kfree(codec->private_data); - kfree(codec); - - return 0; -} - -struct snd_soc_codec_device soc_codec_dev_rt5621 = { - .probe = rt5621_probe, - .remove = rt5621_remove, - .suspend = rt5621_suspend, - .resume = rt5621_resume, -}; - -EXPORT_SYMBOL_GPL(soc_codec_dev_rt5621); - -static int __init rt5621_modinit(void) -{ - return snd_soc_register_dai(&rt5621_dai); -} - -static void __exit rt5621_exit(void) -{ - snd_soc_unregister_dai(&rt5621_dai); -} - -module_init(rt5621_modinit); -module_exit(rt5621_exit); -MODULE_LICENSE("GPL"); - diff --git a/sound/soc/codecs/alc5621.h b/sound/soc/codecs/alc5621.h deleted file mode 100644 index bdcebbdbe114..000000000000 --- a/sound/soc/codecs/alc5621.h +++ /dev/null @@ -1,516 +0,0 @@ -#ifndef _RT5621_H -#define _RT5621_H - - -#define RT5621_RESET 0X00 //RESET CODEC TO DEFAULT -#define RT5621_SPK_OUT_VOL 0X02 //SPEAKER OUT VOLUME -#define RT5621_HP_OUT_VOL 0X04 //HEADPHONE OUTPUT VOLUME -#define RT5621_MONO_AUX_OUT_VOL 0X06 //MONO OUTPUT/AUXOUT VOLUME -#define RT5621_AUXIN_VOL 0X08 //AUXIN VOLUME -#define RT5621_LINE_IN_VOL 0X0A //LINE IN VOLUME -#define RT5621_STEREO_DAC_VOL 0X0C //STEREO DAC VOLUME -#define RT5621_MIC_VOL 0X0E //MICROPHONE VOLUME -#define RT5621_MIC_ROUTING_CTRL 0X10 //MIC ROUTING CONTROL -#define RT5621_ADC_REC_GAIN 0X12 //ADC RECORD GAIN -#define RT5621_ADC_REC_MIXER 0X14 //ADC RECORD MIXER CONTROL -#define RT5621_SOFT_VOL_CTRL_TIME 0X16 //SOFT VOLUME CONTROL TIME -#define RT5621_OUTPUT_MIXER_CTRL 0X1C //OUTPUT MIXER CONTROL -#define RT5621_MIC_CTRL 0X22 //MICROPHONE CONTROL -#define RT5621_AUDIO_INTERFACE 0X34 //AUDIO INTERFACE -#define RT5621_STEREO_AD_DA_CLK_CTRL 0X36 //STEREO AD/DA CLOCK CONTROL -#define RT5621_COMPANDING_CTRL 0X38 //COMPANDING CONTROL -#define RT5621_PWR_MANAG_ADD1 0X3A //POWER MANAGMENT ADDITION 1 -#define RT5621_PWR_MANAG_ADD2 0X3C //POWER MANAGMENT ADDITION 2 -#define RT5621_PWR_MANAG_ADD3 0X3E //POWER MANAGMENT ADDITION 3 -#define RT5621_ADD_CTRL_REG 0X40 //ADDITIONAL CONTROL REGISTER -#define RT5621_GLOBAL_CLK_CTRL_REG 0X42 //GLOBAL CLOCK CONTROL REGISTER -#define RT5621_PLL_CTRL 0X44 //PLL CONTROL -#define RT5621_GPIO_OUTPUT_PIN_CTRL 0X4A //GPIO OUTPUT PIN CONTROL -#define RT5621_GPIO_PIN_CONFIG 0X4C //GPIO PIN CONFIGURATION -#define RT5621_GPIO_PIN_POLARITY 0X4E //GPIO PIN POLARITY/TYPE -#define RT5621_GPIO_PIN_STICKY 0X50 //GPIO PIN STICKY -#define RT5621_GPIO_PIN_WAKEUP 0X52 //GPIO PIN WAKE UP -#define RT5621_GPIO_PIN_STATUS 0X54 //GPIO PIN STATUS -#define RT5621_GPIO_PIN_SHARING 0X56 //GPIO PIN SHARING -#define RT5621_OVER_TEMP_CURR_STATUS 0X58 //OVER TEMPERATURE AND CURRENT STATUS -#define RT5621_JACK_DET_CTRL 0X5A //JACK DETECT CONTROL REGISTER -#define RT5621_MISC_CTRL 0X5E //MISC CONTROL -#define RT5621_PSEDUEO_SPATIAL_CTRL 0X60 //PSEDUEO STEREO & SPATIAL EFFECT BLOCK CONTROL -#define RT5621_EQ_CTRL 0X62 //EQ CONTROL -#define RT5621_EQ_MODE_ENABLE 0X66 //EQ MODE CHANGE ENABLE -#define RT5621_AVC_CTRL 0X68 //AVC CONTROL -#define RT5621_HID_CTRL_INDEX 0X6A //HIDDEN CONTROL INDEX PORT -#define RT5621_HID_CTRL_DATA 0X6C //HIDDEN CONTROL DATA PORT -#define RT5621_VENDOR_ID1 0x7C //VENDOR ID1 -#define RT5621_VENDOR_ID2 0x7E //VENDOR ID2 - - -//global definition -#define RT_L_MUTE (0x1<<15) //MUTE LEFT CONTROL BIT -#define RT_L_ZC (0x1<<14) //LEFT ZERO CROSS CONTROL BIT -#define RT_L_SM (0x1<<13) //LEFT SOFTMUTE CONTROL BIT -#define RT_R_MUTE (0x1<<7) //MUTE RIGHT CONTROL BIT -#define RT_R_ZC (0x1<<6) //RIGHT ZERO CROSS CONTROL BIT -#define RT_R_SM (0x1<<5) //RIGHT SOFTMUTE CONTROL BIT -#define RT_M_HP_MIXER (0x1<<15) //Mute source to HP Mixer -#define RT_M_SPK_MIXER (0x1<<14) //Mute source to Speaker Mixer -#define RT_M_MONO_MIXER (0x1<<13) //Mute source to Mono Mixer -#define SPK_CLASS_AB 0 -#define SPK_CLASS_D 1 - -//Mic Routing Control(0x10) -#define M_MIC1_TO_HP_MIXER (0x1<<15) //Mute MIC1 to HP mixer -#define M_MIC1_TO_SPK_MIXER (0x1<<14) //Mute MiC1 to SPK mixer -#define M_MIC1_TO_MONO_MIXER (0x1<<13) //Mute MIC1 to MONO mixer -#define MIC1_DIFF_INPUT_CTRL (0x1<<12) //MIC1 different input control -#define M_MIC2_TO_HP_MIXER (0x1<<7) //Mute MIC2 to HP mixer -#define M_MIC2_TO_SPK_MIXER (0x1<<6) //Mute MiC2 to SPK mixer -#define M_MIC2_TO_MONO_MIXER (0x1<<5) //Mute MIC2 to MONO mixer -#define MIC2_DIFF_INPUT_CTRL (0x1<<4) //MIC2 different input control - -//ADC Record Gain(0x12) -#define M_ADC_L_TO_HP_MIXER (0x1<<15) //Mute left of ADC to HP Mixer -#define M_ADC_R_TO_HP_MIXER (0x1<<14) //Mute right of ADC to HP Mixer -#define M_ADC_L_TO_MONO_MIXER (0x1<<13) //Mute left of ADC to MONO Mixer -#define M_ADC_R_TO_MONO_MIXER (0x1<<12) //Mute right of ADC to MONO Mixer -#define ADC_L_GAIN_MASK (0x1f<<7) //ADC Record Gain Left channel Mask -#define ADC_L_ZC_DET (0x1<<6) //ADC Zero-Cross Detector Control -#define ADC_R_ZC_DET (0x1<<5) //ADC Zero-Cross Detector Control -#define ADC_R_GAIN_MASK (0x1f<<0) //ADC Record Gain Right channel Mask - -//ADC Input Mixer Control(0x14) -#define M_MIC1_TO_ADC_L_MIXER (0x1<<14) //Mute mic1 to left channel of ADC mixer -#define M_MIC2_TO_ADC_L_MIXER (0x1<<13) //Mute mic2 to left channel of ADC mixer -#define M_LINEIN_L_TO_ADC_L_MIXER (0x1<<12) //Mute line In left channel to left channel of ADC mixer -#define M_AUXIN_L_TO_ADC_L_MIXER (0x1<<11) //Mute aux In left channel to left channel of ADC mixer -#define M_HPMIXER_L_TO_ADC_L_MIXER (0x1<<10) //Mute HP mixer left channel to left channel of ADC mixer -#define M_SPKMIXER_L_TO_ADC_L_MIXER (0x1<<9) //Mute SPK mixer left channel to left channel of ADC mixer -#define M_MONOMIXER_L_TO_ADC_L_MIXER (0x1<<8) //Mute MONO mixer left channel to left channel of ADC mixer -#define M_MIC1_TO_ADC_R_MIXER (0x1<<6) //Mute mic1 to right channel of ADC mixer -#define M_MIC2_TO_ADC_R_MIXER (0x1<<5) //Mute mic2 to right channel of ADC mixer -#define M_LINEIN_R_TO_ADC_R_MIXER (0x1<<4) //Mute lineIn right channel to right channel of ADC mixer -#define M_AUXIN_R_TO_ADC_R_MIXER (0x1<<3) //Mute aux In right channel to right channel of ADC mixer -#define M_HPMIXER_R_TO_ADC_R_MIXER (0x1<<2) //Mute HP mixer right channel to right channel of ADC mixer -#define M_SPKMIXER_R_TO_ADC_R_MIXER (0x1<<1) //Mute SPK mixer right channel to right channel of ADC mixer -#define M_MONOMIXER_R_TO_ADC_R_MIXER (0x1<<0) //Mute MONO mixer right channel to right channel of ADC mixer - -//Output Mixer Control(0x1C) -#define SPKOUT_N_SOUR_MASK (0x3<<14) -#define SPKOUT_N_SOUR_LN (0x2<<14) -#define SPKOUT_N_SOUR_RP (0x1<<14) -#define SPKOUT_N_SOUR_RN (0x0<<14) -#define SPK_OUTPUT_CLASS_AB (0x0<<13) -#define SPK_OUTPUT_CLASS_D (0x1<<13) -#define SPK_CLASS_AB_S_AMP (0x0<<12) -#define SPK_CALSS_AB_W_AMP (0x1<<12) -#define SPKOUT_INPUT_SEL_MASK (0x3<<10) -#define SPKOUT_INPUT_SEL_MONOMIXER (0x3<<10) -#define SPKOUT_INPUT_SEL_SPKMIXER (0x2<<10) -#define SPKOUT_INPUT_SEL_HPMIXER (0x1<<10) -#define SPKOUT_INPUT_SEL_VMID (0x0<<10) -#define HPL_INPUT_SEL_HPLMIXER (0x1<<9) -#define HPR_INPUT_SEL_HPRMIXER (0x1<<8) -#define MONO_AUX_INPUT_SEL_MASK (0x3<<6) -#define MONO_AUX_INPUT_SEL_MONO (0x3<<6) -#define MONO_AUX_INPUT_SEL_SPK (0x2<<6) -#define MONO_AUX_INPUT_SEL_HP (0x1<<6) -#define MONO_AUX_INPUT_SEL_VMID (0x0<<6) - -//Micphone Control define(0x22) -#define MIC1 1 -#define MIC2 2 -#define MIC_BIAS_90_PRECNET_AVDD 1 -#define MIC_BIAS_75_PRECNET_AVDD 2 - -#define MIC1_BOOST_CTRL_MASK (0x3<<10) -#define MIC1_BOOST_CTRL_BYPASS (0x0<<10) -#define MIC1_BOOST_CTRL_20DB (0x1<<10) -#define MIC1_BOOST_CTRL_30DB (0x2<<10) -#define MIC1_BOOST_CTRL_40DB (0x3<<10) - -#define MIC2_BOOST_CTRL_MASK (0x3<<8) -#define MIC2_BOOST_CTRL_BYPASS (0x0<<8) -#define MIC2_BOOST_CTRL_20DB (0x1<<8) -#define MIC2_BOOST_CTRL_30DB (0x2<<8) -#define MIC2_BOOST_CTRL_40DB (0x3<<8) - -#define MICBIAS_VOLT_CTRL_MASK (0x1<<5) -#define MICBIAS_VOLT_CTRL_90P (0x0<<5) -#define MICBIAS_VOLT_CTRL_75P (0x1<<5) - -#define MICBIAS_SHORT_CURR_DET_MASK (0x3) -#define MICBIAS_SHORT_CURR_DET_600UA (0x0) -#define MICBIAS_SHORT_CURR_DET_1200UA (0x1) -#define MICBIAS_SHORT_CURR_DET_1800UA (0x2) - -//Audio Interface(0x34) -#define SDP_MASTER_MODE (0x0<<15) //Main I2S interface select Master mode -#define SDP_SLAVE_MODE (0x1<<15) //Main I2S interface select Slave mode -#define I2S_PCM_MODE (0x1<<14) //PCM 0:mode A ,1:mode B -#define MAIN_I2S_BCLK_POL_CTRL (0x1<<7) //0:Normal 1:Invert -#define ADC_DATA_L_R_SWAP (0x1<<5) //0:ADC data appear at left phase of LRCK - //1:ADC data appear at right phase of LRCK -#define DAC_DATA_L_R_SWAP (0x1<<4) //0:DAC data appear at left phase of LRCK - //1:DAC data appear at right phase of LRCK -//Data Length Slection -#define I2S_DL_MASK (0x3<<2) //main i2s Data Length mask -#define I2S_DL_16 (0x0<<2) //16 bits -#define I2S_DL_20 (0x1<<2) //20 bits -#define I2S_DL_24 (0x2<<2) //24 bits -#define I2S_DL_32 (0x3<<2) //32 bits - -//PCM Data Format Selection -#define I2S_DF_MASK (0x3) //main i2s Data Format mask -#define I2S_DF_I2S (0x0) //I2S FORMAT -#define I2S_DF_RIGHT (0x1) //RIGHT JUSTIFIED format -#define I2S_DF_LEFT (0x2) //LEFT JUSTIFIED format -#define I2S_DF_PCM (0x3) //PCM format - -//Stereo AD/DA Clock Control(0x36h) -#define I2S_PRE_DIV_MASK (0x7<<12) -#define I2S_PRE_DIV_1 (0x0<<12) //DIV 1 -#define I2S_PRE_DIV_2 (0x1<<12) //DIV 2 -#define I2S_PRE_DIV_4 (0x2<<12) //DIV 4 -#define I2S_PRE_DIV_8 (0x3<<12) //DIV 8 -#define I2S_PRE_DIV_16 (0x4<<12) //DIV 16 -#define I2S_PRE_DIV_32 (0x5<<12) //DIV 32 - -#define I2S_SCLK_DIV_MASK (0x7<<9) -#define I2S_SCLK_DIV_1 (0x0<<9) //DIV 1 -#define I2S_SCLK_DIV_2 (0x1<<9) //DIV 2 -#define I2S_SCLK_DIV_3 (0x2<<9) //DIV 3 -#define I2S_SCLK_DIV_4 (0x3<<9) //DIV 4 -#define I2S_SCLK_DIV_6 (0x4<<9) //DIV 6 -#define I2S_SCLK_DIV_8 (0x5<<9) //DIV 8 -#define I2S_SCLK_DIV_12 (0x6<<9) //DIV 12 -#define I2S_SCLK_DIV_16 (0x7<<9) //DIV 16 - -#define I2S_WCLK_DIV_PRE_MASK (0xF<<5) -#define I2S_WCLK_PRE_DIV_1 (0x0<<5) //DIV 1 -#define I2S_WCLK_PRE_DIV_2 (0x1<<5) //DIV 2 -#define I2S_WCLK_PRE_DIV_3 (0x2<<5) //DIV 3 -#define I2S_WCLK_PRE_DIV_4 (0x3<<5) //DIV 4 -#define I2S_WCLK_PRE_DIV_5 (0x4<<5) //DIV 5 -#define I2S_WCLK_PRE_DIV_6 (0x5<<5) //DIV 6 -#define I2S_WCLK_PRE_DIV_7 (0x6<<5) //DIV 7 -#define I2S_WCLK_PRE_DIV_8 (0x7<<5) //DIV 8 -//........................ - -#define I2S_WCLK_DIV_MASK (0x7<<2) -#define I2S_WCLK_DIV_2 (0x0<<2) //DIV 2 -#define I2S_WCLK_DIV_4 (0x1<<2) //DIV 4 -#define I2S_WCLK_DIV_8 (0x2<<2) //DIV 8 -#define I2S_WCLK_DIV_16 (0x3<<2) //DIV 16 -#define I2S_WCLK_DIV_32 (0x4<<2) //DIV 32 - -#define ADDA_FILTER_CLK_SEL_256FS (0<<1) //256FS -#define ADDA_FILTER_CLK_SEL_384FS (1<<1) //384FS - -#define ADDA_OSR_SEL_64FS (0) //64FS -#define ADDA_OSR_SEL_128FS (1) //128FS - -//Power managment addition 1 (0x3A),0:Disable,1:Enable -#define PWR_MAIN_I2S_EN (0x1<<15) -#define PWR_ZC_DET_PD_EN (0x1<<14) -#define PWR_MIC1_BIAS_EN (0x1<<11) -#define PWR_SHORT_CURR_DET_EN (0x1<<10) -#define PWR_SOFTGEN_EN (0x1<<8) -#define PWR_DEPOP_BUF_HP (0x1<<6) -#define PWR_HP_OUT_AMP (0x1<<5) -#define PWR_HP_OUT_ENH_AMP (0x1<<4) -#define PWR_DEPOP_BUF_AUX (0x1<<2) -#define PWR_AUX_OUT_AMP (0x1<<1) -#define PWR_AUX_OUT_ENH_AMP (0x1) - - -//Power managment addition 2(0x3C),0:Disable,1:Enable -#define PWR_CLASS_AB (0x1<<15) -#define PWR_CLASS_D (0x1<<14) -#define PWR_VREF (0x1<<13) -#define PWR_PLL (0x1<<12) -#define PWR_DAC_REF_CIR (0x1<<10) -#define PWR_L_DAC_CLK (0x1<<9) -#define PWR_R_DAC_CLK (0x1<<8) -#define PWR_L_ADC_CLK_GAIN (0x1<<7) -#define PWR_R_ADC_CLK_GAIN (0x1<<6) -#define PWR_L_HP_MIXER (0x1<<5) -#define PWR_R_HP_MIXER (0x1<<4) -#define PWR_SPK_MIXER (0x1<<3) -#define PWR_MONO_MIXER (0x1<<2) -#define PWR_L_ADC_REC_MIXER (0x1<<1) -#define PWR_R_ADC_REC_MIXER (0x1) - -//Power managment addition 3(0x3E),0:Disable,1:Enable -#define PWR_MAIN_BIAS (0x1<<15) -#define PWR_AUXOUT_L_VOL_AMP (0x1<<14) -#define PWR_AUXOUT_R_VOL_AMP (0x1<<13) -#define PWR_SPK_OUT (0x1<<12) -#define PWR_HP_L_OUT_VOL (0x1<<10) -#define PWR_HP_R_OUT_VOL (0x1<<9) -#define PWR_LINEIN_L_VOL (0x1<<7) -#define PWR_LINEIN_R_VOL (0x1<<6) -#define PWR_AUXIN_L_VOL (0x1<<5) -#define PWR_AUXIN_R_VOL (0x1<<4) -#define PWR_MIC1_FUN_CTRL (0x1<<3) -#define PWR_MIC2_FUN_CTRL (0x1<<2) -#define PWR_MIC1_BOOST_MIXER (0x1<<1) -#define PWR_MIC2_BOOST_MIXER (0x1) - - -//Additional Control Register(0x40) -#define AUXOUT_SEL_DIFF (0x1<<15) //Differential Mode -#define AUXOUT_SEL_SE (0x1<<15) //Single-End Mode - -#define SPK_AB_AMP_CTRL_MASK (0x7<<12) -#define SPK_AB_AMP_CTRL_RATIO_225 (0x0<<12) //2.25 Vdd -#define SPK_AB_AMP_CTRL_RATIO_200 (0x1<<12) //2.00 Vdd -#define SPK_AB_AMP_CTRL_RATIO_175 (0x2<<12) //1.75 Vdd -#define SPK_AB_AMP_CTRL_RATIO_150 (0x3<<12) //1.50 Vdd -#define SPK_AB_AMP_CTRL_RATIO_125 (0x4<<12) //1.25 Vdd -#define SPK_AB_AMP_CTRL_RATIO_100 (0x5<<12) //1.00 Vdd - -#define SPK_D_AMP_CTRL_MASK (0x3<<10) -#define SPK_D_AMP_CTRL_RATIO_175 (0x0<<10) //1.75 Vdd -#define SPK_D_AMP_CTRL_RATIO_150 (0x1<<10) //1.50 Vdd -#define SPK_D_AMP_CTRL_RATIO_125 (0x2<<10) //1.25 Vdd -#define SPK_D_AMP_CTRL_RATIO_100 (0x3<<10) //1.00 Vdd - -#define STEREO_DAC_HI_PASS_FILTER_EN (0x1<<9) //Stereo DAC high pass filter enable -#define STEREO_ADC_HI_PASS_FILTER_EN (0x1<<8) //Stereo ADC high pass filter enable - -#define DIG_VOL_BOOST_MASK (0x3<<4) //Digital volume Boost mask -#define DIG_VOL_BOOST_0DB (0x0<<4) //Digital volume Boost 0DB -#define DIG_VOL_BOOST_6DB (0x1<<4) //Digital volume Boost 6DB -#define DIG_VOL_BOOST_12DB (0x2<<4) //Digital volume Boost 12DB -#define DIG_VOL_BOOST_18DB (0x3<<4) //Digital volume Boost 18DB - - -//Global Clock Control Register(0x42) -#define SYSCLK_SOUR_SEL_MASK (0x1<<15) -#define SYSCLK_SOUR_SEL_MCLK (0x0<<15) //system Clock source from MCLK -#define SYSCLK_SOUR_SEL_PLL (0x1<<15) //system Clock source from PLL -#define PLLCLK_SOUR_SEL_MCLK (0x0<<14) //PLL clock source from MCLK -#define PLLCLK_SOUR_SEL_BITCLK (0x1<<14) //PLL clock source from BITCLK - -#define PLLCLK_DIV_RATIO_MASK (0x3<<1) -#define PLLCLK_DIV_RATIO_DIV1 (0x0<<1) //DIV 1 -#define PLLCLK_DIV_RATIO_DIV2 (0x1<<1) //DIV 2 -#define PLLCLK_DIV_RATIO_DIV4 (0x2<<1) //DIV 4 -#define PLLCLK_DIV_RATIO_DIV8 (0x3<<1) //DIV 8 - -#define PLLCLK_PRE_DIV1 (0x0) //DIV 1 -#define PLLCLK_PRE_DIV2 (0x1) //DIV 2 - -//PLL Control(0x44) - -#define PLL_CTRL_M_VAL(m) ((m)&0xf) -#define PLL_CTRL_K_VAL(k) (((k)&0x7)<<4) -#define PLL_CTRL_N_VAL(n) (((n)&0xff)<<8) - -//GPIO Pin Configuration(0x4C) -#define GPIO_PIN_MASK (0x1<<1) -#define GPIO_PIN_SET_INPUT (0x1<<1) -#define GPIO_PIN_SET_OUTPUT (0x0<<1) - -//Pin Sharing(0x56) -#define LINEIN_L_PIN_SHARING (0x1<<15) -#define LINEIN_L_PIN_AS_LINEIN_L (0x0<<15) -#define LINEIN_L_PIN_AS_JD1 (0x1<<15) - -#define LINEIN_R_PIN_SHARING (0x1<<14) -#define LINEIN_R_PIN_AS_LINEIN_R (0x0<<14) -#define LINEIN_R_PIN_AS_JD2 (0x1<<14) - -#define GPIO_PIN_SHARING (0x3) -#define GPIO_PIN_AS_GPIO (0x0) -#define GPIO_PIN_AS_IRQOUT (0x1) -#define GPIO_PIN_AS_PLLOUT (0x3) - -//Jack Detect Control Register(0x5A) -#define JACK_DETECT_MASK (0x3<<14) -#define JACK_DETECT_USE_JD2 (0x3<<14) -#define JACK_DETECT_USE_JD1 (0x2<<14) -#define JACK_DETECT_USE_GPIO (0x1<<14) -#define JACK_DETECT_OFF (0x0<<14) - -#define SPK_EN_IN_HI (0x1<<11) -#define AUX_R_EN_IN_HI (0x1<<10) -#define AUX_L_EN_IN_HI (0x1<<9) -#define HP_EN_IN_HI (0x1<<8) -#define SPK_EN_IN_LO (0x1<<7) -#define AUX_R_EN_IN_LO (0x1<<6) -#define AUX_L_EN_IN_LO (0x1<<5) -#define HP_EN_IN_LO (0x1<<4) - -////MISC CONTROL(0x5E) -#define DISABLE_FAST_VREG (0x1<<15) -#define SPK_CLASS_AB_OC_PD (0x1<<13) -#define SPK_CLASS_AB_OC_DET (0x1<<12) -#define HP_DEPOP_MODE3_EN (0x1<<10) -#define HP_DEPOP_MODE2_EN (0x1<<9) -#define HP_DEPOP_MODE1_EN (0x1<<8) -#define AUXOUT_DEPOP_MODE3_EN (0x1<<6) -#define AUXOUT_DEPOP_MODE2_EN (0x1<<5) -#define AUXOUT_DEPOP_MODE1_EN (0x1<<4) -#define M_DAC_L_INPUT (0x1<<3) -#define M_DAC_R_INPUT (0x1<<2) -#define IRQOUT_INV_CTRL (0x1<<0) - -//Psedueo Stereo & Spatial Effect Block Control(0x60) -#define SPATIAL_CTRL_EN (0x1<<15) -#define ALL_PASS_FILTER_EN (0x1<<14) -#define PSEUDO_STEREO_EN (0x1<<13) -#define STEREO_EXPENSION_EN (0x1<<12) - -#define GAIN_3D_PARA_L_MASK (0x7<<9) -#define GAIN_3D_PARA_L_1_00 (0x0<<9) -#define GAIN_3D_PARA_L_1_25 (0x1<<9) -#define GAIN_3D_PARA_L_1_50 (0x2<<9) -#define GAIN_3D_PARA_L_1_75 (0x3<<9) -#define GAIN_3D_PARA_L_2_00 (0x4<<9) - -#define GAIN_3D_PARA_R_MASK (0x7<<6) -#define GAIN_3D_PARA_R_1_00 (0x0<<6) -#define GAIN_3D_PARA_R_1_25 (0x1<<6) -#define GAIN_3D_PARA_R_1_50 (0x2<<6) -#define GAIN_3D_PARA_R_1_75 (0x3<<6) -#define GAIN_3D_PARA_R_2_00 (0x4<<6) - -#define RATIO_3D_L_MASK (0x3<<4) -#define RATIO_3D_L_0_0 (0x0<<4) -#define RATIO_3D_L_0_66 (0x1<<4) -#define RATIO_3D_L_1_0 (0x2<<4) - -#define RATIO_3D_R_MASK (0x3<<2) -#define RATIO_3D_R_0_0 (0x0<<2) -#define RATIO_3D_R_0_66 (0x1<<2) -#define RATIO_3D_R_1_0 (0x2<<2) - -#define APF_MASK (0x3) -#define APF_FOR_48K (0x3) -#define APF_FOR_44_1K (0x2) -#define APF_FOR_32K (0x1) - -//EQ CONTROL(0x62) - -#define EN_HW_EQ_BLK (0x1<<15) //HW EQ block control -#define EN_HW_EQ_HPF_MODE (0x1<<14) //High Frequency shelving filter mode -#define EN_HW_EQ_SOUR (0x1<<11) //0:DAC PATH,1:ADC PATH -#define EN_HW_EQ_HPF (0x1<<4) //EQ High Pass Filter Control -#define EN_HW_EQ_BP3 (0x1<<3) //EQ Band-3 Control -#define EN_HW_EQ_BP2 (0x1<<2) //EQ Band-2 Control -#define EN_HW_EQ_BP1 (0x1<<1) //EQ Band-1 Control -#define EN_HW_EQ_LPF (0x1<<0) //EQ Low Pass Filter Control - -//EQ Mode Change Enable(0x66) -#define EQ_HPF_CHANGE_EN (0x1<<4) //EQ High Pass Filter Mode Change Enable -#define EQ_BP3_CHANGE_EN (0x1<<3) //EQ Band-3 Pass Filter Mode Change Enable -#define EQ_BP2_CHANGE_EN (0x1<<2) //EQ Band-2 Pass Filter Mode Change Enable -#define EQ_BP1_CHANGE_EN (0x1<<1) //EQ Band-1 Pass Filter Mode Change Enable -#define EQ_LPF_CHANGE_EN (0x1<<0) //EQ Low Pass Filter Mode Change Enable - - -//AVC Control(0x68) -#define AVC_ENABLE (0x1<<15) -#define AVC_TARTGET_SEL_MASK (0x1<<14) -#define AVC_TARTGET_SEL_R (0x1<<14) -#define AVC_TARTGET_SEL_L (0x0<<14) - - -struct rt5621_setup_data { - unsigned short i2c_address; - unsigned short i2c_bus; -}; - - - -#define RT5621_PLL_FR_MCLK 0 -#define RT5621_PLL_FR_BCLK 1 - - -#define USE_DAPM_CONTROL 0 -#define REALTEK_HWDEP 0 - -//WaveOut channel for realtek codec -enum -{ - RT_WAVOUT_SPK =(0x1<<0), - RT_WAVOUT_SPK_R =(0x1<<1), - RT_WAVOUT_SPK_L =(0x1<<2), - RT_WAVOUT_HP =(0x1<<3), - RT_WAVOUT_HP_R =(0x1<<4), - RT_WAVOUT_HP_L =(0x1<<5), - RT_WAVOUT_MONO =(0x1<<6), - RT_WAVOUT_AUXOUT =(0x1<<7), - RT_WAVOUT_AUXOUT_R =(0x1<<8), - RT_WAVOUT_AUXOUT_L =(0x1<<9), - RT_WAVOUT_LINEOUT =(0x1<<10), - RT_WAVOUT_LINEOUT_R =(0x1<<11), - RT_WAVOUT_LINEOUT_L =(0x1<<12), - RT_WAVOUT_DAC =(0x1<<13), - RT_WAVOUT_ALL_ON =(0x1<<14), -}; - -//WaveIn channel for realtek codec -enum -{ - RT_WAVIN_R_MONO_MIXER =(0x1<<0), - RT_WAVIN_R_SPK_MIXER =(0x1<<1), - RT_WAVIN_R_HP_MIXER =(0x1<<2), - RT_WAVIN_R_PHONE =(0x1<<3), - RT_WAVIN_R_AUXIN =(0x1<<3), - RT_WAVIN_R_LINE_IN =(0x1<<4), - RT_WAVIN_R_MIC2 =(0x1<<5), - RT_WAVIN_R_MIC1 =(0x1<<6), - - RT_WAVIN_L_MONO_MIXER =(0x1<<8), - RT_WAVIN_L_SPK_MIXER =(0x1<<9), - RT_WAVIN_L_HP_MIXER =(0x1<<10), - RT_WAVIN_L_PHONE =(0x1<<11), - RT_WAVIN_L_AUXIN =(0x1<<11), - RT_WAVIN_L_LINE_IN =(0x1<<12), - RT_WAVIN_L_MIC2 =(0x1<<13), - RT_WAVIN_L_MIC1 =(0x1<<14), -}; - -enum -{ - POWER_STATE_D0=0, - POWER_STATE_D1, - POWER_STATE_D1_PLAYBACK, - POWER_STATE_D1_RECORD, - POWER_STATE_D2, - POWER_STATE_D2_PLAYBACK, - POWER_STATE_D2_RECORD, - POWER_STATE_D3, - POWER_STATE_D4 - -}; - -#if REALTEK_HWDEP - -struct rt56xx_reg_state -{ - unsigned int reg_index; - unsigned int reg_value; -}; - -struct rt56xx_cmd -{ - size_t number; - struct rt56xx_reg_state __user *buf; -}; - -enum -{ - RT_READ_CODEC_REG_IOCTL = _IOR('R', 0x01, struct rt56xx_cmd), - RT_READ_ALL_CODEC_REG_IOCTL = _IOR('R', 0x02, struct rt56xx_cmd), - RT_WRITE_CODEC_REG_IOCTL = _IOW('R', 0x03, struct rt56xx_cmd), -}; - -#endif - -extern struct snd_soc_dai rt5621_dai; -extern struct snd_soc_codec_device soc_codec_dev_rt5621; - -#endif diff --git a/sound/soc/rk29/rk29_rt5621.c b/sound/soc/rk29/rk29_rt5621.c deleted file mode 100644 index 92c221e6f317..000000000000 --- a/sound/soc/rk29/rk29_rt5621.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * rk29_rt5621.c -- SoC audio for rockchip - * - * Driver for rockchip rt5621 audio - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../codecs/rt5621.h" -#include "rk29_pcm.h" -#include "rk29_i2s.h" - -#if 0 -#define DBG(x...) printk(KERN_INFO x) -#else -#define DBG(x...) -#endif - -static int rk29_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - unsigned int pll_out = 0; - unsigned int lrclk = 0; - int ret; - - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - - /*by Vincent Hsiung for EQ Vol Change*/ - #define HW_PARAMS_FLAG_EQVOL_ON 0x21 - #define HW_PARAMS_FLAG_EQVOL_OFF 0x22 - if ((params->flags == HW_PARAMS_FLAG_EQVOL_ON)||(params->flags == HW_PARAMS_FLAG_EQVOL_OFF)) - { - ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai); //by Vincent - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - } else { - /* set codec DAI configuration */ -#if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); -#endif -#if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM ); -#endif - if (ret < 0) - return ret; - /* set cpu DAI configuration */ -#if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); -#endif -#if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); -#endif - if (ret < 0) - return ret; - } - - switch(params_rate(params)) { - case 8000: - case 16000: - case 24000: - case 32000: - case 48000: - pll_out = 12288000; - break; - case 11025: - case 22050: - case 44100: - pll_out = 11289600; - break; - default: - DBG("Enter:%s, %d, Error rate=%d\n",__FUNCTION__,__LINE__,params_rate(params)); - return -EINVAL; - break; - } - DBG("Enter:%s, %d, rate=%d\n",__FUNCTION__,__LINE__,params_rate(params)); - -#if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) -#if 0 //use pll from blck - /*Set the pll of rt5621,the Pll source from BITCLK on CPU is master mode*/ - //bitclk is 64fs - ret=snd_soc_dai_set_pll(codec_dai,RT5621_PLL_FR_BCLK,params_rate(params)*64,pll_out); - if (ret < 0) { - DBG("rk29_hw_params_rt5621:failed to set the pll for codec side\n"); - return ret; - } -#endif - /*Set the system clk for codec*/ - ret=snd_soc_dai_set_sysclk(codec_dai, 0,pll_out,SND_SOC_CLOCK_IN); - if (ret < 0) { - DBG("rk29_hw_params_rt5621:failed to set the sysclk for codec side\n"); - return ret; - } -#endif - - - #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) - - if((24576000%params_rate(params))==0) //for 8k,16k,32k,48k - { - snd_soc_dai_set_pll(codec_dai,RT5621_PLL_FR_MCLK,pll_out, 24576000); - snd_soc_dai_set_sysclk(codec_dai,0, 24576000, SND_SOC_CLOCK_IN); - } - else if((22579200%params_rate(params))==0) //for 11k,22k,44k - { - snd_soc_dai_set_pll(codec_dai,RT5621_PLL_FR_MCLK,pll_out, 22579200); - snd_soc_dai_set_sysclk(codec_dai,0, 22579200, SND_SOC_CLOCK_IN); - } - -#endif - - -#if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) - snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0); - snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK, (pll_out/4)/params_rate(params)-1); - snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, 3); -#endif - - DBG("Enter:%s, %d, LRCK=%d\n",__FUNCTION__,__LINE__,(pll_out/4)/params_rate(params)); - - return 0; -} - -static const struct snd_soc_dapm_widget rt5621_dapm_widgets[] = { - - SND_SOC_DAPM_MIC("Mic Jack", NULL), - SND_SOC_DAPM_SPK("Ext Spk", NULL), - SND_SOC_DAPM_HP("Headphone Jack", NULL), - -}; - -static const struct snd_soc_dapm_route audio_map[]={ - - /* Mic Jack --> MIC_IN*/ - {"Mic Bias1", NULL, "Mic Jack"}, - {"MIC1", NULL, "Mic Bias1"}, - /* HP_OUT --> Headphone Jack */ - {"Headphone Jack", NULL, "HPOL"}, - {"Headphone Jack", NULL, "HPOR"}, - /* LINE_OUT --> Ext Speaker */ - {"Ext Spk", NULL, "SPOL"}, - {"Ext Spk", NULL, "SPOR"}, - -} ; - -/* - * Logic for a rt5621 as connected on a rockchip board. - */ -static int rk29_wm8988_init(struct snd_soc_pcm_runtime *rtd) -{ - return 0; -} - -static struct snd_soc_ops rk29_ops = { - .hw_params = rk29_hw_params, -}; - -static struct snd_soc_dai_link rk29_dai = { - .name = "RT5621", - .stream_name = "RT5621 PCM", - .codec_name = "RT5621.0-001a", - .platform_name = "rockchip-audio", - .cpu_dai_name = "rk29_i2s.0", - .codec_dai_name = "RT5621 HiFi", - .init = rk29_wm8988_init, - .ops = &rk29_ops, -}; - -static struct snd_soc_card snd_soc_card_rk29 = { - .name = "RK29_RT5621", - .dai_link = &rk29_dai, - .num_links = 1, -}; - -static struct platform_device *rk29_snd_device; - -static int __init audio_card_init(void) -{ - int ret =0; - - //rk29_speaker = rk29_speaker_init(RK29_PIN6_PB6, GPIO_HIGH, 2, (200*1000*1000)); - - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - rk29_snd_device = platform_device_alloc("soc-audio", -1); - if (!rk29_snd_device) { - DBG("platform device allocation failed\n"); - ret = -ENOMEM; - return ret; - } - platform_set_drvdata(rk29_snd_device, &snd_soc_card_rk29); - ret = platform_device_add(rk29_snd_device); - if (ret) { - DBG("platform device add failed\n"); - platform_device_put(rk29_snd_device); - return ret; - } - return ret; -} - -static void __exit audio_card_exit(void) -{ - platform_device_unregister(rk29_snd_device); -} - -module_init(audio_card_init); -module_exit(audio_card_exit); -/* Module information */ -MODULE_AUTHOR("rockchip"); -MODULE_DESCRIPTION("ROCKCHIP i2s ASoC Interface"); -MODULE_LICENSE("GPL"); -- 2.34.1