static void amp_path_control(int mode) { int amp_path; /* SPK <- HP */ if((mode & 0xf) == MM_AUDIO_OUT_SPK) { amp_path = AK4671_AMP_PATH_SPK; } /* SPK -> HP */ if((mode & 0xf) == MM_AUDIO_OUT_HP) { amp_path = AK4671_AMP_PATH_HP; } /* SPK & HP */ if(((mode & 0xf) == MM_AUDIO_OUT_SPK_HP) || ((mode & 0xf) == MM_AUDIO_OUT_RING_SPK_HP)) { amp_path = AK4671_AMP_PATH_SPK_HP; } if((mode & 0xf0) == MM_AUDIO_VOICEMEMO) { if((mode & 0xf) == MM_AUDIO_OUT_HP) amp_path = AK4671_AMP_PATH_HP; else amp_path = AK4671_AMP_PATH_SPK; } if (ak4671_amp_path != amp_path && ak4671_path != mode) { amp_set_path(amp_path); ak4671_amp_path = amp_path; } }
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_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; }