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); }
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; }
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; }
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; }
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; }
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; }