Home | History | Annotate | Download | only in alsa_sound
      1 /* AudioHardwareALSA.cpp
      2  **
      3  ** Copyright 2008-2010 Wind River Systems
      4  ** Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
      5  **
      6  ** Licensed under the Apache License, Version 2.0 (the "License");
      7  ** you may not use this file except in compliance with the License.
      8  ** You may obtain a copy of the License at
      9  **
     10  **     http://www.apache.org/licenses/LICENSE-2.0
     11  **
     12  ** Unless required by applicable law or agreed to in writing, software
     13  ** distributed under the License is distributed on an "AS IS" BASIS,
     14  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  ** See the License for the specific language governing permissions and
     16  ** limitations under the License.
     17  */
     18 
     19 #include <errno.h>
     20 #include <stdarg.h>
     21 #include <sys/stat.h>
     22 #include <fcntl.h>
     23 #include <stdlib.h>
     24 #include <unistd.h>
     25 #include <dlfcn.h>
     26 #include <math.h>
     27 
     28 #define LOG_TAG "AudioHardwareALSA"
     29 //#define LOG_NDEBUG 0
     30 #define LOG_NDDEBUG 0
     31 #include <utils/Log.h>
     32 #include <utils/String8.h>
     33 #include <sys/prctl.h>
     34 #include <sys/resource.h>
     35 #include <sys/poll.h>
     36 #include <sys/ioctl.h>
     37 #include <cutils/properties.h>
     38 #include <media/AudioRecord.h>
     39 #include <hardware_legacy/power.h>
     40 
     41 #include "AudioHardwareALSA.h"
     42 #ifdef QCOM_USBAUDIO_ENABLED
     43 #include "AudioUsbALSA.h"
     44 #endif
     45 #include "AudioUtil.h"
     46 
     47 extern "C"
     48 {
     49     //
     50     // Function for dlsym() to look up for creating a new AudioHardwareInterface.
     51     //
     52     android_audio_legacy::AudioHardwareInterface *createAudioHardware(void) {
     53         return android_audio_legacy::AudioHardwareALSA::create();
     54     }
     55 #ifdef QCOM_ACDB_ENABLED
     56     static int (*acdb_init)();
     57     static void (*acdb_deallocate)();
     58 #endif
     59 #ifdef QCOM_CSDCLIENT_ENABLED
     60     static int (*csd_client_init)();
     61     static int (*csd_client_deinit)();
     62     static int (*csd_start_playback)();
     63     static int (*csd_stop_playback)();
     64 #endif
     65 }         // extern "C"
     66 
     67 namespace android_audio_legacy
     68 {
     69 
     70 // ----------------------------------------------------------------------------
     71 
     72 AudioHardwareInterface *AudioHardwareALSA::create() {
     73     return new AudioHardwareALSA();
     74 }
     75 
     76 AudioHardwareALSA::AudioHardwareALSA() :
     77     mALSADevice(0),mVoipStreamCount(0),mVoipBitRate(0)
     78     ,mCallState(0),mAcdbHandle(NULL),mCsdHandle(NULL),mMicMute(0)
     79 {
     80     FILE *fp;
     81     char soundCardInfo[200];
     82     hw_module_t *module;
     83     char platform[128], baseband[128];
     84     int err = hw_get_module(ALSA_HARDWARE_MODULE_ID,
     85             (hw_module_t const**)&module);
     86     int codec_rev = 2;
     87     ALOGD("hw_get_module(ALSA_HARDWARE_MODULE_ID) returned err %d", err);
     88     if (err == 0) {
     89         hw_device_t* device;
     90         err = module->methods->open(module, ALSA_HARDWARE_NAME, &device);
     91         if (err == 0) {
     92             mALSADevice = (alsa_device_t *)device;
     93             mALSADevice->init(mALSADevice, mDeviceList);
     94             mCSCallActive = 0;
     95             mVolteCallActive = 0;
     96             mIsFmActive = 0;
     97             mDevSettingsFlag = 0;
     98 #ifdef QCOM_USBAUDIO_ENABLED
     99             mAudioUsbALSA = new AudioUsbALSA();
    100             musbPlaybackState = 0;
    101             musbRecordingState = 0;
    102 #endif
    103 #ifdef USES_FLUENCE_INCALL
    104             mDevSettingsFlag |= TTY_OFF | DMIC_FLAG;
    105 #else
    106             mDevSettingsFlag |= TTY_OFF;
    107 #endif
    108             mBluetoothVGS = false;
    109             mFusion3Platform = false;
    110 
    111 #ifdef QCOM_ACDB_ENABLED
    112             mAcdbHandle = ::dlopen("/system/lib/libacdbloader.so", RTLD_NOW);
    113             if (mAcdbHandle == NULL) {
    114                 ALOGE("AudioHardware: DLOPEN not successful for ACDBLOADER");
    115             } else {
    116                 ALOGD("AudioHardware: DLOPEN successful for ACDBLOADER");
    117                 acdb_init = (int (*)())::dlsym(mAcdbHandle,"acdb_loader_init_ACDB");
    118                 if (acdb_init == NULL) {
    119                     ALOGE("dlsym:Error:%s Loading acdb_loader_init_ACDB", dlerror());
    120                 }else {
    121                    acdb_init();
    122                    acdb_deallocate = (void (*)())::dlsym(mAcdbHandle,"acdb_loader_deallocate_ACDB");
    123                 }
    124             }
    125 #endif
    126 
    127 #ifdef QCOM_CSDCLIENT_ENABLED
    128              mCsdHandle = ::dlopen("/system/lib/libcsd-client.so", RTLD_NOW);
    129              if (mCsdHandle == NULL) {
    130                  ALOGE("AudioHardware: DLOPEN not successful for CSD CLIENT");
    131              } else {
    132                  ALOGD("AudioHardware: DLOPEN successful for CSD CLIENT");
    133                  csd_client_init = (int (*)())::dlsym(mCsdHandle,"csd_client_init");
    134                  csd_client_deinit = (int (*)())::dlsym(mCsdHandle,"csd_client_deinit");
    135                  csd_start_playback = (int (*)())::dlsym(mCsdHandle,"csd_client_start_playback");
    136                  csd_stop_playback = (int (*)())::dlsym(mCsdHandle,"csd_client_stop_playback");
    137 
    138                  if (csd_client_init == NULL) {
    139                     ALOGE("dlsym: Error:%s Loading csd_client_init", dlerror());
    140                  } else {
    141                     csd_client_init();
    142                  }
    143              }
    144              mALSADevice->setCsdHandle(mCsdHandle);
    145 #endif
    146             if((fp = fopen("/proc/asound/cards","r")) == NULL) {
    147                 ALOGE("Cannot open /proc/asound/cards file to get sound card info");
    148             } else {
    149                 while((fgets(soundCardInfo, sizeof(soundCardInfo), fp) != NULL)) {
    150                     ALOGV("SoundCardInfo %s", soundCardInfo);
    151                     if (strstr(soundCardInfo, "msm8960-tabla1x-snd-card")) {
    152                         codec_rev = 1;
    153                         break;
    154                     } else if (strstr(soundCardInfo, "msm-snd-card")) {
    155                         codec_rev = 2;
    156                         break;
    157                     } else if (strstr(soundCardInfo, "msm8930-sitar-snd-card")) {
    158                         codec_rev = 3;
    159                         break;
    160                     }
    161                 }
    162                 fclose(fp);
    163             }
    164 
    165             if (codec_rev == 1) {
    166                     ALOGV("Detected tabla 1.x sound card");
    167                     snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm");
    168             } else if (codec_rev == 3) {
    169                     ALOGV("Detected sitar 1.x sound card");
    170                     snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_Sitar");
    171             } else {
    172                     property_get("ro.board.platform", platform, "");
    173                     property_get("ro.baseband", baseband, "");
    174                     if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband)) {
    175                         ALOGV("Detected Fusion tabla 2.x");
    176                         mFusion3Platform = true;
    177                         snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_2x_Fusion3");
    178                     } else {
    179                         ALOGV("Detected tabla 2.x sound card");
    180                         snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_2x");
    181                     }
    182             }
    183 
    184             if (mUcMgr < 0) {
    185                 ALOGE("Failed to open ucm instance: %d", errno);
    186             } else {
    187                 ALOGI("ucm instance opened: %u", (unsigned)mUcMgr);
    188                 mUcMgr->acdb_handle = NULL;
    189 #ifdef QCOM_ACDB_ENABLED
    190                 if (mAcdbHandle) {
    191                     mUcMgr->acdb_handle = static_cast<void*> (mAcdbHandle);
    192                     if (mFusion3Platform)
    193                         mUcMgr->isFusion3Platform = true;
    194                     else
    195                         mUcMgr->isFusion3Platform = false;
    196                 }
    197 #endif
    198             }
    199         } else {
    200             ALOGE("ALSA Module could not be opened!!!");
    201         }
    202     } else {
    203         ALOGE("ALSA Module not found!!!");
    204     }
    205 }
    206 
    207 AudioHardwareALSA::~AudioHardwareALSA()
    208 {
    209     if (mUcMgr != NULL) {
    210         ALOGV("closing ucm instance: %u", (unsigned)mUcMgr);
    211         snd_use_case_mgr_close(mUcMgr);
    212     }
    213     if (mALSADevice) {
    214         mALSADevice->common.close(&mALSADevice->common);
    215     }
    216     for(ALSAHandleList::iterator it = mDeviceList.begin();
    217             it != mDeviceList.end(); ++it) {
    218         it->useCase[0] = 0;
    219         mDeviceList.erase(it);
    220     }
    221 #ifdef QCOM_ACDB_ENABLED
    222      if (acdb_deallocate == NULL) {
    223         ALOGE("dlsym: Error:%s Loading acdb_deallocate_ACDB", dlerror());
    224      } else {
    225         acdb_deallocate();
    226      }
    227      if (mAcdbHandle) {
    228         ::dlclose(mAcdbHandle);
    229         mAcdbHandle = NULL;
    230      }
    231 #endif
    232 #ifdef QCOM_USBAUDIO_ENABLED
    233     delete mAudioUsbALSA;
    234 #endif
    235 
    236 #ifdef QCOM_CSDCLEINT_ENABLED
    237      if (mCsdHandle) {
    238          if (csd_client_deinit == NULL) {
    239              ALOGE("dlsym: Error:%s Loading csd_client_deinit", dlerror());
    240          } else {
    241              csd_client_deinit();
    242          }
    243          ::dlclose(mCsdHandle);
    244          mCsdHandle = NULL;
    245      }
    246 #endif
    247 }
    248 
    249 status_t AudioHardwareALSA::initCheck()
    250 {
    251     if (!mALSADevice)
    252         return NO_INIT;
    253 
    254     return NO_ERROR;
    255 }
    256 
    257 status_t AudioHardwareALSA::setVoiceVolume(float v)
    258 {
    259     ALOGV("setVoiceVolume(%f)\n", v);
    260     if (v < 0.0) {
    261         ALOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v);
    262         v = 0.0;
    263     } else if (v > 1.0) {
    264         ALOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v);
    265         v = 1.0;
    266     }
    267 
    268     int newMode = mode();
    269     ALOGV("setVoiceVolume  newMode %d",newMode);
    270     int vol = lrint(v * 100.0);
    271 
    272     // Voice volume levels from android are mapped to driver volume levels as follows.
    273     // 0 -> 5, 20 -> 4, 40 ->3, 60 -> 2, 80 -> 1, 100 -> 0
    274     // So adjust the volume to get the correct volume index in driver
    275     vol = 100 - vol;
    276 
    277     if (mALSADevice) {
    278         if(newMode == AudioSystem::MODE_IN_COMMUNICATION) {
    279             mALSADevice->setVoipVolume(vol);
    280         } else if (newMode == AudioSystem::MODE_IN_CALL){
    281                if (mCSCallActive == CS_ACTIVE)
    282                    mALSADevice->setVoiceVolume(vol);
    283                if (mVolteCallActive == IMS_ACTIVE)
    284                    mALSADevice->setVoLTEVolume(vol);
    285         }
    286     }
    287 
    288     return NO_ERROR;
    289 }
    290 
    291 #ifdef QCOM_FM_ENABLED
    292 status_t  AudioHardwareALSA::setFmVolume(float value)
    293 {
    294     status_t status = NO_ERROR;
    295 
    296     int vol;
    297 
    298     if (value < 0.0) {
    299         ALOGW("setFmVolume(%f) under 0.0, assuming 0.0\n", value);
    300         value = 0.0;
    301     } else if (value > 1.0) {
    302         ALOGW("setFmVolume(%f) over 1.0, assuming 1.0\n", value);
    303         value = 1.0;
    304     }
    305     vol  = lrint((value * 0x2000) + 0.5);
    306 
    307     ALOGV("setFmVolume(%f)\n", value);
    308     ALOGV("Setting FM volume to %d (available range is 0 to 0x2000)\n", vol);
    309 
    310     mALSADevice->setFmVolume(vol);
    311 
    312     return status;
    313 }
    314 #endif
    315 
    316 status_t AudioHardwareALSA::setMasterVolume(float volume)
    317 {
    318     return NO_ERROR;
    319 }
    320 
    321 status_t AudioHardwareALSA::setMode(int mode)
    322 {
    323     status_t status = NO_ERROR;
    324 
    325     if (mode != mMode) {
    326         status = AudioHardwareBase::setMode(mode);
    327     }
    328 
    329     if (mode == AudioSystem::MODE_IN_CALL) {
    330         mCallState = CS_ACTIVE;
    331     }else if (mode == AudioSystem::MODE_NORMAL) {
    332         mCallState = 0;
    333     }
    334 
    335     return status;
    336 }
    337 
    338 status_t AudioHardwareALSA::setParameters(const String8& keyValuePairs)
    339 {
    340     AudioParameter param = AudioParameter(keyValuePairs);
    341     String8 key;
    342     String8 value;
    343     status_t status = NO_ERROR;
    344     int device;
    345     int btRate;
    346     int state;
    347     ALOGV("setParameters() %s", keyValuePairs.string());
    348 
    349     key = String8(TTY_MODE_KEY);
    350     if (param.get(key, value) == NO_ERROR) {
    351         mDevSettingsFlag &= TTY_CLEAR;
    352         if (value == "tty_full") {
    353             mDevSettingsFlag |= TTY_FULL;
    354         } else if (value == "tty_hco") {
    355             mDevSettingsFlag |= TTY_HCO;
    356         } else if (value == "tty_vco") {
    357             mDevSettingsFlag |= TTY_VCO;
    358         } else {
    359             mDevSettingsFlag |= TTY_OFF;
    360         }
    361         ALOGI("Changed TTY Mode=%s", value.string());
    362         mALSADevice->setFlags(mDevSettingsFlag);
    363         if(mMode != AudioSystem::MODE_IN_CALL){
    364            return NO_ERROR;
    365         }
    366         doRouting(0);
    367     }
    368 
    369     key = String8(FLUENCE_KEY);
    370     if (param.get(key, value) == NO_ERROR) {
    371         if (value == "quadmic") {
    372             mDevSettingsFlag |= QMIC_FLAG;
    373             mDevSettingsFlag &= (~DMIC_FLAG);
    374             ALOGV("Fluence quadMic feature Enabled");
    375         } else if (value == "dualmic") {
    376             mDevSettingsFlag |= DMIC_FLAG;
    377             mDevSettingsFlag &= (~QMIC_FLAG);
    378             ALOGV("Fluence dualmic feature Enabled");
    379         } else if (value == "none") {
    380             mDevSettingsFlag &= (~DMIC_FLAG);
    381             mDevSettingsFlag &= (~QMIC_FLAG);
    382             ALOGV("Fluence feature Disabled");
    383         }
    384         mALSADevice->setFlags(mDevSettingsFlag);
    385         doRouting(0);
    386     }
    387 
    388 #ifdef QCOM_CSDCLIENT_ENABLED
    389     if (mFusion3Platform) {
    390         key = String8(INCALLMUSIC_KEY);
    391         if (param.get(key, value) == NO_ERROR) {
    392             if (value == "true") {
    393                 ALOGV("Enabling Incall Music setting in the setparameter\n");
    394                 if (csd_start_playback == NULL) {
    395                     ALOGE("dlsym: Error:%s Loading csd_client_start_playback", dlerror());
    396                 } else {
    397                     csd_start_playback();
    398                 }
    399             } else {
    400                 ALOGV("Disabling Incall Music setting in the setparameter\n");
    401                 if (csd_stop_playback == NULL) {
    402                     ALOGE("dlsym: Error:%s Loading csd_client_stop_playback", dlerror());
    403                 } else {
    404                     csd_stop_playback();
    405                 }
    406             }
    407         }
    408     }
    409 #endif
    410 
    411     key = String8(ANC_KEY);
    412     if (param.get(key, value) == NO_ERROR) {
    413         if (value == "true") {
    414             ALOGV("Enabling ANC setting in the setparameter\n");
    415             mDevSettingsFlag |= ANC_FLAG;
    416         } else {
    417             ALOGV("Disabling ANC setting in the setparameter\n");
    418             mDevSettingsFlag &= (~ANC_FLAG);
    419         }
    420         mALSADevice->setFlags(mDevSettingsFlag);
    421         doRouting(0);
    422     }
    423 
    424     key = String8(AudioParameter::keyRouting);
    425     if (param.getInt(key, device) == NO_ERROR) {
    426         // Ignore routing if device is 0.
    427         if(device) {
    428             doRouting(device);
    429         }
    430         param.remove(key);
    431     }
    432 
    433     key = String8(BT_SAMPLERATE_KEY);
    434     if (param.getInt(key, btRate) == NO_ERROR) {
    435         mALSADevice->setBtscoRate(btRate);
    436         param.remove(key);
    437     }
    438 
    439     key = String8(BTHEADSET_VGS);
    440     if (param.get(key, value) == NO_ERROR) {
    441         if (value == "on") {
    442             mBluetoothVGS = true;
    443         } else {
    444             mBluetoothVGS = false;
    445         }
    446     }
    447 
    448     key = String8(WIDEVOICE_KEY);
    449     if (param.get(key, value) == NO_ERROR) {
    450         bool flag = false;
    451         if (value == "true") {
    452             flag = true;
    453         }
    454         if(mALSADevice) {
    455             mALSADevice->enableWideVoice(flag);
    456         }
    457         param.remove(key);
    458     }
    459 
    460     key = String8(VOIPRATE_KEY);
    461     if (param.get(key, value) == NO_ERROR) {
    462             mVoipBitRate = atoi(value);
    463         param.remove(key);
    464     }
    465 
    466     key = String8(FENS_KEY);
    467     if (param.get(key, value) == NO_ERROR) {
    468         bool flag = false;
    469         if (value == "true") {
    470             flag = true;
    471         }
    472         if(mALSADevice) {
    473             mALSADevice->enableFENS(flag);
    474         }
    475         param.remove(key);
    476     }
    477 
    478 #ifdef QCOM_FM_ENABLED
    479     key = String8(AudioParameter::keyHandleFm);
    480     if (param.getInt(key, device) == NO_ERROR) {
    481         // Ignore if device is 0
    482         if(device) {
    483             handleFm(device);
    484         }
    485         param.remove(key);
    486     }
    487 #endif
    488 
    489     key = String8(ST_KEY);
    490     if (param.get(key, value) == NO_ERROR) {
    491         bool flag = false;
    492         if (value == "true") {
    493             flag = true;
    494         }
    495         if(mALSADevice) {
    496             mALSADevice->enableSlowTalk(flag);
    497         }
    498         param.remove(key);
    499     }
    500     key = String8(MODE_CALL_KEY);
    501     if (param.getInt(key,state) == NO_ERROR) {
    502         if (mCallState != state) {
    503             mCallState = state;
    504             doRouting(0);
    505         }
    506         mCallState = state;
    507     }
    508     if (param.size()) {
    509         status = BAD_VALUE;
    510     }
    511     return status;
    512 }
    513 
    514 String8 AudioHardwareALSA::getParameters(const String8& keys)
    515 {
    516     AudioParameter param = AudioParameter(keys);
    517     String8 value;
    518 
    519     String8 key = String8(DUALMIC_KEY);
    520     if (param.get(key, value) == NO_ERROR) {
    521         value = String8("false");
    522         param.add(key, value);
    523     }
    524 
    525     key = String8(FLUENCE_KEY);
    526     if (param.get(key, value) == NO_ERROR) {
    527     if ((mDevSettingsFlag & QMIC_FLAG) &&
    528                                (mDevSettingsFlag & ~DMIC_FLAG))
    529             value = String8("quadmic");
    530     else if ((mDevSettingsFlag & DMIC_FLAG) &&
    531                                 (mDevSettingsFlag & ~QMIC_FLAG))
    532             value = String8("dualmic");
    533     else if ((mDevSettingsFlag & ~DMIC_FLAG) &&
    534                                 (mDevSettingsFlag & ~QMIC_FLAG))
    535             value = String8("none");
    536         param.add(key, value);
    537     }
    538 
    539 #ifdef QCOM_FM_ENABLED
    540     key = String8("Fm-radio");
    541     if ( param.get(key,value) == NO_ERROR ) {
    542         if ( mIsFmActive ) {
    543             param.addInt(String8("isFMON"), true );
    544         }
    545     }
    546 #endif
    547 
    548     key = String8(BTHEADSET_VGS);
    549     if (param.get(key, value) == NO_ERROR) {
    550         if(mBluetoothVGS)
    551            param.addInt(String8("isVGS"), true);
    552     }
    553 
    554     ALOGV("AudioHardwareALSA::getParameters() %s", param.toString().string());
    555     return param.toString();
    556 }
    557 
    558 #ifdef QCOM_USBAUDIO_ENABLED
    559 void AudioHardwareALSA::closeUSBPlayback()
    560 {
    561     ALOGV("closeUSBPlayback, musbPlaybackState: %d", musbPlaybackState);
    562     musbPlaybackState = 0;
    563     mAudioUsbALSA->exitPlaybackThread(SIGNAL_EVENT_KILLTHREAD);
    564 }
    565 
    566 void AudioHardwareALSA::closeUSBRecording()
    567 {
    568     ALOGV("closeUSBRecording");
    569     musbRecordingState = 0;
    570     mAudioUsbALSA->exitRecordingThread(SIGNAL_EVENT_KILLTHREAD);
    571 }
    572 
    573 void AudioHardwareALSA::closeUsbPlaybackIfNothingActive(){
    574     ALOGV("closeUsbPlaybackIfNothingActive, musbPlaybackState: %d", musbPlaybackState);
    575     if(!musbPlaybackState && mAudioUsbALSA != NULL) {
    576         mAudioUsbALSA->exitPlaybackThread(SIGNAL_EVENT_TIMEOUT);
    577     }
    578 }
    579 
    580 void AudioHardwareALSA::closeUsbRecordingIfNothingActive(){
    581     ALOGV("closeUsbRecordingIfNothingActive, musbRecordingState: %d", musbRecordingState);
    582     if(!musbRecordingState && mAudioUsbALSA != NULL) {
    583         ALOGD("Closing USB Recording Session as no stream is active");
    584         mAudioUsbALSA->setkillUsbRecordingThread(true);
    585     }
    586 }
    587 
    588 void AudioHardwareALSA::startUsbPlaybackIfNotStarted(){
    589     ALOGV("Starting the USB playback %d kill %d", musbPlaybackState,
    590              mAudioUsbALSA->getkillUsbPlaybackThread());
    591     if((!musbPlaybackState) || (mAudioUsbALSA->getkillUsbPlaybackThread() == true)) {
    592         mAudioUsbALSA->startPlayback();
    593     }
    594 }
    595 
    596 void AudioHardwareALSA::startUsbRecordingIfNotStarted(){
    597     ALOGV("Starting the recording musbRecordingState: %d killUsbRecordingThread %d",
    598           musbRecordingState, mAudioUsbALSA->getkillUsbRecordingThread());
    599     if((!musbRecordingState) || (mAudioUsbALSA->getkillUsbRecordingThread() == true)) {
    600         mAudioUsbALSA->startRecording();
    601     }
    602 }
    603 #endif
    604 
    605 void AudioHardwareALSA::doRouting(int device)
    606 {
    607     Mutex::Autolock autoLock(mLock);
    608     int newMode = mode();
    609     bool isRouted = false;
    610 
    611     if ((device == AudioSystem::DEVICE_IN_VOICE_CALL)
    612 #ifdef QCOM_FM_ENABLED
    613         || (device == AudioSystem::DEVICE_IN_FM_RX)
    614         || (device == AudioSystem::DEVICE_OUT_DIRECTOUTPUT)
    615         || (device == AudioSystem::DEVICE_IN_FM_RX_A2DP)
    616 #endif
    617         || (device == AudioSystem::DEVICE_IN_COMMUNICATION)
    618         ) {
    619         ALOGV("Ignoring routing for FM/INCALL/VOIP recording");
    620         return;
    621     }
    622     if (device == 0)
    623         device = mCurDevice;
    624     ALOGV("doRouting: device %d newMode %d mCSCallActive %d mVolteCallActive %d"
    625          "mIsFmActive %d", device, newMode, mCSCallActive, mVolteCallActive,
    626          mIsFmActive);
    627 
    628     isRouted = routeVoLTECall(device, newMode);
    629     isRouted |= routeVoiceCall(device, newMode);
    630 
    631     if(!isRouted) {
    632 #ifdef QCOM_USBAUDIO_ENABLED
    633         if(!(device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET) &&
    634             !(device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET) &&
    635             !(device & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) &&
    636              (musbPlaybackState)){
    637                 //USB unplugged
    638                 device &= ~ AudioSystem::DEVICE_OUT_PROXY;
    639                 device &= ~ AudioSystem::DEVICE_IN_PROXY;
    640                 ALSAHandleList::iterator it = mDeviceList.end();
    641                 it--;
    642                 mALSADevice->route(&(*it), (uint32_t)device, newMode);
    643                 ALOGD("USB UNPLUGGED, setting musbPlaybackState to 0");
    644                 musbPlaybackState = 0;
    645                 musbRecordingState = 0;
    646                 closeUSBRecording();
    647                 closeUSBPlayback();
    648         } else if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
    649                   (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
    650                     ALOGD("Routing everything to prox now");
    651                     ALSAHandleList::iterator it = mDeviceList.end();
    652                     it--;
    653                     mALSADevice->route(&(*it), AudioSystem::DEVICE_OUT_PROXY,
    654                                        newMode);
    655                     for(it = mDeviceList.begin(); it != mDeviceList.end(); ++it) {
    656                          if((!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
    657                             (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_LPA))) {
    658                                  ALOGV("doRouting: LPA device switch to proxy");
    659                                  startUsbPlaybackIfNotStarted();
    660                                  musbPlaybackState |= USBPLAYBACKBIT_LPA;
    661                                  break;
    662                          } else if((!strcmp(it->useCase, SND_USE_CASE_VERB_VOICECALL)) ||
    663                                    (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_VOICE))) {
    664                                     ALOGV("doRouting: VOICE device switch to proxy");
    665                                     startUsbRecordingIfNotStarted();
    666                                     startUsbPlaybackIfNotStarted();
    667                                     musbPlaybackState |= USBPLAYBACKBIT_VOICECALL;
    668                                     musbRecordingState |= USBPLAYBACKBIT_VOICECALL;
    669                                     break;
    670                         }else if((!strcmp(it->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
    671                                  (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_FM))) {
    672                                     ALOGV("doRouting: FM device switch to proxy");
    673                                     startUsbPlaybackIfNotStarted();
    674                                     musbPlaybackState |= USBPLAYBACKBIT_FM;
    675                                     break;
    676                          }
    677                     }
    678         } else
    679 #endif
    680         {
    681              ALSAHandleList::iterator it = mDeviceList.end();
    682              it--;
    683              mALSADevice->route(&(*it), (uint32_t)device, newMode);
    684         }
    685     }
    686     mCurDevice = device;
    687 }
    688 
    689 uint32_t AudioHardwareALSA::getVoipMode(int format)
    690 {
    691     switch(format) {
    692     case AudioSystem::PCM_16_BIT:
    693                return MODE_PCM;
    694          break;
    695     case AudioSystem::AMR_NB:
    696                return MODE_AMR;
    697          break;
    698     case AudioSystem::AMR_WB:
    699                return MODE_AMR_WB;
    700          break;
    701 
    702 #ifdef QCOM_QCHAT_ENABLED
    703     case AudioSystem::EVRC:
    704                return MODE_IS127;
    705          break;
    706 
    707     case AudioSystem::EVRCB:
    708                return MODE_4GV_NB;
    709          break;
    710     case AudioSystem::EVRCWB:
    711                return MODE_4GV_WB;
    712          break;
    713 #endif
    714 
    715     default:
    716                return MODE_PCM;
    717     }
    718 }
    719 
    720 AudioStreamOut *
    721 AudioHardwareALSA::openOutputStream(uint32_t devices,
    722                                     int *format,
    723                                     uint32_t *channels,
    724                                     uint32_t *sampleRate,
    725                                     status_t *status)
    726 {
    727     Mutex::Autolock autoLock(mLock);
    728     ALOGV("openOutputStream: devices 0x%x channels %d sampleRate %d",
    729          devices, *channels, *sampleRate);
    730 
    731     audio_output_flags_t flag = static_cast<audio_output_flags_t> (*status);
    732 
    733     status_t err = BAD_VALUE;
    734     *status = NO_ERROR;
    735     AudioStreamOutALSA *out = 0;
    736     ALSAHandleList::iterator it;
    737 
    738     if (devices & (devices - 1)) {
    739         if (status) *status = err;
    740         ALOGE("openOutputStream called with bad devices");
    741         return out;
    742     }
    743 
    744 
    745 # if 0
    746     if((devices == AudioSystem::DEVICE_OUT_DIRECTOUTPUT) &&
    747        ((*sampleRate == VOIP_SAMPLING_RATE_8K) || (*sampleRate == VOIP_SAMPLING_RATE_16K))) {
    748         bool voipstream_active = false;
    749         for(it = mDeviceList.begin();
    750             it != mDeviceList.end(); ++it) {
    751                 if((!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
    752                    (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
    753                     ALOGD("openOutput:  it->rxHandle %d it->handle %d",it->rxHandle,it->handle);
    754                     voipstream_active = true;
    755                     break;
    756                 }
    757         }
    758       if(voipstream_active == false) {
    759          mVoipStreamCount = 0;
    760          alsa_handle_t alsa_handle;
    761          unsigned long bufferSize;
    762          if(*sampleRate == VOIP_SAMPLING_RATE_8K) {
    763              bufferSize = VOIP_BUFFER_SIZE_8K;
    764          }
    765          else if(*sampleRate == VOIP_SAMPLING_RATE_16K) {
    766              bufferSize = VOIP_BUFFER_SIZE_16K;
    767          }
    768          else {
    769              ALOGE("unsupported samplerate %d for voip",*sampleRate);
    770              if (status) *status = err;
    771                  return out;
    772           }
    773           alsa_handle.module = mALSADevice;
    774           alsa_handle.bufferSize = bufferSize;
    775           alsa_handle.devices = devices;
    776           alsa_handle.handle = 0;
    777           if(*format == AudioSystem::PCM_16_BIT)
    778               alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
    779           else
    780               alsa_handle.format = *format;
    781           alsa_handle.channels = VOIP_DEFAULT_CHANNEL_MODE;
    782           alsa_handle.channelMask = AUDIO_CHANNEL_IN_MONO;
    783           alsa_handle.sampleRate = *sampleRate;
    784           alsa_handle.latency = VOIP_PLAYBACK_LATENCY;
    785           alsa_handle.rxHandle = 0;
    786           alsa_handle.ucMgr = mUcMgr;
    787           mALSADevice->setVoipConfig(getVoipMode(*format), mVoipBitRate);
    788           char *use_case;
    789           snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
    790           if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
    791               strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_IP_VOICECALL, sizeof(alsa_handle.useCase));
    792           } else {
    793               strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_VOIP, sizeof(alsa_handle.useCase));
    794           }
    795           free(use_case);
    796           mDeviceList.push_back(alsa_handle);
    797           it = mDeviceList.end();
    798           it--;
    799           ALOGV("openoutput: mALSADevice->route useCase %s mCurDevice %d mVoipStreamCount %d mode %d", it->useCase,mCurDevice,mVoipStreamCount, mode());
    800           if((mCurDevice & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
    801              (mCurDevice & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)||
    802              (mCurDevice & AudioSystem::DEVICE_OUT_PROXY)){
    803               ALOGD("Routing to proxy for normal voip call in openOutputStream");
    804               mCurDevice |= AudioSystem::DEVICE_OUT_PROXY;
    805               alsa_handle.devices = AudioSystem::DEVICE_OUT_PROXY;
    806               mALSADevice->route(&(*it), mCurDevice, AudioSystem::MODE_IN_COMMUNICATION);
    807               ALOGD("enabling VOIP in openoutputstream, musbPlaybackState: %d", musbPlaybackState);
    808               startUsbPlaybackIfNotStarted();
    809               musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL;
    810               ALOGD("Starting recording in openoutputstream, musbRecordingState: %d", musbRecordingState);
    811               startUsbRecordingIfNotStarted();
    812               musbRecordingState |= USBRECBIT_VOIPCALL;
    813           } else{
    814               mALSADevice->route(&(*it), mCurDevice, AudioSystem::MODE_IN_COMMUNICATION);
    815           }
    816           if(!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) {
    817               snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_IP_VOICECALL);
    818           } else {
    819               snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_VOIP);
    820           }
    821           err = mALSADevice->startVoipCall(&(*it));
    822           if (err) {
    823               ALOGE("Device open failed");
    824               return NULL;
    825           }
    826       }
    827       out = new AudioStreamOutALSA(this, &(*it));
    828       err = out->set(format, channels, sampleRate, devices);
    829       if(err == NO_ERROR) {
    830           mVoipStreamCount++;   //increment VoipstreamCount only if success
    831           ALOGD("openoutput mVoipStreamCount %d",mVoipStreamCount);
    832       }
    833       if (status) *status = err;
    834       return out;
    835     } else
    836 #endif
    837     if ((flag & AUDIO_OUTPUT_FLAG_DIRECT) &&
    838         (devices == AudioSystem::DEVICE_OUT_AUX_DIGITAL)) {
    839         ALOGD("Multi channel PCM");
    840         alsa_handle_t alsa_handle;
    841         EDID_AUDIO_INFO info = { 0 };
    842 
    843         alsa_handle.module = mALSADevice;
    844         alsa_handle.devices = devices;
    845         alsa_handle.handle = 0;
    846         alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
    847 
    848         if (!AudioUtil::getHDMIAudioSinkCaps(&info)) {
    849             ALOGE("openOutputStream: Failed to get HDMI sink capabilities");
    850             return NULL;
    851         }
    852         if (0 == *channels) {
    853             alsa_handle.channels = info.AudioBlocksArray[info.nAudioBlocks-1].nChannels;
    854             if (alsa_handle.channels > 6) {
    855                 alsa_handle.channels = 6;
    856             }
    857             *channels = audio_channel_out_mask_from_count(alsa_handle.channels);
    858         } else {
    859             alsa_handle.channels = AudioSystem::popCount(*channels);
    860         }
    861         alsa_handle.channelMask = *channels;
    862 
    863         if (6 == alsa_handle.channels) {
    864             alsa_handle.bufferSize = DEFAULT_MULTI_CHANNEL_BUF_SIZE;
    865         } else {
    866             alsa_handle.bufferSize = DEFAULT_BUFFER_SIZE;
    867         }
    868         if (0 == *sampleRate) {
    869             alsa_handle.sampleRate = info.AudioBlocksArray[info.nAudioBlocks-1].nSamplingFreq;
    870             *sampleRate = alsa_handle.sampleRate;
    871         } else {
    872             alsa_handle.sampleRate = *sampleRate;
    873         }
    874         alsa_handle.latency = PLAYBACK_LATENCY;
    875         alsa_handle.rxHandle = 0;
    876         alsa_handle.ucMgr = mUcMgr;
    877         ALOGD("alsa_handle.channels %d alsa_handle.sampleRate %d",alsa_handle.channels,alsa_handle.sampleRate);
    878 
    879         char *use_case;
    880         snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
    881         if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
    882             strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI2 , sizeof(alsa_handle.useCase));
    883         } else {
    884             strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_MUSIC2, sizeof(alsa_handle.useCase));
    885         }
    886         free(use_case);
    887         mDeviceList.push_back(alsa_handle);
    888         ALSAHandleList::iterator it = mDeviceList.end();
    889         it--;
    890         ALOGD("it->useCase %s", it->useCase);
    891         mALSADevice->route(&(*it), devices, mode());
    892         if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI2)) {
    893             snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI2 );
    894         } else {
    895             snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_MUSIC2);
    896         }
    897         ALOGD("channels: %d", AudioSystem::popCount(*channels));
    898         err = mALSADevice->open(&(*it));
    899 
    900         if (err) {
    901             ALOGE("Device open failed err:%d",err);
    902         } else {
    903             out = new AudioStreamOutALSA(this, &(*it));
    904             err = out->set(format, channels, sampleRate, devices);
    905         }
    906         if (status) *status = err;
    907         return out;
    908     } else {
    909 
    910       alsa_handle_t alsa_handle;
    911       unsigned long bufferSize = DEFAULT_BUFFER_SIZE;
    912 
    913       for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1)
    914           bufferSize &= ~b;
    915 
    916       alsa_handle.module = mALSADevice;
    917       alsa_handle.bufferSize = bufferSize;
    918       alsa_handle.devices = devices;
    919       alsa_handle.handle = 0;
    920       alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
    921       alsa_handle.channels = DEFAULT_CHANNEL_MODE;
    922       alsa_handle.channelMask = AUDIO_CHANNEL_OUT_STEREO;
    923       alsa_handle.sampleRate = DEFAULT_SAMPLING_RATE;
    924       alsa_handle.latency = PLAYBACK_LATENCY;
    925       alsa_handle.rxHandle = 0;
    926       alsa_handle.ucMgr = mUcMgr;
    927       alsa_handle.isDeepbufferOutput = false;
    928 
    929       char *use_case;
    930       snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
    931 
    932       if (flag & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) {
    933       ALOGD("openOutputStream: DeepBuffer Output");
    934           alsa_handle.isDeepbufferOutput = true;
    935           if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
    936                strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI, sizeof(alsa_handle.useCase));
    937           } else {
    938                strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_MUSIC, sizeof(alsa_handle.useCase));
    939           }
    940       } else {
    941       ALOGD("openOutputStream: Lowlatency Output");
    942           alsa_handle.bufferSize = PLAYBACK_LOW_LATENCY_BUFFER_SIZE;
    943           alsa_handle.latency = PLAYBACK_LOW_LATENCY_MEASURED;
    944           if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
    945                strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase));
    946           } else {
    947                strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase));
    948           }
    949       }
    950       free(use_case);
    951       mDeviceList.push_back(alsa_handle);
    952       ALSAHandleList::iterator it = mDeviceList.end();
    953       it--;
    954       ALOGV("useCase %s", it->useCase);
    955 #ifdef QCOM_USBAUDIO_ENABLED
    956       if((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
    957          (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
    958           ALOGD("Routing to proxy for normal playback in openOutputStream");
    959           devices |= AudioSystem::DEVICE_OUT_PROXY;
    960       }
    961 #endif
    962       mALSADevice->route(&(*it), devices, mode());
    963       if (flag & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) {
    964           if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI)) {
    965              snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI);
    966           } else {
    967              snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_MUSIC);
    968           }
    969       } else {
    970           if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) {
    971              snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC);
    972           } else {
    973              snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC);
    974           }
    975       }
    976       err = mALSADevice->open(&(*it));
    977       if (err) {
    978           ALOGE("Device open failed");
    979       } else {
    980           out = new AudioStreamOutALSA(this, &(*it));
    981           err = out->set(format, channels, sampleRate, devices);
    982       }
    983 
    984       if (status) *status = err;
    985       return out;
    986     }
    987 }
    988 
    989 void
    990 AudioHardwareALSA::closeOutputStream(AudioStreamOut* out)
    991 {
    992     delete out;
    993 }
    994 
    995 #ifdef QCOM_TUNNEL_LPA_ENABLED
    996 AudioStreamOut *
    997 AudioHardwareALSA::openOutputSession(uint32_t devices,
    998                                      int *format,
    999                                      status_t *status,
   1000                                      int sessionId,
   1001                                      uint32_t samplingRate,
   1002                                      uint32_t channels)
   1003 {
   1004     Mutex::Autolock autoLock(mLock);
   1005     ALOGD("openOutputSession = %d" ,sessionId);
   1006     AudioStreamOutALSA *out = 0;
   1007     status_t err = BAD_VALUE;
   1008 
   1009     alsa_handle_t alsa_handle;
   1010     unsigned long bufferSize = DEFAULT_BUFFER_SIZE;
   1011 
   1012     for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1)
   1013         bufferSize &= ~b;
   1014 
   1015     alsa_handle.module = mALSADevice;
   1016     alsa_handle.bufferSize = bufferSize;
   1017     alsa_handle.devices = devices;
   1018     alsa_handle.handle = 0;
   1019     alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
   1020     alsa_handle.channels = DEFAULT_CHANNEL_MODE;
   1021     alsa_handle.channelMask = AUDIO_CHANNEL_OUT_STEREO;
   1022     alsa_handle.sampleRate = DEFAULT_SAMPLING_RATE;
   1023     alsa_handle.latency = VOICE_LATENCY;
   1024     alsa_handle.rxHandle = 0;
   1025     alsa_handle.ucMgr = mUcMgr;
   1026 
   1027     char *use_case;
   1028     if(sessionId == TUNNEL_SESSION_ID) {
   1029         snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
   1030         if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
   1031             strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_TUNNEL, sizeof(alsa_handle.useCase));
   1032         } else {
   1033             strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_TUNNEL, sizeof(alsa_handle.useCase));
   1034         }
   1035     } else {
   1036         snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
   1037         if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
   1038             strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER, sizeof(alsa_handle.useCase));
   1039         } else {
   1040             strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_LPA, sizeof(alsa_handle.useCase));
   1041         }
   1042     }
   1043     free(use_case);
   1044     mDeviceList.push_back(alsa_handle);
   1045     ALSAHandleList::iterator it = mDeviceList.end();
   1046     it--;
   1047     ALOGD("useCase %s", it->useCase);
   1048 #ifdef QCOM_USBAUDIO_ENABLED
   1049     if((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
   1050        (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
   1051         ALOGD("Routing to proxy for LPA in openOutputSession");
   1052         devices |= AudioSystem::DEVICE_OUT_PROXY;
   1053         mALSADevice->route(&(*it), devices, mode());
   1054         devices = AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET;
   1055         ALOGD("Starting USBPlayback for LPA");
   1056         startUsbPlaybackIfNotStarted();
   1057         musbPlaybackState |= USBPLAYBACKBIT_LPA;
   1058     } else
   1059 #endif
   1060     {
   1061         mALSADevice->route(&(*it), devices, mode());
   1062     }
   1063     if(sessionId == TUNNEL_SESSION_ID) {
   1064         if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) {
   1065             snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_TUNNEL);
   1066         } else {
   1067             snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_TUNNEL);
   1068         }
   1069     }
   1070     else {
   1071         if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) {
   1072             snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_LOW_POWER);
   1073         } else {
   1074             snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_LPA);
   1075         }
   1076     }
   1077     err = mALSADevice->open(&(*it));
   1078     out = new AudioStreamOutALSA(this, &(*it));
   1079 
   1080     if (status) *status = err;
   1081        return out;
   1082 }
   1083 
   1084 void
   1085 AudioHardwareALSA::closeOutputSession(AudioStreamOut* out)
   1086 {
   1087     delete out;
   1088 }
   1089 #endif
   1090 
   1091 AudioStreamIn *
   1092 AudioHardwareALSA::openInputStream(uint32_t devices,
   1093                                    int *format,
   1094                                    uint32_t *channels,
   1095                                    uint32_t *sampleRate,
   1096                                    status_t *status,
   1097                                    AudioSystem::audio_in_acoustics acoustics)
   1098 {
   1099     Mutex::Autolock autoLock(mLock);
   1100     char *use_case;
   1101     int newMode = mode();
   1102     uint32_t route_devices;
   1103 
   1104     status_t err = BAD_VALUE;
   1105     AudioStreamInALSA *in = 0;
   1106     ALSAHandleList::iterator it;
   1107 
   1108     ALOGD("openInputStream: devices 0x%x channels %d sampleRate %d", devices, *channels, *sampleRate);
   1109     if (devices & (devices - 1)) {
   1110         if (status) *status = err;
   1111         return in;
   1112     }
   1113 
   1114     if((devices == AudioSystem::DEVICE_IN_COMMUNICATION) &&
   1115        ((*sampleRate == VOIP_SAMPLING_RATE_8K) || (*sampleRate == VOIP_SAMPLING_RATE_16K))) {
   1116         bool voipstream_active = false;
   1117         for(it = mDeviceList.begin();
   1118             it != mDeviceList.end(); ++it) {
   1119                 if((!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
   1120                    (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
   1121                     ALOGD("openInput:  it->rxHandle %p it->handle %p",it->rxHandle,it->handle);
   1122                     voipstream_active = true;
   1123                     break;
   1124                 }
   1125         }
   1126         if(voipstream_active == false) {
   1127            mVoipStreamCount = 0;
   1128            alsa_handle_t alsa_handle;
   1129            unsigned long bufferSize;
   1130            if(*sampleRate == VOIP_SAMPLING_RATE_8K) {
   1131                bufferSize = VOIP_BUFFER_SIZE_8K;
   1132            }
   1133            else if(*sampleRate == VOIP_SAMPLING_RATE_16K) {
   1134                bufferSize = VOIP_BUFFER_SIZE_16K;
   1135            }
   1136            else {
   1137                ALOGE("unsupported samplerate %d for voip",*sampleRate);
   1138                if (status) *status = err;
   1139                return in;
   1140            }
   1141            alsa_handle.module = mALSADevice;
   1142            alsa_handle.bufferSize = bufferSize;
   1143            alsa_handle.devices = devices;
   1144            alsa_handle.handle = 0;
   1145           if(*format == AudioSystem::PCM_16_BIT)
   1146               alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
   1147           else
   1148               alsa_handle.format = *format;
   1149            alsa_handle.channels = VOIP_DEFAULT_CHANNEL_MODE;
   1150            alsa_handle.channelMask = AUDIO_CHANNEL_IN_MONO;
   1151            alsa_handle.sampleRate = *sampleRate;
   1152            alsa_handle.latency = VOIP_RECORD_LATENCY;
   1153            alsa_handle.rxHandle = 0;
   1154            alsa_handle.ucMgr = mUcMgr;
   1155           mALSADevice->setVoipConfig(getVoipMode(*format), mVoipBitRate);
   1156            snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
   1157            if ((use_case != NULL) && (strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
   1158                 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_VOIP, sizeof(alsa_handle.useCase));
   1159            } else {
   1160                 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_IP_VOICECALL, sizeof(alsa_handle.useCase));
   1161            }
   1162            free(use_case);
   1163            mDeviceList.push_back(alsa_handle);
   1164            it = mDeviceList.end();
   1165            it--;
   1166            ALOGD("mCurrDevice: %d", mCurDevice);
   1167 #ifdef QCOM_USBAUDIO_ENABLED
   1168            if((mCurDevice == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
   1169               (mCurDevice == AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
   1170               ALOGD("Routing everything from proxy for voipcall");
   1171               mALSADevice->route(&(*it), AudioSystem::DEVICE_IN_PROXY, AudioSystem::MODE_IN_COMMUNICATION);
   1172               ALOGD("enabling VOIP in openInputstream, musbPlaybackState: %d", musbPlaybackState);
   1173               startUsbPlaybackIfNotStarted();
   1174               musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL;
   1175               ALOGD("Starting recording in openoutputstream, musbRecordingState: %d", musbRecordingState);
   1176               startUsbRecordingIfNotStarted();
   1177               musbRecordingState |= USBRECBIT_VOIPCALL;
   1178            } else
   1179 #endif
   1180            {
   1181                mALSADevice->route(&(*it),mCurDevice, AudioSystem::MODE_IN_COMMUNICATION);
   1182            }
   1183            if(!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) {
   1184                snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_IP_VOICECALL);
   1185            } else {
   1186                snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_VOIP);
   1187            }
   1188            if(sampleRate) {
   1189                it->sampleRate = *sampleRate;
   1190            }
   1191            if(channels)
   1192                it->channels = AudioSystem::popCount(*channels);
   1193            err = mALSADevice->startVoipCall(&(*it));
   1194            if (err) {
   1195                ALOGE("Error opening pcm input device");
   1196                return NULL;
   1197            }
   1198         }
   1199         in = new AudioStreamInALSA(this, &(*it), acoustics);
   1200         err = in->set(format, channels, sampleRate, devices);
   1201         if(err == NO_ERROR) {
   1202             mVoipStreamCount++;   //increment VoipstreamCount only if success
   1203             ALOGD("OpenInput mVoipStreamCount %d",mVoipStreamCount);
   1204         }
   1205         ALOGD("openInput: After Get alsahandle");
   1206         if (status) *status = err;
   1207         return in;
   1208       } else {
   1209         alsa_handle_t alsa_handle;
   1210         unsigned long bufferSize = MIN_CAPTURE_BUFFER_SIZE_PER_CH;
   1211 
   1212         alsa_handle.module = mALSADevice;
   1213         alsa_handle.bufferSize = bufferSize;
   1214         alsa_handle.devices = devices;
   1215         alsa_handle.handle = 0;
   1216         alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
   1217         alsa_handle.channels = VOICE_CHANNEL_MODE;
   1218         alsa_handle.channelMask = AUDIO_CHANNEL_IN_MONO;
   1219         alsa_handle.sampleRate = android::AudioRecord::DEFAULT_SAMPLE_RATE;
   1220         alsa_handle.latency = RECORD_LATENCY;
   1221         alsa_handle.rxHandle = 0;
   1222         alsa_handle.ucMgr = mUcMgr;
   1223         snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
   1224         if ((use_case != NULL) && (strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
   1225             if ((devices == AudioSystem::DEVICE_IN_VOICE_CALL) &&
   1226                 (newMode == AudioSystem::MODE_IN_CALL)) {
   1227                 ALOGD("openInputStream: into incall recording, channels %d", *channels);
   1228                 mIncallMode = *channels;
   1229                 if ((*channels & AudioSystem::CHANNEL_IN_VOICE_UPLINK) &&
   1230                     (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) {
   1231                     if (mFusion3Platform) {
   1232                         mALSADevice->setVocRecMode(INCALL_REC_STEREO);
   1233                         strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
   1234                                 sizeof(alsa_handle.useCase));
   1235                     } else {
   1236                         strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
   1237                                 sizeof(alsa_handle.useCase));
   1238                     }
   1239                 } else if (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) {
   1240                     if (mFusion3Platform) {
   1241                         mALSADevice->setVocRecMode(INCALL_REC_MONO);
   1242                         strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
   1243                                 sizeof(alsa_handle.useCase));
   1244                     } else {
   1245                         strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
   1246                                 sizeof(alsa_handle.useCase));
   1247                     }
   1248                 }
   1249 #ifdef QCOM_FM_ENABLED
   1250             } else if((devices == AudioSystem::DEVICE_IN_FM_RX)) {
   1251                 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_FM, sizeof(alsa_handle.useCase));
   1252             } else if(devices == AudioSystem::DEVICE_IN_FM_RX_A2DP) {
   1253                 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM, sizeof(alsa_handle.useCase));
   1254 #endif
   1255             } else {
   1256         char value[128];
   1257         property_get("persist.audio.lowlatency.rec",value,"0");
   1258                 if (!strcmp("true", value)) {
   1259                     strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase));
   1260                 } else {
   1261                     strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, sizeof(alsa_handle.useCase));
   1262                 }
   1263             }
   1264         } else {
   1265             if ((devices == AudioSystem::DEVICE_IN_VOICE_CALL) &&
   1266                 (newMode == AudioSystem::MODE_IN_CALL)) {
   1267                 ALOGD("openInputStream: incall recording, channels %d", *channels);
   1268                 mIncallMode = *channels;
   1269                 if ((*channels & AudioSystem::CHANNEL_IN_VOICE_UPLINK) &&
   1270                     (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) {
   1271                     if (mFusion3Platform) {
   1272                         mALSADevice->setVocRecMode(INCALL_REC_STEREO);
   1273                         strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_INCALL_REC,
   1274                                 sizeof(alsa_handle.useCase));
   1275                     } else {
   1276                         strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_UL_DL_REC,
   1277                                 sizeof(alsa_handle.useCase));
   1278                     }
   1279                 } else if (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) {
   1280                     if (mFusion3Platform) {
   1281                         mALSADevice->setVocRecMode(INCALL_REC_MONO);
   1282                         strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_INCALL_REC,
   1283                                 sizeof(alsa_handle.useCase));
   1284                     } else {
   1285                        strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_DL_REC,
   1286                                sizeof(alsa_handle.useCase));
   1287                     }
   1288                 }
   1289 #ifdef QCOM_FM_ENABLED
   1290             } else if(devices == AudioSystem::DEVICE_IN_FM_RX) {
   1291                 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_FM_REC, sizeof(alsa_handle.useCase));
   1292             } else if (devices == AudioSystem::DEVICE_IN_FM_RX_A2DP) {
   1293                 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_FM_A2DP_REC, sizeof(alsa_handle.useCase));
   1294 #endif
   1295             } else {
   1296                 char value[128];
   1297                 property_get("persist.audio.lowlatency.rec",value,"0");
   1298                 if (!strcmp("true", value)) {
   1299                     strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC, sizeof(alsa_handle.useCase));
   1300                 } else {
   1301                     strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_REC, sizeof(alsa_handle.useCase));
   1302                 }
   1303             }
   1304         }
   1305         free(use_case);
   1306         mDeviceList.push_back(alsa_handle);
   1307         ALSAHandleList::iterator it = mDeviceList.end();
   1308         it--;
   1309         //update channel info before do routing
   1310         if(channels) {
   1311             it->channels = AudioSystem::popCount((*channels) &
   1312                       (AudioSystem::CHANNEL_IN_STEREO
   1313                        | AudioSystem::CHANNEL_IN_MONO
   1314 #ifdef QCOM_SSR_ENABLED
   1315                        | AudioSystem::CHANNEL_IN_5POINT1
   1316 #endif
   1317                        | AUDIO_CHANNEL_IN_FRONT_BACK));
   1318             it->channelMask = *channels;
   1319             ALOGV("updated channel info: channels=%d channelMask %08x",
   1320                   it->channels, it->channelMask);
   1321         }
   1322         if (devices == AudioSystem::DEVICE_IN_VOICE_CALL){
   1323            /* Add current devices info to devices to do route */
   1324 #ifdef QCOM_USBAUDIO_ENABLED
   1325             if(mCurDevice == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET ||
   1326                mCurDevice == AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET){
   1327                 ALOGD("Routing everything from proxy for VOIP call");
   1328                 route_devices = devices | AudioSystem::DEVICE_IN_PROXY;
   1329             } else
   1330 #endif
   1331             {
   1332             route_devices = devices | mCurDevice;
   1333             }
   1334             mALSADevice->route(&(*it), route_devices, mode());
   1335         } else {
   1336 #ifdef QCOM_USBAUDIO_ENABLED
   1337             if(devices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET ||
   1338                devices & AudioSystem::DEVICE_IN_PROXY) {
   1339                 devices |= AudioSystem::DEVICE_IN_PROXY;
   1340                 ALOGD("routing everything from proxy");
   1341             mALSADevice->route(&(*it), devices, mode());
   1342             } else
   1343 #endif
   1344             {
   1345                 mALSADevice->route(&(*it), devices, mode());
   1346             }
   1347         }
   1348         if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_REC) ||
   1349            !strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC) ||
   1350 #ifdef QCOM_FM_ENABLED
   1351            !strcmp(it->useCase, SND_USE_CASE_VERB_FM_REC) ||
   1352            !strcmp(it->useCase, SND_USE_CASE_VERB_FM_A2DP_REC) ||
   1353 #endif
   1354            !strcmp(it->useCase, SND_USE_CASE_VERB_DL_REC) ||
   1355            !strcmp(it->useCase, SND_USE_CASE_VERB_UL_DL_REC) ||
   1356            !strcmp(it->useCase, SND_USE_CASE_VERB_INCALL_REC)) {
   1357             snd_use_case_set(mUcMgr, "_verb", it->useCase);
   1358         } else {
   1359             snd_use_case_set(mUcMgr, "_enamod", it->useCase);
   1360         }
   1361         if(sampleRate) {
   1362             it->sampleRate = *sampleRate;
   1363         }
   1364         if (!strncmp(it->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
   1365             || !strncmp(it->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
   1366             ALOGV("OpenInoutStream: Use larger buffer size for 5.1(%s) recording ", it->useCase);
   1367             it->bufferSize = getInputBufferSize(it->sampleRate,*format,it->channels);
   1368         }
   1369         err = mALSADevice->open(&(*it));
   1370         if (err) {
   1371            ALOGE("Error opening pcm input device");
   1372         } else {
   1373            in = new AudioStreamInALSA(this, &(*it), acoustics);
   1374            err = in->set(format, channels, sampleRate, devices);
   1375         }
   1376         if (status) *status = err;
   1377         return in;
   1378       }
   1379 }
   1380 
   1381 void
   1382 AudioHardwareALSA::closeInputStream(AudioStreamIn* in)
   1383 {
   1384     delete in;
   1385 }
   1386 
   1387 status_t AudioHardwareALSA::setMicMute(bool state)
   1388 {
   1389     if (mMicMute != state) {
   1390         mMicMute = state;
   1391         ALOGD("setMicMute: mMicMute %d", mMicMute);
   1392         if(mALSADevice) {
   1393             mALSADevice->setMicMute(state);
   1394         }
   1395     }
   1396     return NO_ERROR;
   1397 }
   1398 
   1399 status_t AudioHardwareALSA::getMicMute(bool *state)
   1400 {
   1401     *state = mMicMute;
   1402     return NO_ERROR;
   1403 }
   1404 
   1405 status_t AudioHardwareALSA::dump(int fd, const Vector<String16>& args)
   1406 {
   1407     return NO_ERROR;
   1408 }
   1409 
   1410 size_t AudioHardwareALSA::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
   1411 {
   1412     size_t bufferSize = 0;
   1413     if (format == AudioSystem::PCM_16_BIT) {
   1414         if(sampleRate == 8000 || sampleRate == 16000 || sampleRate == 32000) {
   1415             bufferSize = (sampleRate * channelCount * 20 * sizeof(int16_t)) / 1000;
   1416         } else if (sampleRate == 11025 || sampleRate == 12000) {
   1417             bufferSize = 256 * sizeof(int16_t)  * channelCount;
   1418         } else if (sampleRate == 22050 || sampleRate == 24000) {
   1419             bufferSize = 512 * sizeof(int16_t)  * channelCount;
   1420         } else if (sampleRate == 44100 || sampleRate == 48000) {
   1421             bufferSize = 1024 * sizeof(int16_t) * channelCount;
   1422         }
   1423     } else {
   1424         ALOGE("getInputBufferSize bad format: %d", format);
   1425     }
   1426     return bufferSize;
   1427 }
   1428 
   1429 #ifdef QCOM_FM_ENABLED
   1430 void AudioHardwareALSA::handleFm(int device)
   1431 {
   1432 int newMode = mode();
   1433     if(device & AudioSystem::DEVICE_OUT_FM && mIsFmActive == 0) {
   1434         // Start FM Radio on current active device
   1435         unsigned long bufferSize = FM_BUFFER_SIZE;
   1436         alsa_handle_t alsa_handle;
   1437         char *use_case;
   1438         ALOGV("Start FM");
   1439         snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
   1440         if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
   1441             strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_DIGITAL_RADIO, sizeof(alsa_handle.useCase));
   1442         } else {
   1443             strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_FM, sizeof(alsa_handle.useCase));
   1444         }
   1445         free(use_case);
   1446 
   1447         for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1)
   1448         bufferSize &= ~b;
   1449         alsa_handle.module = mALSADevice;
   1450         alsa_handle.bufferSize = bufferSize;
   1451         alsa_handle.devices = device;
   1452         alsa_handle.handle = 0;
   1453         alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
   1454         alsa_handle.channels = DEFAULT_CHANNEL_MODE;
   1455         alsa_handle.channelMask = AUDIO_CHANNEL_OUT_STEREO;
   1456         alsa_handle.sampleRate = DEFAULT_SAMPLING_RATE;
   1457         alsa_handle.latency = VOICE_LATENCY;
   1458         alsa_handle.rxHandle = 0;
   1459         alsa_handle.ucMgr = mUcMgr;
   1460         mIsFmActive = 1;
   1461         mDeviceList.push_back(alsa_handle);
   1462         ALSAHandleList::iterator it = mDeviceList.end();
   1463         it--;
   1464         if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
   1465            (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
   1466             device |= AudioSystem::DEVICE_OUT_PROXY;
   1467             alsa_handle.devices = AudioSystem::DEVICE_OUT_PROXY;
   1468             ALOGD("Routing to proxy for FM case");
   1469         }
   1470         mALSADevice->route(&(*it), (uint32_t)device, newMode);
   1471         if(!strcmp(it->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) {
   1472             snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_DIGITAL_RADIO);
   1473         } else {
   1474             snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_FM);
   1475         }
   1476         mALSADevice->startFm(&(*it));
   1477         if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
   1478            (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
   1479             ALOGD("Starting FM, musbPlaybackState %d", musbPlaybackState);
   1480             startUsbPlaybackIfNotStarted();
   1481             musbPlaybackState |= USBPLAYBACKBIT_FM;
   1482         }
   1483     } else if (!(device & AudioSystem::DEVICE_OUT_FM) && mIsFmActive == 1) {
   1484         //i Stop FM Radio
   1485         ALOGV("Stop FM");
   1486         for(ALSAHandleList::iterator it = mDeviceList.begin();
   1487             it != mDeviceList.end(); ++it) {
   1488             if((!strcmp(it->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
   1489               (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_FM))) {
   1490                 mALSADevice->close(&(*it));
   1491                 //mALSADevice->route(&(*it), (uint32_t)device, newMode);
   1492                 mDeviceList.erase(it);
   1493                 break;
   1494             }
   1495         }
   1496         mIsFmActive = 0;
   1497         musbPlaybackState &= ~USBPLAYBACKBIT_FM;
   1498         if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
   1499            (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
   1500             closeUsbPlaybackIfNothingActive();
   1501         }
   1502     }
   1503 }
   1504 #endif
   1505 
   1506 void AudioHardwareALSA::disableVoiceCall(char* verb, char* modifier, int mode, int device)
   1507 {
   1508     for(ALSAHandleList::iterator it = mDeviceList.begin();
   1509          it != mDeviceList.end(); ++it) {
   1510         if((!strcmp(it->useCase, verb)) ||
   1511            (!strcmp(it->useCase, modifier))) {
   1512             ALOGV("Disabling voice call");
   1513             mALSADevice->close(&(*it));
   1514             mALSADevice->route(&(*it), (uint32_t)device, mode);
   1515             mDeviceList.erase(it);
   1516             break;
   1517         }
   1518     }
   1519 #ifdef QCOM_USBAUDIO_ENABLED
   1520    if(musbPlaybackState & USBPLAYBACKBIT_VOICECALL) {
   1521           ALOGD("Voice call ended on USB");
   1522           musbPlaybackState &= ~USBPLAYBACKBIT_VOICECALL;
   1523           musbRecordingState &= ~USBRECBIT_VOICECALL;
   1524           closeUsbRecordingIfNothingActive();
   1525           closeUsbPlaybackIfNothingActive();
   1526    }
   1527 #endif
   1528 }
   1529 void AudioHardwareALSA::enableVoiceCall(char* verb, char* modifier, int mode, int device)
   1530 {
   1531 // Start voice call
   1532 unsigned long bufferSize = DEFAULT_VOICE_BUFFER_SIZE;
   1533 alsa_handle_t alsa_handle;
   1534 char *use_case;
   1535     snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
   1536     if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
   1537         strlcpy(alsa_handle.useCase, verb, sizeof(alsa_handle.useCase));
   1538     } else {
   1539         strlcpy(alsa_handle.useCase, modifier, sizeof(alsa_handle.useCase));
   1540     }
   1541     free(use_case);
   1542 
   1543     for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1)
   1544     bufferSize &= ~b;
   1545     alsa_handle.module = mALSADevice;
   1546     alsa_handle.bufferSize = bufferSize;
   1547     alsa_handle.devices = device;
   1548     alsa_handle.handle = 0;
   1549     alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
   1550     alsa_handle.channels = VOICE_CHANNEL_MODE;
   1551     alsa_handle.channelMask = AUDIO_CHANNEL_IN_MONO;
   1552     alsa_handle.sampleRate = VOICE_SAMPLING_RATE;
   1553     alsa_handle.latency = VOICE_LATENCY;
   1554     alsa_handle.rxHandle = 0;
   1555     alsa_handle.ucMgr = mUcMgr;
   1556     mDeviceList.push_back(alsa_handle);
   1557     ALSAHandleList::iterator it = mDeviceList.end();
   1558     it--;
   1559 #ifdef QCOM_USBAUDIO_ENABLED
   1560     if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
   1561        (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
   1562         device |= AudioSystem::DEVICE_OUT_PROXY;
   1563         alsa_handle.devices = device;
   1564     }
   1565 #endif
   1566     mALSADevice->route(&(*it), (uint32_t)device, mode);
   1567     if (!strcmp(it->useCase, verb)) {
   1568         snd_use_case_set(mUcMgr, "_verb", verb);
   1569     } else {
   1570         snd_use_case_set(mUcMgr, "_enamod", modifier);
   1571     }
   1572     mALSADevice->startVoiceCall(&(*it));
   1573 #ifdef QCOM_USBAUDIO_ENABLED
   1574     if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
   1575        (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
   1576        startUsbRecordingIfNotStarted();
   1577        startUsbPlaybackIfNotStarted();
   1578        musbPlaybackState |= USBPLAYBACKBIT_VOICECALL;
   1579        musbRecordingState |= USBRECBIT_VOICECALL;
   1580     }
   1581 #endif
   1582 }
   1583 
   1584 bool AudioHardwareALSA::routeVoiceCall(int device, int newMode)
   1585 {
   1586 int csCallState = mCallState&0xF;
   1587  bool isRouted = false;
   1588  switch (csCallState) {
   1589     case CS_INACTIVE:
   1590         if (mCSCallActive != CS_INACTIVE) {
   1591             ALOGD("doRouting: Disabling voice call");
   1592             disableVoiceCall((char *)SND_USE_CASE_VERB_VOICECALL,
   1593                 (char *)SND_USE_CASE_MOD_PLAY_VOICE, newMode, device);
   1594             isRouted = true;
   1595             mCSCallActive = CS_INACTIVE;
   1596         }
   1597     break;
   1598     case CS_ACTIVE:
   1599         if (mCSCallActive == CS_INACTIVE) {
   1600             ALOGD("doRouting: Enabling CS voice call ");
   1601             enableVoiceCall((char *)SND_USE_CASE_VERB_VOICECALL,
   1602                 (char *)SND_USE_CASE_MOD_PLAY_VOICE, newMode, device);
   1603             isRouted = true;
   1604             mCSCallActive = CS_ACTIVE;
   1605         } else if (mCSCallActive == CS_HOLD) {
   1606              ALOGD("doRouting: Resume voice call from hold state");
   1607              ALSAHandleList::iterator vt_it;
   1608              for(vt_it = mDeviceList.begin();
   1609                  vt_it != mDeviceList.end(); ++vt_it) {
   1610                  if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOICECALL,
   1611                      strlen(SND_USE_CASE_VERB_VOICECALL))) ||
   1612                      (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOICE,
   1613                      strlen(SND_USE_CASE_MOD_PLAY_VOICE)))) {
   1614                      alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it));
   1615                      mCSCallActive = CS_ACTIVE;
   1616                      if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,0)<0)
   1617                                    ALOGE("VoLTE resume failed");
   1618                      break;
   1619                  }
   1620              }
   1621         }
   1622     break;
   1623     case CS_HOLD:
   1624         if (mCSCallActive == CS_ACTIVE) {
   1625             ALOGD("doRouting: Voice call going to Hold");
   1626              ALSAHandleList::iterator vt_it;
   1627              for(vt_it = mDeviceList.begin();
   1628                  vt_it != mDeviceList.end(); ++vt_it) {
   1629                  if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOICECALL,
   1630                      strlen(SND_USE_CASE_VERB_VOICECALL))) ||
   1631                      (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOICE,
   1632                          strlen(SND_USE_CASE_MOD_PLAY_VOICE)))) {
   1633                          mCSCallActive = CS_HOLD;
   1634                          alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it));
   1635                          if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,1)<0)
   1636                                    ALOGE("Voice pause failed");
   1637                          break;
   1638                 }
   1639             }
   1640         }
   1641     break;
   1642     }
   1643     return isRouted;
   1644 }
   1645 bool AudioHardwareALSA::routeVoLTECall(int device, int newMode)
   1646 {
   1647 int volteCallState = mCallState&0xF0;
   1648 bool isRouted = false;
   1649 switch (volteCallState) {
   1650     case IMS_INACTIVE:
   1651         if (mVolteCallActive != IMS_INACTIVE) {
   1652             ALOGD("doRouting: Disabling IMS call");
   1653             disableVoiceCall((char *)SND_USE_CASE_VERB_VOLTE,
   1654                 (char *)SND_USE_CASE_MOD_PLAY_VOLTE, newMode, device);
   1655             isRouted = true;
   1656             mVolteCallActive = IMS_INACTIVE;
   1657         }
   1658     break;
   1659     case IMS_ACTIVE:
   1660         if (mVolteCallActive == IMS_INACTIVE) {
   1661             ALOGD("doRouting: Enabling IMS voice call ");
   1662             enableVoiceCall((char *)SND_USE_CASE_VERB_VOLTE,
   1663                 (char *)SND_USE_CASE_MOD_PLAY_VOLTE, newMode, device);
   1664             isRouted = true;
   1665             mVolteCallActive = IMS_ACTIVE;
   1666         } else if (mVolteCallActive == IMS_HOLD) {
   1667              ALOGD("doRouting: Resume IMS call from hold state");
   1668              ALSAHandleList::iterator vt_it;
   1669              for(vt_it = mDeviceList.begin();
   1670                  vt_it != mDeviceList.end(); ++vt_it) {
   1671                  if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOLTE,
   1672                      strlen(SND_USE_CASE_VERB_VOLTE))) ||
   1673                      (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOLTE,
   1674                      strlen(SND_USE_CASE_MOD_PLAY_VOLTE)))) {
   1675                      alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it));
   1676                      mVolteCallActive = IMS_ACTIVE;
   1677                      if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,0)<0)
   1678                                    ALOGE("VoLTE resume failed");
   1679                      break;
   1680                  }
   1681              }
   1682         }
   1683     break;
   1684     case IMS_HOLD:
   1685         if (mVolteCallActive == IMS_ACTIVE) {
   1686              ALOGD("doRouting: IMS ACTIVE going to HOLD");
   1687              ALSAHandleList::iterator vt_it;
   1688              for(vt_it = mDeviceList.begin();
   1689                  vt_it != mDeviceList.end(); ++vt_it) {
   1690                  if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOLTE,
   1691                      strlen(SND_USE_CASE_VERB_VOLTE))) ||
   1692                      (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOLTE,
   1693                          strlen(SND_USE_CASE_MOD_PLAY_VOLTE)))) {
   1694                           mVolteCallActive = IMS_HOLD;
   1695                          alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it));
   1696                          if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,1)<0)
   1697                                    ALOGE("VoLTE Pause failed");
   1698                     break;
   1699                 }
   1700             }
   1701         }
   1702     break;
   1703     }
   1704     return isRouted;
   1705 }
   1706 
   1707 }       // namespace android_audio_legacy
   1708