static ssize_t eamp_openspeaker()
{
    EAMP_PRINTK("");
	set_amp_gain(SPK_ON);
	gsk_on = true;
    return 0;
}
static ssize_t eamp_closespeaker()
{
    EAMP_PRINTK("");
    set_amp_gain(SPK_OFF);
    gsk_on = false;
    return 0;
}
static ssize_t
tpa2028d2_power_on_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
	int val;

	if (sscanf(buf, "%d", &val) != 1)
		return -EINVAL;
	amp_data[1]->state = val;

	if ( val ==0 )
		set_amp_gain(1, SPK_OFF);
	else if (val == 1 )
		set_amp_gain(1, SPK_ON);
	else
		return -EINVAL;

	return count;
}
static int tpa2028d_amp_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	struct amp_config *data;
	struct audio_amp_platform_data *pdata;
	struct i2c_adapter *adapter = client->adapter;
	int err;
	int	 i;
	int	amp_no=0;

//	D("[tpa2028d_amp_probe ] id->name(%s) amp_no(%d) \n", id->name, pamp_no);

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
		err = -EOPNOTSUPP;
		return err;
	}

	pdata = client->dev.platform_data;
	if (pdata == NULL) {
		D("platform data is null\n");
		return -ENODEV;
	}

	data = kzalloc(sizeof(struct amp_config), GFP_KERNEL);
	if (data == NULL)
		return -ENOMEM;

	if ( !strncmp(id->name,"tpa2028d_amp", 12) ) {
		amp_no=0;
		for (i = 0; i < ARRAY_SIZE(tpa2028d_device_attrs); i++) {
			err = device_create_file(&client->dev, &tpa2028d_device_attrs[i]);
			if (err)
				return err;
		}
	}
	else if ( !strncmp(id->name,"tpa2028d2_amp", 13) ) {
		amp_no=1;
		for (i = 0; i < ARRAY_SIZE(tpa2028d2_device_attrs); i++) {
			err = device_create_file(&client->dev, &tpa2028d2_device_attrs[i]);
			if (err)
				return err;
		}
	}

	D("[tpa2028d_amp_probe ] id->name(%s) amp_no(%d) \n", id->name, amp_no);
	amp_data[amp_no] = data;
	amp_data[amp_no]->pdata = pdata;
	amp_data[amp_no]->state = -1;	// Speaker initial status value   0:Speaker Off     1: Speaker On
	data->client = client;
	
	i2c_set_clientdata(client, data);

	set_amp_gain(amp_no, SPK_OFF);

	return 0;
}
Пример #5
0
int idle_mode_enable(struct snd_soc_codec *codec, int mode)
{
	P("Enable Idle Mode : %d\n", mode);

	set_bias(codec, mode);

	switch(mode) {
		case 0:
			break;

		case MM_AUDIO_PLAYBACK_RCV :
			P("set MM_AUDIO_PLAYBACK_RCV");
			codec->write(codec, 0x00, 0x01); 	// VCOM power up
			mdelay(1); 		// wait 100ns
			codec->write(codec, 0x00, 0xC1); 	// D/A power-up
			codec->write(codec, 0x0F, 0x04); 	// LOPS1="1",use for pop noise cancel 
			mdelay(1);		// wait 100ns
			codec->write(codec, 0x0F, 0x07); 	// PML01, PMRO1 power-up
			mdelay(30); 	// wait more than 300ms
			codec->write(codec, 0x0F, 0x23);	// LOPS1='0', RCV mono
			break;

		case MM_AUDIO_PLAYBACK_SPK :
		case MM_AUDIO_PLAYBACK_HP :
		case MM_AUDIO_PLAYBACK_SPK_HP :
		case MM_AUDIO_PLAYBACK_RING_SPK_HP :
			P("set MM_AUDIO_PLAYBACK_SPK");
			codec->write(codec, 0x00, 0x01); 	// VCOM power up
			mdelay(1); 		// wait 100ns
			codec->write(codec, 0x00, 0xC1); 	// D/A power-up
			codec->write(codec, 0x10, 0x63); 	// PMLO2,PMRO2,PMLO2S,PMRO2s='1'
			mdelay(1);		// wait 100ns
			codec->write(codec, 0x10, 0x67); 	// MUTEN='1'
			if (mode != MM_AUDIO_PLAYBACK_SPK)
				mdelay(130);
			break;

		case MM_AUDIO_PLAYBACK_BT :
			P("set MM_AUDIO_PLAYBACK_BT");
			codec->write(codec, 0x15, 0x00); 	// 5-band EQ Rch=STDI Rch
			codec->write(codec, 0x15, 0x41); 	// SRC-A = MIX Rch
			mdelay(1);		// wait 100ns
			codec->write(codec, 0x00, 0x01); 	// PMPCM, PMSRA='1', PCM ref = BICKA
			mdelay(40);
			
			break;

		default :
			printk("[SOUND MODE] invalid IDLE mode!!! \n");
	}

	set_amp_gain(codec, mode);

	return 0;
}
static void tpa2028d_amp_shutdown(struct i2c_client *client)
{
	int amp_no =0;
	if ( !strncmp(client->name,"tpa2028d_amp", 12) ) {
		amp_no=0;
	} else if ( !strncmp(client->name,"tpa2028d2_amp", 13) ) {
		amp_no=1;
	}
	D("%s : shutdown no %d amp\n",__func__, amp_no);
	set_amp_gain(amp_no, SPK_OFF);
}
Пример #7
0
static int tpa2028d_amp_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	struct amp_config *data;
	struct audio_amp_platform_data *pdata;
	struct i2c_adapter *adapter = client->adapter;
	int err, i;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
		err = -EOPNOTSUPP;
		return err;
	}

	pdata = client->dev.platform_data;
	if (pdata == NULL) {
		D("platform data is null\n");
		return -ENODEV;
	}

	data = kzalloc(sizeof(struct amp_config), GFP_KERNEL);
	if (data == NULL)
		return -ENOMEM;

	amp_data = data;
	amp_data->pdata = pdata;
	data->client = client;
	i2c_set_clientdata(client, data);

	set_amp_gain(SPK_OFF);

	for (i = 0; i < ARRAY_SIZE(tpa2028d_device_attrs); i++) {
		err = device_create_file(&client->dev, &tpa2028d_device_attrs[i]);
		if (err)
			return err;
	}
	return 0;
}
static ssize_t eamp_resetRegister()
{
	set_amp_gain(SPK_OFF);
	eamp_closeheadPhone();
	return 0;
}
static int tpa2028d_amp_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	struct amp_config *data;
	struct audio_amp_platform_data *pdata;
	struct i2c_adapter *adapter = client->adapter;
	int err;
	int	 i;
	int	amp_no=0;

//	D("[tpa2028d_amp_probe ] id->name(%s) amp_no(%d) \n", id->name, pamp_no);
	pr_err("%s: [tpa2028d_amp_probe ] id->name(%s) \n", __func__, client->name);

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
		err = -EOPNOTSUPP;
		return err;
	}

#ifdef CONFIG_SND_SOC_TPA2028D_STEREO
	if (&client->dev.of_node) {
		pdata = devm_kzalloc(&client->dev,
				sizeof(struct audio_amp_platform_data),
				GFP_KERNEL);
		if (!pdata) {
			pr_err("%s: Failed to allocate memory\n", __func__);
			return -ENOMEM;
		}
		err = tpa2028d_parse_dt(&client->dev, pdata);
		if (err != 0)
			return err;
	} else {
		pdata = client->dev.platform_data;
	}
#else
	pdata = client->dev.platform_data;
#endif
	if (pdata == NULL) {
		D("platform data is null\n");
		return -ENODEV;
	}

	data = kzalloc(sizeof(struct amp_config), GFP_KERNEL);
	if (data == NULL)
		return -ENOMEM;

	if ( !strncmp(client->name,"tpa2028d1", 9) ) {
		amp_no=0;
		for (i = 0; i < ARRAY_SIZE(tpa2028d_device_attrs); i++) {
			err = device_create_file(&client->dev, &tpa2028d_device_attrs[i]);
			if (err)
				return err;
		}
	}

	else if ( !strncmp(client->name,"tpa2028d2", 9) ) {
		amp_no=1;
		for (i = 0; i < ARRAY_SIZE(tpa2028d2_device_attrs); i++) {
			err = device_create_file(&client->dev, &tpa2028d2_device_attrs[i]);
			if (err)
				return err;
		}
	}

	D("[tpa2028d_amp_probe ] client->name(%s) amp_no(%d) \n", client->name, amp_no);
	amp_data[amp_no] = data;
	amp_data[amp_no]->pdata = pdata;
	amp_data[amp_no]->state = -1;	// Speaker initial status value   0:Speaker Off     1: Speaker On
	data->client = client;

	i2c_set_clientdata(client, data);

#ifdef CONFIG_SND_SOC_TPA2028D_STEREO
	err = gpio_request(amp_data[amp_no]->pdata->enable_gpio, "speaker amp enable");
	if (err) {
		pr_err("%s : Error requesting GPIO %d err(%d)\n",
				__func__, amp_data[amp_no]->pdata->enable_gpio, err);
		return err;
	}
#endif
	set_amp_gain(amp_no, SPK_OFF);

	return 0;
}
Пример #10
0
int path_enable(struct snd_soc_codec *codec, int mode)
{
	P("Enable PATH : 0x%02x\n", mode);

	/* general init register */
	if(mode) {
		//codec->write(codec, 0x02, 0x01); 	// PLL Mode and Power up
		codec->write(codec, 0x01, reg_pll_mode); 	
		codec->write(codec, 0x02, 0x03); 	// PLL Mode and Power up, Master Mode
		codec->write(codec, 0x03, 0x03); 	// I2S mode
	}

	/* Set gain value */
	set_codec_gain(codec, mode);	

	/* Set Bias */
	set_bias(codec, mode);

	/* Set path register sequence */
	switch(mode) {
		case 0:
			break;

		case MM_AUDIO_PLAYBACK_RCV :
			P("set MM_AUDIO_PLAYBACK_RCV");
			codec->write(codec, 0x09, 0x01); 	// D/A Lch -> Lout1
			codec->write(codec, 0x0A, 0x01); 	// D/A Rch -> Rout1
			codec->write(codec, 0x00, 0x01); 	// VCOM power up
			mdelay(1); 		// wait 100ns
			codec->write(codec, 0x00, 0xC1); 	// D/A power-up
			codec->write(codec, 0x0F, 0x04); 	// LOPS1="1",use for pop noise cancel 
			mdelay(1);		// wait 100ns
			codec->write(codec, 0x0F, 0x07); 	// PML01, PMRO1 power-up
			mdelay(30); 	// wait more than 300ms
			codec->write(codec, 0x0F, 0x23);	// LOPS1='0', RCV mono
			break;

		case MM_AUDIO_PLAYBACK_SPK :
		case MM_AUDIO_PLAYBACK_HP :
		case MM_AUDIO_PLAYBACK_SPK_HP :
		case MM_AUDIO_PLAYBACK_RING_SPK_HP :
			P("set MM_AUDIO_PLAYBACK_SPK");
			codec->write(codec, 0x0B, 0x01); 	// D/A Lch -> Lout2
			codec->write(codec, 0x0C, 0x01); 	// D/A Rch -> Rout2
			codec->write(codec, 0x00, 0x01); 	// VCOM power up
			mdelay(1); 		// wait 100ns
			codec->write(codec, 0x00, 0xC1); 	// D/A power-up
			codec->write(codec, 0x10, 0x63); 	// PMLO2,PMRO2,PMLO2S,PMRO2s='1'
			mdelay(1);		// wait 100ns
			codec->write(codec, 0x10, 0x67); 	// MUTEN='1'
			if (mode != MM_AUDIO_PLAYBACK_SPK)
				mdelay(130);
			break;

		case MM_AUDIO_PLAYBACK_BT :
			P("set MM_AUDIO_PLAYBACK_BT");
			codec->write(codec, 0x15, 0x00); 	// 5-band EQ Rch=STDI Rch
			codec->write(codec, 0x15, 0x41); 	// SRC-A = MIX Rch
			mdelay(1);		// wait 100ns
			codec->write(codec, 0x00, 0x01); 	// PMPCM, PMSRA='1', PCM ref = BICKA
			mdelay(40);
			
			break;

		case MM_AUDIO_VOICECALL_RCV :
			P("set MM_AUDIO_VOICECALL_RCV");
			codec->write(codec, 0x0F, 0x20);	// RCP/RCN mode
			codec->write(codec, 0x11, 0xA0);	// LOP/LON, gain=0dB
			codec->write(codec, 0x0A, 0x20);	// MIC-AMP Rch -> RCP/RCN
			codec->write(codec, 0x0D, 0x20);	// MIC-AMP Lch -> LOP/LON
			codec->write(codec, 0x04, 0x9C);	// MIC-AMP Lch=IN1+/-, IN4+/- Differential Input
			codec->write(codec, 0x00, 0x01);	// VCOM power-up
			codec->write(codec, 0x00, 0x0D);	// MIC-AMP, A/D power-up
			codec->write(codec, 0x06, 0x03);	// PMLOOPL, PMLOOPR power-up
			codec->write(codec, 0x0F, 0x27);	// PMLO1, PMRO1 power-up
			mdelay(1);
			codec->write(codec, 0x0F, 0x23);	// LOPS1=0
			codec->write(codec, 0x11, 0x24);	// LOPS3=1, use for pop noise cancel
			codec->write(codec, 0x11, 0x27);	// PMLO3, PMRO3 power-up
			mdelay(30); // Wait more than 300ms(Output capacitor=1uF, AVDD=3.3V)
			codec->write(codec, 0x11, 0x23);	// LOPS3=0

			/* MIC-AMP Rch + A/P Rch => RCP/RCN */
			codec->write(codec, 0x00, 0x8D);	// DAC-Rch power-up
			mdelay(2);
			codec->write(codec, 0x0A, 0x21);	// (MIC-AMP-Rch mixing DAC-Rch) to RCP/RCN

			break;
		case MM_AUDIO_VOICECALL_SPK :
		case MM_AUDIO_VOICECALL_HP :
			{
			P("set MM_AUDIO_VOICECALL_SPK,HP");
			if (mode == MM_AUDIO_VOICECALL_SPK)
				codec->write(codec, 0x04, 0x9C);// MIC-AMP Lch= IN3+/-, Rch= IN4+/-
		
			if(tty_mode == 2) {
				codec->write(codec, 0x0F, 0x20);// RCP/RCN mode
				codec->write(codec, 0x0A, 0x20);// MIC-AMP Rch -> RCP/RCN
			}
			else {
				codec->write(codec, 0x0C, 0x20);// MIC-AMP-Lch to Lout2
				codec->write(codec, 0x10, 0x08);// MIC-AMP-Lch to Rout2
			}
				codec->write(codec, 0x0D, 0x20);// MIC-AMP Lch -> LOP/LON
	
			if (mode == MM_AUDIO_VOICECALL_SPK)
				codec->write(codec, 0x11, 0x20);// LOP/LON gain=-6dB
			else // HP
				codec->write(codec, 0x11, 0xA0);// LOP/LON gain=0dB
			if ((mode == MM_AUDIO_VOICECALL_SPK)|(tty_mode == 3)) {
				codec->write(codec, 0x04, 0x9C);// MIC-AMP Lch= IN3+/-, Rch= IN4+/-
			}
			else
				codec->write(codec, 0x04, 0xCE);// MIC-AMP Lch=IN3+/-, Rch=IN4+/-
					
			/* Other setting if needed except for power setting */
			codec->write(codec, 0x00, 0x01);	// VCOM power-up
			codec->write(codec, 0x06, 0x03);	// PMLOOPL, PMLOOPR power-up
			codec->write(codec, 0x00, 0x0D);	// MIC-AMP power-up
			if(tty_mode == 2) {
				codec->write(codec, 0x0F, 0x27);// PMLO1, PMRO1 power-up
				mdelay(1);
				codec->write(codec, 0x0F, 0x23);// LOPS1=0
			}
			else {
				codec->write(codec, 0x10, 0x73);// PMLO2, PMRO2, PMLO2S,PMRO2s=1
				codec->write(codec, 0x10, 0x77);// MUTEN=1
			}
			if ((mode == MM_AUDIO_VOICECALL_SPK)|(tty_mode == 2))
				codec->write(codec, 0x11, 0x24);// LOPS3=1, use for pop noise cancel
			else // HP
				codec->write(codec, 0x11, 0xA4);// LOPS3=1, use for pop noise cancel
		
			if ((mode == MM_AUDIO_VOICECALL_SPK)|(tty_mode == 2))
				codec->write(codec, 0x11, 0x27);// PMLO3, PMRO3 power-up
			else // HP
				codec->write(codec, 0x11, 0xA7);// PMLO3, PMRO3 power-up
					
			mdelay(30); 		// Wait more than 300ms(Output capacitor=1uF, AVDD=3.3V)
					
			if ((mode == MM_AUDIO_VOICECALL_SPK)|(tty_mode == 2))
				codec->write(codec, 0x11, 0x23);	// LOPS3=0 , gain = -6dB
			else // HP
				codec->write(codec, 0x11, 0xA3);	// LOPS3=0 , gain = 0dB
					
			/* MIC-AMP Rch + A/P Rch => Lout2/Rout2 */
			if(tty_mode == 2) {
				codec->write(codec, 0x00, 0x8D);// DAC-Rch power-up
				mdelay(2);
				codec->write(codec, 0x0A, 0x21);// (MIC-AMP-Rch mixing DAC-Rch) to RCP/RCN
			}
		       	else {
				codec->write(codec, 0x00, 0xCD);// DAC-Rch power-up
				mdelay(2);
				codec->write(codec, 0x0B, 0x01);// (MIC-AMP-Rch mixing DAC-Rch) to Lout2
				codec->write(codec, 0x0C, 0x21);// (MIC-AMP-Rch mixing DAC-Rch) to Rout2
			}
			break;
			}
		case MM_AUDIO_VOICECALL_BT :
			P("set MM_AUDIO_VOICECALL_BT");
			codec->write(codec, 0x01, 0xF8); 		// fs=44.1kHz, MCKI=19.2MHz input

			codec->write(codec, 0x11, 0xA0); 		// LOP/LON, gain=0dB
			codec->write(codec, 0x0D, 0x01); 		// D/A Lch -> LOP/LON
			codec->write(codec, 0x04, 0xCE); 		// MIC-AMP Rch= IN4+/- be selected
			codec->write(codec, 0x15, 0x14); 		// 5-band EQ Lch=SRC-B, Rch=SVOLA Rch
			codec->write(codec, 0x19, 0x41); 		// OVOLC, SRC-A : Rch
			codec->write(codec, 0x00, 0x01); 		// VCOM power-up
			mdelay(40);
			codec->write(codec, 0x00, 0x69); 		// PMVCM, PMMICR, PMADR, PMDAL, PMDAR power up
			codec->write(codec, 0x53, 0x17); 		// PLLBT1,PMSRA/B, PMPCM power up
													//PLLBT lock time: max 40ms (base on BICKA)
			mdelay(40);
			codec->write(codec, 0x11, 0x24); 		// LOPS3=1, use for pop noise cancel
			mdelay(1); 		// Wait more than 100ns
			codec->write(codec, 0x11, 0x27); 		// PMLO3, PMRO3 power-up
			mdelay(100);							// Wait more than 300ms
													// (Output capacitor=1uF, AVDD=3.3V)
			codec->write(codec, 0x11, 0x23); 		// LOPS3=0
			
			/* Mixing ADC Rch and A/P Rch */
			codec->write(codec, 0x15, 0x18); 		// Lch: from SRC-B;
													//Rch: from (SVOLA Rch + SDTI Rch)
			break;
		
		case MM_AUDIO_VOICEMEMO_MAIN :
			P("set MM_AUDIO_VOICEMEMO_MAIN");
			mic_set_path(AK4671_MIC_PATH_MAIN);
			codec->write(codec, 0x04, 0x14); 		// => MIC-AMP Lch=IN1+/-
			codec->write(codec, 0x0B, 0x01); 		// D/A Lch -> Lout2
			codec->write(codec, 0x0C, 0x01); 		// D/A Rch -> Rout2
			codec->write(codec, 0x00, 0x01); 		// => VCOM power-up
			mdelay(2); 		// Wait more than 100ns
			codec->write(codec, 0x00, 0xD5); 		// D/A power-up
			codec->write(codec, 0x10, 0x63); 		// PMLO2,PMRO2,PMLO2S,PMRO2s='1'
			mdelay(1);		// wait 100ns
			codec->write(codec, 0x10, 0x67); 		// MUTEN='1'

			break;

		case MM_AUDIO_VOICEMEMO_SUB :
			P("set MM_AUDIO_VOICEMEMO_SUB");
			mic_set_path(AK4671_MIC_PATH_MAIN);
			codec->write(codec, 0x04, 0x14); 		// => MIC-AMP Lch=IN1+/-
			codec->write(codec, 0x0B, 0x01); 		// D/A Lch -> Lout2
			codec->write(codec, 0x0C, 0x01); 		// D/A Rch -> Rout2
			codec->write(codec, 0x00, 0x01); 		// => VCOM power-up
			mdelay(2); 		// Wait more than 100ns
			codec->write(codec, 0x00, 0xD5); 		// D/A power-up
			codec->write(codec, 0x10, 0x63); 		// PMLO2,PMRO2,PMLO2S,PMRO2s='1'
			mdelay(1);		// wait 100ns
			codec->write(codec, 0x10, 0x67); 		// MUTEN='1'
			
			break;
		case MM_AUDIO_VOICEMEMO_EAR :
			P("set MM_AUDIO_VOICEMEMO_EAR");
			codec->write(codec, 0x04, 0x42); 		// => MIC-AMP Lch=IN3+/-
			codec->write(codec, 0x0B, 0x01); 		// D/A Lch -> Lout2
			codec->write(codec, 0x0C, 0x01); 		// D/A Rch -> Rout2
			codec->write(codec, 0x00, 0x01); 		// => VCOM power-up
			mdelay(2); 		// Wait more than 100ns
			codec->write(codec, 0x00, 0xD5); 		// D/A power-up
			codec->write(codec, 0x10, 0x63); 		// PMLO2,PMRO2,PMLO2S,PMRO2s='1'
			mdelay(1);		// wait 100ns
			codec->write(codec, 0x10, 0x67); 		// MUTEN='1'
			mdelay(130);
			break;
		case MM_AUDIO_VOICEMEMO_BT :
			P("set MM_AUDIO_VOICEMEMO_BT");
			codec->write(codec, 0x59, 0x10); 		// => SDTO Lch=SRC-B
			codec->write(codec, 0x00, 0x01); 		// => VCOM power-up
			mdelay(2); 		//Wait more than 100ns
			codec->write(codec, 0x53, 0x0F); 		// => PMPCM,PMSRA, PMSRB=1
													// PCM reference= BICKA(VCOCBT=10kohm&4.7nF)
			mdelay(40); 		// Lock time= 40ms
			break;

		case MM_AUDIO_FMRADIO_RCV :
			P("set MM_AUDIO_FMRADIO_RCV");
			codec->write(codec, 0x09, 0x04);	// => LOUT1= LIN2
			codec->write(codec, 0x0A, 0x04);	// => ROUT1= RIN2
			codec->write(codec, 0x08, 0xB5);	// => gain=0dB(default)
			codec->write(codec, 0x00, 0x01);	// => VCOM power-up
			mdelay(2);							// Wait more than 100ns
			codec->write(codec, 0x07, 0x0C);	// => PMAINL2, PMAINR2 power-up
			codec->write(codec, 0x0F, 0x04);	// => LOPS1=1
			mdelay(2);							// Wait more than 100ns
			codec->write(codec, 0x0F, 0x07);	// => PMLO1, PMRO1 power-up
			mdelay(310);						// Wait more than 300ms 
												// (Output capacitor=1uF, AVDD=3.3V)
			codec->write(codec, 0x0F, 0x03);	// => LOPS1=0
			codec->write(codec, 0x0F, 0x23);	// LOPS1='0', RCV mono

                   /* RIN2(FM_ROUT) Rch + DAC(A/P) Rch => RCP/RCN */
			codec->write(codec, 0x00, 0x81);	// DAC-Rch power-up
			mdelay(2);
			codec->write(codec, 0x0A, 0x05);	// (FM_ROUT mixing DAC-Rch) to RCP/RCN
			break;

		case MM_AUDIO_FMRADIO_SPK :
		case MM_AUDIO_FMRADIO_HP :
		case MM_AUDIO_FMRADIO_SPK_HP : 		            
			P("set MM_AUDIO_FMRADIO_SPK, HP, SPK_HP");

#if 0 // for FM radio recording
			/* FM Radio -> LOUT2/ROUT2 */
			codec->write(codec, 0x0B, 0x04);	// => LOUT2= LIN2
			codec->write(codec, 0x0C, 0x04);	// => ROUT2= RIN2
			// codec->write(codec, 0x08, 0xD5);	// => L1OUT/R1OUT = 0dB, L2/R2 gain=0dB -> 6dB
			codec->write(codec, 0x07, 0x0C);	// => PMAINL2, PMAINR2 = 1
			codec->write(codec, 0x00, 0x01);	// => VCOM power-up
			mdelay(2);							// Wait more than 100ns
			codec->write(codec, 0x10, 0x63);	// => PMLO2, PMRO2, PMLO2S, PMRO2S = 1
			mdelay(2);							// Wait more than 100ns
			codec->write(codec, 0x10, 0x67);	// => MUTEN=1

			mdelay(2);							// Wait more than 100ns
			/* MIC-AMP-Lch -> ADC Lch/Rch -> AP Lch/Rch */
			codec->write(codec, 0x02, 0x26);	// MCKO out, BCKO=64fs, PLL master mode
			codec->write(codec, 0x04, 0x05); 	// MIC-AMP Lch:LIN2, Rch:RIN2
			codec->write(codec, 0x01, 0xF8);	// fs=44.1kHz, MCKI=19.2MHz input
			codec->write(codec, 0x02, 0x27);	// PLL power-up
			mdelay(40);
			codec->write(codec, 0x00, 0x3D);	// ADC power-up
			mdelay(24);

                    	/* FM Radio + DAC => Lout2/Rout2 */
			codec->write(codec, 0x00, 0xC1);	// DAC-Rch power-up
			mdelay(2);
			codec->write(codec, 0x0B, 0x05);	// (FM_LOUT mixing DAC-Lch) to Lout2
			codec->write(codec, 0x0C, 0x05);	// (FM_ROUT mixing DAC-Rch) to Rout2
#else
			/* FM Radio Path Setting */
			codec->write(codec, 0x0B, 0x20);	// MIC-AMP Lch => LOUT2
			codec->write(codec, 0x0C, 0x20);	// MIC-AMP Rch => ROUT2

		  	codec->write(codec, 0x04, 0x05); 	// MDIF2[5] = 0 , [3:0] = 0x5 
			// codec->write(codec, 0x08, 0xB5);	// => gain=0dB(default)
			codec->write(codec, 0x07, 0x0C);	// => PMAINL2, PMAINR2 = 1
			codec->write(codec, 0x00, 0x01);	// => VCOM power-up
			mdelay(2);							// Wait more than 100ns
			codec->write(codec, 0x00, 0x0D);	// => MIC-AMP
			codec->write(codec, 0x06, 0x03);	// => PMLOOPL,PMLOOPR power-up
			codec->write(codec, 0x10, 0x63);	// => PMLO2, PMRO2, PMLO2S, PMRO2S = 1
			mdelay(2);							// Wait more than 100ns
			codec->write(codec, 0x10, 0x67);	// => MUTEN=1

			/* FM Radio Recording */
			codec->write(codec, 0x01, 0xF8);	// Fs = 44.1kHz, MCKI=19.2MHz input
			// codec->write(codec, 0x05, 0x55);	// MIC-AMP Lch/Rch Gain = 0dB
			// ALC Setting
			codec->write(codec, 0x16, 0x05);	// WTM[2:0] = 1(5.8ms) , [ZTM[1:0] = 1(3.8ms)
			codec->write(codec, 0x14, 0xE1);	// +30dB
			codec->write(codec, 0x17, 0x01);	// LMTH[1:0] = 1 
			codec->write(codec, 0x18, 0x03);	// ALC Enable
			codec->write(codec, 0x00, 0x3D);	// => MIC-AMP + A/D power-up
		
			/* AP Path Setting */	
			/* FM Radio + DAC => LOUT2/ROUT2  */
			codec->write(codec, 0x00, 0xFD); 	// => MIC-AMP + ADC Lch/Rch power-up + DAC Rch/Lch power-up
			codec->write(codec, 0x0B, 0x21);	// => MIC_AMP Lch + DAC Lch => LOUT2
			codec->write(codec, 0x0C, 0x21); 	// => MIC_AMP Rch + DAC Rch => ROUT2
#endif

			break;

		case MM_AUDIO_FMRADIO_BT :
			P("set MM_AUDIO_FMRADIO_BT");
			codec->write(codec, 0x04, 0x24);	// => MIC-AMP Rch=IN2+/-
			codec->write(codec, 0x19, 0x41);	// => SRC-A= MIX Rch
			codec->write(codec, 0x15, 0x04);	// => 5-band EQ Rch=SVOLA Rch
			codec->write(codec, 0x00, 0x01);	// => VCOM power-up
			mdelay(2); 							// Wait more than 100ns
			codec->write(codec, 0x00, 0x39);	// => A/D, MIC-AMP Rch power-up
			codec->write(codec, 0x53, 0x00);	// => PMPCM, PMSRA, PMSRB= ¡°1¡±,
												// PCM reference= BICKA(if VCOCBT=10kohm & 4.7nF)
			mdelay(40); 						// Lock time= 40ms
			break;

		default :
			printk("[SOUND MODE] invalid mode: %x !!!!! \n", mode);
	}

	/* disable soft mute */
	if (mode ==  MM_AUDIO_VOICECALL_BT)
		codec->write(codec, 0x19, 0x41); 		// OVOLC, SRC-A : Rch
	else
	codec->write(codec, 0x19, 0x01); 	// disable soft mute 

	set_amp_gain(codec, mode);

	return 0;
}