14765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* AudioHardwareALSA.cpp 24765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** 34765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** Copyright 2008-2010 Wind River Systems 44765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. 54765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** 64765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** Licensed under the Apache License, Version 2.0 (the "License"); 74765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** you may not use this file except in compliance with the License. 84765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** You may obtain a copy of the License at 94765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** 104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** http://www.apache.org/licenses/LICENSE-2.0 114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** 124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** Unless required by applicable law or agreed to in writing, software 134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** distributed under the License is distributed on an "AS IS" BASIS, 144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** See the License for the specific language governing permissions and 164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** limitations under the License. 174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */ 184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <errno.h> 204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <stdarg.h> 214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <sys/stat.h> 224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <fcntl.h> 234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <stdlib.h> 244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <unistd.h> 254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <dlfcn.h> 264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <math.h> 274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 289746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#define LOG_TAG "AudioHardwareALSA" 294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev//#define LOG_NDEBUG 0 309746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#define LOG_NDDEBUG 0 314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <utils/Log.h> 324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <utils/String8.h> 334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <sys/prctl.h> 344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <sys/resource.h> 354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <sys/poll.h> 364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <sys/ioctl.h> 374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <cutils/properties.h> 384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <media/AudioRecord.h> 394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <hardware_legacy/power.h> 404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include "AudioHardwareALSA.h" 429746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_USBAUDIO_ENABLED 434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include "AudioUsbALSA.h" 449746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#endif 45bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani#include "AudioUtil.h" 464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevextern "C" 484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // 504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // Function for dlsym() to look up for creating a new AudioHardwareInterface. 514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // 524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev android_audio_legacy::AudioHardwareInterface *createAudioHardware(void) { 534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return android_audio_legacy::AudioHardwareALSA::create(); 544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 555ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani#ifdef QCOM_ACDB_ENABLED 565ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani static int (*acdb_init)(); 575ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani static void (*acdb_deallocate)(); 585ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani#endif 595ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani#ifdef QCOM_CSDCLIENT_ENABLED 60295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani static int (*csd_client_init)(); 61295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani static int (*csd_client_deinit)(); 625ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani static int (*csd_start_playback)(); 635ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani static int (*csd_stop_playback)(); 645ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani#endif 654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} // extern "C" 664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevnamespace android_audio_legacy 684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// ---------------------------------------------------------------------------- 714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 724765c439491ddda3de658e62cc4a64d10e726b34Iliyan MalchevAudioHardwareInterface *AudioHardwareALSA::create() { 734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return new AudioHardwareALSA(); 744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 764765c439491ddda3de658e62cc4a64d10e726b34Iliyan MalchevAudioHardwareALSA::AudioHardwareALSA() : 776ccde10fdc6591e5cd21ed32c2b5817aaeb1a208SathishKumar Mani mALSADevice(0),mVoipStreamCount(0),mVoipBitRate(0) 786ccde10fdc6591e5cd21ed32c2b5817aaeb1a208SathishKumar Mani ,mCallState(0),mAcdbHandle(NULL),mCsdHandle(NULL),mMicMute(0) 794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev FILE *fp; 814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev char soundCardInfo[200]; 824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev hw_module_t *module; 834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev char platform[128], baseband[128]; 844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int err = hw_get_module(ALSA_HARDWARE_MODULE_ID, 854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (hw_module_t const**)&module); 864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int codec_rev = 2; 874113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("hw_get_module(ALSA_HARDWARE_MODULE_ID) returned err %d", err); 884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (err == 0) { 894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev hw_device_t* device; 904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev err = module->methods->open(module, ALSA_HARDWARE_NAME, &device); 914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (err == 0) { 924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice = (alsa_device_t *)device; 934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->init(mALSADevice, mDeviceList); 944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mCSCallActive = 0; 954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mVolteCallActive = 0; 964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mIsFmActive = 0; 974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDevSettingsFlag = 0; 989746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_USBAUDIO_ENABLED 994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mAudioUsbALSA = new AudioUsbALSA(); 1009746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani musbPlaybackState = 0; 1019746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani musbRecordingState = 0; 1029746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#endif 103924f79851aaa4eebe593a456203d1c39d3c53d73ty.lee#ifdef USES_FLUENCE_INCALL 104924f79851aaa4eebe593a456203d1c39d3c53d73ty.lee mDevSettingsFlag |= TTY_OFF | DMIC_FLAG; 105924f79851aaa4eebe593a456203d1c39d3c53d73ty.lee#else 1064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDevSettingsFlag |= TTY_OFF; 107924f79851aaa4eebe593a456203d1c39d3c53d73ty.lee#endif 1084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mBluetoothVGS = false; 1094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mFusion3Platform = false; 1109746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani 1119746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_ACDB_ENABLED 1125ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani mAcdbHandle = ::dlopen("/system/lib/libacdbloader.so", RTLD_NOW); 1135ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani if (mAcdbHandle == NULL) { 1145ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani ALOGE("AudioHardware: DLOPEN not successful for ACDBLOADER"); 1155ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani } else { 1165ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani ALOGD("AudioHardware: DLOPEN successful for ACDBLOADER"); 1175ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani acdb_init = (int (*)())::dlsym(mAcdbHandle,"acdb_loader_init_ACDB"); 1185ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani if (acdb_init == NULL) { 1195ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani ALOGE("dlsym:Error:%s Loading acdb_loader_init_ACDB", dlerror()); 1205ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani }else { 1215ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani acdb_init(); 1225ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani acdb_deallocate = (void (*)())::dlsym(mAcdbHandle,"acdb_loader_deallocate_ACDB"); 1235ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani } 1249746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani } 1259746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#endif 1264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1275ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani#ifdef QCOM_CSDCLIENT_ENABLED 1285ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani mCsdHandle = ::dlopen("/system/lib/libcsd-client.so", RTLD_NOW); 1295ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani if (mCsdHandle == NULL) { 1305ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani ALOGE("AudioHardware: DLOPEN not successful for CSD CLIENT"); 1315ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani } else { 1325ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani ALOGD("AudioHardware: DLOPEN successful for CSD CLIENT"); 133295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani csd_client_init = (int (*)())::dlsym(mCsdHandle,"csd_client_init"); 134295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani csd_client_deinit = (int (*)())::dlsym(mCsdHandle,"csd_client_deinit"); 1355ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani csd_start_playback = (int (*)())::dlsym(mCsdHandle,"csd_client_start_playback"); 1365ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani csd_stop_playback = (int (*)())::dlsym(mCsdHandle,"csd_client_stop_playback"); 137295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani 138295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani if (csd_client_init == NULL) { 139295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani ALOGE("dlsym: Error:%s Loading csd_client_init", dlerror()); 140295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani } else { 141295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani csd_client_init(); 142295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani } 1435ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani } 1445ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani mALSADevice->setCsdHandle(mCsdHandle); 1455ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani#endif 1464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((fp = fopen("/proc/asound/cards","r")) == NULL) { 1474113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("Cannot open /proc/asound/cards file to get sound card info"); 1484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 1494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev while((fgets(soundCardInfo, sizeof(soundCardInfo), fp) != NULL)) { 1504113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("SoundCardInfo %s", soundCardInfo); 1514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (strstr(soundCardInfo, "msm8960-tabla1x-snd-card")) { 1524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev codec_rev = 1; 1534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 1544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else if (strstr(soundCardInfo, "msm-snd-card")) { 1554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev codec_rev = 2; 1564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 1574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else if (strstr(soundCardInfo, "msm8930-sitar-snd-card")) { 1584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev codec_rev = 3; 1594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 1604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 1614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 1624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fclose(fp); 1634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 1644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (codec_rev == 1) { 1664113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("Detected tabla 1.x sound card"); 1674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm"); 1684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else if (codec_rev == 3) { 1694113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("Detected sitar 1.x sound card"); 1704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_Sitar"); 1714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 1724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev property_get("ro.board.platform", platform, ""); 1734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev property_get("ro.baseband", baseband, ""); 1744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband)) { 1754113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("Detected Fusion tabla 2.x"); 1764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mFusion3Platform = true; 1774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_2x_Fusion3"); 1784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 1794113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("Detected tabla 2.x sound card"); 1804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_2x"); 1814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 1824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 1834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (mUcMgr < 0) { 1854113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("Failed to open ucm instance: %d", errno); 1864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 1874113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGI("ucm instance opened: %u", (unsigned)mUcMgr); 1885ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani mUcMgr->acdb_handle = NULL; 1895ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani#ifdef QCOM_ACDB_ENABLED 1905ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani if (mAcdbHandle) { 1915ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani mUcMgr->acdb_handle = static_cast<void*> (mAcdbHandle); 192295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani if (mFusion3Platform) 193295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani mUcMgr->isFusion3Platform = true; 194295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani else 195295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani mUcMgr->isFusion3Platform = false; 1965ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani } 1975ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani#endif 1984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 1994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 2004113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("ALSA Module could not be opened!!!"); 2014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 2034113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("ALSA Module not found!!!"); 2044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 2064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2074765c439491ddda3de658e62cc4a64d10e726b34Iliyan MalchevAudioHardwareALSA::~AudioHardwareALSA() 2084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 2094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (mUcMgr != NULL) { 2109efed76df6b7c75d170e8f900f875f4329587719SathishKumar Mani ALOGV("closing ucm instance: %u", (unsigned)mUcMgr); 2114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_mgr_close(mUcMgr); 2124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (mALSADevice) { 2144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->common.close(&mALSADevice->common); 2154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev for(ALSAHandleList::iterator it = mDeviceList.begin(); 2174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it != mDeviceList.end(); ++it) { 2184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it->useCase[0] = 0; 2194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDeviceList.erase(it); 2204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2219746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_ACDB_ENABLED 2225ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani if (acdb_deallocate == NULL) { 2235ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani ALOGE("dlsym: Error:%s Loading acdb_deallocate_ACDB", dlerror()); 2245ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani } else { 2255ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani acdb_deallocate(); 2265ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani } 2275ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani if (mAcdbHandle) { 2285ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani ::dlclose(mAcdbHandle); 2295ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani mAcdbHandle = NULL; 2305ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani } 2319746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#endif 2329746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_USBAUDIO_ENABLED 2334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev delete mAudioUsbALSA; 2349746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#endif 2355ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani 2365ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani#ifdef QCOM_CSDCLEINT_ENABLED 2375ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani if (mCsdHandle) { 238295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani if (csd_client_deinit == NULL) { 239295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani ALOGE("dlsym: Error:%s Loading csd_client_deinit", dlerror()); 240295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani } else { 241295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani csd_client_deinit(); 242295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani } 243295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani ::dlclose(mCsdHandle); 244295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani mCsdHandle = NULL; 2455ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani } 2465ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani#endif 2474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 2484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatus_t AudioHardwareALSA::initCheck() 2504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 2514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!mALSADevice) 2524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return NO_INIT; 2534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return NO_ERROR; 2554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 2564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatus_t AudioHardwareALSA::setVoiceVolume(float v) 2584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 2598a9785b5e6a199a6c64ac671afc2e8036c7ec13fAjay Dudani ALOGV("setVoiceVolume(%f)\n", v); 2604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (v < 0.0) { 2614113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v); 2624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev v = 0.0; 2634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else if (v > 1.0) { 2644113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v); 2654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev v = 1.0; 2664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int newMode = mode(); 2698a9785b5e6a199a6c64ac671afc2e8036c7ec13fAjay Dudani ALOGV("setVoiceVolume newMode %d",newMode); 2704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int vol = lrint(v * 100.0); 2714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // Voice volume levels from android are mapped to driver volume levels as follows. 2734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // 0 -> 5, 20 -> 4, 40 ->3, 60 -> 2, 80 -> 1, 100 -> 0 2744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // So adjust the volume to get the correct volume index in driver 2754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev vol = 100 - vol; 2764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (mALSADevice) { 2784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(newMode == AudioSystem::MODE_IN_COMMUNICATION) { 2794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->setVoipVolume(vol); 2804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else if (newMode == AudioSystem::MODE_IN_CALL){ 2819746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani if (mCSCallActive == CS_ACTIVE) 2824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->setVoiceVolume(vol); 2839746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani if (mVolteCallActive == IMS_ACTIVE) 2844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->setVoLTEVolume(vol); 2854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return NO_ERROR; 2894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 2904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2919746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_FM_ENABLED 2924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatus_t AudioHardwareALSA::setFmVolume(float value) 2934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 2944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev status_t status = NO_ERROR; 2954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int vol; 2974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (value < 0.0) { 2994113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGW("setFmVolume(%f) under 0.0, assuming 0.0\n", value); 3004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev value = 0.0; 3014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else if (value > 1.0) { 3024113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGW("setFmVolume(%f) over 1.0, assuming 1.0\n", value); 3034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev value = 1.0; 3044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev vol = lrint((value * 0x2000) + 0.5); 3064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3079efed76df6b7c75d170e8f900f875f4329587719SathishKumar Mani ALOGV("setFmVolume(%f)\n", value); 3089efed76df6b7c75d170e8f900f875f4329587719SathishKumar Mani ALOGV("Setting FM volume to %d (available range is 0 to 0x2000)\n", vol); 3094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->setFmVolume(vol); 3114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return status; 3134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 3144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 3154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatus_t AudioHardwareALSA::setMasterVolume(float volume) 3174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 3184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return NO_ERROR; 3194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 3204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatus_t AudioHardwareALSA::setMode(int mode) 3224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 3234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev status_t status = NO_ERROR; 3244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (mode != mMode) { 3264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev status = AudioHardwareBase::setMode(mode); 3274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (mode == AudioSystem::MODE_IN_CALL) { 3309746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani mCallState = CS_ACTIVE; 3314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev }else if (mode == AudioSystem::MODE_NORMAL) { 3324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mCallState = 0; 3334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return status; 3364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 3374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatus_t AudioHardwareALSA::setParameters(const String8& keyValuePairs) 3394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 3404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev AudioParameter param = AudioParameter(keyValuePairs); 3414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev String8 key; 3424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev String8 value; 3434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev status_t status = NO_ERROR; 3444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int device; 3454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int btRate; 3464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int state; 3479efed76df6b7c75d170e8f900f875f4329587719SathishKumar Mani ALOGV("setParameters() %s", keyValuePairs.string()); 3484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev key = String8(TTY_MODE_KEY); 3504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.get(key, value) == NO_ERROR) { 3514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDevSettingsFlag &= TTY_CLEAR; 352a97e6f657522513449514a677f19a0ff28df0059ty.lee if (value == "tty_full") { 3534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDevSettingsFlag |= TTY_FULL; 354a97e6f657522513449514a677f19a0ff28df0059ty.lee } else if (value == "tty_hco") { 3554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDevSettingsFlag |= TTY_HCO; 356a97e6f657522513449514a677f19a0ff28df0059ty.lee } else if (value == "tty_vco") { 3574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDevSettingsFlag |= TTY_VCO; 3584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 3594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDevSettingsFlag |= TTY_OFF; 3604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3614113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGI("Changed TTY Mode=%s", value.string()); 3624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->setFlags(mDevSettingsFlag); 3634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(mMode != AudioSystem::MODE_IN_CALL){ 3644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return NO_ERROR; 3654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev doRouting(0); 3674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev key = String8(FLUENCE_KEY); 3704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.get(key, value) == NO_ERROR) { 3714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (value == "quadmic") { 3724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDevSettingsFlag |= QMIC_FLAG; 3734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDevSettingsFlag &= (~DMIC_FLAG); 3744113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("Fluence quadMic feature Enabled"); 3754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else if (value == "dualmic") { 3764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDevSettingsFlag |= DMIC_FLAG; 3774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDevSettingsFlag &= (~QMIC_FLAG); 3784113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("Fluence dualmic feature Enabled"); 3794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else if (value == "none") { 3804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDevSettingsFlag &= (~DMIC_FLAG); 3814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDevSettingsFlag &= (~QMIC_FLAG); 3824113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("Fluence feature Disabled"); 3834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->setFlags(mDevSettingsFlag); 3854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev doRouting(0); 3864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3889746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_CSDCLIENT_ENABLED 3894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (mFusion3Platform) { 3904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev key = String8(INCALLMUSIC_KEY); 3914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.get(key, value) == NO_ERROR) { 3924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (value == "true") { 3934113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("Enabling Incall Music setting in the setparameter\n"); 3945ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani if (csd_start_playback == NULL) { 3955ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani ALOGE("dlsym: Error:%s Loading csd_client_start_playback", dlerror()); 3965ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani } else { 3975ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani csd_start_playback(); 3985ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani } 3994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 4004113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("Disabling Incall Music setting in the setparameter\n"); 4015ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani if (csd_stop_playback == NULL) { 4025ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani ALOGE("dlsym: Error:%s Loading csd_client_stop_playback", dlerror()); 4035ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani } else { 4045ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani csd_stop_playback(); 4055ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani } 4064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4099746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#endif 4104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev key = String8(ANC_KEY); 4124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.get(key, value) == NO_ERROR) { 4134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (value == "true") { 4144113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("Enabling ANC setting in the setparameter\n"); 4154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDevSettingsFlag |= ANC_FLAG; 4164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 4174113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("Disabling ANC setting in the setparameter\n"); 4184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDevSettingsFlag &= (~ANC_FLAG); 4194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->setFlags(mDevSettingsFlag); 4214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev doRouting(0); 4224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev key = String8(AudioParameter::keyRouting); 4254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.getInt(key, device) == NO_ERROR) { 4264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // Ignore routing if device is 0. 4274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(device) { 4284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev doRouting(device); 4294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param.remove(key); 4314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev key = String8(BT_SAMPLERATE_KEY); 4344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.getInt(key, btRate) == NO_ERROR) { 4354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->setBtscoRate(btRate); 4364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param.remove(key); 4374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev key = String8(BTHEADSET_VGS); 4404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.get(key, value) == NO_ERROR) { 4414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (value == "on") { 4424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mBluetoothVGS = true; 4434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 4444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mBluetoothVGS = false; 4454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev key = String8(WIDEVOICE_KEY); 4494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.get(key, value) == NO_ERROR) { 4504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bool flag = false; 4514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (value == "true") { 4524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev flag = true; 4534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(mALSADevice) { 4554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->enableWideVoice(flag); 4564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param.remove(key); 4584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev key = String8(VOIPRATE_KEY); 4614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.get(key, value) == NO_ERROR) { 4624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mVoipBitRate = atoi(value); 4634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param.remove(key); 4644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev key = String8(FENS_KEY); 4674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.get(key, value) == NO_ERROR) { 4684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bool flag = false; 4694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (value == "true") { 4704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev flag = true; 4714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(mALSADevice) { 4734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->enableFENS(flag); 4744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param.remove(key); 4764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4789746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_FM_ENABLED 4794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev key = String8(AudioParameter::keyHandleFm); 4804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.getInt(key, device) == NO_ERROR) { 4814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // Ignore if device is 0 4824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(device) { 4834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev handleFm(device); 4844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param.remove(key); 4864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 4884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev key = String8(ST_KEY); 4904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.get(key, value) == NO_ERROR) { 4914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bool flag = false; 4924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (value == "true") { 4934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev flag = true; 4944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(mALSADevice) { 4964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->enableSlowTalk(flag); 4974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param.remove(key); 4994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev key = String8(MODE_CALL_KEY); 5014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.getInt(key,state) == NO_ERROR) { 5024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (mCallState != state) { 5034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mCallState = state; 5044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev doRouting(0); 5054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mCallState = state; 5074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.size()) { 5094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev status = BAD_VALUE; 5104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return status; 5124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 5134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5144765c439491ddda3de658e62cc4a64d10e726b34Iliyan MalchevString8 AudioHardwareALSA::getParameters(const String8& keys) 5154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 5164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev AudioParameter param = AudioParameter(keys); 5174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev String8 value; 5184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev String8 key = String8(DUALMIC_KEY); 5204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.get(key, value) == NO_ERROR) { 5214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev value = String8("false"); 5224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param.add(key, value); 5234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev key = String8(FLUENCE_KEY); 5264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.get(key, value) == NO_ERROR) { 5274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if ((mDevSettingsFlag & QMIC_FLAG) && 5284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (mDevSettingsFlag & ~DMIC_FLAG)) 5294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev value = String8("quadmic"); 5304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else if ((mDevSettingsFlag & DMIC_FLAG) && 5314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (mDevSettingsFlag & ~QMIC_FLAG)) 5324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev value = String8("dualmic"); 5334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else if ((mDevSettingsFlag & ~DMIC_FLAG) && 5344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (mDevSettingsFlag & ~QMIC_FLAG)) 5354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev value = String8("none"); 5364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param.add(key, value); 5374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5399746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_FM_ENABLED 5404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev key = String8("Fm-radio"); 5414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if ( param.get(key,value) == NO_ERROR ) { 5424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if ( mIsFmActive ) { 5434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param.addInt(String8("isFMON"), true ); 5444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 5474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev key = String8(BTHEADSET_VGS); 5494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.get(key, value) == NO_ERROR) { 5504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(mBluetoothVGS) 5514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param.addInt(String8("isVGS"), true); 5524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5544113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("AudioHardwareALSA::getParameters() %s", param.toString().string()); 5554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return param.toString(); 5564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 5574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5589746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_USBAUDIO_ENABLED 5594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid AudioHardwareALSA::closeUSBPlayback() 5604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 5614113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("closeUSBPlayback, musbPlaybackState: %d", musbPlaybackState); 5624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbPlaybackState = 0; 5634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mAudioUsbALSA->exitPlaybackThread(SIGNAL_EVENT_KILLTHREAD); 5644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 5654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid AudioHardwareALSA::closeUSBRecording() 5674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 5684113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("closeUSBRecording"); 5694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbRecordingState = 0; 5704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mAudioUsbALSA->exitRecordingThread(SIGNAL_EVENT_KILLTHREAD); 5714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 5724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid AudioHardwareALSA::closeUsbPlaybackIfNothingActive(){ 5744113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("closeUsbPlaybackIfNothingActive, musbPlaybackState: %d", musbPlaybackState); 5754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(!musbPlaybackState && mAudioUsbALSA != NULL) { 5764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mAudioUsbALSA->exitPlaybackThread(SIGNAL_EVENT_TIMEOUT); 5774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 5794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid AudioHardwareALSA::closeUsbRecordingIfNothingActive(){ 5814113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("closeUsbRecordingIfNothingActive, musbRecordingState: %d", musbRecordingState); 5824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(!musbRecordingState && mAudioUsbALSA != NULL) { 5834113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("Closing USB Recording Session as no stream is active"); 5844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mAudioUsbALSA->setkillUsbRecordingThread(true); 5854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 5874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid AudioHardwareALSA::startUsbPlaybackIfNotStarted(){ 5894113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("Starting the USB playback %d kill %d", musbPlaybackState, 5904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mAudioUsbALSA->getkillUsbPlaybackThread()); 5914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((!musbPlaybackState) || (mAudioUsbALSA->getkillUsbPlaybackThread() == true)) { 5924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mAudioUsbALSA->startPlayback(); 5934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 5954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid AudioHardwareALSA::startUsbRecordingIfNotStarted(){ 5974113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("Starting the recording musbRecordingState: %d killUsbRecordingThread %d", 5984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbRecordingState, mAudioUsbALSA->getkillUsbRecordingThread()); 5994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((!musbRecordingState) || (mAudioUsbALSA->getkillUsbRecordingThread() == true)) { 6004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mAudioUsbALSA->startRecording(); 6014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 6024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 6039746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#endif 6044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid AudioHardwareALSA::doRouting(int device) 6064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 6074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev Mutex::Autolock autoLock(mLock); 6084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int newMode = mode(); 6094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bool isRouted = false; 6104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6119746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani if ((device == AudioSystem::DEVICE_IN_VOICE_CALL) 6129746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_FM_ENABLED 6139746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani || (device == AudioSystem::DEVICE_IN_FM_RX) 6149746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani || (device == AudioSystem::DEVICE_OUT_DIRECTOUTPUT) 6159746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani || (device == AudioSystem::DEVICE_IN_FM_RX_A2DP) 6164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 6179746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani || (device == AudioSystem::DEVICE_IN_COMMUNICATION) 6189746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani ) { 6194113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("Ignoring routing for FM/INCALL/VOIP recording"); 6204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return; 6214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 6224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (device == 0) 6234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev device = mCurDevice; 6244113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("doRouting: device %d newMode %d mCSCallActive %d mVolteCallActive %d" 6254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "mIsFmActive %d", device, newMode, mCSCallActive, mVolteCallActive, 6264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mIsFmActive); 6274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev isRouted = routeVoLTECall(device, newMode); 6294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev isRouted |= routeVoiceCall(device, newMode); 6304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(!isRouted) { 6329746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_USBAUDIO_ENABLED 6334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(!(device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET) && 6344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev !(device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET) && 6354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev !(device & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) && 6364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (musbPlaybackState)){ 6374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev //USB unplugged 6384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev device &= ~ AudioSystem::DEVICE_OUT_PROXY; 6394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev device &= ~ AudioSystem::DEVICE_IN_PROXY; 6404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ALSAHandleList::iterator it = mDeviceList.end(); 6414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it--; 6424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->route(&(*it), (uint32_t)device, newMode); 6430a019914794cc27f5dacddf4e5dbc019dbe21788SathishKumar Mani ALOGD("USB UNPLUGGED, setting musbPlaybackState to 0"); 6444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbPlaybackState = 0; 6454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbRecordingState = 0; 6464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev closeUSBRecording(); 6474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev closeUSBPlayback(); 6484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 6494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 6500a019914794cc27f5dacddf4e5dbc019dbe21788SathishKumar Mani ALOGD("Routing everything to prox now"); 6514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ALSAHandleList::iterator it = mDeviceList.end(); 6524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it--; 6534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->route(&(*it), AudioSystem::DEVICE_OUT_PROXY, 6544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev newMode); 6554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev for(it = mDeviceList.begin(); it != mDeviceList.end(); ++it) { 6564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) || 6574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_LPA))) { 6588a9785b5e6a199a6c64ac671afc2e8036c7ec13fAjay Dudani ALOGV("doRouting: LPA device switch to proxy"); 6594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev startUsbPlaybackIfNotStarted(); 6604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbPlaybackState |= USBPLAYBACKBIT_LPA; 6614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 6624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else if((!strcmp(it->useCase, SND_USE_CASE_VERB_VOICECALL)) || 6634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_VOICE))) { 6648a9785b5e6a199a6c64ac671afc2e8036c7ec13fAjay Dudani ALOGV("doRouting: VOICE device switch to proxy"); 6654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev startUsbRecordingIfNotStarted(); 6664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev startUsbPlaybackIfNotStarted(); 6674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbPlaybackState |= USBPLAYBACKBIT_VOICECALL; 6684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbRecordingState |= USBPLAYBACKBIT_VOICECALL; 6694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 6704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev }else if((!strcmp(it->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) || 6714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_FM))) { 6728a9785b5e6a199a6c64ac671afc2e8036c7ec13fAjay Dudani ALOGV("doRouting: FM device switch to proxy"); 6734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev startUsbPlaybackIfNotStarted(); 6744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbPlaybackState |= USBPLAYBACKBIT_FM; 6754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 6764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 6774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 678e42406e02e32dbb398a2fa0c452e52526b763c8dSathishKumar Mani } else 6794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 680e42406e02e32dbb398a2fa0c452e52526b763c8dSathishKumar Mani { 6814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ALSAHandleList::iterator it = mDeviceList.end(); 6824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it--; 6834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->route(&(*it), (uint32_t)device, newMode); 6844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 6854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 6864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mCurDevice = device; 6874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 6884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevuint32_t AudioHardwareALSA::getVoipMode(int format) 6904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 6914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev switch(format) { 6924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case AudioSystem::PCM_16_BIT: 6934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return MODE_PCM; 6944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 6954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case AudioSystem::AMR_NB: 6964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return MODE_AMR; 6974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 6984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case AudioSystem::AMR_WB: 6994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return MODE_AMR_WB; 7004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 7014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7029746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_QCHAT_ENABLED 7034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case AudioSystem::EVRC: 7044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return MODE_IS127; 7054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 7064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case AudioSystem::EVRCB: 7084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return MODE_4GV_NB; 7094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 7104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case AudioSystem::EVRCWB: 7114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return MODE_4GV_WB; 7124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 7139746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#endif 7144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev default: 7164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return MODE_PCM; 7174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 7184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 7194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7204765c439491ddda3de658e62cc4a64d10e726b34Iliyan MalchevAudioStreamOut * 7214765c439491ddda3de658e62cc4a64d10e726b34Iliyan MalchevAudioHardwareALSA::openOutputStream(uint32_t devices, 7224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int *format, 7234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t *channels, 7244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t *sampleRate, 7254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev status_t *status) 7264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 7274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev Mutex::Autolock autoLock(mLock); 7288a9785b5e6a199a6c64ac671afc2e8036c7ec13fAjay Dudani ALOGV("openOutputStream: devices 0x%x channels %d sampleRate %d", 7294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev devices, *channels, *sampleRate); 7304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7318861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani audio_output_flags_t flag = static_cast<audio_output_flags_t> (*status); 7328861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani 7334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev status_t err = BAD_VALUE; 7348861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani *status = NO_ERROR; 7354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev AudioStreamOutALSA *out = 0; 7364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ALSAHandleList::iterator it; 7374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (devices & (devices - 1)) { 7394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (status) *status = err; 7404113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("openOutputStream called with bad devices"); 7414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return out; 7424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 7438861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani 7448861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani 7454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev# if 0 7464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((devices == AudioSystem::DEVICE_OUT_DIRECTOUTPUT) && 7474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ((*sampleRate == VOIP_SAMPLING_RATE_8K) || (*sampleRate == VOIP_SAMPLING_RATE_16K))) { 7484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bool voipstream_active = false; 7494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev for(it = mDeviceList.begin(); 7504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it != mDeviceList.end(); ++it) { 7514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) || 7524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) { 7534113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("openOutput: it->rxHandle %d it->handle %d",it->rxHandle,it->handle); 7544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev voipstream_active = true; 7554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 7564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 7574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 7584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(voipstream_active == false) { 7594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mVoipStreamCount = 0; 7604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle_t alsa_handle; 7614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev unsigned long bufferSize; 7624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(*sampleRate == VOIP_SAMPLING_RATE_8K) { 7634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bufferSize = VOIP_BUFFER_SIZE_8K; 7644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 7654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else if(*sampleRate == VOIP_SAMPLING_RATE_16K) { 7664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bufferSize = VOIP_BUFFER_SIZE_16K; 7674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 7684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else { 7694113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("unsupported samplerate %d for voip",*sampleRate); 7704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (status) *status = err; 7714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return out; 7724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 7734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.module = mALSADevice; 7744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.bufferSize = bufferSize; 7754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.devices = devices; 7764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.handle = 0; 7774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(*format == AudioSystem::PCM_16_BIT) 7784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 7794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else 7804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.format = *format; 7814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.channels = VOIP_DEFAULT_CHANNEL_MODE; 78261f449827974e117406693ef2cc6bdfdaf1fc00bEric Laurent alsa_handle.channelMask = AUDIO_CHANNEL_IN_MONO; 7834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.sampleRate = *sampleRate; 7844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.latency = VOIP_PLAYBACK_LATENCY; 7854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.rxHandle = 0; 7864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.ucMgr = mUcMgr; 7874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->setVoipConfig(getVoipMode(*format), mVoipBitRate); 7884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev char *use_case; 7894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 7904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 7914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_IP_VOICECALL, sizeof(alsa_handle.useCase)); 7924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 7934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_VOIP, sizeof(alsa_handle.useCase)); 7944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 7954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev free(use_case); 7964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDeviceList.push_back(alsa_handle); 7974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it = mDeviceList.end(); 7984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it--; 7994113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("openoutput: mALSADevice->route useCase %s mCurDevice %d mVoipStreamCount %d mode %d", it->useCase,mCurDevice,mVoipStreamCount, mode()); 8004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((mCurDevice & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 8014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (mCurDevice & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)|| 8024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (mCurDevice & AudioSystem::DEVICE_OUT_PROXY)){ 8034113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("Routing to proxy for normal voip call in openOutputStream"); 8044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mCurDevice |= AudioSystem::DEVICE_OUT_PROXY; 8054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.devices = AudioSystem::DEVICE_OUT_PROXY; 8064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->route(&(*it), mCurDevice, AudioSystem::MODE_IN_COMMUNICATION); 8074113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("enabling VOIP in openoutputstream, musbPlaybackState: %d", musbPlaybackState); 8084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev startUsbPlaybackIfNotStarted(); 8094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL; 8104113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("Starting recording in openoutputstream, musbRecordingState: %d", musbRecordingState); 8114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev startUsbRecordingIfNotStarted(); 8124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbRecordingState |= USBRECBIT_VOIPCALL; 8134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else{ 8144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->route(&(*it), mCurDevice, AudioSystem::MODE_IN_COMMUNICATION); 8154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 8164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) { 8174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_IP_VOICECALL); 8184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 8194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_VOIP); 8204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 8214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev err = mALSADevice->startVoipCall(&(*it)); 8224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (err) { 8234113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("Device open failed"); 8244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return NULL; 8254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 8264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 8274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out = new AudioStreamOutALSA(this, &(*it)); 8284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev err = out->set(format, channels, sampleRate, devices); 8294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(err == NO_ERROR) { 8304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mVoipStreamCount++; //increment VoipstreamCount only if success 8314113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("openoutput mVoipStreamCount %d",mVoipStreamCount); 8324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 8334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (status) *status = err; 8344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return out; 8354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else 8364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 837bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani if ((flag & AUDIO_OUTPUT_FLAG_DIRECT) && 838bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani (devices == AudioSystem::DEVICE_OUT_AUX_DIGITAL)) { 839bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani ALOGD("Multi channel PCM"); 840bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani alsa_handle_t alsa_handle; 841bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani EDID_AUDIO_INFO info = { 0 }; 842bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani 843bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani alsa_handle.module = mALSADevice; 844bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani alsa_handle.devices = devices; 845bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani alsa_handle.handle = 0; 846bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 847bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani 848bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani if (!AudioUtil::getHDMIAudioSinkCaps(&info)) { 849bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani ALOGE("openOutputStream: Failed to get HDMI sink capabilities"); 850bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani return NULL; 851bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani } 852bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani if (0 == *channels) { 853bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani alsa_handle.channels = info.AudioBlocksArray[info.nAudioBlocks-1].nChannels; 854bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani if (alsa_handle.channels > 6) { 855bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani alsa_handle.channels = 6; 856bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani } 857bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani *channels = audio_channel_out_mask_from_count(alsa_handle.channels); 858bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani } else { 859bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani alsa_handle.channels = AudioSystem::popCount(*channels); 860bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani } 86161f449827974e117406693ef2cc6bdfdaf1fc00bEric Laurent alsa_handle.channelMask = *channels; 86261f449827974e117406693ef2cc6bdfdaf1fc00bEric Laurent 863bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani if (6 == alsa_handle.channels) { 864bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani alsa_handle.bufferSize = DEFAULT_MULTI_CHANNEL_BUF_SIZE; 865bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani } else { 866bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani alsa_handle.bufferSize = DEFAULT_BUFFER_SIZE; 867bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani } 868bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani if (0 == *sampleRate) { 869bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani alsa_handle.sampleRate = info.AudioBlocksArray[info.nAudioBlocks-1].nSamplingFreq; 870bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani *sampleRate = alsa_handle.sampleRate; 871bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani } else { 872bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani alsa_handle.sampleRate = *sampleRate; 873bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani } 874bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani alsa_handle.latency = PLAYBACK_LATENCY; 875bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani alsa_handle.rxHandle = 0; 876bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani alsa_handle.ucMgr = mUcMgr; 877bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani ALOGD("alsa_handle.channels %d alsa_handle.sampleRate %d",alsa_handle.channels,alsa_handle.sampleRate); 878bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani 879bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani char *use_case; 880bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 881bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 882bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI2 , sizeof(alsa_handle.useCase)); 883bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani } else { 884bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_MUSIC2, sizeof(alsa_handle.useCase)); 885bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani } 886bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani free(use_case); 887bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani mDeviceList.push_back(alsa_handle); 888bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani ALSAHandleList::iterator it = mDeviceList.end(); 889bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani it--; 890bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani ALOGD("it->useCase %s", it->useCase); 891bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani mALSADevice->route(&(*it), devices, mode()); 892bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI2)) { 893bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI2 ); 894bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani } else { 895bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_MUSIC2); 896bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani } 897bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani ALOGD("channels: %d", AudioSystem::popCount(*channels)); 898bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani err = mALSADevice->open(&(*it)); 899bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani 900bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani if (err) { 901bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani ALOGE("Device open failed err:%d",err); 902bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani } else { 903bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani out = new AudioStreamOutALSA(this, &(*it)); 904bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani err = out->set(format, channels, sampleRate, devices); 905bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani } 906bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani if (status) *status = err; 907bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani return out; 908bf1c87481d62736cab8832e9085c121fbafdbb6bSathishKumar Mani } else { 9094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 9104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle_t alsa_handle; 9114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev unsigned long bufferSize = DEFAULT_BUFFER_SIZE; 9124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 9134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1) 9144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bufferSize &= ~b; 9154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 9164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.module = mALSADevice; 9174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.bufferSize = bufferSize; 9184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.devices = devices; 9194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.handle = 0; 9204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 9214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.channels = DEFAULT_CHANNEL_MODE; 92261f449827974e117406693ef2cc6bdfdaf1fc00bEric Laurent alsa_handle.channelMask = AUDIO_CHANNEL_OUT_STEREO; 9234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.sampleRate = DEFAULT_SAMPLING_RATE; 9244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.latency = PLAYBACK_LATENCY; 9254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.rxHandle = 0; 9264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.ucMgr = mUcMgr; 9278861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani alsa_handle.isDeepbufferOutput = false; 9284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 9294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev char *use_case; 9304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 9318861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani 9328861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani if (flag & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) { 9339efed76df6b7c75d170e8f900f875f4329587719SathishKumar Mani ALOGD("openOutputStream: DeepBuffer Output"); 9348861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani alsa_handle.isDeepbufferOutput = true; 9358861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 9368861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI, sizeof(alsa_handle.useCase)); 9378861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani } else { 9388861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_MUSIC, sizeof(alsa_handle.useCase)); 9398861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani } 9404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 9419efed76df6b7c75d170e8f900f875f4329587719SathishKumar Mani ALOGD("openOutputStream: Lowlatency Output"); 9428861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani alsa_handle.bufferSize = PLAYBACK_LOW_LATENCY_BUFFER_SIZE; 94377780382b45794eb5bc0e8589d9b7c96bb406772SathishKumar Mani alsa_handle.latency = PLAYBACK_LOW_LATENCY_MEASURED; 9448861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 9458861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase)); 9468861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani } else { 9478861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase)); 9488861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani } 9494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 9504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev free(use_case); 9514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDeviceList.push_back(alsa_handle); 9524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ALSAHandleList::iterator it = mDeviceList.end(); 9534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it--; 9548a9785b5e6a199a6c64ac671afc2e8036c7ec13fAjay Dudani ALOGV("useCase %s", it->useCase); 9559746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_USBAUDIO_ENABLED 9564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 9574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 9580a019914794cc27f5dacddf4e5dbc019dbe21788SathishKumar Mani ALOGD("Routing to proxy for normal playback in openOutputStream"); 9594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev devices |= AudioSystem::DEVICE_OUT_PROXY; 9604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 9614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 9624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->route(&(*it), devices, mode()); 9638861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani if (flag & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) { 9648861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI)) { 9658861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI); 9668861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani } else { 9678861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_MUSIC); 9688861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani } 9694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 9708861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) { 9718861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC); 9728861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani } else { 9738861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC); 9748861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani } 9754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 9764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev err = mALSADevice->open(&(*it)); 9774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (err) { 9784113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("Device open failed"); 9794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 9804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out = new AudioStreamOutALSA(this, &(*it)); 9814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev err = out->set(format, channels, sampleRate, devices); 9824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 9834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 9844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (status) *status = err; 9854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return out; 9864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 9874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 9884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 9894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid 9904765c439491ddda3de658e62cc4a64d10e726b34Iliyan MalchevAudioHardwareALSA::closeOutputStream(AudioStreamOut* out) 9914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 9924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev delete out; 9934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 9944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 9959746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_TUNNEL_LPA_ENABLED 9964765c439491ddda3de658e62cc4a64d10e726b34Iliyan MalchevAudioStreamOut * 9974765c439491ddda3de658e62cc4a64d10e726b34Iliyan MalchevAudioHardwareALSA::openOutputSession(uint32_t devices, 9984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int *format, 9994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev status_t *status, 10004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int sessionId, 10014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t samplingRate, 10024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t channels) 10034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 10044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev Mutex::Autolock autoLock(mLock); 10054113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("openOutputSession = %d" ,sessionId); 10064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev AudioStreamOutALSA *out = 0; 10074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev status_t err = BAD_VALUE; 10084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 10094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle_t alsa_handle; 10104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev unsigned long bufferSize = DEFAULT_BUFFER_SIZE; 10114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 10124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1) 10134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bufferSize &= ~b; 10144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 10154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.module = mALSADevice; 10164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.bufferSize = bufferSize; 10174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.devices = devices; 10184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.handle = 0; 10194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 10204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.channels = DEFAULT_CHANNEL_MODE; 102161f449827974e117406693ef2cc6bdfdaf1fc00bEric Laurent alsa_handle.channelMask = AUDIO_CHANNEL_OUT_STEREO; 10224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.sampleRate = DEFAULT_SAMPLING_RATE; 10234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.latency = VOICE_LATENCY; 10244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.rxHandle = 0; 10254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.ucMgr = mUcMgr; 10264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 10274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev char *use_case; 10284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(sessionId == TUNNEL_SESSION_ID) { 10294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 10304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 10314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_TUNNEL, sizeof(alsa_handle.useCase)); 10324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 10334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_TUNNEL, sizeof(alsa_handle.useCase)); 10344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 10354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 10364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 10374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 10384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER, sizeof(alsa_handle.useCase)); 10394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 10404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_LPA, sizeof(alsa_handle.useCase)); 10414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 10424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 10434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev free(use_case); 10444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDeviceList.push_back(alsa_handle); 10454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ALSAHandleList::iterator it = mDeviceList.end(); 10464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it--; 10474113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("useCase %s", it->useCase); 10489746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_USBAUDIO_ENABLED 10494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 10504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 10510a019914794cc27f5dacddf4e5dbc019dbe21788SathishKumar Mani ALOGD("Routing to proxy for LPA in openOutputSession"); 10524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev devices |= AudioSystem::DEVICE_OUT_PROXY; 10534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->route(&(*it), devices, mode()); 10544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev devices = AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; 10554113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("Starting USBPlayback for LPA"); 10564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev startUsbPlaybackIfNotStarted(); 10574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbPlaybackState |= USBPLAYBACKBIT_LPA; 10584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else 10594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 10604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev { 10614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->route(&(*it), devices, mode()); 10624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 10634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(sessionId == TUNNEL_SESSION_ID) { 10644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) { 10654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_TUNNEL); 10664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 10674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_TUNNEL); 10684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 10694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 10704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else { 10714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) { 10724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_LOW_POWER); 10734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 10744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_LPA); 10754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 10764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 10774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev err = mALSADevice->open(&(*it)); 10784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out = new AudioStreamOutALSA(this, &(*it)); 10794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 10804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (status) *status = err; 10814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return out; 10824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 10834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 10844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid 10854765c439491ddda3de658e62cc4a64d10e726b34Iliyan MalchevAudioHardwareALSA::closeOutputSession(AudioStreamOut* out) 10864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 10874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev delete out; 10884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 10899746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#endif 10904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 10914765c439491ddda3de658e62cc4a64d10e726b34Iliyan MalchevAudioStreamIn * 10924765c439491ddda3de658e62cc4a64d10e726b34Iliyan MalchevAudioHardwareALSA::openInputStream(uint32_t devices, 10934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int *format, 10944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t *channels, 10954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t *sampleRate, 10964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev status_t *status, 10974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev AudioSystem::audio_in_acoustics acoustics) 10984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 10994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev Mutex::Autolock autoLock(mLock); 11004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev char *use_case; 11014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int newMode = mode(); 11024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t route_devices; 11034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 11044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev status_t err = BAD_VALUE; 11054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev AudioStreamInALSA *in = 0; 11064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ALSAHandleList::iterator it; 11074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 11084113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("openInputStream: devices 0x%x channels %d sampleRate %d", devices, *channels, *sampleRate); 11094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (devices & (devices - 1)) { 11104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (status) *status = err; 11114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return in; 11124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 11134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 11144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((devices == AudioSystem::DEVICE_IN_COMMUNICATION) && 11154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ((*sampleRate == VOIP_SAMPLING_RATE_8K) || (*sampleRate == VOIP_SAMPLING_RATE_16K))) { 11164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bool voipstream_active = false; 11174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev for(it = mDeviceList.begin(); 11184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it != mDeviceList.end(); ++it) { 11194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) || 11204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) { 11219746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani ALOGD("openInput: it->rxHandle %p it->handle %p",it->rxHandle,it->handle); 11224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev voipstream_active = true; 11234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 11244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 11254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 11264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(voipstream_active == false) { 11274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mVoipStreamCount = 0; 11284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle_t alsa_handle; 11294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev unsigned long bufferSize; 11304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(*sampleRate == VOIP_SAMPLING_RATE_8K) { 11314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bufferSize = VOIP_BUFFER_SIZE_8K; 11324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 11334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else if(*sampleRate == VOIP_SAMPLING_RATE_16K) { 11344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bufferSize = VOIP_BUFFER_SIZE_16K; 11354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 11364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else { 11374113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("unsupported samplerate %d for voip",*sampleRate); 11384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (status) *status = err; 11394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return in; 11404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 11414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.module = mALSADevice; 11424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.bufferSize = bufferSize; 11434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.devices = devices; 11444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.handle = 0; 11454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(*format == AudioSystem::PCM_16_BIT) 11464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 11474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else 11484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.format = *format; 11494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.channels = VOIP_DEFAULT_CHANNEL_MODE; 115061f449827974e117406693ef2cc6bdfdaf1fc00bEric Laurent alsa_handle.channelMask = AUDIO_CHANNEL_IN_MONO; 11514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.sampleRate = *sampleRate; 11524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.latency = VOIP_RECORD_LATENCY; 11534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.rxHandle = 0; 11544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.ucMgr = mUcMgr; 11554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->setVoipConfig(getVoipMode(*format), mVoipBitRate); 11564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 11574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if ((use_case != NULL) && (strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 11584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_VOIP, sizeof(alsa_handle.useCase)); 11594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 11604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_IP_VOICECALL, sizeof(alsa_handle.useCase)); 11614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 11624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev free(use_case); 11634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDeviceList.push_back(alsa_handle); 11644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it = mDeviceList.end(); 11654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it--; 11660a019914794cc27f5dacddf4e5dbc019dbe21788SathishKumar Mani ALOGD("mCurrDevice: %d", mCurDevice); 11679746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_USBAUDIO_ENABLED 11684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((mCurDevice == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 11694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (mCurDevice == AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 11700a019914794cc27f5dacddf4e5dbc019dbe21788SathishKumar Mani ALOGD("Routing everything from proxy for voipcall"); 11714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->route(&(*it), AudioSystem::DEVICE_IN_PROXY, AudioSystem::MODE_IN_COMMUNICATION); 11724113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("enabling VOIP in openInputstream, musbPlaybackState: %d", musbPlaybackState); 11734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev startUsbPlaybackIfNotStarted(); 11744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL; 11754113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("Starting recording in openoutputstream, musbRecordingState: %d", musbRecordingState); 11764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev startUsbRecordingIfNotStarted(); 11774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbRecordingState |= USBRECBIT_VOIPCALL; 1178e42406e02e32dbb398a2fa0c452e52526b763c8dSathishKumar Mani } else 11794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 11804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev { 11814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->route(&(*it),mCurDevice, AudioSystem::MODE_IN_COMMUNICATION); 11824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 11834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) { 11844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_IP_VOICECALL); 11854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 11864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_VOIP); 11874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 11884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(sampleRate) { 11894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it->sampleRate = *sampleRate; 11904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 11914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(channels) 11924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it->channels = AudioSystem::popCount(*channels); 11934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev err = mALSADevice->startVoipCall(&(*it)); 11944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (err) { 11954113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("Error opening pcm input device"); 11964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return NULL; 11974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 11984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 11994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev in = new AudioStreamInALSA(this, &(*it), acoustics); 12004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev err = in->set(format, channels, sampleRate, devices); 12014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(err == NO_ERROR) { 12024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mVoipStreamCount++; //increment VoipstreamCount only if success 12034113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("OpenInput mVoipStreamCount %d",mVoipStreamCount); 12044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 12050a019914794cc27f5dacddf4e5dbc019dbe21788SathishKumar Mani ALOGD("openInput: After Get alsahandle"); 12064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (status) *status = err; 12074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return in; 1208ed3c0fdecb72890240d52a8ba3b5ecd05331736aSathishKumar Mani } else { 12094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle_t alsa_handle; 121077780382b45794eb5bc0e8589d9b7c96bb406772SathishKumar Mani unsigned long bufferSize = MIN_CAPTURE_BUFFER_SIZE_PER_CH; 12114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 12124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.module = mALSADevice; 12134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.bufferSize = bufferSize; 12144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.devices = devices; 12154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.handle = 0; 12164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 12174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.channels = VOICE_CHANNEL_MODE; 121861f449827974e117406693ef2cc6bdfdaf1fc00bEric Laurent alsa_handle.channelMask = AUDIO_CHANNEL_IN_MONO; 12194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.sampleRate = android::AudioRecord::DEFAULT_SAMPLE_RATE; 12204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.latency = RECORD_LATENCY; 12214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.rxHandle = 0; 12224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.ucMgr = mUcMgr; 12234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 12244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if ((use_case != NULL) && (strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 12254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if ((devices == AudioSystem::DEVICE_IN_VOICE_CALL) && 12264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (newMode == AudioSystem::MODE_IN_CALL)) { 12274113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("openInputStream: into incall recording, channels %d", *channels); 12284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mIncallMode = *channels; 12294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if ((*channels & AudioSystem::CHANNEL_IN_VOICE_UPLINK) && 12304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) { 12314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (mFusion3Platform) { 12324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->setVocRecMode(INCALL_REC_STEREO); 12334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE, 12344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev sizeof(alsa_handle.useCase)); 12354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 12364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL, 12374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev sizeof(alsa_handle.useCase)); 12384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 12394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else if (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) { 12404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (mFusion3Platform) { 12414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->setVocRecMode(INCALL_REC_MONO); 12424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE, 12434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev sizeof(alsa_handle.useCase)); 12444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 12454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL, 12464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev sizeof(alsa_handle.useCase)); 12474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 12484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 12499746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_FM_ENABLED 12504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else if((devices == AudioSystem::DEVICE_IN_FM_RX)) { 12514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_FM, sizeof(alsa_handle.useCase)); 12524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else if(devices == AudioSystem::DEVICE_IN_FM_RX_A2DP) { 12534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM, sizeof(alsa_handle.useCase)); 12544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 12554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 12569efed76df6b7c75d170e8f900f875f4329587719SathishKumar Mani char value[128]; 12579efed76df6b7c75d170e8f900f875f4329587719SathishKumar Mani property_get("persist.audio.lowlatency.rec",value,"0"); 12588861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani if (!strcmp("true", value)) { 12598861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase)); 12608861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani } else { 12618861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, sizeof(alsa_handle.useCase)); 12628861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani } 12634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 12644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 12654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if ((devices == AudioSystem::DEVICE_IN_VOICE_CALL) && 12664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (newMode == AudioSystem::MODE_IN_CALL)) { 12674113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("openInputStream: incall recording, channels %d", *channels); 12684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mIncallMode = *channels; 12694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if ((*channels & AudioSystem::CHANNEL_IN_VOICE_UPLINK) && 12704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) { 12714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (mFusion3Platform) { 12724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->setVocRecMode(INCALL_REC_STEREO); 12734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_INCALL_REC, 12744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev sizeof(alsa_handle.useCase)); 12754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 12764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_UL_DL_REC, 12774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev sizeof(alsa_handle.useCase)); 12784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 12794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else if (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) { 12804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (mFusion3Platform) { 12814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->setVocRecMode(INCALL_REC_MONO); 12824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_INCALL_REC, 12834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev sizeof(alsa_handle.useCase)); 12844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 12854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_DL_REC, 12864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev sizeof(alsa_handle.useCase)); 12874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 12884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 12899746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_FM_ENABLED 12904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else if(devices == AudioSystem::DEVICE_IN_FM_RX) { 12914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_FM_REC, sizeof(alsa_handle.useCase)); 12924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else if (devices == AudioSystem::DEVICE_IN_FM_RX_A2DP) { 12934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_FM_A2DP_REC, sizeof(alsa_handle.useCase)); 12944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 12954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 12968861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani char value[128]; 12978861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani property_get("persist.audio.lowlatency.rec",value,"0"); 12988861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani if (!strcmp("true", value)) { 12998861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC, sizeof(alsa_handle.useCase)); 13008861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani } else { 13018861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_REC, sizeof(alsa_handle.useCase)); 13028861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani } 13034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 13044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 13054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev free(use_case); 13064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDeviceList.push_back(alsa_handle); 13074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ALSAHandleList::iterator it = mDeviceList.end(); 13084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it--; 13094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev //update channel info before do routing 13104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(channels) { 13114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it->channels = AudioSystem::popCount((*channels) & 13129746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani (AudioSystem::CHANNEL_IN_STEREO 13139746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani | AudioSystem::CHANNEL_IN_MONO 13149746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_SSR_ENABLED 13154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev | AudioSystem::CHANNEL_IN_5POINT1 13164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 131761f449827974e117406693ef2cc6bdfdaf1fc00bEric Laurent | AUDIO_CHANNEL_IN_FRONT_BACK)); 131861f449827974e117406693ef2cc6bdfdaf1fc00bEric Laurent it->channelMask = *channels; 131961f449827974e117406693ef2cc6bdfdaf1fc00bEric Laurent ALOGV("updated channel info: channels=%d channelMask %08x", 132061f449827974e117406693ef2cc6bdfdaf1fc00bEric Laurent it->channels, it->channelMask); 13214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 13224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (devices == AudioSystem::DEVICE_IN_VOICE_CALL){ 13234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev /* Add current devices info to devices to do route */ 13249746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_USBAUDIO_ENABLED 13254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(mCurDevice == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET || 13264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mCurDevice == AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET){ 13274113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("Routing everything from proxy for VOIP call"); 13284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev route_devices = devices | AudioSystem::DEVICE_IN_PROXY; 13294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else 13304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 13314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev { 13324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev route_devices = devices | mCurDevice; 13334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 13344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->route(&(*it), route_devices, mode()); 13354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 13369746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_USBAUDIO_ENABLED 13374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(devices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET || 13384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev devices & AudioSystem::DEVICE_IN_PROXY) { 13394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev devices |= AudioSystem::DEVICE_IN_PROXY; 13400a019914794cc27f5dacddf4e5dbc019dbe21788SathishKumar Mani ALOGD("routing everything from proxy"); 13414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->route(&(*it), devices, mode()); 13424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else 13434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 13444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev { 13454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->route(&(*it), devices, mode()); 13464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 13474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 13484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_REC) || 13498861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani !strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC) || 13509746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_FM_ENABLED 13514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev !strcmp(it->useCase, SND_USE_CASE_VERB_FM_REC) || 13524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev !strcmp(it->useCase, SND_USE_CASE_VERB_FM_A2DP_REC) || 13534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 13544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev !strcmp(it->useCase, SND_USE_CASE_VERB_DL_REC) || 13554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev !strcmp(it->useCase, SND_USE_CASE_VERB_UL_DL_REC) || 13564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev !strcmp(it->useCase, SND_USE_CASE_VERB_INCALL_REC)) { 13574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_set(mUcMgr, "_verb", it->useCase); 13584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 13594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_set(mUcMgr, "_enamod", it->useCase); 13604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 13614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(sampleRate) { 13624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it->sampleRate = *sampleRate; 13634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 136477780382b45794eb5bc0e8589d9b7c96bb406772SathishKumar Mani if (!strncmp(it->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC)) 136577780382b45794eb5bc0e8589d9b7c96bb406772SathishKumar Mani || !strncmp(it->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) { 136677780382b45794eb5bc0e8589d9b7c96bb406772SathishKumar Mani ALOGV("OpenInoutStream: Use larger buffer size for 5.1(%s) recording ", it->useCase); 136777780382b45794eb5bc0e8589d9b7c96bb406772SathishKumar Mani it->bufferSize = getInputBufferSize(it->sampleRate,*format,it->channels); 13684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 13694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev err = mALSADevice->open(&(*it)); 13704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (err) { 13714113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("Error opening pcm input device"); 13724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 13734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev in = new AudioStreamInALSA(this, &(*it), acoustics); 13744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev err = in->set(format, channels, sampleRate, devices); 13754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 13764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (status) *status = err; 13774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return in; 13784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 13794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 13804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 13814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid 13824765c439491ddda3de658e62cc4a64d10e726b34Iliyan MalchevAudioHardwareALSA::closeInputStream(AudioStreamIn* in) 13834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 13844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev delete in; 13854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 13864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 13874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatus_t AudioHardwareALSA::setMicMute(bool state) 13884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 13896ccde10fdc6591e5cd21ed32c2b5817aaeb1a208SathishKumar Mani if (mMicMute != state) { 13906ccde10fdc6591e5cd21ed32c2b5817aaeb1a208SathishKumar Mani mMicMute = state; 13916ccde10fdc6591e5cd21ed32c2b5817aaeb1a208SathishKumar Mani ALOGD("setMicMute: mMicMute %d", mMicMute); 13926ccde10fdc6591e5cd21ed32c2b5817aaeb1a208SathishKumar Mani if(mALSADevice) { 13936ccde10fdc6591e5cd21ed32c2b5817aaeb1a208SathishKumar Mani mALSADevice->setMicMute(state); 13944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 13954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 13964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return NO_ERROR; 13974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 13984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 13994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatus_t AudioHardwareALSA::getMicMute(bool *state) 14004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 14016ccde10fdc6591e5cd21ed32c2b5817aaeb1a208SathishKumar Mani *state = mMicMute; 14024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return NO_ERROR; 14034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 14044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 14054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatus_t AudioHardwareALSA::dump(int fd, const Vector<String16>& args) 14064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 14074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return NO_ERROR; 14084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 14094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 14104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevsize_t AudioHardwareALSA::getInputBufferSize(uint32_t sampleRate, int format, int channelCount) 14114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 141277780382b45794eb5bc0e8589d9b7c96bb406772SathishKumar Mani size_t bufferSize = 0; 141377780382b45794eb5bc0e8589d9b7c96bb406772SathishKumar Mani if (format == AudioSystem::PCM_16_BIT) { 141477780382b45794eb5bc0e8589d9b7c96bb406772SathishKumar Mani if(sampleRate == 8000 || sampleRate == 16000 || sampleRate == 32000) { 141577780382b45794eb5bc0e8589d9b7c96bb406772SathishKumar Mani bufferSize = (sampleRate * channelCount * 20 * sizeof(int16_t)) / 1000; 141677780382b45794eb5bc0e8589d9b7c96bb406772SathishKumar Mani } else if (sampleRate == 11025 || sampleRate == 12000) { 141777780382b45794eb5bc0e8589d9b7c96bb406772SathishKumar Mani bufferSize = 256 * sizeof(int16_t) * channelCount; 141877780382b45794eb5bc0e8589d9b7c96bb406772SathishKumar Mani } else if (sampleRate == 22050 || sampleRate == 24000) { 141977780382b45794eb5bc0e8589d9b7c96bb406772SathishKumar Mani bufferSize = 512 * sizeof(int16_t) * channelCount; 142077780382b45794eb5bc0e8589d9b7c96bb406772SathishKumar Mani } else if (sampleRate == 44100 || sampleRate == 48000) { 142177780382b45794eb5bc0e8589d9b7c96bb406772SathishKumar Mani bufferSize = 1024 * sizeof(int16_t) * channelCount; 142277780382b45794eb5bc0e8589d9b7c96bb406772SathishKumar Mani } 14234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 142477780382b45794eb5bc0e8589d9b7c96bb406772SathishKumar Mani ALOGE("getInputBufferSize bad format: %d", format); 14254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 14264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return bufferSize; 14274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 14284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 14299746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_FM_ENABLED 14304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid AudioHardwareALSA::handleFm(int device) 14314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 14324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint newMode = mode(); 14334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(device & AudioSystem::DEVICE_OUT_FM && mIsFmActive == 0) { 14344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // Start FM Radio on current active device 14354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev unsigned long bufferSize = FM_BUFFER_SIZE; 14364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle_t alsa_handle; 14374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev char *use_case; 14384113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("Start FM"); 14394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 14404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 14414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_DIGITAL_RADIO, sizeof(alsa_handle.useCase)); 14424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 14434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_FM, sizeof(alsa_handle.useCase)); 14444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 14454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev free(use_case); 14464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 14474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1) 14484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bufferSize &= ~b; 14494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.module = mALSADevice; 14504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.bufferSize = bufferSize; 14514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.devices = device; 14524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.handle = 0; 14534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 14544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.channels = DEFAULT_CHANNEL_MODE; 145561f449827974e117406693ef2cc6bdfdaf1fc00bEric Laurent alsa_handle.channelMask = AUDIO_CHANNEL_OUT_STEREO; 14564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.sampleRate = DEFAULT_SAMPLING_RATE; 14574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.latency = VOICE_LATENCY; 14584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.rxHandle = 0; 14594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.ucMgr = mUcMgr; 14604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mIsFmActive = 1; 14614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDeviceList.push_back(alsa_handle); 14624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ALSAHandleList::iterator it = mDeviceList.end(); 14634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it--; 14644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 14654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 14664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev device |= AudioSystem::DEVICE_OUT_PROXY; 14674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.devices = AudioSystem::DEVICE_OUT_PROXY; 14680a019914794cc27f5dacddf4e5dbc019dbe21788SathishKumar Mani ALOGD("Routing to proxy for FM case"); 14694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 14704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->route(&(*it), (uint32_t)device, newMode); 14714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(!strcmp(it->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) { 14724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_DIGITAL_RADIO); 14734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 14744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_FM); 14754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 14764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->startFm(&(*it)); 14774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 14784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 14790a019914794cc27f5dacddf4e5dbc019dbe21788SathishKumar Mani ALOGD("Starting FM, musbPlaybackState %d", musbPlaybackState); 14804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev startUsbPlaybackIfNotStarted(); 14814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbPlaybackState |= USBPLAYBACKBIT_FM; 14824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 14834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else if (!(device & AudioSystem::DEVICE_OUT_FM) && mIsFmActive == 1) { 14844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev //i Stop FM Radio 14854113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("Stop FM"); 14864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev for(ALSAHandleList::iterator it = mDeviceList.begin(); 14874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it != mDeviceList.end(); ++it) { 14884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((!strcmp(it->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) || 14894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_FM))) { 14904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->close(&(*it)); 14914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev //mALSADevice->route(&(*it), (uint32_t)device, newMode); 14924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDeviceList.erase(it); 14934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 14944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 14954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 14964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mIsFmActive = 0; 14974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbPlaybackState &= ~USBPLAYBACKBIT_FM; 14984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 14994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 15004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev closeUsbPlaybackIfNothingActive(); 15014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 15024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 15034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 15044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 15054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 15064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid AudioHardwareALSA::disableVoiceCall(char* verb, char* modifier, int mode, int device) 15074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 15084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev for(ALSAHandleList::iterator it = mDeviceList.begin(); 15094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it != mDeviceList.end(); ++it) { 15104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((!strcmp(it->useCase, verb)) || 15114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (!strcmp(it->useCase, modifier))) { 15124113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("Disabling voice call"); 15134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->close(&(*it)); 15144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->route(&(*it), (uint32_t)device, mode); 15154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDeviceList.erase(it); 15164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 15174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 15184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 15199746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_USBAUDIO_ENABLED 15204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(musbPlaybackState & USBPLAYBACKBIT_VOICECALL) { 15210a019914794cc27f5dacddf4e5dbc019dbe21788SathishKumar Mani ALOGD("Voice call ended on USB"); 15224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbPlaybackState &= ~USBPLAYBACKBIT_VOICECALL; 15234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbRecordingState &= ~USBRECBIT_VOICECALL; 15244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev closeUsbRecordingIfNothingActive(); 15254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev closeUsbPlaybackIfNothingActive(); 15264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 15279746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#endif 15284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 15294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid AudioHardwareALSA::enableVoiceCall(char* verb, char* modifier, int mode, int device) 15304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 15314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// Start voice call 1532018d1c5b5746dc189b2d7b86a87f1d2fd219994aSathishKumar Maniunsigned long bufferSize = DEFAULT_VOICE_BUFFER_SIZE; 15334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevalsa_handle_t alsa_handle; 15344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevchar *use_case; 15354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 15364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 15374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, verb, sizeof(alsa_handle.useCase)); 15384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 15394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(alsa_handle.useCase, modifier, sizeof(alsa_handle.useCase)); 15404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 15414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev free(use_case); 15424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 15434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1) 15444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bufferSize &= ~b; 15454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.module = mALSADevice; 15464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.bufferSize = bufferSize; 15474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.devices = device; 15484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.handle = 0; 15494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 15504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.channels = VOICE_CHANNEL_MODE; 155161f449827974e117406693ef2cc6bdfdaf1fc00bEric Laurent alsa_handle.channelMask = AUDIO_CHANNEL_IN_MONO; 15524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.sampleRate = VOICE_SAMPLING_RATE; 15534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.latency = VOICE_LATENCY; 15544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.rxHandle = 0; 15554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.ucMgr = mUcMgr; 15564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDeviceList.push_back(alsa_handle); 15574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ALSAHandleList::iterator it = mDeviceList.end(); 15584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it--; 15599746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_USBAUDIO_ENABLED 15604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 15614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 15624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev device |= AudioSystem::DEVICE_OUT_PROXY; 15634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle.devices = device; 15644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 15654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 15664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->route(&(*it), (uint32_t)device, mode); 15674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!strcmp(it->useCase, verb)) { 15684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_set(mUcMgr, "_verb", verb); 15694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 15704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_use_case_set(mUcMgr, "_enamod", modifier); 15714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 15724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mALSADevice->startVoiceCall(&(*it)); 15739746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_USBAUDIO_ENABLED 15744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 15754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 15764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev startUsbRecordingIfNotStarted(); 15774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev startUsbPlaybackIfNotStarted(); 15784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbPlaybackState |= USBPLAYBACKBIT_VOICECALL; 15794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev musbRecordingState |= USBRECBIT_VOICECALL; 15804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 15819746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#endif 15824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 15834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 15844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevbool AudioHardwareALSA::routeVoiceCall(int device, int newMode) 15854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 15864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint csCallState = mCallState&0xF; 15874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bool isRouted = false; 15884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev switch (csCallState) { 15899746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani case CS_INACTIVE: 15909746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani if (mCSCallActive != CS_INACTIVE) { 15914113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("doRouting: Disabling voice call"); 15924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev disableVoiceCall((char *)SND_USE_CASE_VERB_VOICECALL, 15934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (char *)SND_USE_CASE_MOD_PLAY_VOICE, newMode, device); 15944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev isRouted = true; 15959746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani mCSCallActive = CS_INACTIVE; 15964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 15974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 15989746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani case CS_ACTIVE: 15999746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani if (mCSCallActive == CS_INACTIVE) { 16004113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("doRouting: Enabling CS voice call "); 16014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev enableVoiceCall((char *)SND_USE_CASE_VERB_VOICECALL, 16024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (char *)SND_USE_CASE_MOD_PLAY_VOICE, newMode, device); 16034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev isRouted = true; 16049746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani mCSCallActive = CS_ACTIVE; 16059746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani } else if (mCSCallActive == CS_HOLD) { 16064113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("doRouting: Resume voice call from hold state"); 16074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ALSAHandleList::iterator vt_it; 16084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev for(vt_it = mDeviceList.begin(); 16094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev vt_it != mDeviceList.end(); ++vt_it) { 16104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOICECALL, 16114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlen(SND_USE_CASE_VERB_VOICECALL))) || 16124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOICE, 16134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlen(SND_USE_CASE_MOD_PLAY_VOICE)))) { 16144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it)); 16159746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani mCSCallActive = CS_ACTIVE; 16164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,0)<0) 16174113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("VoLTE resume failed"); 16184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 16194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 16204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 16214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 16224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 16239746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani case CS_HOLD: 16249746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani if (mCSCallActive == CS_ACTIVE) { 16254113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("doRouting: Voice call going to Hold"); 16264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ALSAHandleList::iterator vt_it; 16274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev for(vt_it = mDeviceList.begin(); 16284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev vt_it != mDeviceList.end(); ++vt_it) { 16294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOICECALL, 16304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlen(SND_USE_CASE_VERB_VOICECALL))) || 16314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOICE, 16324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlen(SND_USE_CASE_MOD_PLAY_VOICE)))) { 16339746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani mCSCallActive = CS_HOLD; 16344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it)); 16354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,1)<0) 16364113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("Voice pause failed"); 16374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 16384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 16394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 16404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 16414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 16424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 16434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return isRouted; 16444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 16454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevbool AudioHardwareALSA::routeVoLTECall(int device, int newMode) 16464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 16474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint volteCallState = mCallState&0xF0; 16484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevbool isRouted = false; 16494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevswitch (volteCallState) { 16509746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani case IMS_INACTIVE: 16519746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani if (mVolteCallActive != IMS_INACTIVE) { 16524113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("doRouting: Disabling IMS call"); 16534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev disableVoiceCall((char *)SND_USE_CASE_VERB_VOLTE, 16544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (char *)SND_USE_CASE_MOD_PLAY_VOLTE, newMode, device); 16554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev isRouted = true; 16569746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani mVolteCallActive = IMS_INACTIVE; 16574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 16584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 16599746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani case IMS_ACTIVE: 16609746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani if (mVolteCallActive == IMS_INACTIVE) { 16614113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("doRouting: Enabling IMS voice call "); 16624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev enableVoiceCall((char *)SND_USE_CASE_VERB_VOLTE, 16634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (char *)SND_USE_CASE_MOD_PLAY_VOLTE, newMode, device); 16644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev isRouted = true; 16659746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani mVolteCallActive = IMS_ACTIVE; 16669746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani } else if (mVolteCallActive == IMS_HOLD) { 16674113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("doRouting: Resume IMS call from hold state"); 16684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ALSAHandleList::iterator vt_it; 16694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev for(vt_it = mDeviceList.begin(); 16704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev vt_it != mDeviceList.end(); ++vt_it) { 16714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOLTE, 16724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlen(SND_USE_CASE_VERB_VOLTE))) || 16734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOLTE, 16744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlen(SND_USE_CASE_MOD_PLAY_VOLTE)))) { 16754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it)); 16769746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani mVolteCallActive = IMS_ACTIVE; 16774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,0)<0) 16784113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("VoLTE resume failed"); 16794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 16804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 16814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 16824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 16834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 16849746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani case IMS_HOLD: 16859746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani if (mVolteCallActive == IMS_ACTIVE) { 16864113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("doRouting: IMS ACTIVE going to HOLD"); 16874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ALSAHandleList::iterator vt_it; 16884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev for(vt_it = mDeviceList.begin(); 16894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev vt_it != mDeviceList.end(); ++vt_it) { 16904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOLTE, 16914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlen(SND_USE_CASE_VERB_VOLTE))) || 16924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOLTE, 16934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlen(SND_USE_CASE_MOD_PLAY_VOLTE)))) { 16949746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani mVolteCallActive = IMS_HOLD; 16954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it)); 16964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,1)<0) 16974113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("VoLTE Pause failed"); 16984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 16994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 17004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 17014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 17024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 17034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 17044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return isRouted; 17054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 17064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 17074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} // namespace android_audio_legacy 1708