예제 #1
0
static void set_bias (struct snd_soc_codec *codec, int mode)
{
	P("BIAS Control (%x)", mode);

	/* Set MIC BIAS */
	/* VOICECALL, VOICEMEMO */
	if ((mode & 0xf0) == MM_AUDIO_VOICECALL || 
		(mode & 0xf0) == MM_AUDIO_VOICEMEMO) 
	{
		if( mode == MM_AUDIO_VOICECALL_RCV || 
		    mode == MM_AUDIO_VOICEMEMO_MAIN || 
		    mode == MM_AUDIO_VOICEMEMO_SUB) 
		{
			P("Main Mic");
			mic_set_path(AK4671_MIC_PATH_MAIN);
		} 
		else if ( mode== MM_AUDIO_VOICECALL_SPK ) 
		{
			P("Sub Mic");
			mic_set_path(AK4671_MIC_PATH_SUB);
		}

		P("Mic En : 1");
		mic_enable(1);
	}
	else 
	{	
		P("Mic En : 0");
		mic_enable(0);
	}	

	/* Disable Mics for all BT operations */
	if ((mode & 0x0f) == MM_AUDIO_OUT_BT)
	{	
		P("Mic En : 0");
		mic_enable(0);
	}	

	/* Set AMP BIAS */
	/* SPK, EARJACK, VOICEMEMO */
	if ((mode & 0x0f) == MM_AUDIO_OUT_SPK || 
		(mode & 0x0f) == MM_AUDIO_OUT_HP || 
		(mode & 0x0f) == MM_AUDIO_OUT_SPK_HP || 
		(mode & 0x0f) == MM_AUDIO_OUT_RING_SPK_HP || 
		(mode & 0xf0) == MM_AUDIO_VOICEMEMO ) 
	{
		if (mode != MM_AUDIO_VOICECALL_BT)
			amp_enable(1);	
	} else
		amp_enable(0);	
}
예제 #2
0
static int ak4671_set_mic_path(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	P("");
	if (ucontrol->value.integer.value[0] == 0) { // MAIN MIC
		mic_set_path(AK4671_MIC_PATH_MAIN);
	} else if (ucontrol->value.integer.value[0] == 1) { // SUB MIC
		mic_set_path(AK4671_MIC_PATH_SUB);
	} else {
		P("invalid Mic value");
		return -1;
	}
	ak4671_mic_path = ucontrol->value.integer.value[0];

	return 1;
}
예제 #3
0
static int ak4671_probe(struct platform_device *pdev)
{
	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
	struct ak4671_setup_data *setup;
	struct snd_soc_codec *codec;
	struct ak4671_priv *ak4671;
	int ret = 0;

	printk(KERN_INFO "AK4671 Audio Codec %s", AK4671_VERSION);

	/* Board Specific function */
	audio_init();
	if (amp_init() < 0)
		printk("amp init failed.\n");
	audio_power(1);
	ak4671_power = 1;
	amp_set_path(AK4671_AMP_PATH_SPK);
	mic_set_path(AK4671_MIC_PATH_MAIN);

	ret = device_create_file(&pdev->dev, &dev_attr_ak4671_control);

	setup = socdev->codec_data;
	codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
	if (codec == NULL)
		return -ENOMEM;

	ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL);
	if (ak4671 == NULL) {
		kfree(codec);
		return -ENOMEM;
	}

	codec->private_data = ak4671;
	socdev->codec = codec;
	mutex_init(&codec->mutex);
	INIT_LIST_HEAD(&codec->dapm_widgets);
	INIT_LIST_HEAD(&codec->dapm_paths);

	ak4671_socdev = socdev;

#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
	if (setup->i2c_address) {
		normal_i2c[0] = setup->i2c_address;
		codec->hw_write = (hw_write_t)i2c_master_send;
		codec->hw_read = (hw_read_t)i2c_master_recv;
		ret = i2c_add_driver(&ak4671_i2c_driver);
		if (ret != 0)
			printk(KERN_ERR "can't add i2c driver");
	}
#else
	/* Add other interfaces here */
#endif

	if (ret != 0) {
		kfree(codec->private_data);
		kfree(codec);
	}
	return ret;
}
예제 #4
0
int path_enable(struct snd_soc_codec *codec, int mode)
{
    P("Enable PATH : 0x%x\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_path_gain(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 30ms
        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 :
        //P("set MM_AUDIO_PLAYBACK_SPK, HP, SPK_HP");
        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'
        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, 0xA4);	// LOPS3=1, use for pop noise cancel
        codec->write(codec, 0x11, 0xA7);	// PMLO3, PMRO3 power-up
        mdelay(30); 				// Wait more than 30ms(Output capacitor=1uF, AVDD=3.3V)
        codec->write(codec, 0x11, 0xA3);	// 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 :
    case MM_AUDIO_VOICECALL_SPK_LOOP:
        //P("set MM_AUDIO_VOICECALL_SPK,HP");
        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
        codec->write(codec, 0x11, 0xA0); 	// LOP/LON gain=0dB
        if (mode == MM_AUDIO_VOICECALL_SPK || mode == MM_AUDIO_VOICECALL_SPK_LOOP)
            codec->write(codec, 0x04, 0x8D); 	// MIC-AMP Lch= LIN2, Rch= IN4+/-
        //codec->write(codec, 0x04, 0x0D); 	// MIC-AMP Lch= LIN2, Rch= RIN4
        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
        codec->write(codec, 0x10, 0x73); 	// PMLO2, PMRO2, PMLO2S,PMRO2s=1
        codec->write(codec, 0x10, 0x77); 	// MUTEN=1
        codec->write(codec, 0x11, 0xA4); 	// LOPS3=1, use for pop noise cancel
        codec->write(codec, 0x11, 0xA7); 	// PMLO3, PMRO3 power-up
        mdelay(30); 				// Wait more than 30ms(Output capacitor=1uF, AVDD=3.3V)
        codec->write(codec, 0x11, 0xA3); 	// LOPS3=0

        /* MIC-AMP Rch + A/P Rch => Lout2/Rout2 */
        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

        mdelay(40);					//PLLBT lock time: max 40ms (base on BICKA)
        codec->write(codec, 0x11, 0xA4); 		// LOPS3=1, use for pop noise cancel
        mdelay(1); 		// Wait more than 100ns
        codec->write(codec, 0x11, 0xA7); 		// PMLO3, PMRO3 power-up
        mdelay(100);					// Wait more than 100ms
        // (Output capacitor=1uF, AVDD=3.3V)
        codec->write(codec, 0x11, 0xA3); 		// 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_SUB);
        codec->write(codec, 0x04, 0x04); 		// => MIC-AMP Lch=LIN2
        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'
        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;
    default :
        printk("[SOUND MODE] invalid mode!!! \n");
    }


    set_bias(codec, mode);

    return 0;
}
예제 #5
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;
}
예제 #6
0
int path_change(struct snd_soc_codec *codec, int to_mode, int from_mode)
{
	int ret = 1;

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

	switch (to_mode) {
		case MM_AUDIO_PLAYBACK_SPK :
		case MM_AUDIO_PLAYBACK_HP :
			switch (from_mode) {
				case MM_AUDIO_VOICEMEMO_MAIN :
				case MM_AUDIO_VOICEMEMO_SUB :
				case MM_AUDIO_VOICEMEMO_EAR :
					P("VOICEMEMO->PLAYBACK");
					set_codec_gain(codec, to_mode);
					if (to_mode == MM_AUDIO_PLAYBACK_SPK) 
						amp_set_path(AK4671_AMP_PATH_SPK);
					else
						amp_set_path(AK4671_AMP_PATH_HP);
				
					codec->write(codec, 0x00, 0xC1);        // DAC Enable, ADC Disable, MicAMP Disable
					break;
				default :
					ret = -1;
					break;
			}
			break;

		case MM_AUDIO_PLAYBACK_RCV :
		case MM_AUDIO_PLAYBACK_SPK_HP :
		case MM_AUDIO_PLAYBACK_RING_SPK_HP :
		case MM_AUDIO_PLAYBACK_BT :
		case MM_AUDIO_VOICECALL_RCV :
		case MM_AUDIO_VOICECALL_SPK :
		case MM_AUDIO_VOICECALL_HP :
		case MM_AUDIO_VOICECALL_BT :
			ret = -1;
			break;
		case MM_AUDIO_VOICEMEMO_MAIN :
			switch (from_mode) {
				case MM_AUDIO_PLAYBACK_SPK :
					P("PLAYBACK_SPK->VOICEMEMO_MAIN");
					mic_set_path(AK4671_MIC_PATH_MAIN);
					set_codec_gain(codec, to_mode);
					codec->write(codec, 0x04, 0x14); 		// => MIC-AMP Lch=IN1+/-
					codec->write(codec, 0x00, 0xD5); 		// D/A power-up
					break;
				case MM_AUDIO_VOICEMEMO_EAR :
					P("VOICEMEMO_EAR->VOICEMEMO_MAIN");
					mic_set_path(AK4671_MIC_PATH_MAIN);
					set_codec_gain(codec, to_mode);
					codec->write(codec, 0x04, 0x14); 		// => MIC-AMP Lch=IN1+/-
					amp_set_path(AK4671_AMP_PATH_SPK);
					break;

				default :
					ret = -1;
					break;
			}
			break;

		case MM_AUDIO_VOICEMEMO_SUB :
			switch (from_mode) {
				case MM_AUDIO_PLAYBACK_SPK :
					P("PLAYBACK_SPK->VOICEMEMO_SUB");
					mic_set_path(AK4671_MIC_PATH_MAIN);
					set_codec_gain(codec, to_mode);
					codec->write(codec, 0x04, 0x14); 		// => MIC-AMP Lch=IN1+/-
					codec->write(codec, 0x00, 0xD5); 		// D/A power-up
					break;
				case MM_AUDIO_VOICEMEMO_EAR :
				     	P("VOICEMEMO_EAR->VOICEMEMO_MAIN");
					mic_set_path(AK4671_MIC_PATH_MAIN);
					set_codec_gain(codec, to_mode);
					codec->write(codec, 0x04, 0x14); 		// => MIC-AMP Lch=IN1+/-
					amp_set_path(AK4671_AMP_PATH_SPK);
					break;

				default :
					ret = -1;
					break;
			}
			break;

		case MM_AUDIO_VOICEMEMO_EAR :
			switch (from_mode) {
				case MM_AUDIO_PLAYBACK_HP :
				case MM_AUDIO_VOICEMEMO_MAIN :
				case MM_AUDIO_VOICEMEMO_SUB :
					P("VOICEMEMO_MAIN&SUB&PLAYBACK_HP->VOICEMEMO_EAR");
					if (from_mode != MM_AUDIO_PLAYBACK_HP)
						amp_set_path(AK4671_AMP_PATH_HP);
					if (get_headset_status()) 
					{
				     		P("VOICEMEMO_4POLE_EAR");
						set_codec_gain(codec, to_mode);
						codec->write(codec, 0x04, 0x42); 		// => MIC-AMP Lch=IN3+/-
						codec->write(codec, 0x00, 0xD5); 		// D/A power-up
					}
			        	else
			        	{
						P("VOICEMEMO_3POLE_EAR");
						mic_set_path(AK4671_MIC_PATH_MAIN);
						to_mode = MM_AUDIO_VOICEMEMO_MAIN;
				    		set_codec_gain(codec, to_mode);
				    		codec->write(codec, 0x04, 0x14); 		// => MIC-AMP Lch=IN1+/-
				    		codec->write(codec, 0x00, 0xD5); 		// D/A power-up	
			        	}
					break;

				default :
					ret = -1;
					break;
			}
			break;

		default :
			ret = -1;
			break;
	}

	return ret;
}