ssize_t static eamp_read_byte(u8 addr, u8 *returnData)
{
    char     cmd_buf[1]={0x00};
    char     readData = 0;
    int     ret=0;

    if(!new_client)
    {
        EAMP_PRINTK("I2C client not initialized!!");
        return -1;
    }

    cmd_buf[0] = addr;
    ret = i2c_master_send(new_client, &cmd_buf[0], 1);
    if (ret < 0) {
        EAMP_PRINTK("read sends command error!!");
        return -1;
    }
    ret = i2c_master_recv(new_client, &readData, 1);
    if (ret < 0) {
        EAMP_PRINTK("reads recv data error!!");
        return -1;
    }
    *returnData = readData;
    EAMP_PRINTK("addr 0x%x data 0x%x",addr, readData);
    return 0;
}
static int amp_enable(int on_state)
{
	int err = 0;

	switch (on_state) {
	case 0:
		err = mt_set_gpio_out(GPIO_SPK_AMP_EN, GPIO_OUT_ZERO);
		EAMP_PRINTK("AMP_EN is set to %d\n", mt_get_gpio_out(GPIO_SPK_AMP_EN));
		break;
	case 1:
		err = mt_set_gpio_out(GPIO_SPK_AMP_EN, GPIO_OUT_ONE);
		EAMP_PRINTK("AMP_EN is set to %d\n", mt_get_gpio_out(GPIO_SPK_AMP_EN));
		break;
	case 2:
		EAMP_PRINTK("amp enable bypass(%d)\n", on_state);
		err = 0;
		break;

	default:
		pr_err("amp enable fail\n");
		err = 1;
		break;
	}
	return err;
}
static ssize_t eamp_openspeaker(unsigned long param)
{
	EAMP_PRINTK("eamp_openspeaker");

/*                                                                                        */
	if ( param == 1 ) {
		EAMP_PRINTK("AAT Camcorder Test -> eamp_right_open & eamp_left_close");

		mt_set_gpio_out(GPIO_SPK_AMP_L_EN, GPIO_OUT_ZERO);
		mt_set_gpio_out(GPIO_SPK_AMP_R_EN, GPIO_OUT_ONE);
	}
	else if ( param == 2 ) {
		EAMP_PRINTK("AAT Ring Test -> eamp_right_close & eamp_left_open");

		mt_set_gpio_out(GPIO_SPK_AMP_L_EN, GPIO_OUT_ONE);
		mt_set_gpio_out(GPIO_SPK_AMP_R_EN, GPIO_OUT_ZERO);
	}
	else {
		EAMP_PRINTK("Normal mode -> eamp_openspeaker");

		mt_set_gpio_out(GPIO_SPK_AMP_L_EN, GPIO_OUT_ONE);
		mt_set_gpio_out(GPIO_SPK_AMP_R_EN, GPIO_OUT_ONE);
	}
/*                                                                                        */

	gsk_on = true;

/*                                                                                                      */
    msleep(speaker_response_time);
/*                                                                                                      */

	return 0;
}
static int eamp_write_procmem(struct file *file, const char __user *buffer,
	unsigned long count, void *data)
{
	char *register_data;
	int addr;
	int value;
	int fail;

	register_data = (char*)data;
	copy_from_user(register_data, buffer, count);
	register_data[count] = '\0';
	if(register_data[count - 1] == '\n')
			register_data[count - 1] = '\0';

	sscanf(register_data, "%d %d", &addr, &value);
	EAMP_PRINTK("S register_data=%s %d %d\n", register_data, addr, value);
	if(addr >= IC_CONTROL && addr <= AGC2_CONTROL){
		if(AGC_FIXED_GAIN_CONTROL == addr){
			if(value >= -28 && value <= 30)
				register_setting_mode = value;
			else{
				EAMP_PRINTK("S Wrong value\n");
				return count;
			}

		}
		fail |= I2CWrite(addr, value);
		EAMP_PRINTK("S register Write Done Gain=%d\n", I2CRead(addr));
	}
	else
		EAMP_PRINTK("S Wrong addr or value\n");

	return count;
}
static int eamp_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) {			   
	
	EAMP_PRINTK("+++++++++++++++eamp_i2c_probe++++++++++++++++++"); //add for test
	new_client = client;
	eamp_resetRegister();
	EAMP_PRINTK("client=%x !!",client);
	return 0;																						
} 
static int eamp_register()
{
    EAMP_PRINTK("");
    i2c_register_board_info(SOUND_I2C_CHANNEL,&tpa2028_eamp_dev,1);
    if (i2c_add_driver(&tpa2028_eamp_i2c_driver)){
        EAMP_PRINTK("fail to add device into i2c");
        return -1;
    }
    return 0;
}
static ssize_t eamp_openheadPhone()
{
	EAMP_PRINTK("eamp_openheadPhone");

	mt_set_gpio_out(GPIO_HEADSET_AMP_EN, GPIO_OUT_ONE);

	if(ghplvol == ghprvol)
	{
/*                                                                            */
		if (gMode == 2) {
			msleep(270); // for pop-noise
		}
	}
	else
	{
/*                                                                            */
		if (gMode == 2) {
			msleep(270); // for pop-noise
		}
	}
	ghp_on = true;

/*                                                                                                      */
    msleep(headphone_response_time);
/*                                                                                                      */

	return 0;
}
static ssize_t eamp_closeEarpiece()
{
	EAMP_PRINTK("eamp_closeEarpiece");

	gep_on=false;
	return 0;
}
static ssize_t eamp_openEarpiece()
{
	EAMP_PRINTK("eamp_openEarpiece");

	gep_on=true;
	return 0;
}
static ssize_t eamp_openheadPhone()
{
	EAMP_PRINTK("eamp_openheadPhone");

	mt_set_gpio_out(GPIO_AUDIO_SEL, GPIO_OUT_ONE);

	if(ghplvol == ghprvol)
	{
/* LGE_CHANGE_S : [email protected] , for reduce pop-noise, rev1.0, TD 260828 */
		if (gMode == 2) {
			msleep(270); // for pop-noise
		}
	}
	else
	{
/* LGE_CHANGE_S : [email protected] , for reduce pop-noise, rev1.0, TD 260828 */
		if (gMode == 2) {
			msleep(270); // for pop-noise
		}
	}
	ghp_on = true;

/* LGE_CHANGE_S : 20121031 [email protected] sound play volume change issue fix MTK patch ALPS00373024 */
    msleep(headphone_response_time);
/* LGE_CHANGE_E : 20121031 [email protected] sound play volume change issue fix MTK patch ALPS00373024 */

	return 0;
}
bool Speaker_DeInit(void)
{
	EAMP_PRINTK("Speaker_DeInit");

	eamp_deinit();
	return true;
}
static ssize_t eamp_closespeaker()
{
    EAMP_PRINTK("");
    set_amp_gain(SPK_OFF);
    gsk_on = false;
    return 0;
}
 int eamp_command( unsigned int  type)
{
	switch(type)
	{
		case EAMP_SPEAKER_CLOSE:
		{
			eamp_closespeaker();
			break;
		}
		case EAMP_SPEAKER_OPEN:
		{
			eamp_openspeaker();
			break;
		}
		case EAMP_HEADPHONE_CLOSE:
		{
			eamp_closeheadPhone();
			break;
		}
		case EAMP_HEADPHONE_OPEN:
		{
			eamp_openheadPhone();
			break;
		}	
		default:
			EAMP_PRINTK("eamp_command TYPE = %d",type);
			return 0;
	}	
	return 0;
}
static int tpa2028_eamp_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) {
    int ret = 0;
    EAMP_PRINTK("tpa2028_eamp_i2c_probe success");

    new_client = client;
    ret = eamp_resetRegister();
    EAMP_PRINTK("client=%x !!",client);

    if(ret < 0) {
        new_client = NULL;
        EAMP_PRINTK("[ERROR] maybe, chip is died by .. !!",client);
        return -1;
    }else {
    	return 0;
	}
}
static ssize_t eamp_closespeaker(unsigned long param)
{
	EAMP_PRINTK("eamp_closespeaker param = %d gsk_on = %d", param, gsk_on);

	if ( param == 1 ) {
		if ( gsk_on ) {
			del_timer(&EXT_AMP_ON_Timer);	
			init_timer(&EXT_AMP_ON_Timer);

			spk_amp_on = TPA2015_SPK_ON;
			EXT_AMP_ON_Timer.expires = get_jiffies_64() + (9*HZ/10);  //(1200ms)	
			EXT_AMP_ON_Timer.data = spk_amp_on;
			EXT_AMP_ON_Timer.function = timer_spk_amp_on;

			add_timer(&EXT_AMP_ON_Timer);
			irrc_on = true;
		}
		mt_set_gpio_out(GPIO_SPK_AMP_L_EN, GPIO_OUT_ZERO);
		mt_set_gpio_out(GPIO_SPK_AMP_R_EN, GPIO_OUT_ZERO);
	}
	else { 
		mt_set_gpio_out(GPIO_SPK_AMP_L_EN, GPIO_OUT_ZERO);
		mt_set_gpio_out(GPIO_SPK_AMP_R_EN, GPIO_OUT_ZERO);
		
		gsk_on = false;
		irrc_on = false;
	}	
	
	return 0;
}
static void eamp_powerdown(void)
{
    EAMP_PRINTK("");
    eamp_closeheadPhone();
    eamp_closespeaker();
    return;
}
static ssize_t eamp_closeheadPhone()
{
	mt_set_gpio_out(GPIO_HP_AMP_EN, GPIO_OUT_ZERO);
	EAMP_PRINTK("eamp_closeheadphone : set GPIO_HP_AMP_EN to %d", mt_get_gpio_out(GPIO_HP_AMP_EN));	
	ghp_on = false;
  	return 0;
}
static ssize_t eamp_openspeaker()
{
    EAMP_PRINTK("");
	set_amp_gain(SPK_ON);
	gsk_on = true;
    return 0;
}
static ssize_t eamp_openheadPhone()
{
	mt_set_gpio_out(GPIO_HP_AMP_EN, GPIO_OUT_ONE);
	EAMP_PRINTK("eamp_openheadphone : set GPIO_HP_AMP_EN to %d", mt_get_gpio_out(GPIO_HP_AMP_EN));
	ghp_on = true;
    return 0;
}
static ssize_t eamp_getRegister(unsigned int regName)
{
    EAMP_PRINTK("Regname=%u",regName);
    if(regName >7)
        return -1;
    return I2CRead(regName);
}
static ssize_t eamp_setMode(unsigned long int param)
{
    EAMP_PRINTK("mode(%u)",param);
//                                                                                     
    set_mode = param;
//                                                                                   
    return 0;
}
bool Speaker_Register(void)
{
	EAMP_PRINTK("Speaker_Register");

	eamp_register();

	return true;
}
// mute device when INIT_DL1_STREAM
void AudioAMPDevice_mute(void)
{
	EAMP_PRINTK("AudioAMPDevice_mute");

	if(ghp_on)
		eamp_closeheadPhone();
	// now not control earpiece.
}
static int tpa2028_eamp_i2c_remove(struct i2c_client *client)
{
    EAMP_PRINTK("");
    new_client = NULL;
    i2c_unregister_device(client);
    i2c_del_driver(&tpa2028_eamp_i2c_driver);
    return 0;
}
// for AEE beep sound
void AudioAMPDevice_SpeakerLouderClose(void)
{
	EAMP_PRINTK("");
	if(!gsk_on)
		{
			return;
		}
	eamp_openspeaker();
}
static ssize_t eamp_getCtrlPointTable(unsigned long int param)
{
	EAMP_PRINTK("eamp_getCtrlPointTable CtrlPointTable(0x%x)",param);
	AMP_Control *ampCtl = (AMP_Control*)param;
	if(copy_to_user((void __user *)ampCtl->param2,(void *)gCtrPoint_table[ampCtl->param1], 1<<gCtrPoint[ampCtl->param1])){
		return -1;
	}
	return 0;
}
static int eamp_deinit()
{
	EAMP_PRINTK("");
	eamp_powerdown();
#if !defined(YDA165_SW_I2C)		
	i2c_init = false;
#endif
	return 0;
}
static int eamp_init()
{
#if !defined(YDA165_SW_I2C)	
	if(i2c_init)
		return 0;
	i2c_init=true;
	EAMP_PRINTK("");
	//i2c_register_board_info(EAMP_I2C_CHANNEL,&eamp_dev,1);
	if (i2c_add_driver(&eamp_i2c_driver)){
		EAMP_PRINTK("fail to add device into i2c");
		return -1;
	}
#else
	Init_i2c();
#endif
		eamp_poweron();
	return 0;
}
static ssize_t eamp_closeheadPhone()
{
	EAMP_PRINTK("eamp_closeheadPhone");

	mt_set_gpio_out(GPIO_HEADSET_AMP_EN, GPIO_OUT_ZERO);

	ghp_on = false;

	return 0;
}
static ssize_t eamp_setDevice(unsigned long int param)
{
    EAMP_PRINTK("set Device (%u)", param);
    set_device = param;
	if (set_mode == 2) {
		agc_fixed_gain = AGC_FIXED_GAIN_VOICE;
		I2CWrite(AGC_FIXED_GAIN_CONTROL, register_setting_mode ? register_setting_mode:agc_fixed_gain);
		EAMP_PRINTK("eamp_setDevice : set agc gain VOICE = 0x%x\n", agc_fixed_gain);
	} else if (set_device == DEVICE_OUT_SPEAKER_HEADSET_R) {
		agc_fixed_gain = AGC_FIXED_GAIN_COMBO_RING;
		I2CWrite(AGC_FIXED_GAIN_CONTROL, register_setting_mode ? register_setting_mode:agc_fixed_gain);
		EAMP_PRINTK("eamp_setDevice : set agc gain COMBO_PATH = 0x%x\n", agc_fixed_gain);
	} else {
		agc_fixed_gain = AGC_FIXED_GAIN_AUDIO;
		I2CWrite(AGC_FIXED_GAIN_CONTROL, register_setting_mode ? register_setting_mode:agc_fixed_gain);
		EAMP_PRINTK("eamp_setDevice : set agc gain AUDIO = 0x%x\n", agc_fixed_gain);
	}
    return 0;
}