status_t SpeechPhoneCallController::SetTtyCtmMode(const tty_mode_t tty_mode, const audio_mode_t audio_mode)
{
    ALOGD("+%s(), mTty_Ctm = %d, new tty mode = %d, audio_mode = %d", __FUNCTION__, mTty_Ctm, tty_mode, audio_mode);

    if (mTty_Ctm != tty_mode)
    {
        mTty_Ctm = tty_mode;

        SpeechDriverInterface *pSpeechDriver = mSpeechDriverFactory->GetSpeechDriver();
        const bool bt_device_on = android_audio_legacy::AudioSystem::isBluetoothScoDevice((android_audio_legacy::AudioSystem::audio_devices)mAudioResourceManager->getDlOutputDevice());
        if (bt_device_on == false &&
            pSpeechDriver->GetApSideModemStatus(VT_STATUS_MASK) == false &&
            pSpeechDriver->GetApSideModemStatus(SPEECH_STATUS_MASK) == true)
        {
            mAudioResourceManager->EnableAudioLock(AudioResourceManagerInterface::AUDIO_HARDWARE_LOCK, 3000);
            mAudioResourceManager->EnableAudioLock(AudioResourceManagerInterface::AUDIO_STREAMOUT_LOCK, 3000);

            pSpeechDriver->SetUplinkMute(true);
            if (pSpeechDriver->GetApSideModemStatus(TTY_STATUS_MASK) == true)
            {
                pSpeechDriver->TtyCtmOff();
            }

            mAudioResourceManager->StopOutputDevice();
            mAudioResourceManager->StopInputDevice();
            SetTtyInOutDevice(GetRoutingForTty(), mTty_Ctm, audio_mode);
            mAudioResourceManager->StartOutputDevice();
            mAudioResourceManager->StartInputDevice();

            const audio_devices_t output_device = (audio_devices_t)mAudioResourceManager->getDlOutputDevice();
            const audio_devices_t input_device  = (audio_devices_t)mAudioResourceManager->getUlInputDevice();
            pSpeechDriver->SetSpeechMode(input_device, output_device);

            if ((mTty_Ctm != AUD_TTY_OFF) && (mTty_Ctm != AUD_TTY_ERR) &&
                (pSpeechDriver->GetApSideModemStatus(TTY_STATUS_MASK) == false))
            {
                pSpeechDriver->TtyCtmOn(BAUDOT_MODE);
            }
            pSpeechDriver->SetUplinkMute(mMicMute);

            mAudioResourceManager->DisableAudioLock(AudioResourceManagerInterface::AUDIO_STREAMOUT_LOCK);
            mAudioResourceManager->DisableAudioLock(AudioResourceManagerInterface::AUDIO_HARDWARE_LOCK);
        }
    }

    ALOGD("-%s()", __FUNCTION__);
    return NO_ERROR;
}
void SpeechVMRecorder::SetVMRecordCapability(const AUDIO_CUSTOM_PARAM_STRUCT *pSphParamNB)
{
    ALOGD("%s(), uAutoVM = 0x%x, debug_info[0] = %u, speech_common_para[0] = %u", __FUNCTION__,
          pSphParamNB->uAutoVM, pSphParamNB->debug_info[0], pSphParamNB->speech_common_para[0]);

    mAutoVM = pSphParamNB->uAutoVM;

    SpeechDriverInterface *pSpeechDriver = SpeechDriverFactory::GetInstance()->GetSpeechDriver();
    const bool speech_on = pSpeechDriver->GetApSideModemStatus(SPEECH_STATUS_MASK);
    const bool rec_on    = pSpeechDriver->GetApSideModemStatus(RECORD_STATUS_MASK);

    AudioResourceManager::getInstance()->EnableAudioLock(AudioResourceManagerInterface::AUDIO_STREAMINMANAGER_LOCK, AUDIO_LOCK_TIMEOUT_VALUE_MS);

    if (GetVMRecordCapability() == true && GetVMRecordStatus() == false && speech_on == true)
    {
        // turn off normal phone record
        if (rec_on == true)
        {
            ALOGW("%s(), Turn off normal phone recording!!", __FUNCTION__);
            ALOGW("%s(), The following record file will be silence until VM/EPL is closed.", __FUNCTION__);
            AudioMTKStreamManager::getInstance()->ForceAllStandby(); // TODO: only need to standby input stream
        }

        ALOGD("%s(), Open VM/EPL record", __FUNCTION__);
        Open();
    }
    else if (GetVMRecordCapability() == false && GetVMRecordStatus() == true)
    {
        ALOGD("%s(), Close VM/EPL record", __FUNCTION__);
        ALOGD("%s(), Able to continue to do phone record.", __FUNCTION__);
        Close();
    }

    AudioResourceManager::getInstance()->DisableAudioLock(AudioResourceManagerInterface::AUDIO_STREAMINMANAGER_LOCK);
}
status_t SpeechPhoneCallController::CloseModemSpeechControlFlow(const audio_mode_t audio_mode)
{
    Mutex::Autolock _l(mLock);

    ALOGD("+%s(), audio_mode = %d", __FUNCTION__, audio_mode);

    const modem_index_t modem_index = mSpeechDriverFactory->GetActiveModemIndex();
    ASSERT((modem_index == MODEM_1 && audio_mode == AUDIO_MODE_IN_CALL) ||
           (modem_index == MODEM_2 && audio_mode == AUDIO_MODE_IN_CALL_2));

    // check VM need close
    SpeechVMRecorder *pSpeechVMRecorder = SpeechVMRecorder::GetInstance();
    if (pSpeechVMRecorder->GetVMRecordStatus() == true)
    {
        ALOGD("%s(), Close VM/EPL record", __FUNCTION__);
        pSpeechVMRecorder->Close();
    }

    // Stop PMIC digital/analog part - downlink
    mAudioResourceManager->StopOutputDevice();

    // Stop Side Tone Filter
    mAudioDigitalInstance->EnableSideToneFilter(false);

    // Stop MODEM_PCM
    mAudioDigitalInstance->SetModemPcmEnable(modem_index, false);

    // Stop PMIC digital/analog part - uplink
    mAudioResourceManager->StopInputDevice();

    // Stop AP side digital part
    CloseModemSpeechDigitalPart(modem_index, (audio_devices_t)mAudioResourceManager->getDlOutputDevice());



    // Get current active speech driver
    SpeechDriverInterface *pSpeechDriver = mSpeechDriverFactory->GetSpeechDriver();

    // check BGS need close
    if (pSpeechDriver->GetApSideModemStatus(BGS_STATUS_MASK) == true)
    {
        pSpeechDriver->BGSoundOff();
    }

    // Speech/VT off
    if (pSpeechDriver->GetApSideModemStatus(VT_STATUS_MASK) == true)
    {
        pSpeechDriver->PCM2WayOff();
        pSpeechDriver->VideoTelephonyOff();
    }
    else if (pSpeechDriver->GetApSideModemStatus(SPEECH_STATUS_MASK) == true)
    {
        if (pSpeechDriver->GetApSideModemStatus(TTY_STATUS_MASK) == true)
        {
            pSpeechDriver->TtyCtmOff();
        }
        pSpeechDriver->SpeechOff();
    }
    else
    {
        ALOGE("%s(), audio_mode = %d, Speech & VT are already closed!!", __FUNCTION__, audio_mode);
        ASSERT(pSpeechDriver->GetApSideModemStatus(VT_STATUS_MASK)     == true ||
               pSpeechDriver->GetApSideModemStatus(SPEECH_STATUS_MASK) == true);
    }

    // AFE_ON = false
    mAudioDigitalInstance->SetAfeEnable(false);

    // recover sampling rate
    mAudioAnalogInstance->SetFrequency(AudioAnalogType::DEVICE_OUT_DAC, 44100);
    mAudioAnalogInstance->SetFrequency(AudioAnalogType::DEVICE_IN_ADC, 44100);

    // disable clock
    SetAfeAnalogClock(false);

    // clean VT status
    if (mVtNeedOn == true)
    {
        ALOGD("%s(), Set mVtNeedOn = false");
        mVtNeedOn = false;
    }

    ALOGD("-%s(), audio_mode = %d", __FUNCTION__, audio_mode);

    return NO_ERROR;
}