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