static int msm_device_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int dev_id = ucontrol->value.integer.value[0]; int mute = ucontrol->value.integer.value[1]; struct msm_snddev_info *dev_info; int afe_dev_id = 0; int volume = 0x4000; dev_info = audio_dev_ctrl_find_dev(dev_id); if (IS_ERR(dev_info)) { MM_ERR("pass invalid dev_id %d\n", dev_id); return PTR_ERR(dev_info); } if (dev_info->capability & SNDDEV_CAP_RX) return -EPERM; MM_DBG("Muting device id %d(%s)\n", dev_id, dev_info->name); if (dev_info->copp_id == 0) afe_dev_id = AFE_HW_PATH_CODEC_TX; if (dev_info->copp_id == 1) afe_dev_id = AFE_HW_PATH_AUXPCM_TX; if (dev_info->copp_id == 2) afe_dev_id = AFE_HW_PATH_MI2S_TX; if (mute) volume = 0; afe_device_volume_ctrl(afe_dev_id, volume); return 0; }
static void debugfs_afe_loopback(u32 loop) { int trc; struct msm_afe_config afe_config; struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; struct lpa_codec_config lpa_config; if (loop) { /* Vote for SMPS mode*/ pmapp_smps_mode_vote(SMPS_AUDIO_PLAYBACK_ID, PMAPP_VREG_S4, PMAPP_SMPS_MODE_VOTE_PWM); /* enable MI2S RX master block */ /* enable MI2S RX bit clock */ trc = clk_set_rate(drv->rx_mclk, SNDDEV_ICODEC_CLK_RATE(8000)); if (IS_ERR_VALUE(trc)) MM_ERR("failed to set clk rate\n"); clk_enable(drv->rx_mclk); clk_enable(drv->rx_sclk); clk_enable(drv->lpa_p_clk); clk_enable(drv->lpa_codec_clk); clk_enable(drv->lpa_core_clk); /* Enable LPA sub system */ drv->lpa = lpa_get(); if (!drv->lpa) MM_ERR("failed to enable lpa\n"); lpa_config.sample_rate = 8000; lpa_config.sample_width = 16; lpa_config.output_interface = LPA_OUTPUT_INTF_WB_CODEC; lpa_config.num_channels = 1; lpa_cmd_codec_config(drv->lpa, &lpa_config); /* Set audio interconnect reg to LPA */ audio_interct_codec(AUDIO_INTERCT_LPA); mi2s_set_codec_output_path(MI2S_CHAN_MONO_PACKED, WT_16_BIT); MM_INFO("configure ADIE RX path\n"); /* Configure ADIE */ adie_codec_open(&debug_rx_profile, &debugfs_rx_adie); adie_codec_setpath(debugfs_rx_adie, 8000, 256); lpa_cmd_enable_codec(drv->lpa, 1); /* Start AFE for RX */ afe_config.sample_rate = 0x8; afe_config.channel_mode = 1; afe_config.volume = AFE_VOLUME_UNITY; MM_INFO("enable afe\n"); trc = afe_enable(AFE_HW_PATH_CODEC_RX, &afe_config); if (IS_ERR_VALUE(trc)) MM_ERR("fail to enable afe RX\n"); adie_codec_proceed_stage(debugfs_rx_adie, ADIE_CODEC_DIGITAL_READY); adie_codec_proceed_stage(debugfs_rx_adie, ADIE_CODEC_DIGITAL_ANALOG_READY); /* Vote for PWM mode*/ pmapp_smps_mode_vote(SMPS_AUDIO_RECORD_ID, PMAPP_VREG_S4, PMAPP_SMPS_MODE_VOTE_PWM); MM_INFO("Enable Handset Mic bias\n"); pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_PWM_TCXO); /* enable MI2S TX master block */ /* enable MI2S TX bit clock */ clk_set_rate(drv->tx_mclk, SNDDEV_ICODEC_CLK_RATE(8000)); clk_enable(drv->tx_mclk); clk_enable(drv->tx_sclk); /* Set MI2S */ mi2s_set_codec_input_path(MI2S_CHAN_MONO_PACKED, WT_16_BIT); MM_INFO("configure ADIE TX path\n"); /* Configure ADIE */ adie_codec_open(&debug_tx_profile, &debugfs_tx_adie); adie_codec_setpath(debugfs_tx_adie, 8000, 256); adie_codec_proceed_stage(debugfs_tx_adie, ADIE_CODEC_DIGITAL_READY); adie_codec_proceed_stage(debugfs_tx_adie, ADIE_CODEC_DIGITAL_ANALOG_READY); /* Start AFE for TX */ afe_config.sample_rate = 0x8; afe_config.channel_mode = 1; afe_config.volume = AFE_VOLUME_UNITY; trc = afe_enable(AFE_HW_PATH_CODEC_TX, &afe_config); if (IS_ERR_VALUE(trc)) MM_ERR("failed to enable AFE TX\n"); /* Set the volume level to non unity, to avoid loopback effect */ afe_device_volume_ctrl(AFE_HW_PATH_CODEC_RX, 0x0500); /* enable afe loopback */ afe_loopback(1); MM_INFO("AFE loopback enabled\n"); } else { /* disable afe loopback */ afe_loopback(0); /* Remove the vote for SMPS mode*/ pmapp_smps_mode_vote(SMPS_AUDIO_PLAYBACK_ID, PMAPP_VREG_S4, PMAPP_SMPS_MODE_VOTE_DONTCARE); /* Disable ADIE */ adie_codec_proceed_stage(debugfs_rx_adie, ADIE_CODEC_DIGITAL_OFF); adie_codec_close(debugfs_rx_adie); /* Disable AFE for RX */ afe_disable(AFE_HW_PATH_CODEC_RX); /* Disable LPA Sub system */ lpa_cmd_enable_codec(drv->lpa, 0); lpa_put(drv->lpa); /* Disable LPA clocks */ clk_disable(drv->lpa_p_clk); clk_disable(drv->lpa_codec_clk); clk_disable(drv->lpa_core_clk); /* Disable MI2S RX master block */ /* Disable MI2S RX bit clock */ clk_disable(drv->rx_sclk); clk_disable(drv->rx_mclk); pmapp_smps_mode_vote(SMPS_AUDIO_RECORD_ID, PMAPP_VREG_S4, PMAPP_SMPS_MODE_VOTE_DONTCARE); /* Disable AFE for TX */ afe_disable(AFE_HW_PATH_CODEC_TX); /* Disable ADIE */ adie_codec_proceed_stage(debugfs_tx_adie, ADIE_CODEC_DIGITAL_OFF); adie_codec_close(debugfs_tx_adie); /* Disable MI2S TX master block */ /* Disable MI2S TX bit clock */ clk_disable(drv->tx_sclk); clk_disable(drv->tx_mclk); pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_OFF); MM_INFO("AFE loopback disabled\n"); } }
static void bt_sco_set_loopback_mode(u32 loop) { int trc; struct msm_afe_config afe_config; struct snddev_ecodec_drv_state *drv = &snddev_ecodec_drv; MM_INFO("[BTUI] bt_sco_set_loopback_mode : %d \n", loop); if(loop & 1) { /********************************************************** * Aux PCM Common set up ***********************************************************/ /* request GPIO */ trc = aux_pcm_gpios_request(); if (trc) { MM_ERR("[BTUI] ###### GPIO enable failed\n"); } /* config clocks */ clk_enable(drv->lpa_core_clk); /* enable ecodec clk */ clk_enable(drv->ecodec_clk); /* let ADSP confiure AUX PCM regs */ aux_codec_adsp_codec_ctl_en(ADSP_CTL); /* let adsp configure pcm path */ aux_codec_pcm_path_ctl_en(ADSP_CTL); /* choose ADSP_A */ audio_interct_aux_regsel(AUDIO_ADSP_A); audio_interct_tpcm_source(AUDIO_ADSP_A); audio_interct_rpcm_source(AUDIO_ADSP_A); clk_disable(drv->lpa_core_clk); /* send AUX_CODEC_CONFIG to AFE */ trc = afe_config_aux_codec(TESTMODE_HANDSET_PCM_CTL_VAL,TESTMODE_AUX_CODEC_INTF,TESTMODE_DATA_FORMAT_PADDING); if (IS_ERR_VALUE(trc)) { MM_ERR("[BTUI] ###### afe_config_aux_codec failed\n"); } /********************************************************** * Aux PCM Rx path set up ***********************************************************/ /* send CODEC CONFIG to AFE */ afe_config.sample_rate = 8; afe_config.channel_mode = 1; afe_config.volume = AFE_VOLUME_UNITY; trc = afe_enable(AFE_HW_PATH_AUXPCM_RX, &afe_config); if (IS_ERR_VALUE(trc)){ MM_ERR("[BTUI] ###### afe_enable failed\n"); } /********************************************************** * Aux PCM Tx path set up ***********************************************************/ /* send CODEC CONFIG to AFE */ afe_config.sample_rate = 8; afe_config.channel_mode = 1; afe_config.volume = AFE_VOLUME_UNITY; trc = afe_enable(AFE_HW_PATH_AUXPCM_TX, &afe_config); if (IS_ERR_VALUE(trc)) { MM_ERR("[BTUI] ###### afe_enable tx failed\n"); } /************************************************************************************ * Start LoopBack *************************************************************************************/ /* Set the volume level to non unity, to avoid loopback effect */ afe_device_volume_ctrl(AFE_HW_PATH_AUXPCM_RX, 0x0500); lb_status = loop; MM_INFO("[BTUI] bt_sco_set_loopback_mode : [ENABLED] \n"); afe_config_ext_pcm_loopback(0xFFFF); } else { /*release GPIOs*/ aux_pcm_gpios_free(); afe_config_ext_pcm_loopback(0x0); /*disable clocks*/ clk_disable(drv->ecodec_clk); /*Disable afe configuration */ afe_disable(AFE_HW_PATH_AUXPCM_RX); afe_disable(AFE_HW_PATH_AUXPCM_TX); lb_status = 0; MM_INFO("[BTUI] bt_sco_set_loopback_mode : [DISABLED] \n"); } }