From 8540a6d3d9fc185ae8410006b6ca14d51239de04 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=99=88=E9=87=91=E6=B3=89?= Date: Wed, 10 Aug 2011 10:35:24 +0800 Subject: [PATCH] update wm8994 driver --- arch/arm/configs/rk29_phonepadsdk_defconfig | 14 - arch/arm/mach-rk29/board-rk29phonepadsdk.c | 135 +- sound/soc/codecs/wm8994.c | 4098 +++++++++---------- sound/soc/codecs/wm8994.h | 2 - sound/soc/rk29/Kconfig | 88 - 5 files changed, 2137 insertions(+), 2200 deletions(-) diff --git a/arch/arm/configs/rk29_phonepadsdk_defconfig b/arch/arm/configs/rk29_phonepadsdk_defconfig index 09c7fb3c32ce..73b7c27d4353 100644 --- a/arch/arm/configs/rk29_phonepadsdk_defconfig +++ b/arch/arm/configs/rk29_phonepadsdk_defconfig @@ -1535,20 +1535,6 @@ 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 10e64919aaf5..fc2d5f720b35 100644 --- a/arch/arm/mach-rk29/board-rk29phonepadsdk.c +++ b/arch/arm/mach-rk29/board-rk29phonepadsdk.c @@ -51,6 +51,8 @@ #include #include #include +#include +#include #include "devices.h" #if defined(CONFIG_MU509) @@ -705,7 +707,129 @@ struct bq27510_platform_data bq27510_info = { .bat_num = LI_LION_BAT_NUM, }; #endif +/***************************************************************************************** + * wm8994 codec + * author: qjb@rock-chips.com + *****************************************************************************************/ +//#if defined(CONFIG_MFD_WM8994) +#if defined (CONFIG_REGULATOR_WM8994) +static struct regulator_consumer_supply wm8994_ldo1_consumers[] = { + { + .supply = "DBVDD", + }, + { + .supply = "AVDD1", + }, + { + .supply = "CPVDD", + }, + { + .supply = "SPKVDD1", + } +}; +static struct regulator_consumer_supply wm8994_ldo2_consumers[] = { + { + .supply = "DCVDD", + }, + { + .supply = "AVDD2", + }, + { + .supply = "SPKVDD2", + } +}; +struct regulator_init_data regulator_init_data_ldo1 = { + .constraints = { + .name = "wm8994-ldo1", + .min_uA = 00000, + .max_uA = 18000, + .always_on = true, + .apply_uV = true, + .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_CURRENT, + }, + .num_consumer_supplies = ARRAY_SIZE(wm8994_ldo1_consumers), + .consumer_supplies = wm8994_ldo1_consumers, +}; +struct regulator_init_data regulator_init_data_ldo2 = { + .constraints = { + .name = "wm8994-ldo2", + .min_uA = 00000, + .max_uA = 18000, + .always_on = true, + .apply_uV = true, + .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_CURRENT, + }, + .num_consumer_supplies = ARRAY_SIZE(wm8994_ldo2_consumers), + .consumer_supplies = wm8994_ldo2_consumers, +}; +#endif +struct wm8994_drc_cfg wm8994_drc_cfg_pdata = { + .name = "wm8994_DRC", + .regs = {0,0,0,0,0}, +}; +struct wm8994_retune_mobile_cfg wm8994_retune_mobile_cfg_pdata = { + .name = "wm8994_EQ", + .rate = 0, + .regs = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, +}; + +struct wm8994_pdata wm8994_platdata = { +#if defined (CONFIG_GPIO_WM8994) + .gpio_base = WM8994_GPIO_EXPANDER_BASE, + //Fill value to initialize the GPIO + .gpio_defaults ={}, +#endif + //enable=0 disable ldo +#if defined (CONFIG_REGULATOR_WM8994) + .ldo = { + { + .enable = 0, + //RK29_PIN5_PA1 + .supply = NULL, + .init_data = ®ulator_init_data_ldo1, + }, + { + .enable = 0, + .supply = NULL, + .init_data = ®ulator_init_data_ldo2, + } + }, +#endif + //DRC 0--use default + .num_drc_cfgs = 0, + .drc_cfgs = &wm8994_drc_cfg_pdata, + //EQ 0--use default + .num_retune_mobile_cfgs = 0, + .retune_mobile_cfgs = &wm8994_retune_mobile_cfg_pdata, + + .lineout1_diff = 1, + .lineout2_diff = 1, + + .lineout1fb = 1, + .lineout2fb = 1, + + .micbias1_lvl = 1, + .micbias2_lvl = 1, + + .jd_scthr = 0, + .jd_thr = 0, + + .PA_control_pin = 0, + .Power_EN_Pin = RK29_PIN5_PA1, + + .speaker_incall_vol = 0, + .speaker_incall_mic_vol = -9, + .speaker_normal_vol = 6, + .earpiece_incall_vol = 0, + .headset_incall_vol = 6, + .headset_incall_mic_vol = -6, + .headset_normal_vol = 6, + .BT_incall_vol = 0, + .BT_incall_mic_vol = 0, + .recorder_vol = 50, + +}; /***************************************************************************************** * i2c devices @@ -880,11 +1004,12 @@ static struct i2c_board_info __initdata board_i2c0_devices[] = { }, #endif #if defined (CONFIG_SND_SOC_WM8994) - { - .type = "wm8994", - .addr = 0x1A, - .flags = 0, - }, + { + .type = "wm8994", + .addr = 0x1A, + .flags = 0, + .platform_data = &wm8994_platdata, + }, #endif #if defined (CONFIG_BATTERY_STC3100) { diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index b4d1cf8427d2..47364de93e5a 100755 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include #include @@ -33,17 +35,23 @@ #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 PCM_BB -/* Define what kind of digital BB is used. */ +/* If digital BB is used,open this define. + Define what kind of digital BB is used. */ +//#define PCM_BB #ifdef PCM_BB #define TD688_MODE //#define MU301_MODE @@ -57,44 +65,39 @@ #define DBG(x...) do { } while (0) #endif -#define wm8994_mic_VCC 0x0010 -#define WM8994_DELAY 50 +static struct snd_soc_codec *wm8994_codec; -/* 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_powerdown_speakers, - wm8994_powerdown_headset + 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, }; - /* For voice device route set, add by phc */ enum VoiceDeviceSwitch { @@ -123,173 +126,235 @@ enum VoiceDeviceSwitch ALL_CLOSED }; -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}; +//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}; -/* - * 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 { - unsigned int sysclk; + struct mutex io_lock; + struct mutex route_lock; + int sysclk; + int mclk; + int fmt;//master or salve + int rate;//Sampling rate struct snd_soc_codec codec; - struct snd_pcm_hw_constraint_list *sysclk_constraints; - u16 reg_cache[WM8994_NUM_REG]; + 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; }; -bool wm8994_set_status(void) +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) { - return isWM8994SetChannel; + 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; } +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; - if (isSetChannelErr)return -EIO; - - while(i > 0) { + while(i > 0) + { i--; - if (reg_recv_data(wm8994_client,®s,&values,400000) > 0) { + if (reg_recv_data(wm8994_codec->control_data,®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 (isSetChannelErr)return -EIO; + if(wm8994->RW_status == ERROR) goto out; - while(i > 0) { +#ifdef WM8994_PROC + if(debug_write_read != 0) + DBG("%s:0x%04x = 0x%04x\n",__FUNCTION__,reg,value); +#endif + while(i > 0) + { i--; - 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; - } + if (reg_send_data(wm8994_codec->control_data,®s,&values,400000) > 0) + { + mutex_unlock(&wm8994->io_lock); return 0; - } + } } - isSetChannelErr = true; - + + wm8994->RW_status = ERROR; 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_codec_first_incall(void) +static void wm8994_set_volume(unsigned char wm8994_mode,unsigned char volume,unsigned char max_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) { - - cancel_delayed_work_sync(&delayed_work); + unsigned short lvol=0,rvol=0; +// DBG("%s::volume = %d \n",__FUNCTION__,volume); - wm8994_work_type = WM8994_WORK_FIRSTINCALL; - queue_delayed_work(wm8994_workq, &delayed_work, - msecs_to_jiffies(1500)); + 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; } } static void wm8994_set_all_mute(void) { int i; + struct wm8994_priv *wm8994 = wm8994_codec->private_data; - if (call_vol < 0) + if(wm8994->call_vol < 0) return; - for (i = call_vol; i >= 0; i-=2) + for (i = wm8994->call_vol; i >= 0; i--) wm8994_set_volume(null,i,call_maxvol); } @@ -297,224 +362,461 @@ 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 <= call_vol; i++) { + for (i = 0; i <= wm8994->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); + } } } -#define wm8994_reset() wm8994_set_all_mute();\ - wm8994_write(WM8994_RESET, 0) +/* The size in bits of the FLL divide multiplied by 10 + * to allow rounding later */ +#define FIXED_FLL_SIZE ((1 << 16) * 10) -static void AP_to_headset(void) -{ - DBG("%s::%d\n",__FUNCTION__,__LINE__); +struct fll_div { + u16 outdiv; + u16 n; + u16 k; + u16 clk_ref_div; + u16 fll_fratio; +}; - if (wm8994_current_mode == wm8994_AP_to_headset)return; - wm8994_current_mode = wm8994_AP_to_headset; - wm8994_reset(); - msleep(WM8994_DELAY); +static int wm8994_get_fll_config(struct fll_div *fll, + int freq_in, int freq_out) +{ + u64 Kpart; + unsigned int K, Ndiv, Nmod; - wm8994_write(0x700, 0xA101); - wm8994_write(0x39, 0x006C); - wm8994_write(0x01, 0x0023); - wm8994_write(0x200, 0x0000); - mdelay(WM8994_DELAY); +// DBG("FLL input=%dHz, output=%dHz\n", freq_in, freq_out); - wm8994_write(0x220, 0x0000); - wm8994_write(0x221, 0x0700); - wm8994_write(0x222, 0x3126); - wm8994_write(0x223, 0x0100); + /* Scale the input frequency down to <= 13.5MHz */ + fll->clk_ref_div = 0; + while (freq_in > 13500000) { + fll->clk_ref_div++; + freq_in /= 2; - wm8994_write(0x220, 0x0004); - msleep(10); - wm8994_write(0x220, 0x0005); - msleep(5); + 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 - 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); + 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 - 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 -} + /* Now, calculate N.K */ + Ndiv = freq_out / freq_in; -static void AP_to_speakers(void) -{ - DBG("%s::%d\n",__FUNCTION__,__LINE__); + fll->n = Ndiv; + Nmod = freq_out % freq_in; +// DBG("Nmod=%d\n", Nmod); - if (wm8994_current_mode == wm8994_AP_to_speakers)return; - wm8994_current_mode = wm8994_AP_to_speakers; - wm8994_reset(); - msleep(WM8994_DELAY); + /* Calculate fractional part - scale up so we can round. */ + Kpart = FIXED_FLL_SIZE * (long long)Nmod; - wm8994_write(0x700, 0xA101); - wm8994_write(0x39, 0x006C); - wm8994_write(0x01, 0x0023); - wm8994_write(0x200, 0x0000); - mdelay(WM8994_DELAY); + do_div(Kpart, freq_in); - wm8994_write(0x220, 0x0000); - wm8994_write(0x221, 0x0700); - wm8994_write(0x222, 0x3126); - wm8994_write(0x223, 0x0100); + K = Kpart & 0xFFFFFFFF; - wm8994_write(0x220, 0x0004); - msleep(10); - wm8994_write(0x220, 0x0005); - msleep(5); + if ((K % 10) >= 5) + K += 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(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); + /* Move down to proper range now rounding is done */ + fll->k = K / 10; - wm8994_write(0x601, 0x0001); - wm8994_write(0x602, 0x0001); +// DBG("N=%x K=%x\n", fll->n, fll->k);//8 3127 - 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 + return 0; } -static void AP_to_speakers_and_headset(void) +static int wm8994_set_fll(unsigned int freq_in, unsigned int freq_out) { - 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; - 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); - - wm8994_write(0x220, 0x0004); + 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); msleep(10); - wm8994_write(0x220, 0x0005); + wm8994_write(0x220, 0x0005); msleep(5); + wm8994_write(0x200, 0x0010); // sysclk = MCLK1 + return 0; +} - 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); //DAC1 Left Volume bit0~7 - wm8994_write(0x611, 0x0100); //DAC1 Right Volume bit0~7 - - wm8994_write(0x24, 0x0018); - wm8994_set_channel_vol(); - //wm8994_write(0x25, 0x003F); - - 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); - mdelay(5); - wm8994_write(0x01, 0x3303); - mdelay(50); - wm8994_write(0x60, 0x0022); - wm8994_write(0x60, 0x00EE); - - wm8994_write(0x420, 0x0000); +static int wm8994_sysclk_config(void) +{ + struct wm8994_priv *wm8994 = wm8994_codec->private_data; + unsigned int freq_in,freq_out; - wm8994_write(0x601, 0x0001); - wm8994_write(0x602, 0x0001); + 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; + } - wm8994_write(0x03, 0x3330); - wm8994_write(0x22, 0x0000); - wm8994_write(0x23, 0x0100); - wm8994_write(0x36, 0x0003); - wm8994_write(0x01, 0x3323); + 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(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; +} + +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)); +} + +static int wm8994_reset_ldo(void) +{ + struct wm8994_priv *wm8994 = wm8994_codec->private_data; + struct wm8994_pdata *pdata = wm8994->pdata; + unsigned short value; + + 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); + + 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; + + 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 + } + + vol = pdata->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: + 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; + + 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; + + 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; + + 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(0x610, 0x01C0); //DAC1 Left Volume bit0~7 - wm8994_write(0x611, 0x01C0); //DAC1 Right Volume bit0~7 } -static void recorder_and_AP_to_headset(void) +#define wm8994_reset() wm8994_set_all_mute();\ + wm8994_write(WM8994_RESET, 0) + +void 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; + if(wm8994_current_mode==wm8994_AP_to_headset)return; + wm8994_current_mode=wm8994_AP_to_headset; wm8994_reset(); msleep(WM8994_DELAY); wm8994_write(0x700, 0xA101); - wm8994_write(0x39, 0x006C); - wm8994_write(0x01, 0x0003); + wm8994_write(0x01, 0x0023); wm8994_write(0x200, 0x0000); mdelay(WM8994_DELAY); @@ -532,66 +834,55 @@ static void recorder_and_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_CODEC_SOC_MASTER +#ifdef CONFIG_SND_RK29_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, 0xC050); // i2s 16 bits + 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 - 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(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); - mdelay(5); - wm8994_write(0x01, 0x0303); - mdelay(50); + msleep(5); + wm8994_write(0x01, 0x0323); + msleep(50); wm8994_write(0x60, 0x0022); wm8994_write(0x60, 0x00FF); - 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(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(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(); + wm8994_write(0x22, 0x0000); + wm8994_write(0x23, 0x0100); + wm8994_write(0x36, 0x0003); + wm8994_write(0x1C, 0x017F); //HPOUT1L Volume + wm8994_write(0x1D, 0x017F); //HPOUT1R Volume } -static void recorder_and_AP_to_speakers(void) +void AP_to_speakers(void) { DBG("%s::%d\n",__FUNCTION__,__LINE__); - if (wm8994_current_mode == wm8994_recorder_and_AP_to_speakers)return; - wm8994_current_mode = wm8994_recorder_and_AP_to_speakers; - wm8994_reset(); + if(wm8994_current_mode==wm8994_AP_to_speakers)return; + wm8994_current_mode=wm8994_AP_to_speakers; +// wm8994_reset(); + wm8994_write(0,0); msleep(WM8994_DELAY); - wm8994_write(0x700, 0xA101); - wm8994_write(0x39, 0x006C); - wm8994_write(0x01, 0x0003); +// wm8994_write(0x700, 0xA101); +// wm8994_write(0x39, 0x006C); + wm8994_write(0x01, 0x0023); wm8994_write(0x200, 0x0000); mdelay(WM8994_DELAY); @@ -609,64 +900,57 @@ static void recorder_and_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_CODEC_SOC_MASTER +#ifdef CONFIG_SND_RK29_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, 0xC050); // i2s 16 bits + wm8994_write(0x300, 0xC010); // i2s 16 bits #endif wm8994_write(0x200, 0x0011); // sysclk = fll (bit4 =1) 0x0011 - - 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(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] - - 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, 0x3023); + wm8994_write(0x03, 0x0330); + wm8994_write(0x05, 0x0303); 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(0x23, 0x0100); + wm8994_write(0x2D, 0x0001); + wm8994_write(0x2E, 0x0000); + wm8994_write(0x36, 0x000C); 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); + wm8994_write(0x420, 0x0000); + + 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(0x26, 0x017F); //Speaker Left Output Volume + wm8994_write(0x27, 0x017F); //Speaker Right Output Volume } -static void FM_to_headset(void) +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_reset(); + wm8994_write(0,0); 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); @@ -688,11 +972,11 @@ static void FM_to_headset(void) wm8994_write(0x1D, 0x01F9); //RIGHT OUTPUT VOLUME } -static void FM_to_headset_and_record(void) +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); @@ -701,7 +985,7 @@ static void FM_to_headset_and_record(void) msleep(WM8994_DELAY); wm8994_write(0x221, 0x1900); //8~13BIT div -#ifdef CONFIG_SND_CODEC_SOC_MASTER +#ifdef CONFIG_SND_RK29_CODEC_SOC_MASTER wm8994_write(0x302, 0x4000); // master = 0x4000 // slave= 0x0000 wm8994_write(0x303, 0x0040); // master 0x0050 lrck 7.94kHz bclk 510KHz #endif @@ -734,45 +1018,85 @@ static void FM_to_headset_and_record(void) wm8994_write(0x620, 0x0000); } -static void FM_to_speakers(void) +void FM_test(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); - wm8994_write(0x01, 0x3003); - wm8994_write(0x02, 0x03A0); - wm8994_write(0x03, 0x0330); - wm8994_write(0x19, 0x010B); //LEFT LINE INPUT 3&4 VOLUME - wm8994_write(0x1B, 0x010B); //RIGHT LINE INPUT 3&4 VOLUME - +//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(0x36, 0x000C); - - 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(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(0x200, 0x0011); - wm8994_write(0x20, 0x01F9); - wm8994_write(0x21, 0x01F9); +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); } -static void FM_to_speakers_and_record(void) +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); @@ -780,7 +1104,7 @@ static void FM_to_speakers_and_record(void) wm8994_write(0x01, 0x0003); msleep(WM8994_DELAY); -#ifdef CONFIG_SND_CODEC_SOC_MASTER +#ifdef CONFIG_SND_RK29_CODEC_SOC_MASTER wm8994_write(0x302, 0x4000); // master = 0x4000 // slave= 0x0000 wm8994_write(0x303, 0x0090); // #endif @@ -818,173 +1142,297 @@ static void FM_to_speakers_and_record(void) wm8994_write(0x607, 0x0002); wm8994_write(0x620, 0x0000); } -#ifndef PCM_BB -static void handsetMIC_to_baseband_to_headset(void) + +void record_only(void) { DBG("%s::%d\n",__FUNCTION__,__LINE__); + wm8994_write(0,0); + msleep(WM8994_DELAY); - 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_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; wm8994_reset(); msleep(WM8994_DELAY); - wm8994_write(0x700, 0xA101); - wm8994_write(0x39, 0x006C); - wm8994_write(0x01, 0x0003); - wm8994_write(0x200, 0x0000); - mdelay(WM8994_DELAY); - wm8994_write(0x220, 0x0000); - wm8994_write(0x221, 0x0700); - wm8994_write(0x222, 0x3126); - wm8994_write(0x223, 0x0100); + 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); +} - wm8994_write(0x220, 0x0004); - msleep(10); - wm8994_write(0x220, 0x0005); - msleep(5); +void recorder_and_AP_to_headset(void) +{ + DBG("%s::%d\n",__FUNCTION__,__LINE__); - 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 + 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(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); - mdelay(5); - wm8994_write(0x01, 0x0303); - mdelay(50); + 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(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 + +} + +void recorder_and_AP_to_speakers(void) +{ + DBG("%s::%d\n",__FUNCTION__,__LINE__); + + 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(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_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(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); +} + +#ifndef PCM_BB +void handsetMIC_to_baseband_to_headset(void) +{// + 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; + 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(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(0x601, 0x0001); + wm8994_write(0x602, 0x0001); +//volume 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(); } -static void mainMIC_to_baseband_to_headset(void) -{ +void mainMIC_to_baseband_to_headset(void) +{// DBG("%s::%d\n",__FUNCTION__,__LINE__); - if (wm8994_current_mode == wm8994_mainMIC_to_baseband_to_headset)return; - wm8994_codec_first_incall(); + if(wm8994_current_mode == wm8994_mainMIC_to_baseband_to_headset)return; wm8994_current_mode = wm8994_mainMIC_to_baseband_to_headset; wm8994_reset(); msleep(WM8994_DELAY); - wm8994_write(0x700, 0xA101); - wm8994_write(0x39, 0x006C); - wm8994_write(0x01, 0x0003); + wm8994_write(0x01, 0x0023); 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(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); + wm8994_write(0x60, 0x0022); + wm8994_write(0x60, 0x00EE); + wm8994_write(0x420, 0x0000); + wm8994_write(0x601, 0x0001); + wm8994_write(0x602, 0x0001); +//volume + 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(); +} - wm8994_write(0x220, 0x0000); - wm8994_write(0x221, 0x0700); - wm8994_write(0x222, 0x3126); - wm8994_write(0x223, 0x0100); +void handsetMIC_to_baseband_to_headset_and_record(void) +{ + struct wm8994_priv *wm8994 = wm8994_codec->private_data; + DBG("%s::%d\n",__FUNCTION__,__LINE__); - 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 -#endif - - wm8994_write(0x4C, 0x9F25); - mdelay(5); - wm8994_write(0x01, 0x0303); - mdelay(50); - wm8994_write(0x60, 0x0022); - 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(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_level_volume(); -} - -static void handsetMIC_to_baseband_to_headset_and_record(void) -{ - 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; - wm8994_reset(); - msleep(WM8994_DELAY); + 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); wm8994_write(0x01, 0x0303); wm8994_write(0x02, 0x62C0); @@ -992,7 +1440,7 @@ static 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,call_vol,call_maxvol); + wm8994_set_volume(wm8994_current_mode,wm8994->call_vol,call_maxvol); wm8994_write(0x1E, 0x0006); wm8994_write(0x28, 0x00B0); //IN2LP_TO_IN2L wm8994_write(0x29, 0x0120); @@ -1005,7 +1453,7 @@ static void handsetMIC_to_baseband_to_headset_and_record(void) wm8994_write(0x208, 0x000A); wm8994_write(0x300, 0x0050); -#ifdef CONFIG_SND_CODEC_SOC_MASTER +#ifdef CONFIG_SND_RK29_CODEC_SOC_MASTER wm8994_write(0x302, 0x4000); // master = 0x4000 // slave= 0x0000 wm8994_write(0x303, 0x0090); // master lrck 16k #endif @@ -1015,95 +1463,53 @@ static void handsetMIC_to_baseband_to_headset_and_record(void) wm8994_write(0x620, 0x0000); } -static void mainMIC_to_baseband_to_earpiece(void) -{ +void mainMIC_to_baseband_to_earpiece(void) +{// DBG("%s::%d\n",__FUNCTION__,__LINE__); - if (wm8994_current_mode == wm8994_mainMIC_to_baseband_to_earpiece)return; - wm8994_codec_first_incall(); + if(wm8994_current_mode == wm8994_mainMIC_to_baseband_to_earpiece)return; wm8994_current_mode = wm8994_mainMIC_to_baseband_to_earpiece; wm8994_reset(); msleep(WM8994_DELAY); - wm8994_write(0x700, 0xA101); - wm8994_write(0x39, 0x006C); - wm8994_write(0x01, 0x0003); + 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); - - 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 + msleep(WM8994_DELAY); +//clk + wm8994_sysclk_config(); + wm8994_write(0x300, 0xC010); // i2s 16 bits +//path 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 -#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(0x601, 0x0001); //AIF1DAC1L_TO_DAC1L=1 + wm8994_write(0x602, 0x0001); //AIF1DAC1R_TO_DAC1R=1 + wm8994_write(0x420, 0x0000); +//volume wm8994_write(0x610, 0x01C0); //DAC1_VU=1, DAC1L_VOL=1100_0000 wm8994_write(0x611, 0x01C0); //DAC1_VU=1, DAC1R_VOL=1100_0000 - - wm8994_write(0x420, 0x0000); + 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_set_level_volume(); + wm8994_set_level_volume(); } -static void mainMIC_to_baseband_to_earpiece_and_record(void) +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); @@ -1111,8 +1517,7 @@ static 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 ,0x0147); + wm8994_write(0x1A ,0x014F); wm8994_write(0x1E ,0x0006); wm8994_write(0x1F ,0x0000); wm8994_write(0x28 ,0x0003); //MAINMIC_TO_IN1R @@ -1125,9 +1530,9 @@ static 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,call_vol,call_maxvol); + wm8994_set_volume(wm8994_current_mode,wm8994->call_vol,call_maxvol); -#ifdef CONFIG_SND_CODEC_SOC_MASTER +#ifdef CONFIG_SND_RK29_CODEC_SOC_MASTER wm8994_write(0x302, 0x4000); // master = 0x4000 // slave= 0x0000 wm8994_write(0x303, 0x0090); // master lrck 16k #endif @@ -1137,94 +1542,63 @@ static void mainMIC_to_baseband_to_earpiece_and_record(void) wm8994_write(0x620 ,0x0000); } -static void mainMIC_to_baseband_to_speakers(void) -{ +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_codec_first_incall(); - 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(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); - - 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 - + 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(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(0x36, 0x000C); + wm8994_write(0x60, 0x0022); + wm8994_write(0x36, 0x000C); + wm8994_write(0x60, 0x00EE); wm8994_write(0x420, 0x0000); - msleep(50); - wm8994_write(0x03, 0x1330); - 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(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_level_volume(); + 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(); } -static void mainMIC_to_baseband_to_speakers_and_record(void) +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); @@ -1246,9 +1620,9 @@ static 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,call_vol,call_maxvol); + wm8994_set_volume(wm8994_current_mode,wm8994->call_vol,call_maxvol); -#ifdef CONFIG_SND_CODEC_SOC_MASTER +#ifdef CONFIG_SND_RK29_CODEC_SOC_MASTER wm8994_write(0x302, 0x4000); // master = 0x4000 // slave= 0x0000 wm8994_write(0x303, 0x0090); // master lrck 16k #endif @@ -1258,67 +1632,63 @@ static void mainMIC_to_baseband_to_speakers_and_record(void) wm8994_write(0x620, 0x0000); } -static void BT_baseband(void) -{ +void BT_baseband(void) +{// + struct wm8994_priv *wm8994 = wm8994_codec->private_data; DBG("%s::%d\n",__FUNCTION__,__LINE__); - if (wm8994_current_mode == wm8994_BT_baseband)return; - wm8994_codec_first_incall(); - wm8994_current_mode = wm8994_BT_baseband; + if(wm8994_current_mode==wm8994_BT_baseband)return; + + 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); - - //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); - +//CLK + //AIF1CLK + wm8994_sysclk_config(); + wm8994_write(0x300, 0xC010); // i2s 16 bits + //AIF2CLK use FLL2 wm8994_write(0x204, 0x0000); msleep(WM8994_DELAY); wm8994_write(0x240, 0x0000); - wm8994_write(0x241, 0x2F00); - wm8994_write(0x242, 0x3126); - wm8994_write(0x243, 0x0100); - + 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(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); @@ -1326,46 +1696,29 @@ static 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 - - //roger_chen@20100519 - //enable AIF2 BCLK,LRCK - //Rev.B and Rev.D is different +/* + 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 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(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,call_vol,call_maxvol); - wm8994_write(0x1E, 0x0006); +//path wm8994_write(0x29, 0x0100); wm8994_write(0x2A, 0x0100); - - wm8994_set_channel_vol(); - -#ifdef CONFIG_SND_BB_NORMAL_INPUT - 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; - wm8994_write(0x2B, (vol+12)/3 + 1);*/ - wm8994_write(0x28, 0x00CC); -#endif - wm8994_write(0x22, 0x0000); - wm8994_write(0x23, 0x0100); + wm8994_write(0x28, 0x00C0); wm8994_write(0x24, 0x0009); wm8994_write(0x29, 0x0130); wm8994_write(0x2A, 0x0130); @@ -1373,10 +1726,14 @@ static void BT_baseband(void) 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(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 @@ -1389,28 +1746,168 @@ static void BT_baseband(void) wm8994_write(0x540, 0x0018); wm8994_write(0x580, 0x0000); wm8994_write(0x581, 0x0000); - wm8994_write(0x601, 0x0004); - if (wm8994_work_type != WM8994_WORK_FIRSTINCALL) { - wm8994_write(0x602, 0x0001); - } - wm8994_write(0x603, 0x000C); - wm8994_write(0x604, 0x0010); - wm8994_write(0x605, 0x0010); +//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); - wm8994_write(0x620, 0x0000); - wm8994_write(0x420, 0x0000); -} - + wm8994_write(0x613, 0x01C0); +//other + wm8994_write(0x4C, 0x9F25); + wm8994_write(0x60, 0x00EE); + msleep(5); +//power + wm8994_write(0x01, 0x3033); + 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_set_channel_vol(); + +#ifdef CONFIG_SND_BB_NORMAL_INPUT + 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; + wm8994_write(0x2B, (vol+12)/3 + 1);*/ + 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(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 + 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); + wm8994_write(0x601, 0x0004); + + wm8994_write(0x602, 0x0001); + + wm8994_write(0x603, 0x000C); + wm8994_write(0x604, 0x0010); + wm8994_write(0x605, 0x0010); + wm8994_write(0x610, 0x01C0); + wm8994_write(0x611, 0x01C0); + wm8994_write(0x612, 0x01C0); + 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); -static void BT_baseband_and_record(void) + 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) { + 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); @@ -1420,7 +1917,7 @@ static void BT_baseband_and_record(void) wm8994_write(0x04, 0x3303); wm8994_write(0x05, 0x3002); wm8994_write(0x06, 0x000A); - wm8994_set_volume(wm8994_current_mode,call_vol,call_maxvol); + wm8994_set_volume(wm8994_current_mode,wm8994->call_vol,call_maxvol); wm8994_write(0x1E, 0x0006); wm8994_write(0x28, 0x00CC); wm8994_write(0x29, 0x0100); @@ -1488,12 +1985,12 @@ static void BT_baseband_and_record(void) /******************PCM BB BEGIN*****************/ -static void handsetMIC_to_baseband_to_headset(void) //pcmbaseband +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); @@ -1568,15 +2065,15 @@ static 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); + } -static void handsetMIC_to_baseband_to_headset_and_record(void) //pcmbaseband +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); @@ -1654,15 +2151,15 @@ static 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); + } -static void mainMIC_to_baseband_to_earpiece(void) //pcmbaseband +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); @@ -1738,15 +2235,15 @@ static 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); + } -static void mainMIC_to_baseband_to_earpiece_and_record(void) //pcmbaseband +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); @@ -1764,8 +2261,7 @@ static 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, 0x0101); + wm8994_write(0x1A, 0x010B); wm8994_write(0x1F, 0x0000); wm8994_write(0x28, 0x0003); wm8994_write(0x2A, 0x0020); @@ -1823,15 +2319,15 @@ static 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); + } -static void mainMIC_to_baseband_to_speakers(void) //pcmbaseband +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); @@ -1852,7 +2348,7 @@ static 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); @@ -1909,15 +2405,15 @@ static 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); + } -static void mainMIC_to_baseband_to_speakers_and_record(void) //pcmbaseband +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); @@ -1994,15 +2490,14 @@ static 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); } -static void BT_baseband(void) //pcmbaseband +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); @@ -2017,621 +2512,146 @@ static void BT_baseband(void) //pcmbaseband 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(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; + 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 - DBG("%s::volume = %d \n",__FUNCTION__,volume); + 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); - 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]); - } -} +/////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_check_channel(void) -{ - wm8994_codec_fnc_t **wm8994_fnc_ptr = wm8994_codec_sequence; - unsigned char wm8994_mode = wm8994_current_mode; + wm8994_write(0x06 ,0x0001); - DBG("%s--%d::Enter\n",__FUNCTION__,__LINE__); + wm8994_write(0x02 ,0x0300); + wm8994_write(0x03 ,0x0030); + wm8994_write(0x04 ,0x3301);//ADCL off + wm8994_write(0x05 ,0x3301);//DACL off - 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(0x2A ,0x0005); - wm8994_fnc_ptr += wm8994_mode; + wm8994_write(0x313 ,0x00F0); + wm8994_write(0x314 ,0x0020); + wm8994_write(0x315 ,0x0020); - while(isSetChannelErr) { - gpio_request(WM_EN_PIN, NULL); - gpio_direction_output(WM_EN_PIN,GPIO_LOW); - gpio_free(WM_EN_PIN); + 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 - msleep(50); - gpio_request(WM_EN_PIN, NULL); - gpio_direction_output(WM_EN_PIN,GPIO_HIGH); - gpio_free(WM_EN_PIN); + wm8994_write(0x312 ,0x4000); - msleep(50); + wm8994_write(0x606 ,0x0001); + wm8994_write(0x607 ,0x0003);//R channel for data mix/CPU record data - wm8994_current_mode = null; - isSetChannelErr = false; - (*wm8994_fnc_ptr)() ; - } +////////////HP output test + wm8994_write(0x01 ,0x0303); + wm8994_write(0x4C ,0x9F25); + wm8994_write(0x60 ,0x00EE); +///////////end HP test - DBG("%s--%d::Exit\n",__FUNCTION__,__LINE__); } -static int wm8994_powerdown(void) +void BT_baseband_and_record(void) //pcmbaseband { - printk("Power down wm8994\n"); - - isWM8994SetChannel = true; + DBG("%s::%d\n",__FUNCTION__,__LINE__); - wm8994_write(0x00, 0x0000); + 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(0x01, 0x0023); + wm8994_write(0x01 ,0x0003); + msleep (50); - 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(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); - isWM8994SetChannel = false; - return 0; -} + 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 -static void wm8994_work(struct work_struct *work) -{ - DBG("Enter::wm8994 work\n"); + 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); - 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; +/////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); - case WM8994_WORK_SHUTDOWN: - wm8994_powerdown();//close codec - break; + 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); - case WM8994_WORK_STARTUP: - isWM8994SetChannel = true; + wm8994_write(0x313 ,0x00F0); + wm8994_write(0x314 ,0x0020); + wm8994_write(0x315 ,0x0020); - 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(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_check_channel(); - isWM8994SetChannel = false; - break; + 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 - 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), \ @@ -2659,114 +2679,121 @@ 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 - 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; - } + //before set the route -- disable PA + PA_ctrl(GPIO_LOW); - isWM8994SetChannel = true; + //set rount switch(route) { - /* Speaker*/ - case SPEAKER_NORMAL: //AP-> 8994Codec -> Speaker + case SPEAKER_NORMAL: //AP-> 8994Codec -> Speaker + case SPEAKER_RINGTONE: + case EARPIECE_RINGTONE: recorder_and_AP_to_speakers(); break; - - case SPEAKER_INCALL: //BB-> 8994Codec -> Speaker + case SPEAKER_INCALL: //BB-> 8994Codec -> Speaker mainMIC_to_baseband_to_speakers(); - break; - - /* Headset */ - case HEADSET_NORMAL: //AP-> 8994Codec -> Headset + break; + case HEADSET_NORMAL: //AP-> 8994Codec -> Headset recorder_and_AP_to_headset(); break; - case HEADSET_INCALL: //AP-> 8994Codec -> Headset - //if (isHSKey_MIC()) + case HEADSET_INCALL: //AP-> 8994Codec -> Headset + if(Headset_isMic()) handsetMIC_to_baseband_to_headset(); - //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 + else + mainMIC_to_baseband_to_headset(); + break; + case EARPIECE_INCALL: //BB-> 8994Codec -> EARPIECE mainMIC_to_baseband_to_earpiece(); -#endif - break; - - 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 + 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 BT_baseband(); - break; - - /* BLUETOOTH_A2DP*/ - case BLUETOOTH_A2DP_NORMAL: //AP-> 8994Codec -> BLUETOOTH_A2DP - break; - + break; case MIC_CAPTURE: - 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(); + 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; } 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: - recorder_and_AP_to_speakers(); + case SPEAKER_INCALL: + case EARPIECE_RINGTONE: + case HEADSET_RINGTONE: + msleep(50); + PA_ctrl(GPIO_HIGH); break; - - default: - //codec_daout_route(); + default: break; - } - wm8994_check_channel(); - - isWM8994SetChannel = false; - + } +out: + mutex_unlock(&wm8994->route_lock); + wake_unlock(&wm8994->wm8994_on_wake); 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), @@ -2789,82 +2816,263 @@ SOC_DOUBLE_SWITCH_WM8994CODEC("Speaker ringtone Switch",SPEAKER_RINGTONE), SOC_DOUBLE_SWITCH_WM8994CODEC("Headset ringtone Switch",HEADSET_RINGTONE), }; -static int wm8994_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) +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) { - codec->bias_level = level; + 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_trigger(struct snd_pcm_substream *substream, - int status, - struct snd_soc_dai *dai) +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_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; + struct snd_soc_codec *codec = dai->codec; + struct wm8994_priv *wm8994 = codec->private_data; - DBG("%s::%d status = %d substream->stream '%s'\n",__FUNCTION__,__LINE__, - status, substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? "PLAYBACK":"CAPTURE"); +// DBG("Enter %s::%s---%d\n",__FILE__,__FUNCTION__,__LINE__); - if (status == 1 || status == 0) { - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + wm8994->rate = params_rate(params); +// DBG("Sample rate is %dHz\n",wm8994->rate); - codec_dai->playback.active = status; - }else { + return 0; +} - codec_dai->capture.active = status; - } +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) +{ + return 0; +} + +static int wm8994_trigger(struct snd_pcm_substream *substream, + int cmd, + 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; } - if (!codec_dai->playback.active && !codec_dai->capture.active - && (playback_active || capture_active) - && (wm8994_current_mode < wm8994_handsetMIC_to_baseband_to_headset)) { + if (!wm8994->playback_active && + !wm8994->capture_active ) + {//suspend 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)); + } - cancel_delayed_work_sync(&delayed_work); - - wm8994_work_type = WM8994_WORK_SHUTDOWN; - /* when codec is not using , close it */ + return 0; +} - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { +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); - queue_delayed_work(wm8994_workq, &delayed_work, - msecs_to_jiffies(1000)); - } else { - queue_delayed_work(wm8994_workq, &delayed_work, - msecs_to_jiffies(3000)); + 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(error_count == 0) + { + PA_ctrl(GPIO_LOW); + printk("wm8994 Major problems, give me log,tks, -- qjb\n"); + } + 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)); - } + default: + break; } - - return 0; } -#define WM8994_RATES SNDRV_PCM_RATE_48000 - +#define WM8994_RATES SNDRV_PCM_RATE_8000_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 = { - /*add by qiuen for volume*/ - .set_volume = wm8994_codec_set_volume, + .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, }; struct snd_soc_dai wm8994_dai = { @@ -2892,21 +3100,23 @@ 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; - - cancel_delayed_work_sync(&delayed_work); - - wm8994_work_type = WM8994_WORK_NULL; - - isWM8994SetChannel = true; - - wm8994_set_bias_level(codec,SND_SOC_BIAS_OFF); + 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); wm8994_write(0x00, 0x00); - msleep(50); - - gpio_request(WM_EN_PIN, NULL); - gpio_direction_output(WM_EN_PIN,GPIO_LOW); - gpio_free(WM_EN_PIN); - + + gpio_request(pdata->Power_EN_Pin, NULL); + gpio_direction_output(pdata->Power_EN_Pin,GPIO_LOW); + gpio_free(pdata->Power_EN_Pin); msleep(50); return 0; @@ -2916,502 +3126,228 @@ 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__); - 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); + 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)); - wm8994_powerdown(); - - isWM8994SetChannel = false; return 0; } -static struct snd_soc_codec *wm8994_codec; - #ifdef WM8994_PROC - -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) { +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; case 'r': case 'R': - 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; - } - 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; + 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); } - - 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 'i': - case 'I': - if (*(buffer+1)=='+') { - procadd = 3; - } else if (*(buffer+1)=='-') { - procadd = -3; - } else { - printk("Please press '+' or '-' follow 'i'!\n"); - return -1; + debug_write_read = 0;; + DBG("\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; + else + { + DBG("Error Read reg debug.\n"); + DBG("For example: echo 'r:22,23,24,25'>wm8994_ts\n"); } 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; + 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"); } - 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; - - 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; - - 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); + else + { + DBG("Error Write reg debug.\n"); + DBG("For example: w:22=0,23=0,24=0,25=0\n"); + } + 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 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); + } + 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); + } break; - - default: - printk("Current channel does not match to mic mode!\n"); - return -1; + } + else + { + goto help; } + 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 '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; + case 'F': + case 'f': + PA_ctrl(GPIO_HIGH); + FM_to_speakers(); break; - - 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; + 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); break; - - 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; + case '2': + gpio_request(pdata->Power_EN_Pin, NULL); + gpio_direction_output(pdata->Power_EN_Pin,GPIO_HIGH); + gpio_free(pdata->Power_EN_Pin); break; - default: - printk("Please press 'n' 'i' 'm' 'l' 'c' 'e' !\n"); - return -1; + 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; } - wm8994_set_channel_vol(); - - return 0; + return len; } -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"); } @@ -3424,7 +3360,10 @@ 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(); @@ -3437,18 +3376,12 @@ static int wm8994_probe(struct platform_device *pdev) socdev->card->codec = wm8994_codec; codec = wm8994_codec; - - 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; - } - + 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); /* register pcms */ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); if (ret < 0) { @@ -3465,6 +3398,13 @@ 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: @@ -3513,13 +3453,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) { @@ -3575,7 +3515,6 @@ 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) @@ -3587,7 +3526,16 @@ 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); } @@ -3613,6 +3561,18 @@ 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 }, { } @@ -3629,53 +3589,9 @@ 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) @@ -3765,5 +3681,5 @@ module_exit(wm8994_exit); MODULE_DESCRIPTION("ASoC WM8994 driver"); -MODULE_AUTHOR("chenjq chenjq@rock-chips.com"); +MODULE_AUTHOR("Mark Brown "); MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index 8dc225bdcc50..ebf3a6115b5d 100755 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -14,8 +14,6 @@ #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 ea7a320c4812..a6ac20ef8214 100644 --- a/sound/soc/rk29/Kconfig +++ b/sound/soc/rk29/Kconfig @@ -75,94 +75,6 @@ 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