From 6d339c6e2c07042ae8ec548f6ceea9a108732cb3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=99=88=E9=87=91=E6=B3=89?= Date: Mon, 8 Aug 2011 16:47:29 +0800 Subject: [PATCH] update wm8994 driver --- arch/arm/configs/rk29_phonepadsdk_defconfig | 14 + arch/arm/mach-rk29/board-rk29phonepadsdk.c | 7 + sound/soc/codecs/wm8994.c | 4031 ++++++++++--------- sound/soc/codecs/wm8994.h | 2 + sound/soc/rk29/Kconfig | 88 + 5 files changed, 2168 insertions(+), 1974 deletions(-) diff --git a/arch/arm/configs/rk29_phonepadsdk_defconfig b/arch/arm/configs/rk29_phonepadsdk_defconfig index 55b92af5a0c8..cafb2b439fb1 100644 --- a/arch/arm/configs/rk29_phonepadsdk_defconfig +++ b/arch/arm/configs/rk29_phonepadsdk_defconfig @@ -1510,6 +1510,20 @@ CONFIG_SND_RK29_SOC_I2S_8CH=y # CONFIG_SND_RK29_SOC_alc5631 is not set # CONFIG_SND_RK29_SOC_RT5625 is not set CONFIG_SND_RK29_SOC_WM8994=y +# CONFIG_SND_INSIDE_EARPIECE is not set +# CONFIG_SND_OUTSIDE_EARPIECE is not set +CONFIG_SND_NO_EARPIECE=y +CONFIG_SND_BB_NORMAL_INPUT=y +# CONFIG_SND_BB_DIFFERENTIAL_INPUT is not set +CONFIG_WM8994_SPEAKER_INCALL_VOL=15 +CONFIG_WM8994_SPEAKER_INCALL_MIC_VOL=15 +CONFIG_WM8994_SPEAKER_NORMAL_VOL=15 +CONFIG_WM8994_HEADSET_INCALL_VOL=6 +CONFIG_WM8994_HEADSET_INCALL_MIC_VOL=30 +CONFIG_WM8994_HEADSET_NORMAL_VOL=15 +CONFIG_WM8994_BT_INCALL_VOL=30 +CONFIG_WM8994_BT_INCALL_MIC_VOL=-20 +CONFIG_WM8994_RECORDER_VOL=40 # CONFIG_SND_RK29_SOC_CS42L52 is not set # CONFIG_SND_RK29_CODEC_SOC_MASTER is not set CONFIG_SND_RK29_CODEC_SOC_SLAVE=y diff --git a/arch/arm/mach-rk29/board-rk29phonepadsdk.c b/arch/arm/mach-rk29/board-rk29phonepadsdk.c index 5e10e9a6c34c..e1c21f3c836b 100755 --- a/arch/arm/mach-rk29/board-rk29phonepadsdk.c +++ b/arch/arm/mach-rk29/board-rk29phonepadsdk.c @@ -764,6 +764,13 @@ static struct i2c_board_info __initdata board_i2c0_devices[] = { .flags = 0, }, #endif +#if defined (CONFIG_SND_SOC_WM8994) + { + .type = "wm8994", + .addr = 0x1A, + .flags = 0, + }, +#endif #if defined (CONFIG_BATTERY_STC3100) { .type = "stc3100", diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index e4e8dc12fd45..b4d1cf8427d2 100755 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -26,8 +26,6 @@ #include #include #include -#include -#include #include #include @@ -35,23 +33,17 @@ #include "wm8994.h" #include #include -#include -#include -#include -#include #define WM8994_PROC #ifdef WM8994_PROC #include #include -#include -char debug_write_read = 0; #endif - -/* If digital BB is used,open this define. - Define what kind of digital BB is used. */ +/* If digital BB is used,open this define. */ //#define PCM_BB + +/* Define what kind of digital BB is used. */ #ifdef PCM_BB #define TD688_MODE //#define MU301_MODE @@ -65,39 +57,44 @@ char debug_write_read = 0; #define DBG(x...) do { } while (0) #endif -static struct snd_soc_codec *wm8994_codec; +#define wm8994_mic_VCC 0x0010 +#define WM8994_DELAY 50 +/* For audio stream type */ +#define VOICE_CALL 0 +#define BLUETOOTH_SCO 6 +/* For wm8994 delay work type */ +#define WM8994_WORK_NULL 0 +#define WM8994_WORK_FIRSTINCALL 1 +#define WM8994_WORK_SHUTDOWN 2 +#define WM8994_WORK_STARTUP 3 enum wm8994_codec_mode { - wm8994_AP_to_headset, - wm8994_AP_to_speakers, - wm8994_AP_to_speakers_and_headset, - wm8994_recorder_and_AP_to_headset, - wm8994_recorder_and_AP_to_speakers, - wm8994_FM_to_headset, - wm8994_FM_to_headset_and_record, - wm8994_FM_to_speakers, - wm8994_FM_to_speakers_and_record, - wm8994_handsetMIC_to_baseband_to_headset, - wm8994_mainMIC_to_baseband_to_headset, - wm8994_handsetMIC_to_baseband_to_headset_and_record, - wm8994_mainMIC_to_baseband_to_earpiece, - wm8994_mainMIC_to_baseband_to_earpiece_and_record, - wm8994_mainMIC_to_baseband_to_speakers, - wm8994_mainMIC_to_baseband_to_speakers_and_record, - wm8994_BT_baseband, - wm8994_BT_baseband_and_record, - null -}; -/* wm8994_current_mode:save current wm8994 mode */ -unsigned char wm8994_current_mode=null; -enum stream_type_wm8994 -{ - VOICE_CALL =0, - BLUETOOTH_SCO =6, + wm8994_AP_to_headset, + wm8994_AP_to_speakers, + wm8994_AP_to_speakers_and_headset, + wm8994_recorder_and_AP_to_headset, + wm8994_recorder_and_AP_to_speakers, + wm8994_FM_to_headset, + wm8994_FM_to_headset_and_record, + wm8994_FM_to_speakers, + wm8994_FM_to_speakers_and_record, + wm8994_handsetMIC_to_baseband_to_headset, + wm8994_mainMIC_to_baseband_to_headset, + wm8994_handsetMIC_to_baseband_to_headset_and_record, + wm8994_mainMIC_to_baseband_to_earpiece, + wm8994_mainMIC_to_baseband_to_earpiece_and_record, + wm8994_mainMIC_to_baseband_to_speakers, + wm8994_mainMIC_to_baseband_to_speakers_and_record, + wm8994_BT_baseband, + wm8994_BT_baseband_and_record, + null, + wm8994_powerdown_speakers, + wm8994_powerdown_headset }; + /* For voice device route set, add by phc */ enum VoiceDeviceSwitch { @@ -126,235 +123,173 @@ enum VoiceDeviceSwitch ALL_CLOSED }; -//5:0 000000 0x3F -unsigned short headset_vol_table[6] ={0x012D,0x0133,0x0136,0x0139,0x013B,0x013D}; -unsigned short speakers_vol_table[6] ={0x012D,0x0133,0x0136,0x0139,0x013B,0x013D}; -unsigned short earpiece_vol_table[6] ={0x0127,0x012D,0x0130,0x0135,0x0139,0x013D};//normal -unsigned short BT_vol_table[16] ={0x01DB,0x01DC,0x01DD,0x01DE,0x01DF,0x01E0, - 0x01E1,0x01E2,0x01E3,0x01E4,0x01E5,0x01E6, - 0x01E7,0x01E8,0x01E9,0x01EA}; +static struct i2c_client *wm8994_client; +static bool isWM8994SetChannel = true, isSetChannelErr = false; +static void wm8994_work(struct work_struct *work); +static struct workqueue_struct *wm8994_workq; +static DECLARE_DELAYED_WORK(delayed_work, wm8994_work); +static int reg_send_data(struct i2c_client *client, unsigned short *reg, unsigned short *data, u32 scl_rate); +static int reg_recv_data(struct i2c_client *client, unsigned short *reg, unsigned short *buf, u32 scl_rate); +static void wm8994_set_volume(unsigned char wm8994_mode,unsigned char volume,unsigned char max_volume); +static void wm8994_set_channel_vol(void); +//bool isHSKey_MIC(void); +/* wm8994_current_mode:save current wm8994 mode */ +static unsigned char wm8994_current_mode = null, wm8994_work_type = WM8994_WORK_NULL; + +#ifdef WM8994_PROC +static char wm8994_current_route = SPEAKER_NORMAL; +#endif + +#define WM_EN_PIN RK29_PIN5_PA1 +#define call_maxvol 5 +#define BT_call_maxvol 15 + +/* call_vol: save all kinds of system volume value. */ +unsigned char call_vol = 5, BT_call_vol = 15; +int vol; +//static unsigned short headset_vol_table[6] ={0x012D,0x0133,0x0136,0x0139,0x013B,0x013D}; +//static unsigned short headset_vol_table[6] ={0x012D,0x013B,0x013C,0x013D,0x013E,0x013F}; +static unsigned short speakers_vol_table[6] ={0x012D,0x0133,0x0136,0x0139,0x013B,0x013D}; +#ifdef CONFIG_RAHO_CTA +static unsigned short earpiece_vol_table[6] ={0x0127,0x012D,0x0130,0x0135,0x0137,0x0135};//for cta +static unsigned short headset_vol_table[6] ={0x012D,0x013B,0x013C,0x013D,0x013E,0x013F}; +#elif defined(CONFIG_MACH_K300) || defined(CONFIG_MACH_BENGO_V2) || defined(CONFIG_MACH_USG1) +static unsigned short earpiece_vol_table[6] ={0x013a,0x013b,0x013c,0x013d,0x013e,0x013F};//giayee. +static unsigned short headset_vol_table[6] ={0x012D,0x013B,0x013C,0x013D,0x013E,0x013F}; +#elif defined(CONFIG_MACH_Z5_V2) +static unsigned short earpiece_vol_table[6] ={0x0120,0x0126,0x0129,0x012E,0x0132,0x0136};//normal +unsigned short headset_vol_table[6] ={0x0116,0x0119,0x011C,0x011F,0x0128,0x012A}; //normal +#else +static unsigned short earpiece_vol_table[6] ={0x0127,0x012D,0x0130,0x0135,0x0139,0x013D};//normal +static unsigned short headset_vol_table[6] ={0x012D,0x013B,0x013C,0x013D,0x013E,0x013F}; +#endif +static unsigned short BT_vol_table[16] ={0x01DB,0x01DC,0x01DD,0x01DE,0x01DF,0x01E0, + 0x01E1,0x01E2,0x01E3,0x01E4,0x01E5,0x01E6, + 0x01E7,0x01E8,0x01E9,0x01EA}; + +int speaker_incall_vol = CONFIG_WM8994_SPEAKER_INCALL_VOL, +speaker_incall_mic_vol = CONFIG_WM8994_SPEAKER_INCALL_MIC_VOL, +speaker_normal_vol = CONFIG_WM8994_SPEAKER_NORMAL_VOL, +#if defined(CONFIG_SND_INSIDE_EARPIECE)||defined(CONFIG_SND_OUTSIDE_EARPIECE) +earpiece_incall_vol = CONFIG_WM8994_EARPIECE_INCALL_VOL, +#endif +headset_incall_vol = CONFIG_WM8994_HEADSET_INCALL_VOL, +headset_incall_mic_vol = CONFIG_WM8994_HEADSET_INCALL_MIC_VOL, +headset_normal_vol = CONFIG_WM8994_HEADSET_NORMAL_VOL, +BT_incall_vol = CONFIG_WM8994_BT_INCALL_VOL, +BT_incall_mic_vol = CONFIG_WM8994_BT_INCALL_MIC_VOL, +recorder_vol = CONFIG_WM8994_RECORDER_VOL, +bank_vol[6] = {0,0,-3,3,-6,3}; +/* + * wm8994 register cache + * We can't read the WM8994 register space when we + * are using 2 wire for device control, so we cache them instead. + */ +static const u16 wm8994_reg[] = { + 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */ + 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */ + 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */ + 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */ + 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */ + 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */ + 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ + 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ + 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */ + 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */ + 0x0079, 0x0079, 0x0079, /* 40 */ +}; /* codec private data */ struct wm8994_priv { - struct mutex io_lock; - struct mutex route_lock; - int sysclk; - int mclk; - int fmt;//master or salve - int rate;//Sampling rate + unsigned int sysclk; struct snd_soc_codec codec; - struct snd_kcontrol *kcontrol;//The current working path - char RW_status; //ERROR = -1, TRUE = 0; - struct wm8994_pdata *pdata; - - struct delayed_work wm8994_delayed_work; - int work_type; - - unsigned int playback_active:1; - unsigned int capture_active:1; - /* call_vol: save all kinds of system volume value. */ - unsigned char call_vol; - unsigned char BT_call_vol; - - struct wake_lock wm8994_on_wake; + struct snd_pcm_hw_constraint_list *sysclk_constraints; + u16 reg_cache[WM8994_NUM_REG]; }; -int reg_send_data(struct i2c_client *client, unsigned short *reg, unsigned short *data, u32 scl_rate) -{ - int ret; - struct i2c_adapter *adap = client->adapter; - struct i2c_msg msg; - char tx_buf[4]; - - memcpy(tx_buf, reg, 2); - memcpy(tx_buf+2, data, 2); - msg.addr = client->addr; - msg.buf = tx_buf; - msg.len = 4; - msg.flags = client->flags; - msg.scl_rate = scl_rate; - msg.read_type = 0; - ret = i2c_transfer(adap, &msg, 1); - - return ret; -} - -int reg_recv_data(struct i2c_client *client, unsigned short *reg, unsigned short *buf, u32 scl_rate) +bool wm8994_set_status(void) { - int ret; - struct i2c_adapter *adap = client->adapter; - struct i2c_msg msgs[2]; - - msgs[0].addr = client->addr; - msgs[0].buf = (char *)reg; - msgs[0].flags = client->flags; - msgs[0].len = 2; - msgs[0].scl_rate = scl_rate; - msgs[0].read_type = 2; - - msgs[1].addr = client->addr; - msgs[1].buf = (char *)buf; - msgs[1].flags = client->flags | I2C_M_RD; - msgs[1].len = 2; - msgs[1].scl_rate = scl_rate; - msgs[1].read_type = 2; - - ret = i2c_transfer(adap, msgs, 2); - - return ret; + return isWM8994SetChannel; } -int wm8994_set_status(void) -{ - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - int ret = 1; - mutex_lock(&wm8994->route_lock); - - if(wm8994->work_type == SNDRV_PCM_TRIGGER_SUSPEND) - ret = -2; - - mutex_unlock(&wm8994->route_lock); - return ret; -} EXPORT_SYMBOL_GPL(wm8994_set_status); static int wm8994_read(unsigned short reg,unsigned short *value) { - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - unsigned short regs=((reg>>8)&0x00FF)|((reg<<8)&0xFF00),values; char i = 2; - mutex_lock(&wm8994->io_lock); - if(wm8994->RW_status == ERROR) goto out; - while(i > 0) - { + if (isSetChannelErr)return -EIO; + + while(i > 0) { i--; - if (reg_recv_data(wm8994_codec->control_data,®s,&values,400000) > 0) - { + if (reg_recv_data(wm8994_client,®s,&values,400000) > 0) { *value=((values>>8)& 0x00FF)|((values<<8)&0xFF00); - #ifdef WM8994_PROC - if(debug_write_read != 0) - DBG("%s:0x%04x = 0x%04x",__FUNCTION__,reg,*value); - #endif - mutex_unlock(&wm8994->io_lock); return 0; } } + isSetChannelErr = true; - wm8994->RW_status = ERROR; printk("%s---line->%d:Codec read error! reg = 0x%x , value = 0x%x\n",__FUNCTION__,__LINE__,reg,*value); -out: - mutex_unlock(&wm8994->io_lock); + return -EIO; } static int wm8994_write(unsigned short reg,unsigned short value) { - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - unsigned short regs=((reg>>8)&0x00FF)|((reg<<8)&0xFF00),values=((value>>8)&0x00FF)|((value<<8)&0xFF00); char i = 2; - - mutex_lock(&wm8994->io_lock); - if(wm8994->RW_status == ERROR) goto out; + if (isSetChannelErr)return -EIO; -#ifdef WM8994_PROC - if(debug_write_read != 0) - DBG("%s:0x%04x = 0x%04x\n",__FUNCTION__,reg,value); -#endif - while(i > 0) - { + while(i > 0) { i--; - if (reg_send_data(wm8994_codec->control_data,®s,&values,400000) > 0) - { - mutex_unlock(&wm8994->io_lock); + if (reg_send_data(wm8994_client,®s,&values,400000) > 0) { + if (reg == 0x302) { + wm8994_read(0x406, &values); + wm8994_write(0x406, values); + wm8994_read(reg, &values); + + DBG("read 0x302 = 0x%x write 0x302 = 0x%x \n", values, value); + + if (values != value) + isSetChannelErr = true; + } return 0; - } + } } - - wm8994->RW_status = ERROR; + isSetChannelErr = true; + printk("%s---line->%d:Codec write error! reg = 0x%x , value = 0x%x\n",__FUNCTION__,__LINE__,reg,value); -out: - mutex_unlock(&wm8994->io_lock); return -EIO; } -static void wm8994_set_volume(unsigned char wm8994_mode,unsigned char volume,unsigned char max_volume) +static void wm8994_codec_first_incall(void) { - unsigned short lvol=0,rvol=0; -// DBG("%s::volume = %d \n",__FUNCTION__,volume); + if (wm8994_current_mode == wm8994_AP_to_speakers_and_headset || + wm8994_current_mode == wm8994_recorder_and_AP_to_headset || + wm8994_current_mode == wm8994_recorder_and_AP_to_speakers || + wm8994_current_mode == wm8994_powerdown_headset || + wm8994_current_mode == wm8994_powerdown_speakers) { - if(volume>max_volume) - volume=max_volume; - - switch(wm8994_mode) - { - case wm8994_handsetMIC_to_baseband_to_headset_and_record: - case wm8994_handsetMIC_to_baseband_to_headset: - case wm8994_mainMIC_to_baseband_to_headset: - wm8994_read(0x001C, &lvol); - wm8994_read(0x001D, &rvol); - //HPOUT1L_VOL bit 0~5 /-57dB to +6dB in 1dB steps - wm8994_write(0x001C, (lvol&~0x003f)|headset_vol_table[volume]); - //HPOUT1R_VOL bit 0~5 /-57dB to +6dB in 1dB steps - wm8994_write(0x001D, (rvol&~0x003f)|headset_vol_table[volume]); - break; - case wm8994_mainMIC_to_baseband_to_speakers_and_record: - case wm8994_mainMIC_to_baseband_to_speakers: - wm8994_read(0x0026, &lvol); - wm8994_read(0x0027, &rvol); - //SPKOUTL_VOL bit 0~5 /-57dB to +6dB in 1dB steps - wm8994_write(0x0026, (lvol&~0x003f)|speakers_vol_table[volume]); - //SPKOUTR_VOL bit 0~5 /-57dB to +6dB in 1dB steps - wm8994_write(0x0027, (rvol&~0x003f)|speakers_vol_table[volume]); - break; - case wm8994_mainMIC_to_baseband_to_earpiece: - case wm8994_mainMIC_to_baseband_to_earpiece_and_record: - wm8994_read(0x0020, &lvol); - wm8994_read(0x0021, &rvol); - //MIXOUTL_VOL bit 0~5 /-57dB to +6dB in 1dB steps - wm8994_write(0x0020, (lvol&~0x003f)|earpiece_vol_table[volume]); - //MIXOUTR_VOL bit 0~5 /-57dB to +6dB in 1dB steps - wm8994_write(0x0021, (rvol&~0x003f)|earpiece_vol_table[volume]); - break; - case wm8994_BT_baseband: - case wm8994_BT_baseband_and_record: - //bit 0~4 /-16.5dB to +30dB in 1.5dB steps - DBG("BT_vol_table[volume] = 0x%x\n",BT_vol_table[volume]); - wm8994_write(0x0500, BT_vol_table[volume]); - wm8994_write(0x0501, 0x0100); - break; - default: - // DBG("Set all volume\n"); - wm8994_read(0x001C, &lvol); - wm8994_read(0x001D, &rvol); - wm8994_write(0x001C, (lvol&~0x003f)|headset_vol_table[volume]); - wm8994_write(0x001D, (rvol&~0x003f)|headset_vol_table[volume]); - wm8994_read(0x0026, &lvol); - wm8994_read(0x0027, &rvol); - wm8994_write(0x0026, (lvol&~0x003f)|speakers_vol_table[volume]); - wm8994_write(0x0027, (rvol&~0x003f)|speakers_vol_table[volume]); - wm8994_read(0x0020, &lvol); - wm8994_read(0x0021, &rvol); - wm8994_write(0x0020, (lvol&~0x003f)|earpiece_vol_table[volume]); - wm8994_write(0x0021, (rvol&~0x003f)|earpiece_vol_table[volume]); - break; + cancel_delayed_work_sync(&delayed_work); + + wm8994_work_type = WM8994_WORK_FIRSTINCALL; + queue_delayed_work(wm8994_workq, &delayed_work, + msecs_to_jiffies(1500)); } } static void wm8994_set_all_mute(void) { int i; - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - if(wm8994->call_vol < 0) + if (call_vol < 0) return; - for (i = wm8994->call_vol; i >= 0; i--) + for (i = call_vol; i >= 0; i-=2) wm8994_set_volume(null,i,call_maxvol); } @@ -362,461 +297,224 @@ static void wm8994_set_all_mute(void) static void wm8994_set_level_volume(void) { int i; - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - for (i = 0; i <= wm8994->call_vol; i++) + for (i = 0; i <= call_vol; i++) { wm8994_set_volume(wm8994_current_mode,i,call_maxvol); - -} - -static void PA_ctrl(unsigned char ctrl) -{ - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - struct wm8994_pdata *pdata = wm8994->pdata; - - if(pdata->PA_control_pin > 0) - { - if(ctrl == GPIO_HIGH) - { - DBG("enable PA_control\n"); - gpio_request(pdata->PA_control_pin, NULL); //AUDIO_PA_ON - gpio_direction_output(pdata->PA_control_pin,GPIO_HIGH); - gpio_free(pdata->PA_control_pin); - } - else - { - DBG("disable PA_control\n"); - gpio_request(pdata->PA_control_pin, NULL); //AUDIO_PA_ON - gpio_direction_output(pdata->PA_control_pin,GPIO_LOW); - gpio_free(pdata->PA_control_pin); - } } } -/* The size in bits of the FLL divide multiplied by 10 - * to allow rounding later */ -#define FIXED_FLL_SIZE ((1 << 16) * 10) - -struct fll_div { - u16 outdiv; - u16 n; - u16 k; - u16 clk_ref_div; - u16 fll_fratio; -}; +#define wm8994_reset() wm8994_set_all_mute();\ + wm8994_write(WM8994_RESET, 0) -static int wm8994_get_fll_config(struct fll_div *fll, - int freq_in, int freq_out) +static void AP_to_headset(void) { - u64 Kpart; - unsigned int K, Ndiv, Nmod; - -// DBG("FLL input=%dHz, output=%dHz\n", freq_in, freq_out); - - /* Scale the input frequency down to <= 13.5MHz */ - fll->clk_ref_div = 0; - while (freq_in > 13500000) { - fll->clk_ref_div++; - freq_in /= 2; - - if (fll->clk_ref_div > 3) - return -EINVAL; - } -// DBG("CLK_REF_DIV=%d, Fref=%dHz\n", fll->clk_ref_div, freq_in);//0 12m - - /* Scale the output to give 90MHz<=Fvco<=100MHz */ - fll->outdiv = 3; - while (freq_out * (fll->outdiv + 1) < 90000000) { - fll->outdiv++; - if (fll->outdiv > 63) - return -EINVAL; - } - freq_out *= fll->outdiv + 1; -// DBG("OUTDIV=%d, Fvco=%dHz\n", fll->outdiv, freq_out);//8 98.304MHz + DBG("%s::%d\n",__FUNCTION__,__LINE__); - if (freq_in > 1000000) { - fll->fll_fratio = 0; - } else { - fll->fll_fratio = 3; - freq_in *= 8; - } -// DBG("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in);//0 12M + if (wm8994_current_mode == wm8994_AP_to_headset)return; + wm8994_current_mode = wm8994_AP_to_headset; + wm8994_reset(); + msleep(WM8994_DELAY); - /* Now, calculate N.K */ - Ndiv = freq_out / freq_in; + wm8994_write(0x700, 0xA101); + wm8994_write(0x39, 0x006C); + wm8994_write(0x01, 0x0023); + wm8994_write(0x200, 0x0000); + mdelay(WM8994_DELAY); - fll->n = Ndiv; - Nmod = freq_out % freq_in; -// DBG("Nmod=%d\n", Nmod); + wm8994_write(0x220, 0x0000); + wm8994_write(0x221, 0x0700); + wm8994_write(0x222, 0x3126); + wm8994_write(0x223, 0x0100); - /* Calculate fractional part - scale up so we can round. */ - Kpart = FIXED_FLL_SIZE * (long long)Nmod; + wm8994_write(0x220, 0x0004); + msleep(10); + wm8994_write(0x220, 0x0005); + msleep(5); - do_div(Kpart, freq_in); + wm8994_write(0x200, 0x0010); + wm8994_write(0x208, 0x0008); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 + wm8994_write(0x208, 0x000A); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 + wm8994_write(0x210, 0x0083); // SR=48KHz +#ifdef CONFIG_SND_CODEC_SOC_MASTER + wm8994_write(0x302, 0x3000); // AIF1_MSTR=1 + wm8994_write(0x302, 0x7000); // AIF1_MSTR=1 + wm8994_write(0x303, 0x0040); // AIF1 BCLK DIV--------AIF1CLK/4 + wm8994_write(0x304, 0x0040); // AIF1 ADCLRCK DIV-----BCLK/64 + wm8994_write(0x305, 0x0040); // AIF1 DACLRCK DIV-----BCLK/64 + wm8994_write(0x300, 0x4010); // i2s 16 bits +#endif + wm8994_write(0x200, 0x0011); // sysclk = fll (bit4 =1) 0x0011 + + wm8994_write(0x04, 0x0303); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1, ADCL_ENA=1, ADCR_ENA=1/ q + wm8994_write(0x05, 0x0303); + wm8994_write(0x2D, 0x0100); + wm8994_write(0x2E, 0x0100); + + wm8994_write(0x4C, 0x9F25); + msleep(5); + wm8994_write(0x01, 0x0323); + msleep(50); + wm8994_write(0x60, 0x0022); + wm8994_write(0x60, 0x00FF); - K = Kpart & 0xFFFFFFFF; + wm8994_write(0x420, 0x0000); + wm8994_write(0x601, 0x0001); + wm8994_write(0x602, 0x0001); + + wm8994_write(0x610, 0x01A0); //DAC1 Left Volume bit0~7 + wm8994_write(0x611, 0x01A0); //DAC1 Right Volume bit0~7 + wm8994_write(0x03, 0x3030); + wm8994_write(0x22, 0x0000); + wm8994_write(0x23, 0x0100); + wm8994_write(0x36, 0x0003); + wm8994_write(0x1C, 0x017F); //HPOUT1L Volume + wm8994_write(0x1D, 0x017F); //HPOUT1R Volume +} - if ((K % 10) >= 5) - K += 5; +static void AP_to_speakers(void) +{ + DBG("%s::%d\n",__FUNCTION__,__LINE__); - /* Move down to proper range now rounding is done */ - fll->k = K / 10; + if (wm8994_current_mode == wm8994_AP_to_speakers)return; + wm8994_current_mode = wm8994_AP_to_speakers; + wm8994_reset(); + msleep(WM8994_DELAY); -// DBG("N=%x K=%x\n", fll->n, fll->k);//8 3127 + wm8994_write(0x700, 0xA101); + wm8994_write(0x39, 0x006C); + wm8994_write(0x01, 0x0023); + wm8994_write(0x200, 0x0000); + mdelay(WM8994_DELAY); - return 0; -} + wm8994_write(0x220, 0x0000); + wm8994_write(0x221, 0x0700); + wm8994_write(0x222, 0x3126); + wm8994_write(0x223, 0x0100); -static int wm8994_set_fll(unsigned int freq_in, unsigned int freq_out) -{ - int ret; - struct fll_div fll; - u16 reg=0; -// DBG("Enter %s::%s---%d\n",__FILE__,__FUNCTION__,__LINE__); - wm8994_write(0x220, 0x0000); - /* If we're stopping the FLL redo the old config - no - * registers will actually be written but we avoid GCC flow - * analysis bugs spewing warnings. - */ - ret = wm8994_get_fll_config(&fll, freq_in, freq_out); - if (ret < 0) - return ret; - - reg = (fll.outdiv << WM8994_FLL1_OUTDIV_SHIFT) |(fll.fll_fratio << WM8994_FLL1_FRATIO_SHIFT); - wm8994_write(0x221, reg);//0x221 DIV - wm8994_write(0x222, fll.k);//0x222 K - wm8994_write(0x223, fll.n << WM8994_FLL1_N_SHIFT);//0x223 N - wm8994_write(0x224, fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT);//0x224 - - wm8994_write(0x220, 0x0004); + wm8994_write(0x220, 0x0004); msleep(10); - wm8994_write(0x220, 0x0005); + wm8994_write(0x220, 0x0005); msleep(5); - wm8994_write(0x200, 0x0010); // sysclk = MCLK1 - return 0; -} -static int wm8994_sysclk_config(void) -{ - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - unsigned int freq_in,freq_out; - - wm8994_write(0x200, 0x0000); - freq_in = wm8994->mclk; - switch(wm8994->mclk) - { - case 12288000: - case 11289600: - freq_out = wm8994->mclk; - break; - case 3072000: - case 2822400: - freq_out = wm8994->mclk * 4; - break; - default: - printk("wm8994->mclk error = %d\n",wm8994->mclk); - return -1; - } - - switch(wm8994->sysclk) - { - case WM8994_SYSCLK_FLL1: - wm8994_set_fll(freq_in,freq_out); - break; - case WM8994_SYSCLK_FLL2: - break; - case WM8994_SYSCLK_MCLK2: - wm8994_write(0x701, 0x0000);//MCLK2 - case WM8994_SYSCLK_MCLK1: - if(freq_out == freq_in) - break; - default: - printk("wm8994->sysclk error = %d\n",wm8994->sysclk); - return -1; - } - + wm8994_write(0x200, 0x0010); wm8994_write(0x208, 0x0008); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 - wm8994_write(0x208, 0x000A); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 - - switch(wm8994->rate) - { - case 8000: - printk("wm8994->rate = %d!!!!\n",wm8994->rate); - break; - case 44100: - wm8994_write(0x210, 0x0073); // SR=48KHz - break; - case 48000: - wm8994_write(0x210, 0x0083); // SR=48KHz - break; - case 11025: - case 16000: - case 22050: - case 32000: - default: - printk("wm8994->rate error = %d\n",wm8994->rate); - return -1; - } - - switch(wm8994->fmt) - { - case SND_SOC_DAIFMT_CBS_CFS: - case SND_SOC_DAIFMT_CBM_CFM: - break; - default: - printk("wm8994->fmt error = %d\n",wm8994->fmt); - return -1; - } - - wm8994_write(0x200, wm8994->sysclk << 3|0x01); - return 0; -} + wm8994_write(0x208, 0x000A); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 + wm8994_write(0x210, 0x0083); // SR=48KHz +#ifdef CONFIG_SND_CODEC_SOC_MASTER + wm8994_write(0x302, 0x3000); // AIF1_MSTR=1 + wm8994_write(0x302, 0x7000); // AIF1_MSTR=1 + wm8994_write(0x303, 0x0040); // AIF1 BCLK DIV--------AIF1CLK/4 + wm8994_write(0x304, 0x0040); // AIF1 ADCLRCK DIV-----BCLK/64 + wm8994_write(0x305, 0x0040); // AIF1 DACLRCK DIV-----BCLK/64 + wm8994_write(0x300, 0xC010); // i2s 16 bits +#endif + wm8994_write(0x200, 0x0011); // sysclk = fll (bit4 =1) 0x0011 + + wm8994_write(0x01, 0x3023); + wm8994_write(0x04, 0x0303); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1, ADCL_ENA=1, ADCR_ENA=1 + wm8994_write(0x05, 0x0303); + wm8994_write(0x2D, 0x0100); + wm8994_write(0x2E, 0x0100); + wm8994_write(0x4C, 0x9F25); + wm8994_write(0x60, 0x00EE); + wm8994_write(0x420, 0x0000); -static void wm8994_set_AIF1DAC_EQ(void) -{ - //100HZ. 300HZ. 875HZ 2400HZ 6900HZ -// int bank_vol[6] = {0,0,-3,3,-6,3};//-12DB ~ 12DB default 0DB - int bank_vol[6] = {6,2,0,0,0,0};//-12DB ~ 12DB default 0DB - wm8994_write(0x0480, 0x0001|((bank_vol[1]+12)<<11)| - ((bank_vol[2]+12)<<6)|((bank_vol[3]+12)<<1)); - wm8994_write(0x0481, 0x0000|((bank_vol[4]+12)<<11)| - ((bank_vol[5]+12)<<6)); + wm8994_write(0x601, 0x0001); + wm8994_write(0x602, 0x0001); + + wm8994_write(0x610, 0x01c0); //DAC1 Left Volume bit0~7 + wm8994_write(0x611, 0x01c0); //DAC1 Right Volume bit0~7 + wm8994_write(0x03, 0x0330); + wm8994_write(0x22, 0x0000); + wm8994_write(0x23, 0x0100); + wm8994_write(0x36, 0x0003); + wm8994_write(0x26, 0x017F); //Speaker Left Output Volume + wm8994_write(0x27, 0x017F); //Speaker Right Output Volume } -static int wm8994_reset_ldo(void) +static void AP_to_speakers_and_headset(void) { - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - struct wm8994_pdata *pdata = wm8994->pdata; - unsigned short value; + DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994->RW_status == TRUE) - return 0; - - gpio_request(pdata->Power_EN_Pin, NULL); - gpio_direction_output(pdata->Power_EN_Pin,GPIO_LOW); - gpio_free(pdata->Power_EN_Pin); - msleep(50); - gpio_request(pdata->Power_EN_Pin, NULL); - gpio_direction_output(pdata->Power_EN_Pin,GPIO_HIGH); - gpio_free(pdata->Power_EN_Pin); - msleep(50); - - wm8994->RW_status = TRUE; - wm8994_read(0x00, &value); - - if(value == 0x8994) - DBG("wm8994_reset_ldo Read ID = 0x%x\n",value); - else - { - wm8994->RW_status = ERROR; - printk("wm8994_reset_ldo Read ID error value = 0x%x\n",value); - return -1; - } - - return 0; -} -//Set the volume of each channel (including recording) -static void wm8994_set_channel_vol(void) -{ - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - struct wm8994_pdata *pdata = wm8994->pdata; - int vol; - - switch(wm8994_current_mode){ - case wm8994_AP_to_speakers_and_headset: - MAX_MIN(-57,pdata->speaker_normal_vol,6); - MAX_MIN(-57,pdata->headset_normal_vol,6); - DBG("headset_normal_vol = %ddB \n",pdata->headset_normal_vol); - DBG("speaker_normal_vol = %ddB \n",pdata->speaker_normal_vol); - - vol = pdata->speaker_normal_vol; - wm8994_write(0x26, 320+vol+57); //-57dB~6dB - wm8994_write(0x27, 320+vol+57); //-57dB~6dB - - vol = pdata->headset_normal_vol-4; - //for turn off headset volume when ringtone - if(vol >= -48) - vol -= 14; - else - vol = -57; - - wm8994_write(0x1C, 320+vol+57); //-57dB~6dB - wm8994_write(0x1D, 320+vol+57); //-57dB~6dB - - wm8994_set_AIF1DAC_EQ(); - break; - - case wm8994_recorder_and_AP_to_headset: - MAX_MIN(-57,pdata->headset_normal_vol,6); - MAX_MIN(-16,pdata->recorder_vol,60); - DBG("recorder_vol = %ddB \n",pdata->recorder_vol); - DBG("headset_normal_vol = %ddB \n",pdata->headset_normal_vol); + if (wm8994_current_mode == wm8994_AP_to_speakers_and_headset)return; + wm8994_current_mode = wm8994_AP_to_speakers_and_headset; + wm8994_reset(); + mdelay(WM8994_DELAY); + wm8994_write(0x700, 0xA101); + wm8994_write(0x39, 0x006C); + wm8994_write(0x01, 0x0023); + wm8994_write(0x200, 0x0000); + mdelay(WM8994_DELAY); + wm8994_write(0x220, 0x0000); + wm8994_write(0x221, 0x0700); + wm8994_write(0x222, 0x3126); + wm8994_write(0x223, 0x0100); - vol = pdata->recorder_vol; - if(vol<30) - wm8994_write(0x1A, 320+(vol+16)*10/15); //mic vol - else - { - wm8994_write(0x2A, 0x0030); - wm8994_write(0x1A, 320+(vol-14)*10/15); //mic vol - } - vol = pdata->headset_normal_vol; - wm8994_write(0x1C, 320+vol+57); //-57dB~6dB - wm8994_write(0x1D, 320+vol+57); //-57dB~6dB - // wm8994_set_AIF1DAC_EQ(); - break; + wm8994_write(0x220, 0x0004); + msleep(10); + wm8994_write(0x220, 0x0005); + msleep(5); - case wm8994_recorder_and_AP_to_speakers: - case wm8994_FM_to_speakers: - MAX_MIN(-57,pdata->speaker_normal_vol,6); - MAX_MIN(-16,pdata->recorder_vol,60); - DBG("speaker_normal_vol = %ddB \n",pdata->speaker_normal_vol); - DBG("recorder_vol = %ddB \n",pdata->recorder_vol); - - vol = pdata->recorder_vol; - if(vol<30) - wm8994_write(0x1A, 320+(vol+16)*10/15); //mic vol - else - { - wm8994_write(0x2A, 0x0030); - wm8994_write(0x1A, 320+(vol-14)*10/15); //mic vol - } + wm8994_write(0x200, 0x0010); + wm8994_write(0x208, 0x0008); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 + wm8994_write(0x208, 0x000A); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 + wm8994_write(0x210, 0x0083); // SR=48KHz +#ifdef CONFIG_SND_CODEC_SOC_MASTER + wm8994_write(0x302, 0x3000); // AIF1_MSTR=1 + wm8994_write(0x302, 0x7000); // AIF1_MSTR=1 + wm8994_write(0x303, 0x0040); // AIF1 BCLK DIV--------AIF1CLK/4 + wm8994_write(0x304, 0x0040); // AIF1 ADCLRCK DIV-----BCLK/64 + wm8994_write(0x305, 0x0040); // AIF1 DACLRCK DIV-----BCLK/64 + wm8994_write(0x300, 0xC010); // i2s 16 bits +#endif + wm8994_write(0x200, 0x0011); // sysclk = fll (bit4 =1) 0x0011 - vol = pdata->speaker_normal_vol; - wm8994_write(0x26, 320+vol+57); //-57dB~6dB - wm8994_write(0x27, 320+vol+57); //-57dB~6dB + wm8994_write(0x610, 0x0100); //DAC1 Left Volume bit0~7 + wm8994_write(0x611, 0x0100); //DAC1 Right Volume bit0~7 - wm8994_set_AIF1DAC_EQ(); - break; - case wm8994_handsetMIC_to_baseband_to_headset: - MAX_MIN(-12,pdata->headset_incall_vol,6); - MAX_MIN(-22,pdata->headset_incall_mic_vol,30); - DBG("headset_incall_mic_vol = %ddB \n",pdata->headset_incall_mic_vol); - DBG("headset_incall_vol = %ddB \n",pdata->headset_incall_vol); - - vol = pdata->headset_incall_mic_vol; - if(vol<-16) - { - wm8994_write(0x1E, 0x0016); //mic vol - wm8994_write(0x18, 320+(vol+22)*10/15); //mic vol - } - else - { - wm8994_write(0x1E, 0x0006); //mic vol - wm8994_write(0x18, 320+(vol+16)*10/15); //mic vol - } - break; - case wm8994_mainMIC_to_baseband_to_headset: - MAX_MIN(-12,pdata->headset_incall_vol,6); - MAX_MIN(-22,pdata->speaker_incall_mic_vol,30); - DBG("speaker_incall_mic_vol = %ddB \n",pdata->speaker_incall_mic_vol); - DBG("headset_incall_vol = %ddB \n",pdata->headset_incall_vol); - - vol=pdata->speaker_incall_mic_vol; - if(vol<-16) - { - wm8994_write(0x1E, 0x0016); //mic vol - wm8994_write(0x1A, 320+(vol+22)*10/15); //mic vol - } - else - { - wm8994_write(0x1E, 0x0006); //mic vol - wm8994_write(0x1A, 320+(vol+16)*10/15); //mic vol - } - break; + wm8994_write(0x24, 0x0018); + wm8994_set_channel_vol(); + //wm8994_write(0x25, 0x003F); - case wm8994_mainMIC_to_baseband_to_earpiece: - MAX_MIN(-22,pdata->speaker_incall_mic_vol,30); - MAX_MIN(-21,pdata->earpiece_incall_vol,6); - DBG("earpiece_incall_vol = %ddB \n",pdata->earpiece_incall_vol); - DBG("speaker_incall_mic_vol = %ddB \n",pdata->speaker_incall_mic_vol); - - vol = pdata->earpiece_incall_vol; - if(vol>=0) - { - wm8994_write(0x33, 0x0018); //6dB - wm8994_write(0x31, (((6-vol)/3)<<3)+(6-vol)/3); //-21dB - } - else - { - wm8994_write(0x33, 0x0010); - wm8994_write(0x31, (((-vol)/3)<<3)+(-vol)/3); //-21dB - } - vol = pdata->speaker_incall_mic_vol; - if(vol<-16) - { - wm8994_write(0x1E, 0x0016); - wm8994_write(0x1A, 320+(vol+22)*10/15); - } - else - { - wm8994_write(0x1E, 0x0006); - wm8994_write(0x1A, 320+(vol+16)*10/15); - } - break; + wm8994_write(0x04, 0x0303); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1, ADCL_ENA=1, ADCR_ENA=1 + wm8994_write(0x05, 0x0303); + wm8994_write(0x2D, 0x0100); + wm8994_write(0x2E, 0x0100); - case wm8994_mainMIC_to_baseband_to_speakers: - MAX_MIN(-22,pdata->speaker_incall_mic_vol,30); - MAX_MIN(-21,pdata->speaker_incall_vol,12); - DBG("speaker_incall_vol = %ddB \n",pdata->speaker_incall_vol); - DBG("speaker_incall_mic_vol = %ddB \n",pdata->speaker_incall_mic_vol); - - vol = pdata->speaker_incall_mic_vol; - if(vol<-16) - { - wm8994_write(0x1E, 0x0016); - wm8994_write(0x1A, 320+(vol+22)*10/15); - } - else - { - wm8994_write(0x1E, 0x0006); - wm8994_write(0x1A, 320+(vol+16)*10/15); - } - vol = pdata->speaker_incall_vol; - if(vol<=0) - { - wm8994_write(0x31, (((-vol)/3)<<3)+(-vol)/3); - } - else if(vol <= 9) - { - wm8994_write(0x25, ((vol*10/15)<<3)+vol*10/15); - } - else - { - wm8994_write(0x25, 0x003F); - } - break; + wm8994_write(0x4C, 0x9F25); + mdelay(5); + wm8994_write(0x01, 0x3303); + mdelay(50); + wm8994_write(0x60, 0x0022); + wm8994_write(0x60, 0x00EE); - case wm8994_BT_baseband: - MAX_MIN(-16,pdata->BT_incall_vol,30); - MAX_MIN(-57,pdata->BT_incall_mic_vol,6); - DBG("BT_incall_mic_vol = %ddB \n",pdata->BT_incall_mic_vol); - DBG("BT_incall_vol = %ddB \n",pdata->BT_incall_vol); - vol = pdata->BT_incall_mic_vol; - wm8994_write(0x20, 320+vol+57); - vol = pdata->BT_incall_vol; - wm8994_write(0x19, 0x0500+(vol+16)*10/15); - break; - default: - printk("route error !\n"); - } + wm8994_write(0x420, 0x0000); + + wm8994_write(0x601, 0x0001); + wm8994_write(0x602, 0x0001); + + wm8994_write(0x03, 0x3330); + wm8994_write(0x22, 0x0000); + wm8994_write(0x23, 0x0100); + wm8994_write(0x36, 0x0003); + wm8994_write(0x01, 0x3323); + wm8994_write(0x610, 0x01C0); //DAC1 Left Volume bit0~7 + wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 } -#define wm8994_reset() wm8994_set_all_mute();\ - wm8994_write(WM8994_RESET, 0) - -void AP_to_headset(void) +static void recorder_and_AP_to_headset(void) { DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode==wm8994_AP_to_headset)return; - wm8994_current_mode=wm8994_AP_to_headset; + if (wm8994_current_mode == wm8994_recorder_and_AP_to_headset)return; + wm8994_current_mode = wm8994_recorder_and_AP_to_headset; wm8994_reset(); msleep(WM8994_DELAY); wm8994_write(0x700, 0xA101); - wm8994_write(0x01, 0x0023); + wm8994_write(0x39, 0x006C); + wm8994_write(0x01, 0x0003); wm8994_write(0x200, 0x0000); mdelay(WM8994_DELAY); @@ -834,55 +532,66 @@ void AP_to_headset(void) wm8994_write(0x208, 0x0008); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 wm8994_write(0x208, 0x000A); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 wm8994_write(0x210, 0x0083); // SR=48KHz -#ifdef CONFIG_SND_RK29_CODEC_SOC_MASTER +#ifdef CONFIG_SND_CODEC_SOC_MASTER wm8994_write(0x302, 0x3000); // AIF1_MSTR=1 wm8994_write(0x302, 0x7000); // AIF1_MSTR=1 wm8994_write(0x303, 0x0040); // AIF1 BCLK DIV--------AIF1CLK/4 wm8994_write(0x304, 0x0040); // AIF1 ADCLRCK DIV-----BCLK/64 wm8994_write(0x305, 0x0040); // AIF1 DACLRCK DIV-----BCLK/64 - wm8994_write(0x300, 0x4010); // i2s 16 bits + wm8994_write(0x300, 0xC050); // i2s 16 bits #endif wm8994_write(0x200, 0x0011); // sysclk = fll (bit4 =1) 0x0011 - - wm8994_write(0x04, 0x0303); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1, ADCL_ENA=1, ADCR_ENA=1/ q - wm8994_write(0x05, 0x0303); - wm8994_write(0x2D, 0x0100); - wm8994_write(0x2E, 0x0100); - + + wm8994_write(0x04, 0x0303); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1, ADCL_ENA=1, ADCR_ENA=1 + wm8994_write(0x05, 0x0303); // AIF1DAC1L_ENA=1, AIF1DAC1R_ENA=1, DAC1L_ENA=1, DAC1R_ENA=1 + wm8994_write(0x2D, 0x0100); // DAC1L_TO_HPOUT1L=1 + wm8994_write(0x2E, 0x0100); // DAC1R_TO_HPOUT1R=1 + wm8994_write(0x4C, 0x9F25); - msleep(5); - wm8994_write(0x01, 0x0323); - msleep(50); + mdelay(5); + wm8994_write(0x01, 0x0303); + mdelay(50); wm8994_write(0x60, 0x0022); wm8994_write(0x60, 0x00FF); - wm8994_write(0x420, 0x0000); - wm8994_write(0x601, 0x0001); - wm8994_write(0x602, 0x0001); - - wm8994_write(0x610, 0x01A0); //DAC1 Left Volume bit0~7 - wm8994_write(0x611, 0x01A0); //DAC1 Right Volume bit0~7 + wm8994_write(0x610, 0x0100); // DAC1_VU=1, DAC1L_VOL=1100_0000 + wm8994_write(0x611, 0x0100); // DAC1_VU=1, DAC1R_VOL=1100_0000 + + wm8994_write(0x25, 0x003F); + wm8994_write(0x28, 0x0003); // IN1RP_TO_IN1R=1, IN1RN_TO_IN1R=1 + wm8994_write(0x606, 0x0002); // ADC1L_TO_AIF1ADC1L=1 + wm8994_write(0x607, 0x0002); // ADC1R_TO_AIF1ADC1R=1 + wm8994_write(0x620, 0x0000); + + wm8994_write(0x402, 0x01FF); // AIF1ADC1L_VOL [7:0] + wm8994_write(0x403, 0x01FF); // AIF1ADC1R_VOL [7:0] + wm8994_write(0x440, 0x01BF); + wm8994_write(0x450, 0x01BF); + wm8994_write(0x420, 0x0000); + + wm8994_write(0x01, 0x0333); + wm8994_write(0x02, 0x6110); // TSHUT_ENA=1, TSHUT_OPDIS=1, MIXINR_ENA=1,IN1R_ENA=1 wm8994_write(0x03, 0x3030); - wm8994_write(0x22, 0x0000); - wm8994_write(0x23, 0x0100); - wm8994_write(0x36, 0x0003); - wm8994_write(0x1C, 0x017F); //HPOUT1L Volume - wm8994_write(0x1D, 0x017F); //HPOUT1R Volume + + wm8994_write(0x601, 0x0001); // AIF1DAC1L_TO_DAC1L=1 + wm8994_write(0x602, 0x0001); // AIF1DAC1R_TO_DAC1R=1 + wm8994_write(0x610, 0x01A0); // DAC1_VU=1, DAC1L_VOL=1100_0000 + wm8994_write(0x611, 0x01A0); // DAC1_VU=1, DAC1R_VOL=1100_0000 + wm8994_set_channel_vol(); } -void AP_to_speakers(void) +static void recorder_and_AP_to_speakers(void) { DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode==wm8994_AP_to_speakers)return; - wm8994_current_mode=wm8994_AP_to_speakers; -// wm8994_reset(); - wm8994_write(0,0); + if (wm8994_current_mode == wm8994_recorder_and_AP_to_speakers)return; + wm8994_current_mode = wm8994_recorder_and_AP_to_speakers; + wm8994_reset(); msleep(WM8994_DELAY); -// wm8994_write(0x700, 0xA101); -// wm8994_write(0x39, 0x006C); - wm8994_write(0x01, 0x0023); + wm8994_write(0x700, 0xA101); + wm8994_write(0x39, 0x006C); + wm8994_write(0x01, 0x0003); wm8994_write(0x200, 0x0000); mdelay(WM8994_DELAY); @@ -900,57 +609,64 @@ void AP_to_speakers(void) wm8994_write(0x208, 0x0008); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 wm8994_write(0x208, 0x000A); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 wm8994_write(0x210, 0x0083); // SR=48KHz -#ifdef CONFIG_SND_RK29_CODEC_SOC_MASTER +#ifdef CONFIG_SND_CODEC_SOC_MASTER wm8994_write(0x302, 0x3000); // AIF1_MSTR=1 wm8994_write(0x302, 0x7000); // AIF1_MSTR=1 wm8994_write(0x303, 0x0040); // AIF1 BCLK DIV--------AIF1CLK/4 wm8994_write(0x304, 0x0040); // AIF1 ADCLRCK DIV-----BCLK/64 wm8994_write(0x305, 0x0040); // AIF1 DACLRCK DIV-----BCLK/64 - wm8994_write(0x300, 0xC010); // i2s 16 bits + wm8994_write(0x300, 0xC050); // i2s 16 bits #endif wm8994_write(0x200, 0x0011); // sysclk = fll (bit4 =1) 0x0011 - - wm8994_write(0x01, 0x3023); - wm8994_write(0x03, 0x0330); - wm8994_write(0x05, 0x0303); - wm8994_write(0x22, 0x0000); - wm8994_write(0x23, 0x0100); - wm8994_write(0x2D, 0x0001); - wm8994_write(0x2E, 0x0000); - wm8994_write(0x36, 0x000C); - wm8994_write(0x4C, 0x9F25); - wm8994_write(0x60, 0x00EE); - wm8994_write(0x420, 0x0000); - wm8994_write(0x601, 0x0001); - wm8994_write(0x602, 0x0001); + wm8994_write(0x610, 0x0100); // DAC1_VU=1, DAC1L_VOL=1100_0000 + wm8994_write(0x611, 0x0100); // DAC1_VU=1, DAC1R_VOL=1100_0000 + wm8994_set_channel_vol(); + wm8994_write(0x24, 0x0018); + wm8994_write(0x25, 0x001D); - wm8994_write(0x610, 0x01c0); //DAC1 Left Volume bit0~7 - wm8994_write(0x611, 0x01c0); //DAC1 Right Volume bit0~7 + wm8994_write(0x02, 0x6110); // TSHUT_ENA=1, TSHUT_OPDIS=1, MIXINR_ENA=1,IN1R_ENA=1 + wm8994_write(0x04, 0x0303); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1, ADCL_ENA=1, ADCR_ENA=1 + wm8994_write(0x28, 0x0003); // IN1RP_TO_IN1R=1, IN1RN_TO_IN1R=1 - wm8994_write(0x26, 0x017F); //Speaker Left Output Volume - wm8994_write(0x27, 0x017F); //Speaker Right Output Volume + wm8994_write(0x606, 0x0002); // ADC1L_TO_AIF1ADC1L=1 + wm8994_write(0x607, 0x0002); // ADC1R_TO_AIF1ADC1R=1 + wm8994_write(0x620, 0x0000); + + wm8994_write(0x402, 0x01FF); // AIF1ADC1L_VOL [7:0] + wm8994_write(0x403, 0x01FF); // AIF1ADC1R_VOL [7:0] + + wm8994_write(0x03, 0x0330); // SPKRVOL_ENA=1, SPKLVOL_ENA=1, MIXOUTL_ENA=1, MIXOUTR_ENA=1 + wm8994_write(0x05, 0x0303); // AIF1DAC1L_ENA=1, AIF1DAC1R_ENA=1, DAC1L_ENA=1, DAC1R_ENA=1 + wm8994_write(0x22, 0x0000); + wm8994_write(0x23, 0x0100); // SPKOUT_CLASSAB=1 + + wm8994_write(0x2D, 0x0001); // DAC1L_TO_MIXOUTL=1 + wm8994_write(0x2E, 0x0001); // DAC1R_TO_MIXOUTR=1 + wm8994_write(0x4C, 0x9F25); + wm8994_write(0x60, 0x00EE); + wm8994_write(0x36, 0x000C); // MIXOUTL_TO_SPKMIXL=1, MIXOUTR_TO_SPKMIXR=1 + wm8994_write(0x440, 0x01BF); + wm8994_write(0x450, 0x01BF); + wm8994_write(0x610, 0x01C0); // DAC1_VU=1, DAC1L_VOL=1100_0000 + wm8994_write(0x611, 0x01C0); // DAC1_VU=1, DAC1R_VOL=1100_0000 + wm8994_write(0x601, 0x0001); // AIF1DAC1L_TO_DAC1L=1 + wm8994_write(0x602, 0x0001); // AIF1DAC1R_TO_DAC1R=1 + wm8994_write(0x420, 0x0000); + wm8994_write(0x01, 0x3003); + msleep(20); + wm8994_write(0x01, 0x3033); } -void FM_to_headset(void) +static void FM_to_headset(void) { DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode == wm8994_FM_to_headset)return; + if (wm8994_current_mode == wm8994_FM_to_headset)return; wm8994_current_mode = wm8994_FM_to_headset; - wm8994_write(0,0); + wm8994_reset(); msleep(WM8994_DELAY); -//clk -// wm8994_write(0x701, 0x0000);//MCLK2 - wm8994_write(0x208, 0x0008); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 - wm8994_write(0x208, 0x000A); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 - wm8994_write(0x210, 0x0083); // SR=48KHz - wm8994_write(0x300, 0xC010); // i2s 16 bits - wm8994_write(0x200, 0x0001); // sysclk = MCLK1 -// wm8994_write(0x200, 0x0009); // sysclk = MCLK2 - wm8994_set_channel_vol(); - wm8994_write(0x01, 0x0303); wm8994_write(0x02, 0x03A0); wm8994_write(0x03, 0x0030); @@ -972,11 +688,11 @@ void FM_to_headset(void) wm8994_write(0x1D, 0x01F9); //RIGHT OUTPUT VOLUME } -void FM_to_headset_and_record(void) +static void FM_to_headset_and_record(void) { DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode == wm8994_FM_to_headset_and_record)return; + if (wm8994_current_mode == wm8994_FM_to_headset_and_record)return; wm8994_current_mode = wm8994_FM_to_headset_and_record; wm8994_reset(); msleep(WM8994_DELAY); @@ -985,7 +701,7 @@ void FM_to_headset_and_record(void) msleep(WM8994_DELAY); wm8994_write(0x221, 0x1900); //8~13BIT div -#ifdef CONFIG_SND_RK29_CODEC_SOC_MASTER +#ifdef CONFIG_SND_CODEC_SOC_MASTER wm8994_write(0x302, 0x4000); // master = 0x4000 // slave= 0x0000 wm8994_write(0x303, 0x0040); // master 0x0050 lrck 7.94kHz bclk 510KHz #endif @@ -1018,85 +734,45 @@ void FM_to_headset_and_record(void) wm8994_write(0x620, 0x0000); } -void FM_test(void) +static void FM_to_speakers(void) { DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode == wm8994_FM_to_speakers)return; + if (wm8994_current_mode == wm8994_FM_to_speakers)return; wm8994_current_mode = wm8994_FM_to_speakers; wm8994_reset(); msleep(WM8994_DELAY); -//clk -// wm8994_write(0x701, 0x0000);//MCLK2 - wm8994_write(0x208, 0x0008); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 - wm8994_write(0x208, 0x000A); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 - wm8994_write(0x210, 0x0083); // SR=48KHz - wm8994_write(0x300, 0xC010); // i2s 16 bits - wm8994_write(0x200, 0x0001); // sysclk = MCLK1 -// wm8994_write(0x200, 0x0009); // sysclk = MCLK2 - wm8994_set_channel_vol(); - - wm8994_write(0x20, 0x013F); - wm8994_write(0x21, 0x013F); -//path - wm8994_write(0x28, 0x0044);//IN2RN_TO_IN2R IN2LN_TO_IN2L - wm8994_write(0x29, 0x0107);//IN2L PGA Output to MIXINL UnMute - wm8994_write(0x2A, 0x0107);//IN2R PGA Output to MIXINR UnMute - wm8994_write(0x2D, 0x0040);//MIXINL_TO_MIXOUTL - wm8994_write(0x2E, 0x0040);//MIXINR_TO_MIXOUTR - wm8994_write(0x36, 0x000C);//MIXOUTL_TO_SPKMIXL MIXOUTR_TO_SPKMIXR -//volume - wm8994_write(0x22, 0x0000); - wm8994_write(0x23, 0x0000); - wm8994_write(0x19, 0x013F); //LEFT LINE INPUT 3&4 VOLUME - wm8994_write(0x1B, 0x013F); //RIGHT LINE INPUT 3&4 VOLUME -//power wm8994_write(0x01, 0x3003); wm8994_write(0x02, 0x03A0); - wm8994_write(0x03, 0x0330); -} + wm8994_write(0x03, 0x0330); + wm8994_write(0x19, 0x010B); //LEFT LINE INPUT 3&4 VOLUME + wm8994_write(0x1B, 0x010B); //RIGHT LINE INPUT 3&4 VOLUME + + wm8994_write(0x22, 0x0000); + wm8994_write(0x23, 0x0000); + wm8994_write(0x36, 0x000C); -void FM_to_speakers(void) -{ - DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode == wm8994_FM_to_speakers)return; - wm8994_current_mode = wm8994_FM_to_speakers; - wm8994_reset(); - msleep(WM8994_DELAY); - wm8994_write(0x01, 0x0003); - msleep(WM8994_DELAY); -//clk -// wm8994_write(0x701, 0x0000);//MCLK2 - wm8994_write(0x208, 0x0008); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 - wm8994_write(0x208, 0x000A); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 - wm8994_write(0x210, 0x0083); // SR=48KHz - wm8994_write(0x300, 0xC010); // i2s 16 bits - wm8994_write(0x200, 0x0001); // sysclk = MCLK1 -// wm8994_write(0x200, 0x0009); // sysclk = MCLK2 - wm8994_set_channel_vol(); - -//path - wm8994_write(0x22, 0x0000); - wm8994_write(0x23, 0x0100); - wm8994_write(0x2D, 0x0030); //bit 1 IN2LP_TO_MIXOUTL bit 12 DAC1L_TO_HPOUT1L 0x0102 - wm8994_write(0x2E, 0x0030); //bit 1 IN2RP_TO_MIXOUTR bit 12 DAC1R_TO_HPOUT1R 0x0102 - wm8994_write(0x36, 0x000C);//MIXOUTL_TO_SPKMIXL MIXOUTR_TO_SPKMIXR -//volume - wm8994_write(0x25, 0x003F); - wm8994_write(0x610, 0x01C0); //DAC1 Left Volume bit0~7 - wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 -//power - wm8994_write(0x01, 0x3003); - wm8994_write(0x03, 0x0330); - wm8994_write(0x05, 0x0003); + wm8994_write(0x28, 0x0044); + wm8994_write(0x29, 0x0100); + wm8994_write(0x2A, 0x0100); + wm8994_write(0x2D, 0x0040); + wm8994_write(0x2E, 0x0040); + + wm8994_write(0x220, 0x0003); + wm8994_write(0x221, 0x0700); + wm8994_write(0x224, 0x0CC0); + + wm8994_write(0x200, 0x0011); + wm8994_write(0x20, 0x01F9); + wm8994_write(0x21, 0x01F9); } -void FM_to_speakers_and_record(void) +static void FM_to_speakers_and_record(void) { DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode == wm8994_FM_to_speakers_and_record)return; + if (wm8994_current_mode == wm8994_FM_to_speakers_and_record)return; wm8994_current_mode = wm8994_FM_to_speakers_and_record; wm8994_reset(); msleep(WM8994_DELAY); @@ -1104,7 +780,7 @@ void FM_to_speakers_and_record(void) wm8994_write(0x01, 0x0003); msleep(WM8994_DELAY); -#ifdef CONFIG_SND_RK29_CODEC_SOC_MASTER +#ifdef CONFIG_SND_CODEC_SOC_MASTER wm8994_write(0x302, 0x4000); // master = 0x4000 // slave= 0x0000 wm8994_write(0x303, 0x0090); // #endif @@ -1142,294 +818,170 @@ void FM_to_speakers_and_record(void) wm8994_write(0x607, 0x0002); wm8994_write(0x620, 0x0000); } - -void record_only(void) +#ifndef PCM_BB +static void handsetMIC_to_baseband_to_headset(void) { DBG("%s::%d\n",__FUNCTION__,__LINE__); - wm8994_write(0,0); - msleep(WM8994_DELAY); - - wm8994_write(0x01, 0x0003); - msleep(WM8994_DELAY); -//clk - wm8994_sysclk_config(); - wm8994_write(0x300, 0xC010); //AIF1ADCL_SRC=1, AIF1ADCR_SRC=1, AIF1_WL=00, AIF1_FMT=10 -// wm8994_write(0x300, 0xC050); // AIF1ADCL_SRC=1, AIF1ADCR_SRC=1, AIF1_WL=10, AIF1_FMT=10 - -//path - wm8994_write(0x28, 0x0003); // IN1RP_TO_IN1R=1, IN1RN_TO_IN1R=1 - wm8994_write(0x2A, 0x0030); //IN1R_TO_MIXINR IN1R_MIXINR_VOL - wm8994_write(0x606, 0x0002); // ADC1L_TO_AIF1ADC1L=1 - wm8994_write(0x607, 0x0002); // ADC1R_TO_AIF1ADC1R=1 - wm8994_write(0x620, 0x0000); //ADC_OSR128=0, DAC_OSR128=0 -//DRC - wm8994_write(0x440, 0x01BF); - wm8994_write(0x450, 0x01BF); -//valume - wm8994_write(0x1A, 0x014B);//IN1_VU=1, IN1R_MUTE=0, IN1R_ZC=1, IN1R_VOL=0_1011 - wm8994_write(0x402, 0x01FF); // AIF1ADC1L_VOL [7:0] - wm8994_write(0x403, 0x01FF); // AIF1ADC1R_VOL [7:0] - -//power - wm8994_write(0x02, 0x6110); // TSHUT_ENA=1, TSHUT_OPDIS=1, MIXINR_ENA=1,IN1R_ENA=1 - wm8994_write(0x04, 0x0303); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1, ADCL_ENA=1, ADCR_ENA=1 - wm8994_write(0x01, 0x3033); -} -void AP_to_speakers_and_headset(void) -{ - DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode==wm8994_AP_to_speakers_and_headset)return; - wm8994_current_mode=wm8994_AP_to_speakers_and_headset; + if (wm8994_current_mode == wm8994_handsetMIC_to_baseband_to_headset)return; + wm8994_codec_first_incall(); + wm8994_current_mode = wm8994_handsetMIC_to_baseband_to_headset; wm8994_reset(); msleep(WM8994_DELAY); - + wm8994_write(0x700, 0xA101); wm8994_write(0x39, 0x006C); - wm8994_write(0x01, 0x0023); - msleep(WM8994_DELAY); -//clk - wm8994_sysclk_config(); - wm8994_write(0x300, 0xC010); // i2s 16 bits -//path - wm8994_write(0x2D, 0x0100); - wm8994_write(0x2E, 0x0100); - wm8994_write(0x60, 0x0022); - wm8994_write(0x60, 0x00EE); - wm8994_write(0x420, 0x0000); - wm8994_write(0x601, 0x0001); - wm8994_write(0x602, 0x0001); - wm8994_write(0x36, 0x0003); -// wm8994_write(0x24, 0x0011); -//other - wm8994_write(0x4C, 0x9F25); -//volume - wm8994_write(0x22, 0x0000); - wm8994_write(0x23, 0x0100); - wm8994_write(0x610, 0x01C0); //DAC1 Left Volume bit0~7 - wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 -// wm8994_write(0x25, 0x003F); - wm8994_set_channel_vol(); -//power - wm8994_write(0x04, 0x0303); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1, ADCL_ENA=1, ADCR_ENA=1 - wm8994_write(0x05, 0x0303); - wm8994_write(0x03, 0x3330); - wm8994_write(0x01, 0x3303); - msleep(50); - wm8994_write(0x01, 0x3333); -} - -void recorder_and_AP_to_headset(void) -{ - DBG("%s::%d\n",__FUNCTION__,__LINE__); - - if(wm8994_current_mode==wm8994_recorder_and_AP_to_headset)return; - wm8994_current_mode=wm8994_recorder_and_AP_to_headset; - wm8994_reset(); - msleep(WM8994_DELAY); - - wm8994_write(0x39, 0x006C); - - wm8994_write(0x01, 0x0003); - msleep(35); - wm8994_write(0xFF, 0x0000); - msleep(5); - wm8994_write(0x4C, 0x9F25); - msleep(5); - wm8994_write(0x01, 0x0303); - wm8994_write(0x60, 0x0022); - msleep(5); - wm8994_write(0x54, 0x0033);// - -// wm8994_write(0x01, 0x0003); + wm8994_write(0x01, 0x0003); wm8994_write(0x200, 0x0000); - msleep(WM8994_DELAY); -//clk - wm8994_sysclk_config(); - wm8994_write(0x300, 0xC010); // i2s 16 bits -//recorder - wm8994_write(0x28, 0x0003); // IN1RP_TO_IN1R=1, IN1RN_TO_IN1R=1 - wm8994_write(0x606, 0x0002); // ADC1L_TO_AIF1ADC1L=1 - wm8994_write(0x607, 0x0002); // ADC1R_TO_AIF1ADC1R=1 - wm8994_write(0x620, 0x0001); - wm8994_write(0x402, 0x01FF); // AIF1ADC1L_VOL [7:0] - wm8994_write(0x403, 0x01FF); // AIF1ADC1R_VOL [7:0] -//DRC - wm8994_write(0x440, 0x01BF); - wm8994_write(0x450, 0x01BF); -//path - wm8994_write(0x2D, 0x0100); // DAC1L_TO_HPOUT1L=1 - wm8994_write(0x2E, 0x0100); // DAC1R_TO_HPOUT1R=1 - wm8994_write(0x60, 0x0022); - wm8994_write(0x60, 0x00FF); - wm8994_write(0x420, 0x0000); - wm8994_write(0x601, 0x0001); // AIF1DAC1L_TO_DAC1L=1 - wm8994_write(0x602, 0x0001); // AIF1DAC1R_TO_DAC1R=1 -//volume - wm8994_write(0x610, 0x01FF); // DAC1_VU=1, DAC1L_VOL=1100_0000 - wm8994_write(0x611, 0x01FF); // DAC1_VU=1, DAC1R_VOL=1100_0000 - wm8994_set_channel_vol(); -//other -// wm8994_write(0x4C, 0x9F25); -//power - wm8994_write(0x01, 0x0333); - wm8994_write(0x02, 0x6110); // TSHUT_ENA=1, TSHUT_OPDIS=1, MIXINR_ENA=1,IN1R_ENA=1 - wm8994_write(0x03, 0x3030); - wm8994_write(0x04, 0x0303); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1, ADCL_ENA=1, ADCR_ENA=1 - wm8994_write(0x05, 0x0303); // AIF1DAC1L_ENA=1, AIF1DAC1R_ENA=1, DAC1L_ENA=1, DAC1R_ENA=1 + mdelay(WM8994_DELAY); -} + wm8994_write(0x220, 0x0000); + wm8994_write(0x221, 0x0700); + wm8994_write(0x222, 0x3126); + wm8994_write(0x223, 0x0100); -void recorder_and_AP_to_speakers(void) -{ - DBG("%s::%d\n",__FUNCTION__,__LINE__); + wm8994_write(0x220, 0x0004); + msleep(10); + wm8994_write(0x220, 0x0005); + msleep(5); - if(wm8994_current_mode==wm8994_recorder_and_AP_to_speakers)return; - wm8994_current_mode=wm8994_recorder_and_AP_to_speakers; - wm8994_reset(); - msleep(WM8994_DELAY); + wm8994_write(0x200, 0x0010); + wm8994_write(0x208, 0x0008); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 + wm8994_write(0x208, 0x000A); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 + wm8994_write(0x210, 0x0083); // SR=48KHz +#ifdef CONFIG_SND_CODEC_SOC_MASTER + wm8994_write(0x302, 0x3000); // AIF1_MSTR=1 + wm8994_write(0x302, 0x7000); // AIF1_MSTR=1 + wm8994_write(0x303, 0x0040); // AIF1 BCLK DIV--------AIF1CLK/4 + wm8994_write(0x304, 0x0040); // AIF1 ADCLRCK DIV-----BCLK/64 + wm8994_write(0x305, 0x0040); // AIF1 DACLRCK DIV-----BCLK/64 + wm8994_write(0x300, 0xC010); // i2s 16 bits +#endif + wm8994_write(0x200, 0x0011); // sysclk = fll (bit4 =1) 0x0011 - wm8994_write(0x39, 0x006C); - wm8994_write(0x01, 0x0023); - msleep(WM8994_DELAY); -//clk - wm8994_sysclk_config(); - wm8994_write(0x300, 0xC010); // i2s 16 bits -//recorder - wm8994_write(0x02, 0x6110); // TSHUT_ENA=1, TSHUT_OPDIS=1, MIXINR_ENA=1,IN1R_ENA=1 - wm8994_write(0x04, 0x0303); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1, ADCL_ENA=1, ADCR_ENA=1 - wm8994_write(0x28, 0x0003); // IN1RP_TO_IN1R=1, IN1RN_TO_IN1R=1 - wm8994_write(0x606, 0x0002); // ADC1L_TO_AIF1ADC1L=1 - wm8994_write(0x607, 0x0002); // ADC1R_TO_AIF1ADC1R=1 - wm8994_write(0x620, 0x0000); - wm8994_write(0x402, 0x01FF); // AIF1ADC1L_VOL [7:0] - wm8994_write(0x403, 0x01FF); // AIF1ADC1R_VOL [7:0] -//path - wm8994_write(0x2D, 0x0001); // DAC1L_TO_MIXOUTL=1 - wm8994_write(0x2E, 0x0001); // DAC1R_TO_MIXOUTR=1 - wm8994_write(0x36, 0x000C); // MIXOUTL_TO_SPKMIXL=1, MIXOUTR_TO_SPKMIXR=1 - wm8994_write(0x601, 0x0001); // AIF1DAC1L_TO_DAC1L=1 - wm8994_write(0x602, 0x0001); // AIF1DAC1R_TO_DAC1R=1 - wm8994_write(0x420, 0x0000); -// wm8994_write(0x24, 0x001f); -//volume - wm8994_write(0x22, 0x0000); - wm8994_write(0x23, 0x0100); // SPKOUT_CLASSAB=1 - wm8994_write(0x610, 0x01C0); // DAC1_VU=1, DAC1L_VOL=1100_0000 - wm8994_write(0x611, 0x01C0); // DAC1_VU=1, DAC1R_VOL=1100_0000 - wm8994_write(0x25, 0x003F); - wm8994_set_channel_vol(); -//other + wm8994_write(0x04, 0x0300); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1 + wm8994_write(0x05, 0x0303); +#ifdef CONFIG_SND_BB_DIFFERENTIAL_INPUT + wm8994_write(0x2D, 0x0041); //bit 1 MIXINL_TO_MIXOUTL bit 12 DAC1L_TO_MIXOUTL + wm8994_write(0x2E, 0x0081); //bit 1 MIXINL_TO_MIXOUTR bit 12 DAC1R_TO_MIXOUTR +#endif +#ifdef CONFIG_SND_BB_NORMAL_INPUT + wm8994_write(0x2D, 0x0003); //bit 1 IN2LP_TO_MIXOUTL bit 12 DAC1L_TO_MIXOUTL + wm8994_write(0x2E, 0x0003); //bit 1 IN2RP_TO_MIXOUTR bit 12 DAC1R_TO_MIXOUTR +#endif wm8994_write(0x4C, 0x9F25); -//DRC - wm8994_write(0x440, 0x01BF); - wm8994_write(0x450, 0x01BF); -//power - wm8994_write(0x03, 0x0330); // SPKRVOL_ENA=1, SPKLVOL_ENA=1, MIXOUTL_ENA=1, MIXOUTR_ENA=1 - wm8994_write(0x05, 0x0303); // AIF1DAC1L_ENA=1, AIF1DAC1R_ENA=1, DAC1L_ENA=1, DAC1R_ENA=1 - wm8994_write(0x01, 0x3003); - msleep(50); - wm8994_write(0x01, 0x3033); -} + mdelay(5); + wm8994_write(0x01, 0x0303); + mdelay(50); + wm8994_write(0x60, 0x0022); + wm8994_write(0x60, 0x00FF); -#ifndef PCM_BB -void handsetMIC_to_baseband_to_headset(void) -{// - DBG("%s::%d\n",__FUNCTION__,__LINE__); + wm8994_write(0x610, 0x0100); //DAC1 Left Volume bit0~7 + wm8994_write(0x611, 0x0100); //DAC1 Right Volume bit0~7 + wm8994_set_volume(wm8994_current_mode,0,call_maxvol); + wm8994_set_channel_vol(); - if(wm8994_current_mode == wm8994_handsetMIC_to_baseband_to_headset)return; - wm8994_current_mode = wm8994_handsetMIC_to_baseband_to_headset; - wm8994_reset(); - msleep(WM8994_DELAY); - - wm8994_write(0x01, 0x0023); - wm8994_write(0x200, 0x0000); - msleep(WM8994_DELAY); -//clk - wm8994_sysclk_config(); - wm8994_write(0x300, 0xC010); // i2s 16 bits -//path - wm8994_write(0x22, 0x0000); - wm8994_write(0x23, 0x0100); wm8994_write(0x02, 0x6240); wm8994_write(0x28, 0x0030); //IN1LN_TO_IN1L IN1LP_TO_IN1L - wm8994_write(0x2D, 0x0003); //bit 1 IN2LP_TO_MIXOUTL bit 12 DAC1L_TO_HPOUT1L 0x0102 - wm8994_write(0x2E, 0x0003); //bit 1 IN2RP_TO_MIXOUTR bit 12 DAC1R_TO_HPOUT1R 0x0102 wm8994_write(0x34, 0x0002); //IN1L_TO_LINEOUT1P - wm8994_write(0x36, 0x0003); - wm8994_write(0x60, 0x0022); - wm8994_write(0x60, 0x00EE); wm8994_write(0x420, 0x0000); - wm8994_write(0x601, 0x0001); - wm8994_write(0x602, 0x0001); -//volume + + wm8994_write(0x01, 0x0323); + msleep(20); + wm8994_write(0x03, 0x3030); + if (wm8994_work_type != WM8994_WORK_FIRSTINCALL) { + wm8994_write(0x601, 0x0001); + wm8994_write(0x602, 0x0001); + } wm8994_write(0x610, 0x01A0); //DAC1 Left Volume bit0~7 wm8994_write(0x611, 0x01A0); //DAC1 Right Volume bit0~7 - wm8994_set_channel_vol(); -//other - wm8994_write(0x4C, 0x9F25); -//power - wm8994_write(0x03, 0x3030); - wm8994_write(0x04, 0x0300); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1 - wm8994_write(0x05, 0x0303); - wm8994_write(0x01, 0x0303); - msleep(50); - wm8994_write(0x01, 0x0333); - wm8994_set_level_volume(); } -void mainMIC_to_baseband_to_headset(void) -{// +static void mainMIC_to_baseband_to_headset(void) +{ DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode == wm8994_mainMIC_to_baseband_to_headset)return; + if (wm8994_current_mode == wm8994_mainMIC_to_baseband_to_headset)return; + wm8994_codec_first_incall(); wm8994_current_mode = wm8994_mainMIC_to_baseband_to_headset; wm8994_reset(); msleep(WM8994_DELAY); - wm8994_write(0x01, 0x0023); + wm8994_write(0x700, 0xA101); + wm8994_write(0x39, 0x006C); + wm8994_write(0x01, 0x0003); wm8994_write(0x200, 0x0000); mdelay(WM8994_DELAY); -//clk - wm8994_sysclk_config(); - wm8994_write(0x300, 0xC010); // i2s 16 bits -//path - wm8994_write(0x22, 0x0000); - wm8994_write(0x23, 0x0100); - wm8994_write(0x02, 0x6210); - wm8994_write(0x28, 0x0003); //IN1RN_TO_IN1R IN1RP_TO_IN1R + + wm8994_write(0x220, 0x0000); + wm8994_write(0x221, 0x0700); + wm8994_write(0x222, 0x3126); + wm8994_write(0x223, 0x0100); + + wm8994_write(0x220, 0x0004); + msleep(10); + wm8994_write(0x220, 0x0005); + msleep(5); + + wm8994_write(0x200, 0x0010); + wm8994_write(0x208, 0x0008); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 + wm8994_write(0x208, 0x000A); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 + wm8994_write(0x210, 0x0083); // SR=48KHz +#ifdef CONFIG_SND_CODEC_SOC_MASTER + wm8994_write(0x302, 0x3000); // AIF1_MSTR=1 + wm8994_write(0x302, 0x7000); // AIF1_MSTR=1 + wm8994_write(0x303, 0x0040); // AIF1 BCLK DIV--------AIF1CLK/4 + wm8994_write(0x304, 0x0040); // AIF1 ADCLRCK DIV-----BCLK/64 + wm8994_write(0x305, 0x0040); // AIF1 DACLRCK DIV-----BCLK/64 + wm8994_write(0x300, 0xC010); // i2s 16 bits +#endif + wm8994_write(0x200, 0x0011); // sysclk = fll (bit4 =1) 0x0011 + + wm8994_write(0x04, 0x0300); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1 + wm8994_write(0x05, 0x0303); +#ifdef CONFIG_SND_BB_DIFFERENTIAL_INPUT + wm8994_write(0x2D, 0x0041); //bit 1 MIXINL_TO_MIXOUTL bit 12 DAC1L_TO_HPOUT1L 0x0102 + wm8994_write(0x2E, 0x0081); //bit 1 MIXINL_TO_MIXOUTR bit 12 DAC1R_TO_HPOUT1R 0x0102 +#endif +#ifdef CONFIG_SND_BB_NORMAL_INPUT wm8994_write(0x2D, 0x0003); //bit 1 IN2LP_TO_MIXOUTL bit 12 DAC1L_TO_HPOUT1L 0x0102 wm8994_write(0x2E, 0x0003); //bit 1 IN2RP_TO_MIXOUTR bit 12 DAC1R_TO_HPOUT1R 0x0102 - wm8994_write(0x34, 0x0004); //IN1R_TO_LINEOUT1P - wm8994_write(0x36, 0x0003); +#endif + + wm8994_write(0x4C, 0x9F25); + mdelay(5); + wm8994_write(0x01, 0x0303); + mdelay(50); wm8994_write(0x60, 0x0022); - wm8994_write(0x60, 0x00EE); + wm8994_write(0x60, 0x00FF); + + wm8994_write(0x610, 0x0100); //DAC1 Left Volume bit0~7 + wm8994_write(0x611, 0x0100); //DAC1 Right Volume bit0~7 + wm8994_set_volume(wm8994_current_mode,0,call_maxvol); + wm8994_set_channel_vol(); + + wm8994_write(0x02, 0x6210); + wm8994_write(0x28, 0x0003); //IN1RN_TO_IN1R IN1RP_TO_IN1R + wm8994_write(0x34, 0x0004); //IN1R_TO_LINEOUT1P wm8994_write(0x420, 0x0000); - wm8994_write(0x601, 0x0001); - wm8994_write(0x602, 0x0001); -//volume + + wm8994_write(0x01, 0x0333); + msleep(20); + wm8994_write(0x03, 0x3030); + if (wm8994_work_type != WM8994_WORK_FIRSTINCALL) { + wm8994_write(0x601, 0x0001); + wm8994_write(0x602, 0x0001); + } wm8994_write(0x610, 0x01A0); //DAC1 Left Volume bit0~7 wm8994_write(0x611, 0x01A0); //DAC1 Right Volume bit0~7 - wm8994_set_channel_vol(); -//other - wm8994_write(0x4C, 0x9F25); -//power - wm8994_write(0x03, 0x3030); - wm8994_write(0x04, 0x0300); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1 - wm8994_write(0x05, 0x0303); - wm8994_write(0x01, 0x0303); - msleep(50); - wm8994_write(0x01, 0x0333); - wm8994_set_level_volume(); } -void handsetMIC_to_baseband_to_headset_and_record(void) +static void handsetMIC_to_baseband_to_headset_and_record(void) { - struct wm8994_priv *wm8994 = wm8994_codec->private_data; DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode == wm8994_handsetMIC_to_baseband_to_headset_and_record)return; + if (wm8994_current_mode == wm8994_handsetMIC_to_baseband_to_headset_and_record)return; wm8994_current_mode = wm8994_handsetMIC_to_baseband_to_headset_and_record; wm8994_reset(); msleep(WM8994_DELAY); @@ -1440,7 +992,7 @@ void handsetMIC_to_baseband_to_headset_and_record(void) wm8994_write(0x04, 0x0303); wm8994_write(0x18, 0x014B); //volume wm8994_write(0x19, 0x014B); //volume - wm8994_set_volume(wm8994_current_mode,wm8994->call_vol,call_maxvol); + wm8994_set_volume(wm8994_current_mode,call_vol,call_maxvol); wm8994_write(0x1E, 0x0006); wm8994_write(0x28, 0x00B0); //IN2LP_TO_IN2L wm8994_write(0x29, 0x0120); @@ -1453,7 +1005,7 @@ void handsetMIC_to_baseband_to_headset_and_record(void) wm8994_write(0x208, 0x000A); wm8994_write(0x300, 0x0050); -#ifdef CONFIG_SND_RK29_CODEC_SOC_MASTER +#ifdef CONFIG_SND_CODEC_SOC_MASTER wm8994_write(0x302, 0x4000); // master = 0x4000 // slave= 0x0000 wm8994_write(0x303, 0x0090); // master lrck 16k #endif @@ -1463,53 +1015,95 @@ void handsetMIC_to_baseband_to_headset_and_record(void) wm8994_write(0x620, 0x0000); } -void mainMIC_to_baseband_to_earpiece(void) -{// +static void mainMIC_to_baseband_to_earpiece(void) +{ DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode == wm8994_mainMIC_to_baseband_to_earpiece)return; + if (wm8994_current_mode == wm8994_mainMIC_to_baseband_to_earpiece)return; + wm8994_codec_first_incall(); wm8994_current_mode = wm8994_mainMIC_to_baseband_to_earpiece; wm8994_reset(); msleep(WM8994_DELAY); - wm8994_write(0x01, 0x0023); + wm8994_write(0x700, 0xA101); + wm8994_write(0x39, 0x006C); + wm8994_write(0x01, 0x0003); wm8994_write(0x200, 0x0000); - msleep(WM8994_DELAY); -//clk - wm8994_sysclk_config(); - wm8994_write(0x300, 0xC010); // i2s 16 bits -//path + mdelay(WM8994_DELAY); + + wm8994_write(0x220, 0x0000); + wm8994_write(0x221, 0x0700); + wm8994_write(0x222, 0x3126); + wm8994_write(0x223, 0x0100); + + wm8994_write(0x220, 0x0004); + msleep(10); + wm8994_write(0x220, 0x0005); + msleep(5); + + wm8994_write(0x200, 0x0010); + wm8994_write(0x208, 0x0008); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 + wm8994_write(0x208, 0x000A); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 + wm8994_write(0x210, 0x0083); // SR=48KHz +#ifdef CONFIG_SND_CODEC_SOC_MASTER + wm8994_write(0x302, 0x3000); // AIF1_MSTR=1 + wm8994_write(0x302, 0x7000); // AIF1_MSTR=1 + wm8994_write(0x303, 0x0040); // AIF1 BCLK DIV--------AIF1CLK/4 + wm8994_write(0x304, 0x0040); // AIF1 ADCLRCK DIV-----BCLK/64 + wm8994_write(0x305, 0x0040); // AIF1 DACLRCK DIV-----BCLK/64 + wm8994_write(0x300, 0x4010); // i2s 16 bits +#endif + wm8994_write(0x200, 0x0011); // sysclk = fll (bit4 =1) 0x0011 + + wm8994_set_volume(wm8994_current_mode,0,call_maxvol); + wm8994_write(0x01, 0x0803); //HPOUT2_ENA=1, VMID_SEL=01, BIAS_ENA=1 + wm8994_write(0x4C, 0x9F25); + + wm8994_write(0x02, 0x6250); //bit4 IN1R_ENV bit6 IN1L_ENV + wm8994_write(0x03, 0x30F0); + wm8994_write(0x04, 0x0303); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1, ADCL_ENA=1, ADCR_ENA=1 + wm8994_write(0x05, 0x0303); + wm8994_write(0x1F, 0x0000); + +#if defined(CONFIG_SND_INSIDE_EARPIECE)||defined(CONFIG_SND_OUTSIDE_EARPIECE) + wm8994_set_channel_vol(); +#ifdef CONFIG_SND_INSIDE_EARPIECE wm8994_write(0x28, 0x0003); //IN1RP_TO_IN1R IN1RN_TO_IN1R wm8994_write(0x34, 0x0004); //IN1R_TO_LINEOUT1P +#endif +#ifdef CONFIG_SND_OUTSIDE_EARPIECE + wm8994_write(0x28, 0x0030); //IN1LP_TO_IN1L IN1LN_TO_IN1L + wm8994_write(0x34, 0x0002); //IN1L_TO_LINEOUT1P +#endif +#endif +#ifdef CONFIG_SND_BB_NORMAL_INPUT wm8994_write(0x2D, 0x0003); //bit 1 IN2LP_TO_MIXOUTL bit 12 DAC1L_TO_HPOUT1L 0x0102 wm8994_write(0x2E, 0x0003); //bit 1 IN2RP_TO_MIXOUTR bit 12 DAC1R_TO_HPOUT1R 0x0102 - wm8994_write(0x601, 0x0001); //AIF1DAC1L_TO_DAC1L=1 - wm8994_write(0x602, 0x0001); //AIF1DAC1R_TO_DAC1R=1 - wm8994_write(0x420, 0x0000); -//volume +#endif +#ifdef CONFIG_SND_BB_DIFFERENTIAL_INPUT + wm8994_write(0x2B, 0x0007); //VRX_MIXINL_VOL + wm8994_write(0x2D, 0x0041); //bit 1 MIXINL_TO_MIXOUTL bit 12 DAC1L_TO_HPOUT1L 0x0102 + wm8994_write(0x2E, 0x0081); //bit 1 MIXINL_TO_MIXOUTR bit 12 DAC1R_TO_HPOUT1R 0x0102 +#endif + if (wm8994_work_type != WM8994_WORK_FIRSTINCALL) { + wm8994_write(0x601, 0x0001); //AIF1DAC1L_TO_DAC1L=1 + wm8994_write(0x602, 0x0001); //AIF1DAC1R_TO_DAC1R=1 + } + wm8994_write(0x01, 0x0833); wm8994_write(0x610, 0x01C0); //DAC1_VU=1, DAC1L_VOL=1100_0000 wm8994_write(0x611, 0x01C0); //DAC1_VU=1, DAC1R_VOL=1100_0000 - wm8994_write(0x1F, 0x0000);//HPOUT2 - wm8994_set_channel_vol(); -//other - wm8994_write(0x4C, 0x9F25); -//power - wm8994_write(0x01, 0x0833); //HPOUT2_ENA=1, VMID_SEL=01, BIAS_ENA=1 - wm8994_write(0x02, 0x6250); //bit4 IN1R_ENV bit6 IN1L_ENV - wm8994_write(0x03, 0x30F0); - wm8994_write(0x04, 0x0303); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1, ADCL_ENA=1, ADCR_ENA=1 - wm8994_write(0x05, 0x0303); + + wm8994_write(0x420, 0x0000); - wm8994_set_level_volume(); + wm8994_set_level_volume(); } -void mainMIC_to_baseband_to_earpiece_and_record(void) +static void mainMIC_to_baseband_to_earpiece_and_record(void) { - struct wm8994_priv *wm8994 = wm8994_codec->private_data; DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode==wm8994_mainMIC_to_baseband_to_earpiece_and_record)return; - wm8994_current_mode=wm8994_mainMIC_to_baseband_to_earpiece_and_record; + if (wm8994_current_mode == wm8994_mainMIC_to_baseband_to_earpiece_and_record)return; + wm8994_current_mode = wm8994_mainMIC_to_baseband_to_earpiece_and_record; wm8994_reset(); msleep(WM8994_DELAY); @@ -1517,7 +1111,8 @@ void mainMIC_to_baseband_to_earpiece_and_record(void) wm8994_write(0x02 ,0x6310); wm8994_write(0x03 ,0x30A0); wm8994_write(0x04 ,0x0303); - wm8994_write(0x1A ,0x014F); + //wm8994_write(0x1A ,0x014F); + wm8994_write(0x1A ,0x0147); wm8994_write(0x1E ,0x0006); wm8994_write(0x1F ,0x0000); wm8994_write(0x28 ,0x0003); //MAINMIC_TO_IN1R @@ -1530,9 +1125,9 @@ void mainMIC_to_baseband_to_earpiece_and_record(void) wm8994_write(0x200 ,0x0001); wm8994_write(0x208 ,0x000A); wm8994_write(0x300 ,0xC050); - wm8994_set_volume(wm8994_current_mode,wm8994->call_vol,call_maxvol); + wm8994_set_volume(wm8994_current_mode,call_vol,call_maxvol); -#ifdef CONFIG_SND_RK29_CODEC_SOC_MASTER +#ifdef CONFIG_SND_CODEC_SOC_MASTER wm8994_write(0x302, 0x4000); // master = 0x4000 // slave= 0x0000 wm8994_write(0x303, 0x0090); // master lrck 16k #endif @@ -1542,63 +1137,94 @@ void mainMIC_to_baseband_to_earpiece_and_record(void) wm8994_write(0x620 ,0x0000); } -void mainMIC_to_baseband_to_speakers(void) -{// +static void mainMIC_to_baseband_to_speakers(void) +{ DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode==wm8994_mainMIC_to_baseband_to_speakers)return; - - wm8994_current_mode=wm8994_mainMIC_to_baseband_to_speakers; + if (wm8994_current_mode == wm8994_mainMIC_to_baseband_to_speakers)return; + wm8994_codec_first_incall(); + wm8994_current_mode = wm8994_mainMIC_to_baseband_to_speakers; wm8994_reset(); msleep(WM8994_DELAY); - + wm8994_write(0x700, 0xA101); wm8994_write(0x39, 0x006C); wm8994_write(0x01, 0x0023); wm8994_write(0x200, 0x0000); - msleep(WM8994_DELAY); -//clk - wm8994_sysclk_config(); - wm8994_write(0x300, 0xC010); // i2s 16 bits -//path + mdelay(WM8994_DELAY); + + wm8994_write(0x220, 0x0000); + wm8994_write(0x221, 0x0700); + wm8994_write(0x222, 0x3126); + wm8994_write(0x223, 0x0100); + + wm8994_write(0x220, 0x0004); + msleep(10); + wm8994_write(0x220, 0x0005); + msleep(5); + + wm8994_write(0x200, 0x0010); + wm8994_write(0x208, 0x0008); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 + wm8994_write(0x208, 0x000A); //DSP_FS1CLK_ENA=1, DSP_FSINTCLK_ENA=1 + wm8994_write(0x210, 0x0083); // SR=48KHz +#ifdef CONFIG_SND_CODEC_SOC_MASTER + wm8994_write(0x302, 0x3000); // AIF1_MSTR=1 + wm8994_write(0x302, 0x7000); // AIF1_MSTR=1 + wm8994_write(0x303, 0x0040); // AIF1 BCLK DIV--------AIF1CLK/4 + wm8994_write(0x304, 0x0040); // AIF1 ADCLRCK DIV-----BCLK/64 + wm8994_write(0x305, 0x0040); // AIF1 DACLRCK DIV-----BCLK/64 + wm8994_write(0x300, 0xC010); // i2s 16 bits +#endif + wm8994_write(0x200, 0x0011); // sysclk = fll (bit4 =1) 0x0011 + + wm8994_write(0x610, 0x0100); + wm8994_write(0x611, 0x0100); + wm8994_set_volume(wm8994_current_mode,0,call_maxvol); + wm8994_set_channel_vol(); + + wm8994_write(0x02, 0x6210); + wm8994_write(0x04, 0x0303); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1, ADCL_ENA=1, ADCR_ENA=1 + wm8994_write(0x22, 0x0000); wm8994_write(0x23, 0x0100); + wm8994_write(0x24, 0x0018); wm8994_write(0x28, 0x0003); //IN1LN_TO_IN1L IN1LP_TO_IN1L wm8994_write(0x29, 0x0030); +#ifdef CONFIG_SND_BB_NORMAL_INPUT wm8994_write(0x2D, 0x0003); //bit 1 IN2LP_TO_MIXOUTL bit 12 DAC1L_TO_HPOUT1L 0x0102 wm8994_write(0x2E, 0x0003); //bit 1 IN2RP_TO_MIXOUTR bit 12 DAC1R_TO_HPOUT1R 0x0102 +#endif +#ifdef CONFIG_SND_BB_DIFFERENTIAL_INPUT + wm8994_write(0x2B, 0x0005); //VRX_MIXINL_VOL + wm8994_write(0x2D, 0x0041); //bit 1 MIXINL_TO_MIXOUTL bit 12 DAC1L_TO_HPOUT1L 0x0102 + wm8994_write(0x2E, 0x0081); //bit 1 MIXINL_TO_MIXOUTR bit 12 DAC1R_TO_HPOUT1R 0x0102 +#endif wm8994_write(0x34, 0x000C); //IN1L_TO_LINEOUT1P - wm8994_write(0x60, 0x0022); - wm8994_write(0x36, 0x000C); - wm8994_write(0x60, 0x00EE); + wm8994_write(0x36, 0x000C); wm8994_write(0x420, 0x0000); - wm8994_write(0x601, 0x0001); - wm8994_write(0x602, 0x0001); - wm8994_write(0x24, 0x0011); -//volume -// wm8994_write(0x25, 0x003F); - wm8994_write(0x610, 0x01C0); //DAC1 Left Volume bit0~7 - wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 - wm8994_set_channel_vol(); -//other - wm8994_write(0x4C, 0x9F25); -//power - wm8994_write(0x01, 0x3003); msleep(50); - wm8994_write(0x01, 0x3033); - wm8994_write(0x02, 0x6210); wm8994_write(0x03, 0x1330); - wm8994_write(0x04, 0x0303); // AIF1ADC1L_ENA=1, AIF1ADC1R_ENA=1, ADCL_ENA=1, ADCR_ENA=1 - wm8994_write(0x05, 0x0303); - wm8994_set_level_volume(); + wm8994_write(0x05, 0x0303); + + if (wm8994_work_type != WM8994_WORK_FIRSTINCALL) { + wm8994_write(0x601, 0x0001); + wm8994_write(0x602, 0x0001); + } + wm8994_write(0x01, 0x3003); + msleep(20); + wm8994_write(0x01, 0x3033); + + wm8994_write(0x610, 0x01C0); //DAC1 Left Volume bit0~7 + wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 + + wm8994_set_level_volume(); } -void mainMIC_to_baseband_to_speakers_and_record(void) +static void mainMIC_to_baseband_to_speakers_and_record(void) { - struct wm8994_priv *wm8994 = wm8994_codec->private_data; DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode==wm8994_mainMIC_to_baseband_to_speakers_and_record)return; - wm8994_current_mode=wm8994_mainMIC_to_baseband_to_speakers_and_record; + if (wm8994_current_mode == wm8994_mainMIC_to_baseband_to_speakers_and_record)return; + wm8994_current_mode = wm8994_mainMIC_to_baseband_to_speakers_and_record; wm8994_reset(); msleep(WM8994_DELAY); @@ -1620,9 +1246,9 @@ void mainMIC_to_baseband_to_speakers_and_record(void) wm8994_write(0x200, 0x0001); wm8994_write(0x208, 0x000A); wm8994_write(0x300, 0xC050); - wm8994_set_volume(wm8994_current_mode,wm8994->call_vol,call_maxvol); + wm8994_set_volume(wm8994_current_mode,call_vol,call_maxvol); -#ifdef CONFIG_SND_RK29_CODEC_SOC_MASTER +#ifdef CONFIG_SND_CODEC_SOC_MASTER wm8994_write(0x302, 0x4000); // master = 0x4000 // slave= 0x0000 wm8994_write(0x303, 0x0090); // master lrck 16k #endif @@ -1632,63 +1258,67 @@ void mainMIC_to_baseband_to_speakers_and_record(void) wm8994_write(0x620, 0x0000); } -void BT_baseband(void) -{// - struct wm8994_priv *wm8994 = wm8994_codec->private_data; +static void BT_baseband(void) +{ DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode==wm8994_BT_baseband)return; - - wm8994_current_mode=wm8994_BT_baseband; + if (wm8994_current_mode == wm8994_BT_baseband)return; + wm8994_codec_first_incall(); + wm8994_current_mode = wm8994_BT_baseband; wm8994_reset(); msleep(WM8994_DELAY); + wm8994_write(0x700, 0xA101); + wm8994_write(0x705, 0xA101); + wm8994_write(0x39, 0x006C); wm8994_write(0x01, 0x0023); wm8994_write(0x200, 0x0000); msleep(WM8994_DELAY); -//CLK - //AIF1CLK - wm8994_sysclk_config(); - wm8994_write(0x300, 0xC010); // i2s 16 bits - //AIF2CLK use FLL2 + + //roger_chen@20100524 + //8KHz, BCLK=8KHz*128=1024KHz, Fout=2.048MHz + wm8994_write(0x220, 0x0000); // SMbus_16inx_16dat Write 0x34 * FLL1 Control (1)(220H): 0005 FLL1_FRACN_ENA=0, FLL1_OSC_ENA=0, FLL1_ENA=0 + wm8994_write(0x221, 0x0700); // SMbus_16inx_16dat Write 0x34 * FLL1 Control (2)(221H): 0700 FLL1_OUTDIV=2Fh, FLL1_CTRL_RATE=000, FLL1_FRATIO=000 + wm8994_write(0x222, 0x3126); // SMbus_16inx_16dat Write 0x34 * FLL1 Control (3)(222H): 8FD5 FLL1_K=3126h + wm8994_write(0x223, 0x0100); // SMbus_16inx_16dat Write 0x34 * FLL1 Control (4)(223H): 00E0 FLL1_N=8h, FLL1_GAIN=0000 + + wm8994_write(0x220, 0x0004); // SMbus_16inx_16dat Write 0x34 * FLL1 Control (1)(220H): 0005 FLL1_FRACN_ENA=1, FLL1_OSC_ENA=0, FLL1_ENA=0 + msleep(10); + wm8994_write(0x220, 0x0005); // SMbus_16inx_16dat Write 0x34 * FLL1 Control (1)(220H): 0005 FLL1_FRACN_ENA=1, FLL1_OSC_ENA=0, FLL1_ENA=1 + msleep(5); + + wm8994_write(0x200, 0x0010); + wm8994_write(0x208, 0x0008); + wm8994_write(0x208, 0x000A); + + wm8994_write(0x210, 0x0083); // SMbus_16inx_16dat Write 0x34 * SR=48KHz +#ifdef CONFIG_SND_CODEC_SOC_MASTER + wm8994_write(0x302, 0x3000); + msleep(30); + wm8994_write(0x302, 0x7000); + wm8994_write(0x303, 0x0040); + wm8994_write(0x304, 0x0040); + wm8994_write(0x305, 0x0040); + wm8994_write(0x300, 0xC050); //DSP/PCM; 16bits; ADC L channel = R channel;MODE A +#endif + wm8994_write(0x200, 0x0011); + wm8994_write(0x204, 0x0000); msleep(WM8994_DELAY); wm8994_write(0x240, 0x0000); - switch(wm8994->mclk) - { - case 12288000: - wm8994_write(0x241, 0x2F00);//48 - wm8994_write(0x242, 0); - wm8994_write(0x243, 0x0100); - break; - case 11289600: - wm8994_write(0x241, 0x2b00); - wm8994_write(0x242, 0xfb5b); - wm8994_write(0x243, 0x00e0); - break; - case 3072000: - wm8994_write(0x241, 0x2F00);//48 - wm8994_write(0x242, 0); - wm8994_write(0x243, 0x0400); - break; - case 2822400: - wm8994_write(0x241, 0x2b00); - wm8994_write(0x242, 0xed6d); - wm8994_write(0x243, 0x03e0); - break; - default: - printk("wm8994->mclk error = %d\n",wm8994->mclk); - return; - } - + wm8994_write(0x241, 0x2F00); + wm8994_write(0x242, 0x3126); + wm8994_write(0x243, 0x0100); + wm8994_write(0x240, 0x0004); msleep(10); wm8994_write(0x240, 0x0005); msleep(5); + wm8994_write(0x204, 0x0018); // SMbus_16inx_16dat Write 0x34 * AIF2 Clocking (1)(204H): 0011 AIF2CLK_SRC=10, AIF2CLK_INV=0, AIF2CLK_DIV=0, AIF2CLK_ENA=1 wm8994_write(0x208, 0x000E); wm8994_write(0x211, 0x0003); - +#ifdef CONFIG_SND_CODEC_SOC_MASTER wm8994_write(0x312, 0x3000); // SMbus_16inx_16dat Write 0x34 * AIF2 Master/Slave(312H): 7000 AIF2_TRI=0, AIF2_MSTR=1, AIF2_CLK_FRC=0, AIF2_LRCLK_FRC=0 msleep(30); wm8994_write(0x312, 0x7000); @@ -1696,161 +1326,57 @@ void BT_baseband(void) wm8994_write(0x314, 0x0080); // SMbus_16inx_16dat Write 0x34 * AIF2 ADCLRCK DIV-----BCLK/128 wm8994_write(0x315, 0x0080); wm8994_write(0x310, 0x0118); //DSP/PCM; 16bits; ADC L channel = R channel;MODE A - +#endif wm8994_write(0x204, 0x0019); // SMbus_16inx_16dat Write 0x34 * AIF2 Clocking (1)(204H): 0011 AIF2CLK_SRC=10, AIF2CLK_INV=0, AIF2CLK_DIV=0, AIF2CLK_ENA=1 -/* - wm8994_write(0x310, 0x0118); - wm8994_write(0x204, 0x0001); - wm8994_write(0x208, 0x000F); - wm8994_write(0x211, 0x0009); - wm8994_write(0x312, 0x7000); - wm8994_write(0x313, 0x00F0); -*/ -//GPIO + + //roger_chen@20100519 + //enable AIF2 BCLK,LRCK + //Rev.B and Rev.D is different wm8994_write(0x702, 0x2100); wm8994_write(0x703, 0x2100); + wm8994_write(0x704, 0xA100); wm8994_write(0x707, 0xA100); wm8994_write(0x708, 0x2100); wm8994_write(0x709, 0x2100); wm8994_write(0x70A, 0x2100); - wm8994_write(0x06, 0x000A); -//path - wm8994_write(0x29, 0x0100); - wm8994_write(0x2A, 0x0100); - wm8994_write(0x28, 0x00C0); - wm8994_write(0x24, 0x0009); - wm8994_write(0x29, 0x0130); - wm8994_write(0x2A, 0x0130); - wm8994_write(0x2D, 0x0001); - wm8994_write(0x2E, 0x0001); - wm8994_write(0x34, 0x0001); - wm8994_write(0x36, 0x0004); - wm8994_write(0x601, 0x0004); - wm8994_write(0x602, 0x0001); - wm8994_write(0x603, 0x000C); - wm8994_write(0x604, 0x0010); - wm8994_write(0x605, 0x0010); - wm8994_write(0x620, 0x0000); - wm8994_write(0x420, 0x0000); -//DRC&&EQ - wm8994_write(0x440, 0x0018); - wm8994_write(0x450, 0x0018); - wm8994_write(0x540, 0x01BF); //open nosie gate - wm8994_write(0x550, 0x01BF); //open nosie gate - wm8994_write(0x480, 0x0000); - wm8994_write(0x481, 0x0000); - wm8994_write(0x4A0, 0x0000); - wm8994_write(0x4A1, 0x0000); - wm8994_write(0x520, 0x0000); - wm8994_write(0x540, 0x0018); - wm8994_write(0x580, 0x0000); - wm8994_write(0x581, 0x0000); -//volume - wm8994_set_volume(wm8994_current_mode,wm8994->call_vol,call_maxvol); - wm8994_write(0x1E, 0x0006); - wm8994_set_channel_vol(); - wm8994_write(0x22, 0x0000); - wm8994_write(0x23, 0x0100); - wm8994_write(0x610, 0x01C0); - wm8994_write(0x611, 0x01C0); - wm8994_write(0x612, 0x01C0); - wm8994_write(0x613, 0x01C0); -//other - wm8994_write(0x4C, 0x9F25); - wm8994_write(0x60, 0x00EE); - msleep(5); -//power - wm8994_write(0x01, 0x3033); + + wm8994_write(0x01, 0x3003); wm8994_write(0x02, 0x63A0); wm8994_write(0x03, 0x33F0); wm8994_write(0x04, 0x3303); - wm8994_write(0x05, 0x3303); -} - -void BT_baseband_old(void) -{ - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - DBG("%s::%d\n",__FUNCTION__,__LINE__); - - if(wm8994_current_mode==wm8994_BT_baseband)return; - - wm8994_current_mode=wm8994_BT_baseband; - wm8994_reset(); - msleep(WM8994_DELAY); - - wm8994_write(0x01, 0x3003); - wm8994_write(0x02, 0x63A0); - wm8994_write(0x03, 0x33F0); - wm8994_write(0x04, 0x3303); - wm8994_write(0x05, 0x3303); - wm8994_write(0x06, 0x000A); - wm8994_set_volume(wm8994_current_mode,wm8994->call_vol,call_maxvol); - wm8994_write(0x1E, 0x0006); - wm8994_write(0x29, 0x0100); - wm8994_write(0x2A, 0x0100); + wm8994_write(0x05, 0x3303); + wm8994_write(0x06, 0x000A); + wm8994_set_volume(wm8994_current_mode,call_vol,call_maxvol); + wm8994_write(0x1E, 0x0006); + wm8994_write(0x29, 0x0100); + wm8994_write(0x2A, 0x0100); wm8994_set_channel_vol(); #ifdef CONFIG_SND_BB_NORMAL_INPUT - wm8994_write(0x28, 0x00C0); + wm8994_write(0x28, 0x00C0); #endif #ifdef CONFIG_SND_BB_DIFFERENTIAL_INPUT /*vol = BT_incall_vol; - if(vol>6)vol=6; - if(vol<-12)vol=-12; + if (vol>6)vol=6; + if (vol<-12)vol=-12; wm8994_write(0x2B, (vol+12)/3 + 1);*/ - wm8994_write(0x28, 0x00CC); + wm8994_write(0x28, 0x00CC); #endif - wm8994_write(0x22, 0x0000); - wm8994_write(0x23, 0x0100); - wm8994_write(0x24, 0x0009); - wm8994_write(0x29, 0x0130); - wm8994_write(0x2A, 0x0130); - wm8994_write(0x2D, 0x0001); - wm8994_write(0x2E, 0x0001); - wm8994_write(0x34, 0x0001); - wm8994_write(0x36, 0x0004); - wm8994_write(0x4C, 0x9F25); - wm8994_write(0x60, 0x00EE); - wm8994_write(0x01, 0x3023); - //roger_chen@20100524 - //8KHz, BCLK=8KHz*128=1024KHz, Fout=2.048MHz - wm8994_write(0x200, 0x0001); - wm8994_write(0x204, 0x0001); // SMbus_16inx_16dat Write 0x34 * AIF2 Clocking (1)(204H): 0011 AIF2CLK_SRC=00, AIF2CLK_INV=0, AIF2CLK_DIV=0, AIF2CLK_ENA=1 - wm8994_write(0x208, 0x000E); - wm8994_write(0x220, 0x0000); // SMbus_16inx_16dat Write 0x34 * FLL1 Control (1)(220H): 0005 FLL1_FRACN_ENA=0, FLL1_OSC_ENA=0, FLL1_ENA=0 - wm8994_write(0x221, 0x0700); // SMbus_16inx_16dat Write 0x34 * FLL1 Control (2)(221H): 0700 FLL1_OUTDIV=2Fh, FLL1_CTRL_RATE=000, FLL1_FRATIO=000 - wm8994_write(0x222, 0x3126); // SMbus_16inx_16dat Write 0x34 * FLL1 Control (3)(222H): 8FD5 FLL1_K=3126h - wm8994_write(0x223, 0x0100); // SMbus_16inx_16dat Write 0x34 * FLL1 Control (4)(223H): 00E0 FLL1_N=8h, FLL1_GAIN=0000 - - wm8994_write(0x303, 0x0040); - wm8994_write(0x304, 0x0040); - wm8994_write(0x305, 0x0040); - wm8994_write(0x300, 0xC050); //DSP/PCM; 16bits; ADC L channel = R channel;MODE A - - wm8994_write(0x210, 0x0083); // SMbus_16inx_16dat Write 0x34 * SR=48KHz - wm8994_write(0x220, 0x0004); // SMbus_16inx_16dat Write 0x34 * FLL1 Control (1)(220H): 0005 FLL1_FRACN_ENA=1, FLL1_OSC_ENA=0, FLL1_ENA=0 - msleep(50); - wm8994_write(0x220, 0x0005); // SMbus_16inx_16dat Write 0x34 * FLL1 Control (1)(220H): 0005 FLL1_FRACN_ENA=1, FLL1_OSC_ENA=0, FLL1_ENA=1 - - wm8994_write(0x240, 0x0000); - wm8994_write(0x241, 0x2F00); - wm8994_write(0x242, 0x3126); - wm8994_write(0x243, 0x0100); - - wm8994_write(0x313, 0x0020); // SMbus_16inx_16dat Write 0x34 * AIF2 BCLK DIV--------AIF1CLK/2 - wm8994_write(0x314, 0x0080); // SMbus_16inx_16dat Write 0x34 * AIF2 ADCLRCK DIV-----BCLK/128 - wm8994_write(0x315, 0x0080); - wm8994_write(0x310, 0x0118); //DSP/PCM; 16bits; ADC L channel = R channel;MODE A - - wm8994_write(0x211, 0x0003); // SMbus_16inx_16dat Write 0x34 * SR=8KHz - wm8994_write(0x240, 0x0004); - msleep(50); - wm8994_write(0x240, 0x0005); + wm8994_write(0x22, 0x0000); + wm8994_write(0x23, 0x0100); + wm8994_write(0x24, 0x0009); + wm8994_write(0x29, 0x0130); + wm8994_write(0x2A, 0x0130); + wm8994_write(0x2D, 0x0001); + wm8994_write(0x2E, 0x0001); + wm8994_write(0x34, 0x0001); + wm8994_write(0x36, 0x0004); + wm8994_write(0x4C, 0x9F25); + wm8994_write(0x60, 0x00EE); + wm8994_write(0x01, 0x3023); - wm8994_write(0x200, 0x0011); - wm8994_write(0x204, 0x0019); // SMbus_16inx_16dat Write 0x34 * AIF2 Clocking (1)(204H): 0011 AIF2CLK_SRC=10, AIF2CLK_INV=0, AIF2CLK_DIV=0, AIF2CLK_ENA=1 wm8994_write(0x440, 0x0018); wm8994_write(0x450, 0x0018); wm8994_write(0x540, 0x01BF); //open nosie gate @@ -1864,9 +1390,9 @@ void BT_baseband_old(void) wm8994_write(0x580, 0x0000); wm8994_write(0x581, 0x0000); wm8994_write(0x601, 0x0004); - - wm8994_write(0x602, 0x0001); - + if (wm8994_work_type != WM8994_WORK_FIRSTINCALL) { + wm8994_write(0x602, 0x0001); + } wm8994_write(0x603, 0x000C); wm8994_write(0x604, 0x0010); wm8994_write(0x605, 0x0010); @@ -1876,38 +1402,15 @@ void BT_baseband_old(void) wm8994_write(0x613, 0x01C0); wm8994_write(0x620, 0x0000); wm8994_write(0x420, 0x0000); - - //roger_chen@20100519 - //enable AIF2 BCLK,LRCK - //Rev.B and Rev.D is different - wm8994_write(0x702, 0x2100); - wm8994_write(0x703, 0x2100); - - wm8994_write(0x704, 0xA100); - wm8994_write(0x707, 0xA100); - wm8994_write(0x708, 0x2100); - wm8994_write(0x709, 0x2100); - wm8994_write(0x70A, 0x2100); -#ifdef CONFIG_SND_RK29_CODEC_SOC_MASTER - wm8994_write(0x700, 0xA101); - wm8994_write(0x705, 0xA101); - wm8994_write(0x302, 0x3000); - msleep(30); - wm8994_write(0x302, 0x7000); - msleep(30); - wm8994_write(0x312, 0x3000); // SMbus_16inx_16dat Write 0x34 * AIF2 Master/Slave(312H): 7000 AIF2_TRI=0, AIF2_MSTR=1, AIF2_CLK_FRC=0, AIF2_LRCLK_FRC=0 - msleep(30); - wm8994_write(0x312, 0x7000); -#endif } -void BT_baseband_and_record(void) + +static void BT_baseband_and_record(void) { - struct wm8994_priv *wm8994 = wm8994_codec->private_data; DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode==wm8994_BT_baseband_and_record)return; - wm8994_current_mode=wm8994_BT_baseband_and_record; + if (wm8994_current_mode == wm8994_BT_baseband_and_record)return; + wm8994_current_mode = wm8994_BT_baseband_and_record; wm8994_reset(); msleep(WM8994_DELAY); @@ -1917,7 +1420,7 @@ void BT_baseband_and_record(void) wm8994_write(0x04, 0x3303); wm8994_write(0x05, 0x3002); wm8994_write(0x06, 0x000A); - wm8994_set_volume(wm8994_current_mode,wm8994->call_vol,call_maxvol); + wm8994_set_volume(wm8994_current_mode,call_vol,call_maxvol); wm8994_write(0x1E, 0x0006); wm8994_write(0x28, 0x00CC); wm8994_write(0x29, 0x0100); @@ -1985,12 +1488,12 @@ void BT_baseband_and_record(void) /******************PCM BB BEGIN*****************/ -void handsetMIC_to_baseband_to_headset(void) //pcmbaseband +static void handsetMIC_to_baseband_to_headset(void) //pcmbaseband { DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode==wm8994_handsetMIC_to_baseband_to_headset)return; - wm8994_current_mode=wm8994_handsetMIC_to_baseband_to_headset; + if (wm8994_current_mode == wm8994_handsetMIC_to_baseband_to_headset)return; + wm8994_current_mode = wm8994_handsetMIC_to_baseband_to_headset; wm8994_reset(); msleep(50); @@ -2065,15 +1568,15 @@ void handsetMIC_to_baseband_to_headset(void) //pcmbaseband wm8994_write(0x317, 0x0003); wm8994_write(0x312, 0x0000); /// as slave ///0x4000); //AIF2 SET AS MASTER - + wm8994_set_volume(wm8994_current_mode,call_vol,call_maxvol); } -void handsetMIC_to_baseband_to_headset_and_record(void) //pcmbaseband +static void handsetMIC_to_baseband_to_headset_and_record(void) //pcmbaseband { DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode==wm8994_handsetMIC_to_baseband_to_headset_and_record)return; - wm8994_current_mode=wm8994_handsetMIC_to_baseband_to_headset_and_record; + if (wm8994_current_mode == wm8994_handsetMIC_to_baseband_to_headset_and_record)return; + wm8994_current_mode = wm8994_handsetMIC_to_baseband_to_headset_and_record; wm8994_reset(); msleep(50); @@ -2151,15 +1654,15 @@ void handsetMIC_to_baseband_to_headset_and_record(void) //pcmbaseband wm8994_write(0x602, 0x0001); wm8994_write(0x700, 0x8140);//SYNC issue, AIF1 ADCLRC1 from FLL after AIF1 MASTER!!! - + wm8994_set_volume(wm8994_current_mode,call_vol,call_maxvol); } -void mainMIC_to_baseband_to_earpiece(void) //pcmbaseband +static void mainMIC_to_baseband_to_earpiece(void) //pcmbaseband { DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode==wm8994_mainMIC_to_baseband_to_earpiece)return; - wm8994_current_mode=wm8994_mainMIC_to_baseband_to_earpiece; + if (wm8994_current_mode == wm8994_mainMIC_to_baseband_to_earpiece)return; + wm8994_current_mode = wm8994_mainMIC_to_baseband_to_earpiece; wm8994_reset(); msleep(50); @@ -2235,15 +1738,15 @@ void mainMIC_to_baseband_to_earpiece(void) //pcmbaseband wm8994_write(0x317, 0x0003); wm8994_write(0x312, 0x0000); //AIF2 SET AS MASTER - + wm8994_set_volume(wm8994_current_mode,call_vol,call_maxvol); } -void mainMIC_to_baseband_to_earpiece_and_record(void) //pcmbaseband +static void mainMIC_to_baseband_to_earpiece_and_record(void) //pcmbaseband { DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode==wm8994_mainMIC_to_baseband_to_earpiece_and_record)return; - wm8994_current_mode=wm8994_mainMIC_to_baseband_to_earpiece_and_record; + if (wm8994_current_mode == wm8994_mainMIC_to_baseband_to_earpiece_and_record)return; + wm8994_current_mode = wm8994_mainMIC_to_baseband_to_earpiece_and_record; wm8994_reset(); msleep(50); @@ -2261,7 +1764,8 @@ void mainMIC_to_baseband_to_earpiece_and_record(void) //pcmbaseband wm8994_write(0x03, 0x00F0); wm8994_write(0x04, 0x3003); wm8994_write(0x05, 0x3003); - wm8994_write(0x1A, 0x010B); + //wm8994_write(0x1A, 0x010B); + wm8994_write(0x1A, 0x0101); wm8994_write(0x1F, 0x0000); wm8994_write(0x28, 0x0003); wm8994_write(0x2A, 0x0020); @@ -2319,15 +1823,15 @@ void mainMIC_to_baseband_to_earpiece_and_record(void) //pcmbaseband wm8994_write(0x602, 0x0001); wm8994_write(0x700, 0x8140);//SYNC issue, AIF1 ADCLRC1 from FLL after AIF1 MASTER!!! - + wm8994_set_volume(wm8994_current_mode,call_vol,call_maxvol); } -void mainMIC_to_baseband_to_speakers(void) //pcmbaseband +static void mainMIC_to_baseband_to_speakers(void) //pcmbaseband { DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode==wm8994_mainMIC_to_baseband_to_speakers)return; - wm8994_current_mode=wm8994_mainMIC_to_baseband_to_speakers; + if (wm8994_current_mode == wm8994_mainMIC_to_baseband_to_speakers)return; + wm8994_current_mode = wm8994_mainMIC_to_baseband_to_speakers; wm8994_reset(); msleep(50); @@ -2348,7 +1852,7 @@ void mainMIC_to_baseband_to_speakers(void) //pcmbaseband wm8994_write(0x1A, 0x011F); wm8994_write(0x22, 0x0000); wm8994_write(0x23, 0x0100); ///0x0000); - //wm8994_write(0x25, 0x0152); + wm8994_write(0x25, 0x0152); wm8994_write(0x28, 0x0003); wm8994_write(0x2A, 0x0020); wm8994_write(0x2D, 0x0001); @@ -2405,15 +1909,15 @@ void mainMIC_to_baseband_to_speakers(void) //pcmbaseband wm8994_write(0x317, 0x0003); wm8994_write(0x312, 0x0000); //AIF2 SET AS MASTER - + wm8994_set_volume(wm8994_current_mode,call_vol,call_maxvol); } -void mainMIC_to_baseband_to_speakers_and_record(void) //pcmbaseband +static void mainMIC_to_baseband_to_speakers_and_record(void) //pcmbaseband { DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode==wm8994_mainMIC_to_baseband_to_speakers_and_record)return; - wm8994_current_mode=wm8994_mainMIC_to_baseband_to_speakers_and_record; + if (wm8994_current_mode == wm8994_mainMIC_to_baseband_to_speakers_and_record)return; + wm8994_current_mode = wm8994_mainMIC_to_baseband_to_speakers_and_record; wm8994_reset(); msleep(50); @@ -2490,14 +1994,15 @@ void mainMIC_to_baseband_to_speakers_and_record(void) //pcmbaseband wm8994_write(0x602, 0x0001); wm8994_write(0x700, 0x8140);//SYNC issue, AIF1 ADCLRC1 from FLL after AIF1 MASTER!!! + wm8994_set_volume(wm8994_current_mode,call_vol,call_maxvol); } -void BT_baseband(void) //pcmbaseband +static void BT_baseband(void) //pcmbaseband { DBG("%s::%d\n",__FUNCTION__,__LINE__); - if(wm8994_current_mode==wm8994_BT_baseband)return; - wm8994_current_mode=wm8994_BT_baseband; + if (wm8994_current_mode == wm8994_BT_baseband)return; + wm8994_current_mode = wm8994_BT_baseband; wm8994_reset(); msleep(50); @@ -2517,141 +2022,616 @@ void BT_baseband(void) //pcmbaseband wm8994_write(0x210 ,0x0009);// LRCK=8KHz, Rate=MCLK/1536 wm8994_write(0x300 ,0x4018);// DSP/PCM 16bits - wm8994_write(0x204 ,0x0011);// AIF2 MCLK=FLL1 - wm8994_write(0x211 ,0x0009);// LRCK=8KHz, Rate=MCLK/1536 - wm8994_write(0x310 ,0x4118);// DSP/PCM 16bits - wm8994_write(0x208 ,0x000F); + wm8994_write(0x204 ,0x0011);// AIF2 MCLK=FLL1 + wm8994_write(0x211 ,0x0009);// LRCK=8KHz, Rate=MCLK/1536 + wm8994_write(0x310 ,0x4118);// DSP/PCM 16bits + wm8994_write(0x208 ,0x000F); + +/////AIF1 + wm8994_write(0x700 ,0x8101); +/////AIF2 + wm8994_write(0x702 ,0xC100); + wm8994_write(0x703 ,0xC100); + wm8994_write(0x704 ,0xC100); + wm8994_write(0x706 ,0x4100); +/////AIF3 + wm8994_write(0x707 ,0xA100); + wm8994_write(0x708 ,0xA100); + wm8994_write(0x709 ,0xA100); + wm8994_write(0x70A ,0xA100); + + wm8994_write(0x06 ,0x0001); + + wm8994_write(0x02 ,0x0300); + wm8994_write(0x03 ,0x0030); + wm8994_write(0x04 ,0x3301);//ADCL off + wm8994_write(0x05 ,0x3301);//DACL off + + wm8994_write(0x2A ,0x0005); + + wm8994_write(0x313 ,0x00F0); + wm8994_write(0x314 ,0x0020); + wm8994_write(0x315 ,0x0020); + + wm8994_write(0x2E ,0x0001); + wm8994_write(0x420 ,0x0000); + wm8994_write(0x520 ,0x0000); + wm8994_write(0x601 ,0x0001); + wm8994_write(0x602 ,0x0001); + wm8994_write(0x604 ,0x0001); + wm8994_write(0x605 ,0x0001); + wm8994_write(0x607 ,0x0002); + wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 + wm8994_write(0x612, 0x01C0); //DAC2 Left Volume bit0~7 + wm8994_write(0x613, 0x01C0); //DAC2 Right Volume bit0~7 + + + wm8994_write(0x312 ,0x4000); + + wm8994_write(0x606 ,0x0001); + wm8994_write(0x607 ,0x0003);//R channel for data mix/CPU record data + + +////////////HP output test + wm8994_write(0x01 ,0x0303); + wm8994_write(0x4C ,0x9F25); + wm8994_write(0x60 ,0x00EE); +///////////end HP test + + wm8994_set_volume(wm8994_current_mode,call_vol,call_maxvol); +} + +static void BT_baseband_and_record(void) //pcmbaseband +{ + DBG("%s::%d\n",__FUNCTION__,__LINE__); + + if (wm8994_current_mode == wm8994_BT_baseband_and_record)return; + wm8994_current_mode = wm8994_BT_baseband_and_record; + wm8994_reset(); + msleep(50); + + wm8994_write(0x01 ,0x0003); + msleep (50); + + wm8994_write(0x200 ,0x0001); + wm8994_write(0x221 ,0x0700);//MCLK=12MHz + wm8994_write(0x222 ,0x3127); + wm8994_write(0x223 ,0x0100); + wm8994_write(0x220 ,0x0004); + msleep (50); + wm8994_write(0x220 ,0x0005); + + wm8994_write(0x02 ,0x0000); + wm8994_write(0x200 ,0x0011);// AIF1 MCLK=FLL1 + wm8994_write(0x210 ,0x0009);// LRCK=8KHz, Rate=MCLK/1536 + wm8994_write(0x300 ,0x4018);// DSP/PCM 16bits + + wm8994_write(0x204 ,0x0011);// AIF2 MCLK=FLL1 + wm8994_write(0x211 ,0x0009);// LRCK=8KHz, Rate=MCLK/1536 + wm8994_write(0x310 ,0x4118);// DSP/PCM 16bits + wm8994_write(0x208 ,0x000F); + +/////AIF1 + wm8994_write(0x700 ,0x8101); +/////AIF2 + wm8994_write(0x702 ,0xC100); + wm8994_write(0x703 ,0xC100); + wm8994_write(0x704 ,0xC100); + wm8994_write(0x706 ,0x4100); +/////AIF3 + wm8994_write(0x707 ,0xA100); + wm8994_write(0x708 ,0xA100); + wm8994_write(0x709 ,0xA100); + wm8994_write(0x70A ,0xA100); + + wm8994_write(0x06 ,0x0001); + wm8994_write(0x02 ,0x0300); + wm8994_write(0x03 ,0x0030); + wm8994_write(0x04 ,0x3301);//ADCL off + wm8994_write(0x05 ,0x3301);//DACL off + wm8994_write(0x2A ,0x0005); + + wm8994_write(0x313 ,0x00F0); + wm8994_write(0x314 ,0x0020); + wm8994_write(0x315 ,0x0020); + + wm8994_write(0x2E ,0x0001); + wm8994_write(0x420 ,0x0000); + wm8994_write(0x520 ,0x0000); + wm8994_write(0x602 ,0x0001); + wm8994_write(0x604 ,0x0001); + wm8994_write(0x605 ,0x0001); + wm8994_write(0x607 ,0x0002); + wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 + wm8994_write(0x612, 0x01C0); //DAC2 Left Volume bit0~7 + wm8994_write(0x613, 0x01C0); //DAC2 Right Volume bit0~7 + + wm8994_write(0x312 ,0x4000); + + wm8994_write(0x606 ,0x0001); + wm8994_write(0x607 ,0x0003);//R channel for data mix/CPU record data +////////////HP output test + wm8994_write(0x01 ,0x0303); + wm8994_write(0x4C ,0x9F25); + wm8994_write(0x60 ,0x00EE); +///////////end HP test + + wm8994_set_volume(wm8994_current_mode,call_vol,call_maxvol); +} +#endif //PCM_BB + + +typedef void (wm8994_codec_fnc_t) (void); + +static wm8994_codec_fnc_t *wm8994_codec_sequence[] = { + AP_to_headset, + AP_to_speakers, + AP_to_speakers_and_headset, + recorder_and_AP_to_headset, + recorder_and_AP_to_speakers, + FM_to_headset, + FM_to_headset_and_record, + FM_to_speakers, + FM_to_speakers_and_record, + handsetMIC_to_baseband_to_headset, + mainMIC_to_baseband_to_headset, + handsetMIC_to_baseband_to_headset_and_record, + mainMIC_to_baseband_to_earpiece, + mainMIC_to_baseband_to_earpiece_and_record, + mainMIC_to_baseband_to_speakers, + mainMIC_to_baseband_to_speakers_and_record, + BT_baseband, + BT_baseband_and_record, +}; + +static void wm8994_set_AIF1DAC_EQ(void) { + + wm8994_write(0x0480, 0x0001|((bank_vol[1]+12)<<11)| + ((bank_vol[2]+12)<<6)|((bank_vol[3]+12)<<1)); + wm8994_write(0x0481, 0x0000|((bank_vol[4]+12)<<11)| + ((bank_vol[5]+12)<<6)); +} + +static void wm8994_set_channel_vol(void) +{ + switch(wm8994_current_mode) { + case wm8994_AP_to_speakers_and_headset: + if (speaker_normal_vol > 6) + speaker_normal_vol = 6; + else if (speaker_normal_vol < -57) + speaker_normal_vol = -57; + if (headset_normal_vol > 6) + headset_normal_vol = 6; + else if (headset_normal_vol < -57) + headset_normal_vol = -57; + + DBG("headset_normal_vol = %ddB \n",headset_normal_vol); + DBG("speaker_normal_vol = %ddB \n",speaker_normal_vol); + + vol = speaker_normal_vol; + if (vol<=6) { + wm8994_write(0x26, 320+vol+57); //-57dB~6dB + wm8994_write(0x27, 320+vol+57); //-57dB~6dB + } else { + wm8994_write(0x25, 0x003F); //0~12dB + wm8994_write(0x26, 320+vol+45); //-57dB~6dB + wm8994_write(0x27, 320+vol+45); //-57dB~6dB + } + vol = headset_normal_vol-4; + + /* for turn down headset volume when ringtone */ + if (vol >= -48) + vol -= 14; + else + vol = -57; + + wm8994_write(0x1C, 320+vol+57); //-57dB~6dB + wm8994_write(0x1D, 320+vol+57); //-57dB~6dB + + wm8994_set_AIF1DAC_EQ(); + break; + + case wm8994_recorder_and_AP_to_headset: + if (headset_normal_vol > 6) + headset_normal_vol = 6; + else if (headset_normal_vol < -57) + headset_normal_vol = -57; + if (recorder_vol > 60) + recorder_vol = 60; + else if (recorder_vol < -16) + recorder_vol = -16; + + DBG("recorder_vol = %ddB \n",recorder_vol); + DBG("headset_normal_vol = %ddB \n",headset_normal_vol); + + vol = recorder_vol; + if (vol<30) { + wm8994_write(0x1A, 320+(vol+16)*10/15); //mic vol + } else { + wm8994_write(0x2A, 0x0030); + wm8994_write(0x1A, 320+(vol-14)*10/15); //mic vol + } + vol = headset_normal_vol; + wm8994_write(0x1C, 320+vol+57); //-57dB~6dB + wm8994_write(0x1D, 320+vol+57); //-57dB~6dB + break; + + case wm8994_recorder_and_AP_to_speakers: + if (recorder_vol > 60) + recorder_vol = 60; + else if (recorder_vol < -16) + recorder_vol = -16; + if (speaker_normal_vol > 6) + speaker_normal_vol = 6; + else if (speaker_normal_vol < -57) + speaker_normal_vol = -57; + + DBG("speaker_normal_vol = %ddB \n",speaker_normal_vol); + DBG("recorder_vol = %ddB \n",recorder_vol); + + vol = recorder_vol; + if (vol<30) { + wm8994_write(0x1A, 320+(vol+16)*10/15); //mic vol + } else { + wm8994_write(0x2A, 0x0030); + wm8994_write(0x1A, 320+(vol-14)*10/15); //mic vol + } + + vol = speaker_normal_vol; + wm8994_write(0x26, 320+vol+57); //-57dB~6dB + wm8994_write(0x27, 320+vol+57); //-57dB~6dB + + wm8994_set_AIF1DAC_EQ(); + break; + + case wm8994_handsetMIC_to_baseband_to_headset: + if (headset_incall_vol > 6) + headset_incall_vol = 6; + else if (headset_incall_vol < -12) + headset_incall_vol = -12; + if (headset_incall_mic_vol > 30) + headset_incall_mic_vol = 30; + else if (headset_incall_mic_vol < -22) + headset_incall_mic_vol = -22; + + DBG("headset_incall_mic_vol = %ddB \n",headset_incall_mic_vol); + DBG("headset_incall_vol = %ddB \n",headset_incall_vol); + + vol = headset_incall_mic_vol; + if (vol<-16) { + wm8994_write(0x1E, 0x0016); //mic vol + wm8994_write(0x18, 320+(vol+22)*10/15); //mic vol + } else { + wm8994_write(0x1E, 0x0006); //mic vol + wm8994_write(0x18, 320+(vol+16)*10/15); //mic vol + } +#ifdef CONFIG_SND_BB_DIFFERENTIAL_INPUT + vol = headset_incall_vol; + wm8994_write(0x2B, (vol+12)/3+1); //-12~6dB +#endif + break; + + case wm8994_mainMIC_to_baseband_to_headset: + if (headset_incall_vol > 6) + headset_incall_vol = 6; + else if (headset_incall_vol < -12) + headset_incall_vol = -12; + if (speaker_incall_mic_vol > 30) + speaker_incall_mic_vol = 30; + else if (speaker_incall_mic_vol < -22) + speaker_incall_mic_vol = -22; + + DBG("speaker_incall_mic_vol = %ddB \n",speaker_incall_mic_vol); + DBG("headset_incall_vol = %ddB \n",headset_incall_vol); + + vol=speaker_incall_mic_vol; + if (vol<-16) { + wm8994_write(0x1E, 0x0016); //mic vol + wm8994_write(0x1A, 320+(vol+22)*10/15); //mic vol + } else { + wm8994_write(0x1E, 0x0006); //mic vol + wm8994_write(0x1A, 320+(vol+16)*10/15); //mic vol + } +#ifdef CONFIG_SND_BB_DIFFERENTIAL_INPUT + vol = headset_incall_vol; + wm8994_write(0x2B, (vol+12)/3+1); //-12~6dB +#endif + break; + +#if defined(CONFIG_SND_INSIDE_EARPIECE)||defined(CONFIG_SND_OUTSIDE_EARPIECE) + case wm8994_mainMIC_to_baseband_to_earpiece: + if (speaker_incall_mic_vol > 30) + speaker_incall_mic_vol = 30; + else if (speaker_incall_mic_vol < -22) + speaker_incall_mic_vol = -22; + if (earpiece_incall_vol>6) + earpiece_incall_vol = 6; + else if (earpiece_incall_vol<-21) + earpiece_incall_vol = -21; + + DBG("earpiece_incall_vol = %ddB \n",earpiece_incall_vol); + DBG("speaker_incall_mic_vol = %ddB \n",speaker_incall_mic_vol); + + vol = earpiece_incall_vol; + if (vol>=0) { + wm8994_write(0x33, 0x0018); //6dB + wm8994_write(0x31, (((6-vol)/3)<<3)+(6-vol)/3); //-21dB + } else { + wm8994_write(0x33, 0x0010); + wm8994_write(0x31, (((-vol)/3)<<3)+(-vol)/3); //-21dB + } +#ifdef CONFIG_SND_INSIDE_EARPIECE + vol = speaker_incall_mic_vol; + if (vol<-16) { + wm8994_write(0x1E, 0x0016); + wm8994_write(0x1A, 320+(vol+22)*10/15); + } else { + wm8994_write(0x1E, 0x0006); + wm8994_write(0x1A, 320+(vol+16)*10/15); + } +#endif +#ifdef CONFIG_SND_OUTSIDE_EARPIECE + vol = headset_incall_mic_vol; + if (vol<-16) { + wm8994_write(0x1E, 0x0016); //mic vol + wm8994_write(0x18, 320+(vol+22)*10/15); //mic vol + } else { + wm8994_write(0x1E, 0x0006); //mic vol + wm8994_write(0x18, 320+(vol+16)*10/15); //mic vol + } +#endif + break; +#endif + case wm8994_mainMIC_to_baseband_to_speakers: + if (speaker_incall_mic_vol > 30) + speaker_incall_mic_vol = 30; + else if (speaker_incall_mic_vol < -22) + speaker_incall_mic_vol = -22; + if (speaker_incall_vol > 12) + speaker_incall_vol = 12; + else if (speaker_incall_vol < -21) + speaker_incall_vol = -21; + + DBG("speaker_incall_vol = %ddB \n",speaker_incall_vol); + DBG("speaker_incall_mic_vol = %ddB \n",speaker_incall_mic_vol); + + vol = speaker_incall_mic_vol; + if (vol<-16) { + wm8994_write(0x1E, 0x0016); + wm8994_write(0x1A, 320+(vol+22)*10/15); + } else { + wm8994_write(0x1E, 0x0006); + wm8994_write(0x1A, 320+(vol+16)*10/15); + } + vol = speaker_incall_vol; + if (vol<=0) { + wm8994_write(0x31, (((-vol)/3)<<3)+(-vol)/3); + } else if (vol <= 9) { + wm8994_write(0x25, ((vol*10/15)<<3)+vol*10/15); + } else { + wm8994_write(0x25, 0x003F); + } + break; + + case wm8994_BT_baseband: + if (BT_incall_vol > 30) + BT_incall_vol = 30; + else if (BT_incall_vol < -16) + BT_incall_vol = -16; + if (BT_incall_mic_vol > 6) + BT_incall_mic_vol = 6; + else if (BT_incall_mic_vol < -57) + BT_incall_mic_vol = -57; + + DBG("BT_incall_mic_vol = %ddB \n",BT_incall_mic_vol); + DBG("BT_incall_vol = %ddB \n",BT_incall_vol); + + vol = BT_incall_mic_vol; + wm8994_write(0x20, 320+vol+57); + + vol = BT_incall_vol; + wm8994_write(0x19, 0x0500+(vol+16)*10/15); + break; + default: + printk("route error !\n"); + } + +} + +void wm8994_codec_set_volume(unsigned char system_type,unsigned char volume) +{ + DBG("%s:: system_type = %d volume = %d \n",__FUNCTION__,system_type,volume); + + if (system_type == VOICE_CALL) + { + if (volume <= call_maxvol) + call_vol=volume; + else { + printk("%s----%d::max value is 7\n",__FUNCTION__,__LINE__); + call_vol=call_maxvol; + } + if (wm8994_current_mode <= wm8994_mainMIC_to_baseband_to_speakers_and_record&& + wm8994_current_mode >= wm8994_handsetMIC_to_baseband_to_headset) + wm8994_set_volume(wm8994_current_mode,call_vol,call_maxvol); + } else if (system_type == BLUETOOTH_SCO) { + if (volume <= BT_call_maxvol) + BT_call_vol = volume; + else { + printk("%s----%d::max value is 15\n",__FUNCTION__,__LINE__); + BT_call_vol = BT_call_maxvol; + } + if (wm8994_current_mode= wm8994_BT_baseband) + wm8994_set_volume(wm8994_current_mode,BT_call_vol,BT_call_maxvol); + }else { + return; + printk("%s----%d::system type error!\n",__FUNCTION__,__LINE__); + } +} + +static void wm8994_set_volume(unsigned char wm8994_mode,unsigned char volume,unsigned char max_volume) +{ + unsigned short lvol=0,rvol=0; + + DBG("%s::volume = %d \n",__FUNCTION__,volume); -/////AIF1 - wm8994_write(0x700 ,0x8101); -/////AIF2 - wm8994_write(0x702 ,0xC100); - wm8994_write(0x703 ,0xC100); - wm8994_write(0x704 ,0xC100); - wm8994_write(0x706 ,0x4100); -/////AIF3 - wm8994_write(0x707 ,0xA100); - wm8994_write(0x708 ,0xA100); - wm8994_write(0x709 ,0xA100); - wm8994_write(0x70A ,0xA100); + if (volume>max_volume)volume=max_volume; + + if (wm8994_mode == wm8994_handsetMIC_to_baseband_to_headset_and_record|| + wm8994_mode == wm8994_handsetMIC_to_baseband_to_headset|| + wm8994_mode == wm8994_mainMIC_to_baseband_to_headset) + { + wm8994_read(0x001C, &lvol); + wm8994_read(0x001D, &rvol); + //HPOUT1L_VOL bit 0~5 /-57dB to +6dB in 1dB steps + wm8994_write(0x001C, (lvol&~0x003f)|headset_vol_table[volume]); + //HPOUT1R_VOL bit 0~5 /-57dB to +6dB in 1dB steps + wm8994_write(0x001D, (rvol&~0x003f)|headset_vol_table[volume]); + } else if (wm8994_mode == wm8994_mainMIC_to_baseband_to_speakers_and_record|| + wm8994_mode == wm8994_mainMIC_to_baseband_to_speakers) + { + wm8994_read(0x0026, &lvol); + wm8994_read(0x0027, &rvol); + //SPKOUTL_VOL bit 0~5 /-57dB to +6dB in 1dB steps + wm8994_write(0x0026, (lvol&~0x003f)|speakers_vol_table[volume]); + //SPKOUTR_VOL bit 0~5 /-57dB to +6dB in 1dB steps + wm8994_write(0x0027, (rvol&~0x003f)|speakers_vol_table[volume]); + } else if (wm8994_mode == wm8994_mainMIC_to_baseband_to_earpiece|| + wm8994_mode == wm8994_mainMIC_to_baseband_to_earpiece_and_record) + { + wm8994_read(0x0020, &lvol); + wm8994_read(0x0021, &rvol); + + //MIXOUTL_VOL bit 0~5 /-57dB to +6dB in 1dB steps + wm8994_write(0x0020, (lvol&~0x003f)|earpiece_vol_table[volume]); + //MIXOUTR_VOL bit 0~5 /-57dB to +6dB in 1dB steps + wm8994_write(0x0021, (rvol&~0x003f)|earpiece_vol_table[volume]); + } else if (wm8994_mode == wm8994_BT_baseband||wm8994_mode == wm8994_BT_baseband_and_record) + { + //bit 0~4 /-16.5dB to +30dB in 1.5dB steps + DBG("BT_vol_table[volume] = 0x%x\n",BT_vol_table[volume]); + wm8994_write(0x0500, BT_vol_table[volume]); + wm8994_write(0x0501, 0x0100); + } else if (wm8994_mode == null) + { + wm8994_read(0x001C, &lvol); + wm8994_read(0x001D, &rvol); + wm8994_write(0x001C, (lvol&~0x003f)|headset_vol_table[volume]); + wm8994_write(0x001D, (rvol&~0x003f)|headset_vol_table[volume]); + wm8994_read(0x0026, &lvol); + wm8994_read(0x0027, &rvol); + wm8994_write(0x0026, (lvol&~0x003f)|speakers_vol_table[volume]); + wm8994_write(0x0027, (rvol&~0x003f)|speakers_vol_table[volume]); + wm8994_read(0x0020, &lvol); + wm8994_read(0x0021, &rvol); + wm8994_write(0x0020, (lvol&~0x003f)|earpiece_vol_table[volume]); + wm8994_write(0x0021, (rvol&~0x003f)|earpiece_vol_table[volume]); + } +} - wm8994_write(0x06 ,0x0001); +static void wm8994_check_channel(void) +{ + wm8994_codec_fnc_t **wm8994_fnc_ptr = wm8994_codec_sequence; + unsigned char wm8994_mode = wm8994_current_mode; - wm8994_write(0x02 ,0x0300); - wm8994_write(0x03 ,0x0030); - wm8994_write(0x04 ,0x3301);//ADCL off - wm8994_write(0x05 ,0x3301);//DACL off + DBG("%s--%d::Enter\n",__FUNCTION__,__LINE__); - wm8994_write(0x2A ,0x0005); + if (wm8994_mode < wm8994_AP_to_headset || + wm8994_mode > wm8994_BT_baseband_and_record) + { + wm8994_mode = wm8994_recorder_and_AP_to_speakers; + printk("%s--%d--: Wm8994 set channel with null mode\n",__FUNCTION__,__LINE__); + } - wm8994_write(0x313 ,0x00F0); - wm8994_write(0x314 ,0x0020); - wm8994_write(0x315 ,0x0020); + wm8994_fnc_ptr += wm8994_mode; - wm8994_write(0x2E ,0x0001); - wm8994_write(0x420 ,0x0000); - wm8994_write(0x520 ,0x0000); - wm8994_write(0x601 ,0x0001); - wm8994_write(0x602 ,0x0001); - wm8994_write(0x604 ,0x0001); - wm8994_write(0x605 ,0x0001); - wm8994_write(0x607 ,0x0002); - wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 - wm8994_write(0x612, 0x01C0); //DAC2 Left Volume bit0~7 - wm8994_write(0x613, 0x01C0); //DAC2 Right Volume bit0~7 + while(isSetChannelErr) { + gpio_request(WM_EN_PIN, NULL); + gpio_direction_output(WM_EN_PIN,GPIO_LOW); + gpio_free(WM_EN_PIN); + msleep(50); - wm8994_write(0x312 ,0x4000); + gpio_request(WM_EN_PIN, NULL); + gpio_direction_output(WM_EN_PIN,GPIO_HIGH); + gpio_free(WM_EN_PIN); - wm8994_write(0x606 ,0x0001); - wm8994_write(0x607 ,0x0003);//R channel for data mix/CPU record data + msleep(50); + wm8994_current_mode = null; + isSetChannelErr = false; -////////////HP output test - wm8994_write(0x01 ,0x0303); - wm8994_write(0x4C ,0x9F25); - wm8994_write(0x60 ,0x00EE); -///////////end HP test + (*wm8994_fnc_ptr)() ; + } + DBG("%s--%d::Exit\n",__FUNCTION__,__LINE__); } -void BT_baseband_and_record(void) //pcmbaseband +static int wm8994_powerdown(void) { - DBG("%s::%d\n",__FUNCTION__,__LINE__); + printk("Power down wm8994\n"); - if(wm8994_current_mode==wm8994_BT_baseband_and_record)return; - wm8994_current_mode=wm8994_BT_baseband_and_record; - wm8994_reset(); - msleep(50); + isWM8994SetChannel = true; - wm8994_write(0x01 ,0x0003); - msleep (50); + wm8994_write(0x00, 0x0000); + msleep(50); - wm8994_write(0x200 ,0x0001); - wm8994_write(0x221 ,0x0700);//MCLK=12MHz - wm8994_write(0x222 ,0x3127); - wm8994_write(0x223 ,0x0100); - wm8994_write(0x220 ,0x0004); - msleep (50); - wm8994_write(0x220 ,0x0005); + wm8994_write(0x01, 0x0003); + msleep(50); + wm8994_write(0x01, 0x0023); - wm8994_write(0x02 ,0x0000); - wm8994_write(0x200 ,0x0011);// AIF1 MCLK=FLL1 - wm8994_write(0x210 ,0x0009);// LRCK=8KHz, Rate=MCLK/1536 - wm8994_write(0x300 ,0x4018);// DSP/PCM 16bits + if (wm8994_current_mode == wm8994_AP_to_headset || + wm8994_current_mode == wm8994_AP_to_speakers_and_headset || + wm8994_current_mode == wm8994_recorder_and_AP_to_headset) { + wm8994_current_mode = wm8994_powerdown_headset; + } else if (wm8994_current_mode == wm8994_AP_to_speakers || + wm8994_current_mode == wm8994_recorder_and_AP_to_speakers) { + wm8994_current_mode = wm8994_powerdown_speakers; + } else { + wm8994_current_mode = wm8994_powerdown_speakers; + } - wm8994_write(0x204 ,0x0011);// AIF2 MCLK=FLL1 - wm8994_write(0x211 ,0x0009);// LRCK=8KHz, Rate=MCLK/1536 - wm8994_write(0x310 ,0x4118);// DSP/PCM 16bits - wm8994_write(0x208 ,0x000F); + isWM8994SetChannel = false; + return 0; +} -/////AIF1 - wm8994_write(0x700 ,0x8101); -/////AIF2 - wm8994_write(0x702 ,0xC100); - wm8994_write(0x703 ,0xC100); - wm8994_write(0x704 ,0xC100); - wm8994_write(0x706 ,0x4100); -/////AIF3 - wm8994_write(0x707 ,0xA100); - wm8994_write(0x708 ,0xA100); - wm8994_write(0x709 ,0xA100); - wm8994_write(0x70A ,0xA100); +static void wm8994_work(struct work_struct *work) +{ + DBG("Enter::wm8994 work\n"); - wm8994_write(0x06 ,0x0001); - wm8994_write(0x02 ,0x0300); - wm8994_write(0x03 ,0x0030); - wm8994_write(0x04 ,0x3301);//ADCL off - wm8994_write(0x05 ,0x3301);//DACL off - wm8994_write(0x2A ,0x0005); + switch(wm8994_work_type) { + case WM8994_WORK_FIRSTINCALL: + if (wm8994_current_mode == wm8994_BT_baseband) { + wm8994_write(0x602, 0x0001); + } else { + wm8994_write(0x601, 0x0001); + wm8994_write(0x602, 0x0001); + } + break; - wm8994_write(0x313 ,0x00F0); - wm8994_write(0x314 ,0x0020); - wm8994_write(0x315 ,0x0020); + case WM8994_WORK_SHUTDOWN: + wm8994_powerdown();//close codec + break; - wm8994_write(0x2E ,0x0001); - wm8994_write(0x420 ,0x0000); - wm8994_write(0x520 ,0x0000); - wm8994_write(0x602 ,0x0001); - wm8994_write(0x604 ,0x0001); - wm8994_write(0x605 ,0x0001); - wm8994_write(0x607 ,0x0002); - wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 - wm8994_write(0x612, 0x01C0); //DAC2 Left Volume bit0~7 - wm8994_write(0x613, 0x01C0); //DAC2 Right Volume bit0~7 + case WM8994_WORK_STARTUP: + isWM8994SetChannel = true; - wm8994_write(0x312 ,0x4000); + if (wm8994_current_mode == wm8994_powerdown_speakers) { + recorder_and_AP_to_speakers(); + } else if (wm8994_current_mode == wm8994_powerdown_headset) { + recorder_and_AP_to_headset(); + } - wm8994_write(0x606 ,0x0001); - wm8994_write(0x607 ,0x0003);//R channel for data mix/CPU record data -////////////HP output test - wm8994_write(0x01 ,0x0303); - wm8994_write(0x4C ,0x9F25); - wm8994_write(0x60 ,0x00EE); -///////////end HP test + wm8994_check_channel(); + isWM8994SetChannel = false; + break; + default: + break; + } + + wm8994_work_type = WM8994_WORK_NULL; } -#endif //PCM_BB #define SOC_DOUBLE_SWITCH_WM8994CODEC(xname, route) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ @@ -2679,121 +2659,114 @@ int snd_soc_get_route(struct snd_kcontrol *kcontrol, int snd_soc_put_route(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct wm8994_priv *wm8994 = wm8994_codec->private_data; char route = kcontrol->private_value & 0xff; - wake_lock(&wm8994->wm8994_on_wake); - mutex_lock(&wm8994->route_lock); - wm8994->kcontrol = kcontrol;//save rount - //before set the route -- disable PA - PA_ctrl(GPIO_LOW); + DBG("%s--%d::Enter : route = %d \n",__FUNCTION__, __LINE__, route); + +#ifdef WM8994_PROC + wm8994_current_route = route; +#endif + + if (wm8994_work_type != WM8994_WORK_FIRSTINCALL) { + cancel_delayed_work_sync(&delayed_work); + wm8994_work_type = WM8994_WORK_NULL; + } - //set rount + isWM8994SetChannel = true; switch(route) { - case SPEAKER_NORMAL: //AP-> 8994Codec -> Speaker - case SPEAKER_RINGTONE: - case EARPIECE_RINGTONE: + /* Speaker*/ + case SPEAKER_NORMAL: //AP-> 8994Codec -> Speaker recorder_and_AP_to_speakers(); break; - case SPEAKER_INCALL: //BB-> 8994Codec -> Speaker + + case SPEAKER_INCALL: //BB-> 8994Codec -> Speaker mainMIC_to_baseband_to_speakers(); - break; - case HEADSET_NORMAL: //AP-> 8994Codec -> Headset + break; + + /* Headset */ + case HEADSET_NORMAL: //AP-> 8994Codec -> Headset recorder_and_AP_to_headset(); break; - case HEADSET_INCALL: //AP-> 8994Codec -> Headset - if(Headset_isMic()) + case HEADSET_INCALL: //AP-> 8994Codec -> Headset + //if (isHSKey_MIC()) handsetMIC_to_baseband_to_headset(); - else - mainMIC_to_baseband_to_headset(); - break; - case EARPIECE_INCALL: //BB-> 8994Codec -> EARPIECE + //else + // mainMIC_to_baseband_to_headset(); + break; + + /* Earpiece*/ + case EARPIECE_INCALL: //:BB-> 8994Codec -> EARPIECE +#ifdef CONFIG_SND_NO_EARPIECE + mainMIC_to_baseband_to_speakers(); +#else mainMIC_to_baseband_to_earpiece(); +#endif break; - case EARPIECE_NORMAL: //BB-> 8994Codec -> EARPIECE - switch(wm8994_current_mode) - { - case wm8994_handsetMIC_to_baseband_to_headset: - case wm8994_mainMIC_to_baseband_to_headset: - recorder_and_AP_to_headset(); - break; - default: - recorder_and_AP_to_speakers(); - break; - } - break; - case BLUETOOTH_SCO_INCALL: //BB-> 8994Codec -> BLUETOOTH_SCO + + case EARPIECE_NORMAL: //:BB-> 8994Codec -> EARPIECE + if (wm8994_current_mode == wm8994_handsetMIC_to_baseband_to_headset|| + wm8994_mainMIC_to_baseband_to_headset) + recorder_and_AP_to_headset(); + else if (wm8994_current_mode == wm8994_recorder_and_AP_to_speakers|| + wm8994_current_mode == wm8994_recorder_and_AP_to_speakers) + break; + else { + recorder_and_AP_to_speakers(); + printk("%s--%d--: wm8994 with null mode\n",__FUNCTION__,__LINE__); + } + break; + + + /* BLUETOOTH_SCO*/ + case BLUETOOTH_SCO_INCALL: //BB-> 8994Codec -> BLUETOOTH_SCO BT_baseband(); - break; + break; + + /* BLUETOOTH_A2DP*/ + case BLUETOOTH_A2DP_NORMAL: //AP-> 8994Codec -> BLUETOOTH_A2DP + break; + case MIC_CAPTURE: - switch(wm8994_current_mode) - { - case wm8994_AP_to_headset: - recorder_and_AP_to_headset(); - break; - case wm8994_AP_to_speakers: - recorder_and_AP_to_speakers(); - break; - case wm8994_recorder_and_AP_to_speakers: - case wm8994_recorder_and_AP_to_headset: - break; - default: - recorder_and_AP_to_speakers(); - break; + if (wm8994_current_mode == wm8994_AP_to_headset || + wm8994_current_mode == wm8994_recorder_and_AP_to_headset || + wm8994_current_mode == wm8994_powerdown_headset) + recorder_and_AP_to_headset(); + else if (wm8994_current_mode == wm8994_AP_to_speakers || + wm8994_current_mode == wm8994_recorder_and_AP_to_speakers || + wm8994_current_mode == wm8994_powerdown_speakers) + recorder_and_AP_to_speakers(); + else { + printk("%s--%d--: wm8994 with error mode\n",__FUNCTION__,__LINE__); + recorder_and_AP_to_speakers(); } break; + + case EARPIECE_RINGTONE: + recorder_and_AP_to_speakers(); + break; + case HEADSET_RINGTONE: AP_to_speakers_and_headset(); break; - case BLUETOOTH_A2DP_NORMAL: //AP-> 8994Codec -> BLUETOOTH_A2DP - case BLUETOOTH_A2DP_INCALL: - case BLUETOOTH_SCO_NORMAL: - printk("this route not use\n"); - break; - default: - printk("wm8994 error route!!!\n"); - goto out; - } - if(wm8994->RW_status == ERROR) - {//Failure to read or write, will re-power on wm8994 - cancel_delayed_work_sync(&wm8994->wm8994_delayed_work); - wm8994->work_type = SNDRV_PCM_TRIGGER_PAUSE_PUSH; - schedule_delayed_work(&wm8994->wm8994_delayed_work, msecs_to_jiffies(10)); - goto out; - } - //after set the route -- enable PA - switch(route) - { - case MIC_CAPTURE: - if(wm8994_current_mode == wm8994_AP_to_headset) - break; - case EARPIECE_NORMAL: - if(wm8994_current_mode == wm8994_handsetMIC_to_baseband_to_headset|| - wm8994_current_mode == wm8994_mainMIC_to_baseband_to_headset) - break; - case SPEAKER_NORMAL: case SPEAKER_RINGTONE: - case SPEAKER_INCALL: - case EARPIECE_RINGTONE: - case HEADSET_RINGTONE: - msleep(50); - PA_ctrl(GPIO_HIGH); + recorder_and_AP_to_speakers(); break; - default: + + default: + //codec_daout_route(); break; - } -out: - mutex_unlock(&wm8994->route_lock); - wake_unlock(&wm8994->wm8994_on_wake); + } + wm8994_check_channel(); + + isWM8994SetChannel = false; + return 0; } -/* - * WM8994 Controls - */ static const struct snd_kcontrol_new wm8994_snd_controls[] = { + SOC_DOUBLE_SWITCH_WM8994CODEC("Speaker incall Switch", SPEAKER_INCALL), SOC_DOUBLE_SWITCH_WM8994CODEC("Speaker normal Switch", SPEAKER_NORMAL), @@ -2816,263 +2789,82 @@ SOC_DOUBLE_SWITCH_WM8994CODEC("Speaker ringtone Switch",SPEAKER_RINGTONE), SOC_DOUBLE_SWITCH_WM8994CODEC("Headset ringtone Switch",HEADSET_RINGTONE), }; -static void wm8994_codec_set_volume(unsigned char system_type,unsigned char volume) -{ - struct wm8994_priv *wm8994 = wm8994_codec->private_data; -// DBG("%s:: system_type = %d volume = %d \n",__FUNCTION__,system_type,volume); - - if(system_type == VOICE_CALL) - { - if(volume <= call_maxvol) - wm8994->call_vol=volume; - else - { - printk("%s----%d::max value is 5\n",__FUNCTION__,__LINE__); - wm8994->call_vol=call_maxvol; - } - if(wm8994_current_mode<=wm8994_mainMIC_to_baseband_to_speakers_and_record&& - wm8994_current_mode>=wm8994_handsetMIC_to_baseband_to_headset) - wm8994_set_volume(wm8994_current_mode,wm8994->call_vol,call_maxvol); - } - else if(system_type == BLUETOOTH_SCO) - { - if(volume <= BT_call_maxvol) - wm8994->BT_call_vol = volume; - else - { - printk("%s----%d::max value is 15\n",__FUNCTION__,__LINE__); - wm8994->BT_call_vol = BT_call_maxvol; - } - if(wm8994_current_mode=wm8994_BT_baseband) - wm8994_set_volume(wm8994_current_mode,wm8994->BT_call_vol,BT_call_maxvol); - } - else - { - printk("%s----%d::system type error!\n",__FUNCTION__,__LINE__); - return; - } -} - -/* - * Note that this should be called from init rather than from hw_params. - */ -static int wm8994_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 wm8994_priv *wm8994 = codec->private_data; - -// DBG("%s----%d\n",__FUNCTION__,__LINE__); - - switch (clk_id) { - case WM8994_SYSCLK_MCLK1: - wm8994->sysclk = WM8994_SYSCLK_MCLK1; - wm8994->mclk = freq; - // DBG("AIF1 using MCLK1 at %uHz\n", freq); - break; - - case WM8994_SYSCLK_MCLK2: - //TODO: Set GPIO AF - wm8994->sysclk = WM8994_SYSCLK_MCLK2; - wm8994->mclk = freq; - // DBG("AIF1 using MCLK2 at %uHz\n",freq); - break; - - case WM8994_SYSCLK_FLL1: - wm8994->sysclk = WM8994_SYSCLK_FLL1; - wm8994->mclk = freq; - // DBG("AIF1 using FLL1 at %uHz\n",freq); - break; - - case WM8994_SYSCLK_FLL2: - wm8994->sysclk = WM8994_SYSCLK_FLL2; - wm8994->mclk = freq; - // DBG("AIF1 using FLL2 at %uHz\n",freq); - break; - - default: - DBG("ERROR:AIF3 shares clocking with AIF1/2. \n"); - return -EINVAL; - } - - return 0; -} - -static int wm8994_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int fmt) -{ - struct snd_soc_codec *codec = codec_dai->codec; - struct wm8994_priv *wm8994 = codec->private_data; -// DBG("Enter %s---%d\n",__FUNCTION__,__LINE__); - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - wm8994->fmt = SND_SOC_DAIFMT_CBS_CFS; - break; - case SND_SOC_DAIFMT_CBM_CFM: - wm8994->fmt = SND_SOC_DAIFMT_CBM_CFM; - break; - default: - return -EINVAL; - } - - - return 0; -} - -static int wm8994_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_codec *codec = dai->codec; - struct wm8994_priv *wm8994 = codec->private_data; - -// DBG("Enter %s::%s---%d\n",__FILE__,__FUNCTION__,__LINE__); - - wm8994->rate = params_rate(params); -// DBG("Sample rate is %dHz\n",wm8994->rate); - - return 0; -} - -static int wm8994_mute(struct snd_soc_dai *dai, int mute) -{ - return 0; -} - static int wm8994_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { + codec->bias_level = level; return 0; } static int wm8994_trigger(struct snd_pcm_substream *substream, - int cmd, + int status, struct snd_soc_dai *dai) { -// struct snd_soc_pcm_runtime *rtd = substream->private_data; -// struct snd_soc_dai_link *machine = rtd->dai; -// struct snd_soc_dai *codec_dai = machine->codec_dai; - struct snd_soc_codec *codec = dai->codec; - struct wm8994_priv *wm8994 = codec->private_data; - - if(wm8994_current_mode >= wm8994_handsetMIC_to_baseband_to_headset && wm8994_current_mode != null) - return 0; -// DBG("%s::%d status = %d substream->stream '%s'\n",__FUNCTION__,__LINE__, -// cmd, substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? "PLAYBACK":"CAPTURE"); - - switch(cmd) - { - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_START: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - { - if(wm8994->playback_active == cmd) - return 0; - wm8994->playback_active = cmd; - } - else - { - if(wm8994->capture_active == cmd) - return 0; - wm8994->capture_active = cmd; - } - break; - default: - return 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai_link *machine = rtd->dai; + struct snd_soc_dai *codec_dai = machine->codec_dai; + unsigned int playback_active = codec_dai->playback.active, capture_active = codec_dai->capture.active; + + DBG("%s::%d status = %d substream->stream '%s'\n",__FUNCTION__,__LINE__, + status, substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? "PLAYBACK":"CAPTURE"); + + if (status == 1 || status == 0) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + + codec_dai->playback.active = status; + }else { + + codec_dai->capture.active = status; + } } - if (!wm8994->playback_active && - !wm8994->capture_active ) - {//suspend + if (!codec_dai->playback.active && !codec_dai->capture.active + && (playback_active || capture_active) + && (wm8994_current_mode < wm8994_handsetMIC_to_baseband_to_headset)) { DBG("It's going to power down wm8994\n"); - cancel_delayed_work_sync(&wm8994->wm8994_delayed_work); - wm8994->work_type = SNDRV_PCM_TRIGGER_STOP; - schedule_delayed_work(&wm8994->wm8994_delayed_work, msecs_to_jiffies(2000)); - } - else if (wm8994->playback_active - || wm8994->capture_active) - {//resume - DBG("Power up wm8994\n"); - if(wm8994->work_type == SNDRV_PCM_TRIGGER_STOP) - cancel_delayed_work_sync(&wm8994->wm8994_delayed_work); - wm8994->work_type = SNDRV_PCM_TRIGGER_START; - schedule_delayed_work(&wm8994->wm8994_delayed_work, msecs_to_jiffies(0)); - } - return 0; -} + cancel_delayed_work_sync(&delayed_work); -static void wm8994_work_fun(struct work_struct *work) -{ - struct snd_soc_codec *codec = wm8994_codec; - struct wm8994_priv *wm8994 = codec->private_data; - struct wm8994_pdata *pdata = wm8994->pdata; - int error_count = 5; -// DBG("Enter %s---%d = %d\n",__FUNCTION__,__LINE__,wm8994_current_mode); + wm8994_work_type = WM8994_WORK_SHUTDOWN; + /* when codec is not using , close it */ - switch(wm8994->work_type) - { - case SNDRV_PCM_TRIGGER_STOP: - if(wm8994_current_mode > wm8994_FM_to_speakers_and_record) - return; - // DBG("wm8994 shutdown\n"); - mutex_lock(&wm8994->route_lock); - PA_ctrl(GPIO_LOW); - msleep(50); - wm8994_write(0,0); - msleep(50); - wm8994_write(0x01, 0x0033); - wm8994_current_mode = null;//Automatically re-set the wake-up time - mutex_unlock(&wm8994->route_lock); - break; - case SNDRV_PCM_TRIGGER_START: - break; - case SNDRV_PCM_TRIGGER_RESUME: - msleep(100); - gpio_request(pdata->Power_EN_Pin, NULL); - gpio_direction_output(pdata->Power_EN_Pin,GPIO_HIGH); - gpio_free(pdata->Power_EN_Pin); - msleep(100); - wm8994_current_mode = null; - snd_soc_put_route(wm8994->kcontrol,NULL); - break; - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - while(error_count) - { - if( wm8994_reset_ldo() == 0) - { - wm8994_current_mode = null; - snd_soc_put_route(wm8994->kcontrol,NULL); - break; - } - error_count --; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + + queue_delayed_work(wm8994_workq, &delayed_work, + msecs_to_jiffies(1000)); + } else { + queue_delayed_work(wm8994_workq, &delayed_work, + msecs_to_jiffies(3000)); } - if(error_count == 0) - { - PA_ctrl(GPIO_LOW); - printk("wm8994 Major problems, give me log,tks, -- qjb\n"); - } - break; - default: - break; + } else if (codec_dai->playback.active || codec_dai->capture.active) { + + if (wm8994_work_type == WM8994_WORK_SHUTDOWN) + cancel_delayed_work_sync(&delayed_work); + + if (wm8994_current_mode == wm8994_powerdown_speakers || + wm8994_current_mode == wm8994_powerdown_headset) { + + printk("Power up wm8994\n"); + + wm8994_work_type = WM8994_WORK_STARTUP; + queue_delayed_work(wm8994_workq, &delayed_work, + msecs_to_jiffies(0)); + } } + + return 0; } -#define WM8994_RATES SNDRV_PCM_RATE_8000_48000 +#define WM8994_RATES SNDRV_PCM_RATE_48000 + #define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) static struct snd_soc_dai_ops wm8994_ops = { - .hw_params = wm8994_pcm_hw_params, - .set_fmt = wm8994_set_dai_fmt, - .set_sysclk = wm8994_set_dai_sysclk, - .digital_mute = wm8994_mute, - .trigger = wm8994_trigger, /*add by qiuen for volume*/ - .set_volume = wm8994_codec_set_volume, + .set_volume = wm8994_codec_set_volume, + .trigger = wm8994_trigger, }; struct snd_soc_dai wm8994_dai = { @@ -3100,23 +2892,21 @@ static int wm8994_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; - struct wm8994_priv *wm8994 = codec->private_data; - struct wm8994_pdata *pdata = wm8994->pdata; - - cancel_delayed_work_sync(&wm8994->wm8994_delayed_work); - - if(wm8994_current_mode>wm8994_FM_to_speakers_and_record && - wm8994_current_mode< null )//incall status,wm8994 not suspend - return 0; - DBG("%s----%d\n",__FUNCTION__,__LINE__); - - wm8994->work_type = SNDRV_PCM_TRIGGER_SUSPEND; - PA_ctrl(GPIO_LOW); + + cancel_delayed_work_sync(&delayed_work); + + wm8994_work_type = WM8994_WORK_NULL; + + isWM8994SetChannel = true; + + wm8994_set_bias_level(codec,SND_SOC_BIAS_OFF); wm8994_write(0x00, 0x00); - - gpio_request(pdata->Power_EN_Pin, NULL); - gpio_direction_output(pdata->Power_EN_Pin,GPIO_LOW); - gpio_free(pdata->Power_EN_Pin); + msleep(50); + + gpio_request(WM_EN_PIN, NULL); + gpio_direction_output(WM_EN_PIN,GPIO_LOW); + gpio_free(WM_EN_PIN); + msleep(50); return 0; @@ -3126,228 +2916,502 @@ static int wm8994_resume(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_codec *codec = socdev->card->codec; - struct wm8994_priv *wm8994 = codec->private_data; -// struct wm8994_pdata *pdata = wm8994->pdata; - if(wm8994_current_mode>wm8994_FM_to_speakers_and_record && - wm8994_current_mode< null )//incall status,wm8994 not suspend - return 0; - DBG("%s----%d\n",__FUNCTION__,__LINE__); - cancel_delayed_work_sync(&wm8994->wm8994_delayed_work); - wm8994->work_type = SNDRV_PCM_TRIGGER_RESUME; - schedule_delayed_work(&wm8994->wm8994_delayed_work, msecs_to_jiffies(0)); + gpio_request(WM_EN_PIN, NULL); + gpio_direction_output(WM_EN_PIN,GPIO_HIGH); + gpio_free(WM_EN_PIN); + + msleep(50); + + wm8994_set_bias_level(codec,SND_SOC_BIAS_STANDBY); + + wm8994_powerdown(); + isWM8994SetChannel = false; return 0; } +static struct snd_soc_codec *wm8994_codec; + #ifdef WM8994_PROC -static ssize_t wm8994_proc_write(struct file *file, const char __user *buffer, - unsigned long len, void *data) -{ - char *cookie_pot; - char *p; - int reg; - int value; - struct snd_kcontrol kcontrol; - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - struct wm8994_pdata *pdata = wm8994->pdata; - - cookie_pot = (char *)vmalloc( len ); - if (!cookie_pot) - { - return -ENOMEM; - } - else - { - if (copy_from_user( cookie_pot, buffer, len )) - return -EFAULT; - } - - switch(cookie_pot[0]) - { - case 'd': - case 'D': - debug_write_read ++; - debug_write_read %= 2; - if(debug_write_read != 0) - DBG("Debug read and write reg on\n"); - else - DBG("Debug read and write reg off\n"); - break; + +void wm8994_read_printk(unsigned short reg) { + unsigned short value; + wm8994_read(reg, &value); + printk("wm8994_read_printk :: reg = 0x%x, value = 0x%x\n", reg, value); +} + +void read_test(void) { + wm8994_read_printk(0x200); + wm8994_read_printk(0x220); + wm8994_read_printk(0x221); + wm8994_read_printk(0x222); + wm8994_read_printk(0x223); + wm8994_read_printk(0x210); + wm8994_read_printk(0x300); + wm8994_read_printk(0x303); + wm8994_read_printk(0x304); + wm8994_read_printk(0x305); + wm8994_read_printk(0x302); + wm8994_read_printk(0x700); + wm8994_read_printk(0x208); +} + +static int CheckCommand(const char __user *buffer) +{ + char procadd = 0; + unsigned short eqvol; + unsigned char wm8994_proc_mode; + wm8994_codec_fnc_t **wm8994_fnc_ptr = wm8994_codec_sequence; + + switch(*buffer) { case 'r': case 'R': - DBG("Read reg debug\n"); - if(cookie_pot[1] ==':') - { - debug_write_read = 1; - strsep(&cookie_pot,":"); - while((p=strsep(&cookie_pot,","))) - { - wm8994_read(simple_strtol(p,NULL,16),(unsigned short *)&value); - } - debug_write_read = 0;; - DBG("\n"); + read_test(); + return 0; + break; + + case 'n': + case 'N': + if (*(buffer+1)=='+') { + procadd = 3; + } else if (*(buffer+1)=='-') { + procadd = -3; + } else { + printk("Please press '+' or '-' follow 'n'!\n"); + return -1; } - else - { - DBG("Error Read reg debug.\n"); - DBG("For example: echo 'r:22,23,24,25'>wm8994_ts\n"); + switch(wm8994_current_route) { + case HEADSET_NORMAL: + if (procadd == 3) + headset_normal_vol += 3; + else + headset_normal_vol -= 3; + + if (headset_normal_vol > 6) + headset_normal_vol = 6; + else if (headset_normal_vol < -57) + headset_normal_vol = -57; + + printk("headset_normal_vol = %ddB \n",headset_normal_vol); + break; + + case SPEAKER_NORMAL: + case EARPIECE_NORMAL: + case SPEAKER_RINGTONE: + case EARPIECE_RINGTONE: + case BLUETOOTH_SCO_INCALL: + if (procadd == 3) + speaker_normal_vol += 3; + else + speaker_normal_vol -= 3; + + if (speaker_normal_vol > 6) + speaker_normal_vol = 6; + else if (speaker_normal_vol < -57) + speaker_normal_vol = -57; + + printk("speaker_normal_vol = %ddB \n",speaker_normal_vol); + break; + + case HEADSET_RINGTONE: + if (procadd == 3) { + headset_normal_vol += 3; + speaker_normal_vol += 3; + } else { + headset_normal_vol -= 3; + speaker_normal_vol -= 3; + } + + if (speaker_normal_vol > 6) + speaker_normal_vol = 6; + else if (speaker_normal_vol < -57) + speaker_normal_vol = -57; + if (headset_normal_vol > 6) + headset_normal_vol = 6; + else if (headset_normal_vol < -57) + headset_normal_vol = -57; + + printk("headset_normal_vol = %ddB \n",headset_normal_vol); + printk("speaker_normal_vol = %ddB \n",speaker_normal_vol); + break; + + default: + printk("Current channel does not match to normal mode!\n"); + return -1; } break; - case 'w': - case 'W': - DBG("Write reg debug\n"); - if(cookie_pot[1] ==':') - { - debug_write_read = 1; - strsep(&cookie_pot,":"); - while((p=strsep(&cookie_pot,"="))) - { - reg = simple_strtol(p,NULL,16); - p=strsep(&cookie_pot,","); - value = simple_strtol(p,NULL,16); - wm8994_write(reg,value); - } - debug_write_read = 0;; - DBG("\n"); + + case 'i': + case 'I': + if (*(buffer+1)=='+') { + procadd = 3; + } else if (*(buffer+1)=='-') { + procadd = -3; + } else { + printk("Please press '+' or '-' follow 'i'!\n"); + return -1; } - else - { - DBG("Error Write reg debug.\n"); - DBG("For example: w:22=0,23=0,24=0,25=0\n"); + + switch(wm8994_current_route) { + case HEADSET_INCALL: + if (procadd == 3) + headset_incall_vol += 3; + else + headset_incall_vol -= 3; + + if (headset_incall_vol > 6) + headset_incall_vol = 6; + else if (headset_incall_vol < -12) + headset_incall_vol = -12; + + printk("headset_incall_vol = %ddB \n",headset_incall_vol); + break; + +#if defined(CONFIG_SND_INSIDE_EARPIECE)||defined(CONFIG_SND_OUTSIDE_EARPIECE) + case EARPIECE_INCALL: + if (procadd == 3) + earpiece_incall_vol += 3; + else + earpiece_incall_vol -= 3; + + if (earpiece_incall_vol>6) + earpiece_incall_vol = 6; + else if (earpiece_incall_vol<-21) + earpiece_incall_vol = -21; + + printk("earpiece_incall_vol = %ddB \n",earpiece_incall_vol); + break; +#endif + case SPEAKER_INCALL: + if (procadd == 3) + speaker_incall_vol += 3; + else + speaker_incall_vol -= 3; + + if (speaker_incall_vol > 12) + speaker_incall_vol = 12; + else if (speaker_incall_vol < -21) + speaker_incall_vol = -21; + + printk("speaker_incall_vol = %ddB \n",speaker_incall_vol); + break; + + case BLUETOOTH_SCO_INCALL: + if (procadd == 3) + BT_incall_vol += 3; + else + BT_incall_vol -= 3; + + if (BT_incall_vol > 30) + BT_incall_vol = 30; + else if (BT_incall_vol < -16) + BT_incall_vol = -16; + + printk("BT_incall_vol = %ddB \n",BT_incall_vol); + break; + + default: + printk("Current channel does not match to incall mode!\n"); + return -1; } - break; - case 'p': - case 'P': - if(cookie_pot[1] =='-') - { - kcontrol.private_value = simple_strtol(&cookie_pot[2],NULL,10); - printk("kcontrol.private_value = %ld\n",kcontrol.private_value); - if(kcontrol.private_valueHEADSET_RINGTONE) - { - printk("route error\n"); - goto help; - } - snd_soc_put_route(&kcontrol,NULL); + break; + + case 'm': + case 'M': + if (*(buffer+1)=='+') { + procadd = 3; + } else if (*(buffer+1)=='-') { + procadd = -3; + } else { + printk("Please press '+' or '-' follow 'm'!\n"); + return -1; + } + switch(wm8994_current_route) { + case HEADSET_INCALL: + if (procadd == 3) + headset_incall_mic_vol += 3; + else + headset_incall_mic_vol -= 3; + + if (speaker_incall_mic_vol > 30) + speaker_incall_mic_vol = 30; + else if (speaker_incall_mic_vol < -22) + speaker_incall_mic_vol = -22; + + printk("speaker_incall_mic_vol = %ddB \n",speaker_incall_mic_vol); break; - } - else if(cookie_pot[1] ==':') - { - strsep(&cookie_pot,":"); - while((p=strsep(&cookie_pot,","))) - { - kcontrol.private_value = simple_strtol(p,NULL,10); - printk("kcontrol.private_value = %ld\n",kcontrol.private_value); - if(kcontrol.private_valueHEADSET_RINGTONE) - { - printk("route error\n"); - goto help; - } - snd_soc_put_route(&kcontrol,NULL); - } + + case EARPIECE_INCALL: + if (procadd == 3) + speaker_incall_mic_vol += 3; + else + speaker_incall_mic_vol -= 3; + + if (speaker_incall_mic_vol > 30) + speaker_incall_mic_vol = 30; + else if (speaker_incall_mic_vol < -22) + speaker_incall_mic_vol = -22; + + printk("speaker_incall_mic_vol = %ddB \n",speaker_incall_mic_vol); break; - } - else - { - goto help; + + case SPEAKER_INCALL: + if (procadd == 3) + speaker_incall_mic_vol += 3; + else + speaker_incall_mic_vol -= 3; + + if (speaker_incall_mic_vol > 30) + speaker_incall_mic_vol = 30; + else if (speaker_incall_mic_vol < -22) + speaker_incall_mic_vol = -22; + + printk("speaker_incall_mic_vol = %ddB \n",speaker_incall_mic_vol); + break; + + case BLUETOOTH_SCO_INCALL: + if (procadd == 3) + BT_incall_mic_vol += 3; + else + BT_incall_mic_vol -= 3; + + if (BT_incall_mic_vol > 6) + BT_incall_mic_vol = 6; + else if (BT_incall_mic_vol < -57) + BT_incall_mic_vol = -57; + + printk("BT_incall_mic_vol = %ddB \n",BT_incall_mic_vol); + break; + + case MIC_CAPTURE: + if (procadd == 3) + recorder_vol += 3; + else + recorder_vol -= 3; + + if (recorder_vol > 60) + recorder_vol = 60; + else if (recorder_vol < -16) + recorder_vol = -16; + + printk("recorder_vol = %ddB \n",recorder_vol); + break; + + default: + printk("Current channel does not match to mic mode!\n"); + return -1; } - help: - printk("snd_soc_put_route list\n"); - printk("SPEAKER_INCALL--\"p-0\",\nSPEAKER_NORMAL--\"p-1\",\nHEADSET_INCALL--\"p-2\",\ - \nHEADSET_NORMAL--\"p-3\",\nEARPIECE_INCALL--\"p-4\",\nEARPIECE_NORMAL--\"p-5\",\ - \nBLUETOOTH_SCO_INCALL--\"p-6\",\nMIC_CAPTURE--\"p-10\",\nEARPIECE_RINGTONE--\"p-11\",\ - \nSPEAKER_RINGTONE--\"p-12\",\nHEADSET_RINGTONE--\"p-13\"\n"); break; - case 'F': - case 'f': - PA_ctrl(GPIO_HIGH); - FM_to_speakers(); + + case 'l': + case 'L': + printk("headset_normal_vol = %ddB \n",headset_normal_vol); + printk("speaker_normal_vol = %ddB \n",speaker_normal_vol); + printk("headset_incall_vol = %ddB \n",headset_incall_vol); +#if defined(CONFIG_SND_INSIDE_EARPIECE)||defined(CONFIG_SND_OUTSIDE_EARPIECE) + printk("earpiece_incall_vol = %ddB \n",earpiece_incall_vol); +#endif + printk("speaker_incall_vol = %ddB \n",speaker_incall_vol); + printk("BT_incall_vol = %ddB \n",BT_incall_vol); + printk("headset_incall_mic_vol = %ddB \n",headset_incall_mic_vol); + printk("speaker_incall_mic_vol = %ddB \n",speaker_incall_mic_vol); + printk("BT_incall_mic_vol = %ddB \n",BT_incall_mic_vol); + printk("recorder_vol = %ddB \n",recorder_vol); + printk("bank_vol[1] = %ddB \n",bank_vol[1]); + printk("bank_vol[2] = %ddB \n",bank_vol[2]); + printk("bank_vol[3] = %ddB \n",bank_vol[3]); + printk("bank_vol[4] = %ddB \n",bank_vol[4]); + printk("bank_vol[5] = %ddB \n",bank_vol[5]); + return 0; break; - case 'S': - case 's': - printk("Debug : Set volume begin\n"); - switch(cookie_pot[1]) - { - case '+': - if(cookie_pot[2] == '\n') - { - - } - else - { - value = simple_strtol(&cookie_pot[2],NULL,10); - printk("value = %d\n",value); - - } - break; - case '-': - if(cookie_pot[2] == '\n') - { - - } - else - { - value = simple_strtol(&cookie_pot[2],NULL,10); - printk("value = %d\n",value); - } - break; - default: - if(cookie_pot[1] == '=') - { - value = simple_strtol(&cookie_pot[2],NULL,10); - printk("value = %d\n",value); - } - else - printk("Help the set volume,Example: echo s+**>wm8994_ts,s=**>wm8994_ts,s-**>wm8994_ts\n"); - - break; - } - break; - case '1': - gpio_request(pdata->Power_EN_Pin, NULL); - gpio_direction_output(pdata->Power_EN_Pin,GPIO_LOW); - gpio_free(pdata->Power_EN_Pin); + + case 'c': + case 'C': + if (((*(buffer+1) == 't') || (*(buffer+1) == 'T')) && + ((*(buffer+2) == 'a') || (*(buffer+2) == 'A'))) { + if (earpiece_vol_table[5] == 0x013D) { + earpiece_vol_table[0] = 0x0127;//for cta + earpiece_vol_table[1] = 0x012D; + earpiece_vol_table[2] = 0x0130; + earpiece_vol_table[3] = 0x0135; + earpiece_vol_table[4] = 0x0137; + earpiece_vol_table[5] = 0x0135; + printk("CTA on,earpiece table value is:0x0127,0x012D,0x0130,0x0135,0x0137,0x0135\n"); + } + return 0; + break; + } + + cancel_delayed_work_sync(&delayed_work); + wm8994_work_type = WM8994_WORK_NULL; + isWM8994SetChannel = true; + + if (*(buffer+1) == '+') { + wm8994_proc_mode = wm8994_current_mode+1; + + if (wm8994_proc_mode > wm8994_BT_baseband) + wm8994_proc_mode = wm8994_AP_to_headset; + } else if (*(buffer+1) == '-') { + wm8994_proc_mode = wm8994_current_mode-1; + + if (wm8994_proc_mode > wm8994_BT_baseband) + wm8994_proc_mode = wm8994_BT_baseband; + } else { + if (wm8994_current_mode > wm8994_BT_baseband) { + wm8994_proc_mode = wm8994_recorder_and_AP_to_speakers; + } + wm8994_proc_mode = wm8994_current_mode; + wm8994_current_mode = null; + } + + wm8994_fnc_ptr += wm8994_proc_mode; + (*wm8994_fnc_ptr)(); + isWM8994SetChannel = false; + + return 0; break; - case '2': - gpio_request(pdata->Power_EN_Pin, NULL); - gpio_direction_output(pdata->Power_EN_Pin,GPIO_HIGH); - gpio_free(pdata->Power_EN_Pin); + + case 'e': + case 'E': + if (*(buffer+1)=='+') { + procadd = 3; + } else if (*(buffer+1)=='-') { + procadd = -3; + } else if (*(buffer+1)=='c') { + wm8994_write(0x0480, 0x0000); + return 0; + } else if (*(buffer+1)=='o') { + wm8994_write(0x0480, 0x0001|((bank_vol[1]+12)<<11)| + ((bank_vol[2]+12)<<6)|((bank_vol[3]+12)<<1)); + wm8994_write(0x0481, 0x0000|((bank_vol[4]+12)<<11)| + ((bank_vol[5]+12)<<6)); + return 0; + }else { + printk("Please press '+' '-' 'o' 'c' follow 'e'!\n"); + return -1; + } + + switch(*(buffer+2)) { + case '1': + if (procadd == 3) + bank_vol[1] += 3; + else + bank_vol[1] -= 3; + + if (bank_vol[1] > 12)bank_vol[1] = 12; + if (bank_vol[1] < -12)bank_vol[1] = -12; + + wm8994_read(0x0480, &eqvol); + wm8994_write(0x0480, (eqvol&0x07FF)|((bank_vol[1]+12)<<11)); + + printk("bank_vol[1] = %ddB \n",bank_vol[1]); + break; + + case '2': + if (procadd == 3) + bank_vol[2] += 3; + else + bank_vol[2] -= 3; + + if (bank_vol[2] > 12)bank_vol[2] = 12; + if (bank_vol[2] < -12)bank_vol[2] = -12; + + wm8994_read(0x0480, &eqvol); + wm8994_write(0x0480, (eqvol&0xF83F)|((bank_vol[2]+12)<<6)); + + printk("bank_vol[2] = %ddB \n",bank_vol[2]); + break; + + case '3': + if (procadd == 3) + bank_vol[3] += 3; + else + bank_vol[3] -= 3; + + if (bank_vol[3] > 12)bank_vol[3] = 12; + if (bank_vol[3] < -12)bank_vol[3] = -12; + + wm8994_read(0x0480, &eqvol); + wm8994_write(0x0480, (eqvol&0xFFC1)|((bank_vol[3]+12)<<1)); + + printk("bank_vol[3] = %ddB \n",bank_vol[3]); + break; + + case '4': + if (procadd == 3) + bank_vol[4] += 3; + else + bank_vol[4] -= 3; + + if (bank_vol[4] > 12)bank_vol[4] = 12; + if (bank_vol[4] < -12)bank_vol[4] = -12; + + wm8994_read(0x0481, &eqvol); + wm8994_write(0x0481, (eqvol&0x07FF)|((bank_vol[4]+12)<<11)); + + printk("bank_vol[4] = %ddB \n",bank_vol[4]); + break; + + case '5': + if (procadd == 3) + bank_vol[5] += 3; + else + bank_vol[5] -= 3; + + if (bank_vol[5] > 12)bank_vol[5] = 12; + if (bank_vol[5] < -12)bank_vol[5] = -12; + + wm8994_read(0x0481, &eqvol); + wm8994_write(0x0481, (eqvol&0xF83F)|((bank_vol[5]+12)<<6)); + + printk("bank_vol[5] = %ddB \n",bank_vol[5]); + break; + + default: + printk("Please press bank '1' to '5' follow 'e+' or 'e-'!\n"); + return -1; + } + return 0; break; + default: - DBG("Help for wm8994_ts .\n-->The Cmd list: \n"); - DBG("-->'d&&D' Open or close the debug\n"); - DBG("-->'r&&R' Read reg debug,Example: echo 'r:22,23,24,25'>wm8994_ts\n"); - DBG("-->'w&&W' Write reg debug,Example: echo 'w:22=0,23=0,24=0,25=0'>wm8994_ts\n"); - DBG("-->'ph&&Ph' cat snd_soc_put_route list\n"); - break; + printk("Please press 'n' 'i' 'm' 'l' 'c' 'e' !\n"); + return -1; } - return len; + wm8994_set_channel_vol(); + + return 0; } +static int wm8994_proc_write(struct file *file, const char __user *buffer, + unsigned long count, void *data) +{ + if (CheckCommand(buffer) != 0) { + printk("Write proc error !\n"); + return -1; + } + + return sizeof(buffer); +} static const struct file_operations wm8994_proc_fops = { .owner = THIS_MODULE, - //.open = snd_mem_proc_open, - //.read = seq_read, -//#ifdef CONFIG_PCI .write = wm8994_proc_write, -//#endif - //.llseek = seq_lseek, - //.release = single_release, }; -static int wm8994_proc_init(void){ +static int wm8994_proc_init(void) { struct proc_dir_entry *wm8994_proc_entry; wm8994_proc_entry = create_proc_entry("driver/wm8994_ts", 0777, NULL); - if(wm8994_proc_entry != NULL){ + if (wm8994_proc_entry != NULL) { wm8994_proc_entry->write_proc = wm8994_proc_write; return -1; - }else{ + }else { printk("create proc error !\n"); } @@ -3360,10 +3424,7 @@ static int wm8994_probe(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_codec *codec; - struct wm8994_priv *wm8994; - struct wm8994_pdata *pdata; int ret = 0; - #ifdef WM8994_PROC wm8994_proc_init(); @@ -3376,13 +3437,18 @@ static int wm8994_probe(struct platform_device *pdev) socdev->card->codec = wm8994_codec; codec = wm8994_codec; - wm8994 = codec->private_data; - pdata = wm8994->pdata; - //disable power_EN - gpio_request(pdata->Power_EN_Pin, NULL); - gpio_direction_output(pdata->Power_EN_Pin,GPIO_LOW); - gpio_free(pdata->Power_EN_Pin); - + + recorder_and_AP_to_speakers(); + + isWM8994SetChannel = false; + + wm8994_workq = create_freezeable_workqueue("wm8994"); + if (wm8994_workq == NULL) { + kfree(codec->private_data); + kfree(codec); + return -ENOMEM; + } + /* register pcms */ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); if (ret < 0) { @@ -3399,13 +3465,6 @@ static int wm8994_probe(struct platform_device *pdev) goto card_err; } - PA_ctrl(GPIO_LOW); - //enable power_EN - msleep(50); - gpio_request(pdata->Power_EN_Pin, NULL); - gpio_direction_output(pdata->Power_EN_Pin,GPIO_HIGH); - gpio_free(pdata->Power_EN_Pin); - return ret; card_err: @@ -3454,13 +3513,13 @@ static int wm8994_register(struct wm8994_priv *wm8994, codec->owner = THIS_MODULE; codec->dai = &wm8994_dai; codec->num_dai = 1; -// codec->reg_cache_size = ARRAY_SIZE(wm8994->reg_cache); -// codec->reg_cache = &wm8994->reg_cache; + codec->reg_cache_size = ARRAY_SIZE(wm8994->reg_cache); + codec->reg_cache = &wm8994->reg_cache; codec->bias_level = SND_SOC_BIAS_OFF; codec->set_bias_level = wm8994_set_bias_level; -// memcpy(codec->reg_cache, wm8994_reg, -// sizeof(wm8994_reg)); + memcpy(codec->reg_cache, wm8994_reg, + sizeof(wm8994_reg)); ret = snd_soc_codec_set_cache_io(codec,7, 9, control); if (ret < 0) { @@ -3516,6 +3575,7 @@ static int wm8994_i2c_probe(struct i2c_client *i2c, { struct wm8994_priv *wm8994; struct snd_soc_codec *codec; + wm8994_client=i2c; wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL); if (wm8994 == NULL) @@ -3527,16 +3587,7 @@ static int wm8994_i2c_probe(struct i2c_client *i2c, codec->control_data = i2c; codec->dev = &i2c->dev; - wm8994->pdata = i2c->dev.platform_data;//add - wm8994->RW_status = TRUE;//add - wm8994->capture_active = 0; - wm8994->playback_active = 0; - wm8994->call_vol = call_maxvol; - wm8994->BT_call_vol = BT_call_maxvol; - INIT_DELAYED_WORK(&wm8994->wm8994_delayed_work, wm8994_work_fun); - mutex_init(&wm8994->io_lock); - mutex_init(&wm8994->route_lock); - wake_lock_init(&wm8994->wm8994_on_wake, WAKE_LOCK_SUSPEND, "wm8994_on_wake"); + return wm8994_register(wm8994, SND_SOC_I2C); } @@ -3562,18 +3613,6 @@ static int wm8994_i2c_resume(struct i2c_client *client) #define wm8994_i2c_resume NULL #endif -static void wm8994_i2c_shutdown(struct i2c_client *client) -{ - struct wm8994_priv *wm8994 = wm8994_codec->private_data; - struct wm8994_pdata *pdata = wm8994->pdata; - DBG("%s----%d\n",__FUNCTION__,__LINE__); - //disable PA - PA_ctrl(GPIO_LOW); - gpio_request(pdata->Power_EN_Pin, NULL); - gpio_direction_output(pdata->Power_EN_Pin,GPIO_LOW); - gpio_free(pdata->Power_EN_Pin); -} - static const struct i2c_device_id wm8994_i2c_id[] = { { "wm8994", 0 }, { } @@ -3590,9 +3629,53 @@ static struct i2c_driver wm8994_i2c_driver = { .suspend = wm8994_i2c_suspend, .resume = wm8994_i2c_resume, .id_table = wm8994_i2c_id, - .shutdown = wm8994_i2c_shutdown, }; +int reg_send_data(struct i2c_client *client, unsigned short *reg, unsigned short *data, u32 scl_rate) +{ + int ret; + struct i2c_adapter *adap = client->adapter; + struct i2c_msg msg; + char tx_buf[4]; + + memcpy(tx_buf, reg, 2); + memcpy(tx_buf+2, data, 2); + msg.addr = client->addr; + msg.buf = tx_buf; + msg.len = 4; + msg.flags = client->flags; + msg.scl_rate = scl_rate; + msg.read_type = 0;//I2C_NORMAL; + ret = i2c_transfer(adap, &msg, 1); + + return ret; +} + +int reg_recv_data(struct i2c_client *client, unsigned short *reg, unsigned short *buf, u32 scl_rate) +{ + int ret; + struct i2c_adapter *adap = client->adapter; + struct i2c_msg msgs[2]; + + msgs[0].addr = client->addr; + msgs[0].buf = (char *)reg; + msgs[0].flags = client->flags; + msgs[0].len = 2; + msgs[0].scl_rate = scl_rate; + msgs[0].read_type = 2;//I2C_NO_STOP; + + msgs[1].addr = client->addr; + msgs[1].buf = (char *)buf; + msgs[1].flags = client->flags | I2C_M_RD; + msgs[1].len = 2; + msgs[1].scl_rate = scl_rate; + msgs[1].read_type = 2;//I2C_NO_STOP; + + ret = i2c_transfer(adap, msgs, 2); + + return ret; +} + #endif #if defined(CONFIG_SPI_MASTER) @@ -3682,5 +3765,5 @@ module_exit(wm8994_exit); MODULE_DESCRIPTION("ASoC WM8994 driver"); -MODULE_AUTHOR("Mark Brown "); +MODULE_AUTHOR("chenjq chenjq@rock-chips.com"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index ebf3a6115b5d..8dc225bdcc50 100755 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -14,6 +14,8 @@ #ifndef _WM8994_H #define _WM8994_H +#define WM8994_NUM_REG 0x44 + /* WM8994 register space */ #define WM8994_RESET 0x00 #define wm8994_SYSCLK_3072M 0 diff --git a/sound/soc/rk29/Kconfig b/sound/soc/rk29/Kconfig index a6ac20ef8214..ea7a320c4812 100644 --- a/sound/soc/rk29/Kconfig +++ b/sound/soc/rk29/Kconfig @@ -75,6 +75,94 @@ config SND_RK29_SOC_WM8994 Say Y if you want to add support for SoC audio on rockchip with the WM8994. +if SND_SOC_WM8994 +choice + prompt "Chose earpiece type" + + config SND_INSIDE_EARPIECE + tristate "Inside earpiece" + + config SND_OUTSIDE_EARPIECE + tristate "Outside earpiece" + + config SND_NO_EARPIECE + tristate "No earpiece" +endchoice + +choice + prompt "Chose BB input signal type" + + config SND_BB_NORMAL_INPUT + tristate "BB normal singnal input" + + config SND_BB_DIFFERENTIAL_INPUT + tristate "BB differential singnal input" + +endchoice + +config WM8994_SPEAKER_INCALL_VOL + default 15 + int "Setting the wm8994 speaker incall vol" + help + -21dB to 12dB + +config WM8994_SPEAKER_INCALL_MIC_VOL + default 15 + int "Setting the wm8994 speaker incall mic vol" + help + -22dB to 30dB + +config WM8994_SPEAKER_NORMAL_VOL + default 15 + int "Setting the wm8994 speaker normal vol" + help + -57dB to 18dB + +if SND_INSIDE_EARPIECE||SND_OUTSIDE_EARPIECE +config WM8994_EARPIECE_INCALL_VOL + default 0 + int "Setting the wm8994 earpiece incall vol(normal)" + help + -27dB to 30dB +endif + +config WM8994_HEADSET_INCALL_VOL + default 6 + int "Setting the wm8994 headset incall vol" + help + -12dB to 6dB + +config WM8994_HEADSET_INCALL_MIC_VOL + default 30 + int "Setting the wm8994 headset incall mic vol" + help + -22dB to 30dB + +config WM8994_HEADSET_NORMAL_VOL + default 15 + int "Setting the wm8994 headset normal vol" + help + -57dB to 6dB + +config WM8994_BT_INCALL_VOL + default 30 + int "Setting the wm8994 BT incall vol" + help + 0dB or 30dB + +config WM8994_BT_INCALL_MIC_VOL + default -20 + int "Setting the wm8994 BT incall mic vol" + help + -57dB to 6dB + +config WM8994_RECORDER_VOL + default 40 + int "Setting the wm8994 recorder vol" + help + -16dB to 60dB +endif + config SND_RK29_SOC_CS42L52 tristate "SoC I2S Audio support for rockchip - CS42L52" depends on SND_RK29_SOC && I2C_RK29 -- 2.34.1