alsa_default.cpp revision c669c27ef9c5663692c3dd8818bb6e7fcdc39b7a
1/* alsa_default.cpp 2 ** 3 ** Copyright 2009 Wind River Systems 4 ** Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. 5 ** 6 ** Licensed under the Apache License, Version 2.0 (the "License"); 7 ** you may not use this file except in compliance with the License. 8 ** You may obtain a copy of the License at 9 ** 10 ** http://www.apache.org/licenses/LICENSE-2.0 11 ** 12 ** Unless required by applicable law or agreed to in writing, software 13 ** distributed under the License is distributed on an "AS IS" BASIS, 14 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 ** See the License for the specific language governing permissions and 16 ** limitations under the License. 17 */ 18 19#define LOG_TAG "ALSAModule" 20//#define LOG_NDEBUG 0 21#define LOG_NDDEBUG 0 22#include <utils/Log.h> 23#include <cutils/properties.h> 24#include <linux/ioctl.h> 25#include "AudioHardwareALSA.h" 26#include <media/AudioRecord.h> 27#include <dlfcn.h> 28#ifdef QCOM_CSDCLIENT_ENABLED 29extern "C" { 30static int (*csd_disable_device)(); 31static int (*csd_enable_device)(int, int, uint32_t); 32static int (*csd_volume)(int); 33static int (*csd_mic_mute)(int); 34static int (*csd_wide_voice)(uint8_t); 35static int (*csd_slow_talk)(uint8_t); 36static int (*csd_fens)(uint8_t); 37static int (*csd_start_voice)(); 38static int (*csd_stop_voice)(); 39} 40#endif 41 42#ifndef ALSA_DEFAULT_SAMPLE_RATE 43#define ALSA_DEFAULT_SAMPLE_RATE 44100 // in Hz 44#endif 45 46#define BTSCO_RATE_16KHZ 16000 47#define USECASE_TYPE_RX 1 48#define USECASE_TYPE_TX 2 49 50namespace android_audio_legacy 51{ 52 53static int s_device_open(const hw_module_t*, const char*, hw_device_t**); 54static int s_device_close(hw_device_t*); 55static status_t s_init(alsa_device_t *, ALSAHandleList &); 56static status_t s_open(alsa_handle_t *); 57static status_t s_close(alsa_handle_t *); 58static status_t s_standby(alsa_handle_t *); 59static status_t s_route(alsa_handle_t *, uint32_t, int); 60static status_t s_start_voice_call(alsa_handle_t *); 61static status_t s_start_voip_call(alsa_handle_t *); 62static status_t s_start_fm(alsa_handle_t *); 63static void s_set_voice_volume(int); 64static void s_set_voip_volume(int); 65static void s_set_mic_mute(int); 66static void s_set_voip_mic_mute(int); 67static void s_set_voip_config(int, int); 68static status_t s_set_fm_vol(int); 69static void s_set_btsco_rate(int); 70static status_t s_set_lpa_vol(int); 71static void s_enable_wide_voice(bool flag); 72static void s_enable_fens(bool flag); 73static void s_set_flags(uint32_t flags); 74static status_t s_set_compressed_vol(int); 75static void s_enable_slow_talk(bool flag); 76static void s_set_voc_rec_mode(uint8_t mode); 77static void s_set_volte_mic_mute(int state); 78static void s_set_volte_volume(int vol); 79#ifdef SEPERATED_AUDIO_INPUT 80static void s_setInput(int); 81 82static int input_source; 83#endif 84#ifdef QCOM_CSDCLIENT_ENABLED 85static void s_set_csd_handle(void*); 86#endif 87 88static char mic_type[25]; 89static char curRxUCMDevice[50]; 90static char curTxUCMDevice[50]; 91static int fluence_mode; 92static int fmVolume; 93#ifdef USES_FLUENCE_INCALL 94static uint32_t mDevSettingsFlag = TTY_OFF | DMIC_FLAG; 95#else 96static uint32_t mDevSettingsFlag = TTY_OFF; 97#endif 98static int btsco_samplerate = 8000; 99static bool pflag = false; 100static ALSAUseCaseList mUseCaseList; 101static void *csd_handle; 102 103static hw_module_methods_t s_module_methods = { 104 open : s_device_open 105}; 106 107extern "C" { 108hw_module_t HAL_MODULE_INFO_SYM = { 109 tag : HARDWARE_MODULE_TAG, 110 version_major : 1, 111 version_minor : 0, 112 id : ALSA_HARDWARE_MODULE_ID, 113 name : "QCOM ALSA module", 114 author : "QuIC Inc", 115 methods : &s_module_methods, 116 dso : 0, 117 reserved : {0,}, 118}; 119} 120 121static int s_device_open(const hw_module_t* module, const char* name, 122 hw_device_t** device) 123{ 124 char value[128]; 125 alsa_device_t *dev; 126 dev = (alsa_device_t *) malloc(sizeof(*dev)); 127 if (!dev) return -ENOMEM; 128 129 memset(dev, 0, sizeof(*dev)); 130 131 /* initialize the procs */ 132 dev->common.tag = HARDWARE_DEVICE_TAG; 133 dev->common.version = 0; 134 dev->common.module = (hw_module_t *) module; 135 dev->common.close = s_device_close; 136 dev->init = s_init; 137 dev->open = s_open; 138 dev->close = s_close; 139 dev->route = s_route; 140 dev->standby = s_standby; 141 dev->startVoiceCall = s_start_voice_call; 142 dev->startVoipCall = s_start_voip_call; 143 dev->startFm = s_start_fm; 144 dev->setVoiceVolume = s_set_voice_volume; 145 dev->setVoipVolume = s_set_voip_volume; 146 dev->setMicMute = s_set_mic_mute; 147 dev->setVoipMicMute = s_set_voip_mic_mute; 148 dev->setVoipConfig = s_set_voip_config; 149 dev->setFmVolume = s_set_fm_vol; 150 dev->setBtscoRate = s_set_btsco_rate; 151 dev->setLpaVolume = s_set_lpa_vol; 152 dev->enableWideVoice = s_enable_wide_voice; 153 dev->enableFENS = s_enable_fens; 154 dev->setFlags = s_set_flags; 155 dev->setCompressedVolume = s_set_compressed_vol; 156 dev->enableSlowTalk = s_enable_slow_talk; 157 dev->setVocRecMode = s_set_voc_rec_mode; 158 dev->setVoLTEMicMute = s_set_volte_mic_mute; 159 dev->setVoLTEVolume = s_set_volte_volume; 160#ifdef SEPERATED_AUDIO_INPUT 161 dev->setInput = s_setInput; 162#endif 163#ifdef QCOM_CSDCLIENT_ENABLED 164 dev->setCsdHandle = s_set_csd_handle; 165#endif 166 *device = &dev->common; 167 168 property_get("persist.audio.handset.mic",value,"0"); 169 strlcpy(mic_type, value, sizeof(mic_type)); 170 property_get("persist.audio.fluence.mode",value,"0"); 171 if (!strcmp("broadside", value)) { 172 fluence_mode = FLUENCE_MODE_BROADSIDE; 173 } else { 174 fluence_mode = FLUENCE_MODE_ENDFIRE; 175 } 176 strlcpy(curRxUCMDevice, "None", sizeof(curRxUCMDevice)); 177 strlcpy(curTxUCMDevice, "None", sizeof(curTxUCMDevice)); 178 ALOGV("ALSA module opened"); 179 180 return 0; 181} 182 183static int s_device_close(hw_device_t* device) 184{ 185 free(device); 186 device = NULL; 187 return 0; 188} 189 190// ---------------------------------------------------------------------------- 191 192static const int DEFAULT_SAMPLE_RATE = ALSA_DEFAULT_SAMPLE_RATE; 193 194static void switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode); 195static char *getUCMDevice(uint32_t devices, int input, char *rxDevice); 196static void disableDevice(alsa_handle_t *handle); 197int getUseCaseType(const char *useCase); 198 199static int callMode = AudioSystem::MODE_NORMAL; 200// ---------------------------------------------------------------------------- 201 202bool platform_is_Fusion3() 203{ 204 char platform[128], baseband[128]; 205 property_get("ro.board.platform", platform, ""); 206 property_get("ro.baseband", baseband, ""); 207 if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband)) 208 return true; 209 else 210 return false; 211} 212 213int deviceName(alsa_handle_t *handle, unsigned flags, char **value) 214{ 215 int ret = 0; 216 char ident[70]; 217 218 if (flags & PCM_IN) { 219 strlcpy(ident, "CapturePCM/", sizeof(ident)); 220 } else { 221 strlcpy(ident, "PlaybackPCM/", sizeof(ident)); 222 } 223 strlcat(ident, handle->useCase, sizeof(ident)); 224 ret = snd_use_case_get(handle->ucMgr, ident, (const char **)value); 225 ALOGD("Device value returned is %s", (*value)); 226 return ret; 227} 228 229status_t setHardwareParams(alsa_handle_t *handle) 230{ 231 struct snd_pcm_hw_params *params; 232 unsigned long bufferSize, reqBuffSize; 233 unsigned int periodTime, bufferTime; 234 unsigned int requestedRate = handle->sampleRate; 235 int status = 0; 236 int channels = handle->channels; 237 snd_pcm_format_t format = SNDRV_PCM_FORMAT_S16_LE; 238 239 params = (snd_pcm_hw_params*) calloc(1, sizeof(struct snd_pcm_hw_params)); 240 if (!params) { 241 ALOGE("Failed to allocate ALSA hardware parameters!"); 242 return NO_INIT; 243 } 244 245 reqBuffSize = handle->bufferSize; 246 ALOGD("setHardwareParams: reqBuffSize %d channels %d sampleRate %d", 247 (int) reqBuffSize, handle->channels, handle->sampleRate); 248 249#ifdef QCOM_SSR_ENABLED 250 if (channels == 6) { 251 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC)) 252 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) { 253 ALOGV("HWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase); 254 channels = 4; 255 reqBuffSize = DEFAULT_IN_BUFFER_SIZE; 256 } 257 } 258#endif 259 260 param_init(params); 261 param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS, 262 SNDRV_PCM_ACCESS_RW_INTERLEAVED); 263 if (handle->format != SNDRV_PCM_FORMAT_S16_LE) { 264 if (handle->format == AudioSystem::AMR_NB 265 || handle->format == AudioSystem::AMR_WB 266#ifdef QCOM_QCHAT_ENABLED 267 || handle->format == AudioSystem::EVRC 268 || handle->format == AudioSystem::EVRCB 269 || handle->format == AudioSystem::EVRCWB 270#endif 271 ) 272 format = SNDRV_PCM_FORMAT_SPECIAL; 273 } 274 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, 275 format); 276 param_set_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT, 277 SNDRV_PCM_SUBFORMAT_STD); 278 param_set_min(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, reqBuffSize); 279 param_set_int(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 16); 280 param_set_int(params, SNDRV_PCM_HW_PARAM_FRAME_BITS, 281 channels * 16); 282 param_set_int(params, SNDRV_PCM_HW_PARAM_CHANNELS, 283 channels); 284 param_set_int(params, SNDRV_PCM_HW_PARAM_RATE, handle->sampleRate); 285 param_set_hw_refine(handle->handle, params); 286 287 if (param_set_hw_params(handle->handle, params)) { 288 ALOGE("cannot set hw params"); 289 return NO_INIT; 290 } 291 param_dump(params); 292 293 handle->handle->buffer_size = pcm_buffer_size(params); 294 handle->handle->period_size = pcm_period_size(params); 295 handle->handle->period_cnt = handle->handle->buffer_size/handle->handle->period_size; 296 ALOGD("setHardwareParams: buffer_size %d, period_size %d, period_cnt %d", 297 handle->handle->buffer_size, handle->handle->period_size, 298 handle->handle->period_cnt); 299 handle->handle->rate = handle->sampleRate; 300 handle->handle->channels = handle->channels; 301 handle->periodSize = handle->handle->period_size; 302 if (strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC) && 303 strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC) && 304 (6 != handle->channels)) { 305 //Do not update buffersize for 5.1 recording 306 handle->bufferSize = handle->handle->period_size; 307 } 308 309 return NO_ERROR; 310} 311 312status_t setSoftwareParams(alsa_handle_t *handle) 313{ 314 struct snd_pcm_sw_params* params; 315 struct pcm* pcm = handle->handle; 316 317 unsigned long periodSize = pcm->period_size; 318 int channels = handle->channels; 319 320 params = (snd_pcm_sw_params*) calloc(1, sizeof(struct snd_pcm_sw_params)); 321 if (!params) { 322 LOG_ALWAYS_FATAL("Failed to allocate ALSA software parameters!"); 323 return NO_INIT; 324 } 325 326#ifdef QCOM_SSR_ENABLED 327 if (channels == 6) { 328 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC)) 329 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) { 330 ALOGV("SWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase); 331 channels = 4; 332 } 333 } 334#endif 335 336 // Get the current software parameters 337 params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE; 338 params->period_step = 1; 339 if(((!strcmp(handle->useCase,SND_USE_CASE_MOD_PLAY_VOIP)) || 340 (!strcmp(handle->useCase,SND_USE_CASE_VERB_IP_VOICECALL)))){ 341 ALOGV("setparam: start & stop threshold for Voip "); 342 params->avail_min = handle->channels - 1 ? periodSize/4 : periodSize/2; 343 params->start_threshold = periodSize/2; 344 params->stop_threshold = INT_MAX; 345 } else { 346 params->avail_min = periodSize/2; 347 params->start_threshold = channels * (periodSize/4); 348 params->stop_threshold = INT_MAX; 349 } 350 params->silence_threshold = 0; 351 params->silence_size = 0; 352 353 if (param_set_sw_params(handle->handle, params)) { 354 ALOGE("cannot set sw params"); 355 return NO_INIT; 356 } 357 return NO_ERROR; 358} 359 360void switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode) 361{ 362 const char **mods_list; 363 use_case_t useCaseNode; 364 unsigned usecase_type = 0; 365 bool inCallDevSwitch = false; 366 char *rxDevice, *txDevice, ident[70], *use_case = NULL; 367 int err = 0, index, mods_size; 368 int rx_dev_id, tx_dev_id; 369 ALOGD("%s: device %d mode:%d", __FUNCTION__, devices, mode); 370 371 if ((mode == AudioSystem::MODE_IN_CALL) || (mode == AudioSystem::MODE_IN_COMMUNICATION)) { 372 if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) || 373 (devices & AudioSystem::DEVICE_IN_WIRED_HEADSET)) { 374 devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADSET | 375 AudioSystem::DEVICE_IN_WIRED_HEADSET); 376 } else if (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) { 377 devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADPHONE | 378 AudioSystem::DEVICE_IN_BUILTIN_MIC); 379 } else if (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) { 380 if (mode == AudioSystem::MODE_IN_CALL) { 381 devices |= AudioSystem::DEVICE_OUT_EARPIECE; 382 } 383 } else if (devices & AudioSystem::DEVICE_OUT_EARPIECE) { 384 devices = devices | AudioSystem::DEVICE_IN_BUILTIN_MIC; 385 } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) { 386 devices = devices | (AudioSystem::DEVICE_IN_BACK_MIC | 387 AudioSystem::DEVICE_OUT_SPEAKER); 388 } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) || 389 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) || 390 (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET)) { 391 devices = devices | (AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET | 392 AudioSystem::DEVICE_OUT_BLUETOOTH_SCO); 393#ifdef QCOM_ANC_HEADSET_ENABLED 394 } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) || 395 (devices & AudioSystem::DEVICE_IN_ANC_HEADSET)) { 396 devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADSET | 397 AudioSystem::DEVICE_IN_ANC_HEADSET); 398 } else if (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE) { 399 devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADPHONE | 400 AudioSystem::DEVICE_IN_BUILTIN_MIC); 401#endif 402 } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) { 403 devices = devices | (AudioSystem::DEVICE_OUT_AUX_DIGITAL | 404 AudioSystem::DEVICE_IN_AUX_DIGITAL); 405#ifdef QCOM_PROXY_DEVICE_ENABLED 406 } else if ((devices & AudioSystem::DEVICE_OUT_PROXY) || 407 (devices & AudioSystem::DEVICE_IN_PROXY)) { 408 devices = devices | (AudioSystem::DEVICE_OUT_PROXY | 409 AudioSystem::DEVICE_IN_PROXY); 410#endif 411 } 412 } 413#ifdef QCOM_SSR_ENABLED 414 if ((devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) && ( 6 == handle->channels)) { 415 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC)) 416 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) { 417 ALOGV(" switchDevice , use ssr devices for channels:%d usecase:%s",handle->channels,handle->useCase); 418 s_set_flags(SSRQMIC_FLAG); 419 } 420 } 421#endif 422 423 rxDevice = getUCMDevice(devices & AudioSystem::DEVICE_OUT_ALL, 0, NULL); 424 txDevice = getUCMDevice(devices & AudioSystem::DEVICE_IN_ALL, 1, rxDevice); 425 426 if ((rxDevice != NULL) && (txDevice != NULL)) { 427 if (((strncmp(rxDevice, curRxUCMDevice, MAX_STR_LEN)) || 428 (strncmp(txDevice, curTxUCMDevice, MAX_STR_LEN))) && 429 ((mode == AudioSystem::MODE_IN_CALL) || 430 (mode == AudioSystem::MODE_IN_COMMUNICATION))) 431 inCallDevSwitch = true; 432 } 433 434#ifdef QCOM_CSDCLIENT_ENABLED 435 if (platform_is_Fusion3() && (inCallDevSwitch == true)) { 436 if (csd_disable_device == NULL) { 437 ALOGE("dlsym:Error:%s Loading csd_client_disable_device", dlerror()); 438 } else { 439 err = csd_disable_device(); 440 if (err < 0) 441 { 442 ALOGE("csd_client_disable_device, failed, error %d", err); 443 } 444 } 445 } 446#endif 447 448 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&use_case); 449 mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list); 450 if (rxDevice != NULL) { 451 if ((strncmp(curRxUCMDevice, "None", 4)) && 452 ((strncmp(rxDevice, curRxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) { 453 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE, 454 strlen(SND_USE_CASE_VERB_INACTIVE)))) { 455 usecase_type = getUseCaseType(use_case); 456 if (usecase_type & USECASE_TYPE_RX) { 457 ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type); 458 strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN); 459 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE); 460 mUseCaseList.push_front(useCaseNode); 461 } 462 } 463 if (mods_size) { 464 for(index = 0; index < mods_size; index++) { 465 usecase_type = getUseCaseType(mods_list[index]); 466 if (usecase_type & USECASE_TYPE_RX) { 467 ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type); 468 strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN); 469 snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]); 470 mUseCaseList.push_back(useCaseNode); 471 } 472 } 473 } 474 snd_use_case_set(handle->ucMgr, "_disdev", curRxUCMDevice); 475 } 476 } 477 if (txDevice != NULL) { 478 if ((strncmp(curTxUCMDevice, "None", 4)) && 479 ((strncmp(txDevice, curTxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) { 480 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE, 481 strlen(SND_USE_CASE_VERB_INACTIVE)))) { 482 usecase_type = getUseCaseType(use_case); 483 if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) { 484 ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type); 485 strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN); 486 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE); 487 mUseCaseList.push_front(useCaseNode); 488 } 489 } 490 if (mods_size) { 491 for(index = 0; index < mods_size; index++) { 492 usecase_type = getUseCaseType(mods_list[index]); 493 if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) { 494 ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type); 495 strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN); 496 snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]); 497 mUseCaseList.push_back(useCaseNode); 498 } 499 } 500 } 501 snd_use_case_set(handle->ucMgr, "_disdev", curTxUCMDevice); 502 } 503 } 504 ALOGD("%s,rxDev:%s, txDev:%s, curRxDev:%s, curTxDev:%s\n", __FUNCTION__, rxDevice, txDevice, curRxUCMDevice, curTxUCMDevice); 505 506 if (rxDevice != NULL) { 507 snd_use_case_set(handle->ucMgr, "_enadev", rxDevice); 508 strlcpy(curRxUCMDevice, rxDevice, sizeof(curRxUCMDevice)); 509#ifdef QCOM_FM_ENABLED 510 if (devices & AudioSystem::DEVICE_OUT_FM) 511 s_set_fm_vol(fmVolume); 512#endif 513 } 514 if (txDevice != NULL) { 515 snd_use_case_set(handle->ucMgr, "_enadev", txDevice); 516 strlcpy(curTxUCMDevice, txDevice, sizeof(curTxUCMDevice)); 517 } 518 for(ALSAUseCaseList::iterator it = mUseCaseList.begin(); it != mUseCaseList.end(); ++it) { 519 ALOGD("Route use case %s\n", it->useCase); 520 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE, 521 strlen(SND_USE_CASE_VERB_INACTIVE))) && (!strncmp(use_case, it->useCase, MAX_UC_LEN))) { 522 snd_use_case_set(handle->ucMgr, "_verb", it->useCase); 523 } else { 524 snd_use_case_set(handle->ucMgr, "_enamod", it->useCase); 525 } 526 } 527 if (!mUseCaseList.empty()) 528 mUseCaseList.clear(); 529 if (use_case != NULL) { 530 free(use_case); 531 use_case = NULL; 532 } 533 ALOGD("switchDevice: curTxUCMDevivce %s curRxDevDevice %s", curTxUCMDevice, curRxUCMDevice); 534 535 if (platform_is_Fusion3() && (inCallDevSwitch == true)) { 536 /* get tx acdb id */ 537 memset(&ident,0,sizeof(ident)); 538 strlcpy(ident, "ACDBID/", sizeof(ident)); 539 strlcat(ident, curTxUCMDevice, sizeof(ident)); 540 tx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL); 541 542 /* get rx acdb id */ 543 memset(&ident,0,sizeof(ident)); 544 strlcpy(ident, "ACDBID/", sizeof(ident)); 545 strlcat(ident, curRxUCMDevice, sizeof(ident)); 546 rx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL); 547 548 if (((rx_dev_id == DEVICE_SPEAKER_MONO_RX_ACDB_ID ) || (rx_dev_id == DEVICE_SPEAKER_STEREO_RX_ACDB_ID )) 549 && tx_dev_id == DEVICE_HANDSET_TX_ACDB_ID) { 550 tx_dev_id = DEVICE_SPEAKER_TX_ACDB_ID; 551 } 552 553#ifdef QCOM_CSDCLIENT_ENABLED 554 ALOGV("rx_dev_id=%d, tx_dev_id=%d\n", rx_dev_id, tx_dev_id); 555 if (csd_enable_device == NULL) { 556 ALOGE("dlsym:Error:%s Loading csd_client_enable_device", dlerror()); 557 } else { 558 err = csd_enable_device(rx_dev_id, tx_dev_id, mDevSettingsFlag); 559 if (err < 0) 560 { 561 ALOGE("csd_client_disable_device failed, error %d", err); 562 } 563 } 564#endif 565 } 566 567 if (rxDevice != NULL) { 568 if (pflag && (((!strncmp(rxDevice, DEVICE_SPEAKER_HEADSET, strlen(DEVICE_SPEAKER_HEADSET))) && 569 ((!strncmp(curRxUCMDevice, DEVICE_HEADPHONES, strlen(DEVICE_HEADPHONES))) || 570 (!strncmp(curRxUCMDevice, DEVICE_HEADSET, strlen(DEVICE_HEADSET))))) || 571 (((!strncmp(curRxUCMDevice, DEVICE_SPEAKER_HEADSET, strlen(DEVICE_SPEAKER_HEADSET))) && 572 ((!strncmp(rxDevice, DEVICE_HEADPHONES, strlen(DEVICE_HEADPHONES))) || 573 (!strncmp(rxDevice, DEVICE_HEADSET, strlen(DEVICE_HEADSET))))))) && 574 ((!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI, strlen(SND_USE_CASE_VERB_HIFI))) || 575 (!strncmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC, strlen(SND_USE_CASE_MOD_PLAY_MUSIC))))) { 576 s_open(handle); 577 pflag = false; 578 } 579 } 580 581 if (rxDevice != NULL) { 582 free(rxDevice); 583 rxDevice = NULL; 584 } 585 if (txDevice != NULL) { 586 free(txDevice); 587 txDevice = NULL; 588 } 589} 590 591// ---------------------------------------------------------------------------- 592 593static status_t s_init(alsa_device_t *module, ALSAHandleList &list) 594{ 595 ALOGV("s_init: Initializing devices for ALSA module"); 596 597 list.clear(); 598 599 return NO_ERROR; 600} 601 602static status_t s_open(alsa_handle_t *handle) 603{ 604 char *devName; 605 unsigned flags = 0; 606 int err = NO_ERROR; 607 608 /* No need to call s_close for LPA as pcm device open and close is handled by LPAPlayer in stagefright */ 609 if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) || (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) 610 ||(!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) || (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) { 611 ALOGV("s_open: Opening LPA /Tunnel playback"); 612 return NO_ERROR; 613 } 614 615 s_close(handle); 616 617 ALOGV("s_open: handle %p", handle); 618 619 // ASoC multicomponent requires a valid path (frontend/backend) for 620 // the device to be opened 621 622 // The PCM stream is opened in blocking mode, per ALSA defaults. The 623 // AudioFlinger seems to assume blocking mode too, so asynchronous mode 624 // should not be used. 625 if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) || 626 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) || 627 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) || 628 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) { 629 ALOGV("LPA/tunnel use case"); 630 flags |= PCM_MMAP; 631 flags |= DEBUG_ON; 632 } else if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI)) || 633 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) || 634 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) || 635 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC))) { 636 ALOGV("Music case"); 637 flags = PCM_OUT; 638 } else { 639 flags = PCM_IN; 640 } 641 if (handle->channels == 1) { 642 flags |= PCM_MONO; 643 } 644#ifdef QCOM_SSR_ENABLED 645 else if (handle->channels == 4 ) { 646 flags |= PCM_QUAD; 647 } else if (handle->channels == 6 ) { 648 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC)) 649 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) { 650 flags |= PCM_QUAD; 651 } else { 652 flags |= PCM_5POINT1; 653 } 654 } 655#endif 656 else { 657 flags |= PCM_STEREO; 658 } 659 if (deviceName(handle, flags, &devName) < 0) { 660 ALOGE("Failed to get pcm device node: %s", devName); 661 return NO_INIT; 662 } 663 if (devName != NULL) { 664 handle->handle = pcm_open(flags, (char*)devName); 665 } else { 666 ALOGE("Failed to get pcm device node"); 667 return NO_INIT; 668 } 669 670 if (!handle->handle) { 671 ALOGE("s_open: Failed to initialize ALSA device '%s'", devName); 672 free(devName); 673 return NO_INIT; 674 } 675 676 handle->handle->flags = flags; 677 err = setHardwareParams(handle); 678 679 if (err == NO_ERROR) { 680 err = setSoftwareParams(handle); 681 } 682 683 if(err != NO_ERROR) { 684 ALOGE("Set HW/SW params failed: Closing the pcm stream"); 685 s_standby(handle); 686 } 687 688 free(devName); 689 return NO_ERROR; 690} 691 692static status_t s_start_voip_call(alsa_handle_t *handle) 693{ 694 695 char* devName; 696 char* devName1; 697 unsigned flags = 0; 698 int err = NO_ERROR; 699 uint8_t voc_pkt[VOIP_BUFFER_MAX_SIZE]; 700 701 s_close(handle); 702 flags = PCM_OUT; 703 flags |= PCM_MONO; 704 ALOGV("s_open:s_start_voip_call handle %p", handle); 705 706 if (deviceName(handle, flags, &devName) < 0) { 707 ALOGE("Failed to get pcm device node"); 708 return NO_INIT; 709 } 710 711 if (devName != NULL) { 712 handle->handle = pcm_open(flags, (char*)devName); 713 } else { 714 ALOGE("Failed to get pcm device node"); 715 return NO_INIT; 716 } 717 718 if (!handle->handle) { 719 free(devName); 720 ALOGE("s_open: Failed to initialize ALSA device '%s'", devName); 721 return NO_INIT; 722 } 723 724 if (!pcm_ready(handle->handle)) { 725 ALOGE(" pcm ready failed"); 726 } 727 728 handle->handle->flags = flags; 729 err = setHardwareParams(handle); 730 731 if (err == NO_ERROR) { 732 err = setSoftwareParams(handle); 733 } 734 735 err = pcm_prepare(handle->handle); 736 if(err != NO_ERROR) { 737 ALOGE("DEVICE_OUT_DIRECTOUTPUT: pcm_prepare failed"); 738 } 739 740 /* first write required start dsp */ 741 memset(&voc_pkt,0,sizeof(voc_pkt)); 742 pcm_write(handle->handle,&voc_pkt,handle->handle->period_size); 743 handle->rxHandle = handle->handle; 744 free(devName); 745 ALOGV("s_open: DEVICE_IN_COMMUNICATION "); 746 flags = PCM_IN; 747 flags |= PCM_MONO; 748 handle->handle = 0; 749 750 if (deviceName(handle, flags, &devName1) < 0) { 751 ALOGE("Failed to get pcm device node"); 752 return NO_INIT; 753 } 754 if (devName != NULL) { 755 handle->handle = pcm_open(flags, (char*)devName1); 756 } else { 757 ALOGE("Failed to get pcm device node"); 758 return NO_INIT; 759 } 760 761 if (!handle->handle) { 762 free(devName); 763 ALOGE("s_open: Failed to initialize ALSA device '%s'", devName); 764 return NO_INIT; 765 } 766 767 if (!pcm_ready(handle->handle)) { 768 ALOGE(" pcm ready in failed"); 769 } 770 771 handle->handle->flags = flags; 772 773 err = setHardwareParams(handle); 774 775 if (err == NO_ERROR) { 776 err = setSoftwareParams(handle); 777 } 778 779 780 err = pcm_prepare(handle->handle); 781 if(err != NO_ERROR) { 782 ALOGE("DEVICE_IN_COMMUNICATION: pcm_prepare failed"); 783 } 784 785 /* first read required start dsp */ 786 memset(&voc_pkt,0,sizeof(voc_pkt)); 787 pcm_read(handle->handle,&voc_pkt,handle->handle->period_size); 788 return NO_ERROR; 789} 790 791static status_t s_start_voice_call(alsa_handle_t *handle) 792{ 793 char* devName; 794 unsigned flags = 0; 795 int err = NO_ERROR; 796 797 ALOGV("s_start_voice_call: handle %p", handle); 798 799 // ASoC multicomponent requires a valid path (frontend/backend) for 800 // the device to be opened 801 802 flags = PCM_OUT | PCM_MONO; 803 if (deviceName(handle, flags, &devName) < 0) { 804 ALOGE("Failed to get pcm device node"); 805 return NO_INIT; 806 } 807 if (devName != NULL) { 808 handle->handle = pcm_open(flags, (char*)devName); 809 } else { 810 ALOGE("Failed to get pcm device node"); 811 return NO_INIT; 812 } 813 if (!handle->handle) { 814 ALOGE("s_start_voicecall: could not open PCM device"); 815 goto Error; 816 } 817 818 handle->handle->flags = flags; 819 err = setHardwareParams(handle); 820 if(err != NO_ERROR) { 821 ALOGE("s_start_voice_call: setHardwareParams failed"); 822 goto Error; 823 } 824 825 err = setSoftwareParams(handle); 826 if(err != NO_ERROR) { 827 ALOGE("s_start_voice_call: setSoftwareParams failed"); 828 goto Error; 829 } 830 831 err = pcm_prepare(handle->handle); 832 if(err != NO_ERROR) { 833 ALOGE("s_start_voice_call: pcm_prepare failed"); 834 goto Error; 835 } 836 837 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) { 838 ALOGE("s_start_voice_call:SNDRV_PCM_IOCTL_START failed\n"); 839 goto Error; 840 } 841 842 // Store the PCM playback device pointer in rxHandle 843 handle->rxHandle = handle->handle; 844 free(devName); 845 846 // Open PCM capture device 847 flags = PCM_IN | PCM_MONO; 848 if (deviceName(handle, flags, &devName) < 0) { 849 ALOGE("Failed to get pcm device node"); 850 goto Error; 851 } 852 if (devName != NULL) { 853 handle->handle = pcm_open(flags, (char*)devName); 854 } else { 855 ALOGE("Failed to get pcm device node"); 856 return NO_INIT; 857 } 858 if (!handle->handle) { 859 free(devName); 860 goto Error; 861 } 862 863 handle->handle->flags = flags; 864 err = setHardwareParams(handle); 865 if(err != NO_ERROR) { 866 ALOGE("s_start_voice_call: setHardwareParams failed"); 867 goto Error; 868 } 869 870 err = setSoftwareParams(handle); 871 if(err != NO_ERROR) { 872 ALOGE("s_start_voice_call: setSoftwareParams failed"); 873 goto Error; 874 } 875 876 err = pcm_prepare(handle->handle); 877 if(err != NO_ERROR) { 878 ALOGE("s_start_voice_call: pcm_prepare failed"); 879 goto Error; 880 } 881 882 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) { 883 ALOGE("s_start_voice_call:SNDRV_PCM_IOCTL_START failed\n"); 884 goto Error; 885 } 886 887 if (platform_is_Fusion3()) { 888#ifdef QCOM_CSDCLIENT_ENABLED 889 if (csd_start_voice == NULL) { 890 ALOGE("dlsym:Error:%s Loading csd_client_start_voice", dlerror()); 891 } else { 892 err = csd_start_voice(); 893 if (err < 0){ 894 ALOGE("s_start_voice_call: csd_client error %d\n", err); 895 goto Error; 896 } 897 } 898#endif 899 } 900 901 free(devName); 902 return NO_ERROR; 903 904Error: 905 ALOGE("s_start_voice_call: Failed to initialize ALSA device '%s'", devName); 906 free(devName); 907 s_close(handle); 908 return NO_INIT; 909} 910 911static status_t s_start_fm(alsa_handle_t *handle) 912{ 913 char *devName; 914 unsigned flags = 0; 915 int err = NO_ERROR; 916 917 ALOGV("s_start_fm: handle %p", handle); 918 919 // ASoC multicomponent requires a valid path (frontend/backend) for 920 // the device to be opened 921 922 flags = PCM_OUT | PCM_STEREO; 923 if (deviceName(handle, flags, &devName) < 0) { 924 ALOGE("Failed to get pcm device node"); 925 goto Error; 926 } 927 if (devName != NULL) { 928 handle->handle = pcm_open(flags, (char*)devName); 929 } else { 930 ALOGE("Failed to get pcm device node"); 931 return NO_INIT; 932 } 933 if (!handle->handle) { 934 ALOGE("s_start_fm: could not open PCM device"); 935 goto Error; 936 } 937 938 handle->handle->flags = flags; 939 err = setHardwareParams(handle); 940 if(err != NO_ERROR) { 941 ALOGE("s_start_fm: setHardwareParams failed"); 942 goto Error; 943 } 944 945 err = setSoftwareParams(handle); 946 if(err != NO_ERROR) { 947 ALOGE("s_start_fm: setSoftwareParams failed"); 948 goto Error; 949 } 950 951 err = pcm_prepare(handle->handle); 952 if(err != NO_ERROR) { 953 ALOGE("s_start_fm: setSoftwareParams failed"); 954 goto Error; 955 } 956 957 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) { 958 ALOGE("s_start_fm: SNDRV_PCM_IOCTL_START failed\n"); 959 goto Error; 960 } 961 962 // Store the PCM playback device pointer in rxHandle 963 handle->rxHandle = handle->handle; 964 free(devName); 965 966 // Open PCM capture device 967 flags = PCM_IN | PCM_STEREO; 968 if (deviceName(handle, flags, &devName) < 0) { 969 ALOGE("Failed to get pcm device node"); 970 goto Error; 971 } 972 if (devName != NULL) { 973 handle->handle = pcm_open(flags, (char*)devName); 974 } else { 975 ALOGE("Failed to get pcm device node"); 976 return NO_INIT; 977 } 978 if (!handle->handle) { 979 goto Error; 980 } 981 982 handle->handle->flags = flags; 983 err = setHardwareParams(handle); 984 if(err != NO_ERROR) { 985 ALOGE("s_start_fm: setHardwareParams failed"); 986 goto Error; 987 } 988 989 err = setSoftwareParams(handle); 990 if(err != NO_ERROR) { 991 ALOGE("s_start_fm: setSoftwareParams failed"); 992 goto Error; 993 } 994 995 err = pcm_prepare(handle->handle); 996 if(err != NO_ERROR) { 997 ALOGE("s_start_fm: pcm_prepare failed"); 998 goto Error; 999 } 1000 1001 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) { 1002 ALOGE("s_start_fm: SNDRV_PCM_IOCTL_START failed\n"); 1003 goto Error; 1004 } 1005 1006 s_set_fm_vol(fmVolume); 1007 free(devName); 1008 return NO_ERROR; 1009 1010Error: 1011 free(devName); 1012 s_close(handle); 1013 return NO_INIT; 1014} 1015 1016static status_t s_set_fm_vol(int value) 1017{ 1018 status_t err = NO_ERROR; 1019 1020 ALSAControl control("/dev/snd/controlC0"); 1021 control.set("Internal FM RX Volume",value,0); 1022 fmVolume = value; 1023 1024 return err; 1025} 1026 1027static status_t s_set_lpa_vol(int value) 1028{ 1029 status_t err = NO_ERROR; 1030 1031 ALSAControl control("/dev/snd/controlC0"); 1032 control.set("LPA RX Volume",value,0); 1033 1034 return err; 1035} 1036 1037static status_t s_start(alsa_handle_t *handle) 1038{ 1039 status_t err = NO_ERROR; 1040 1041 if(!handle->handle) { 1042 ALOGE("No active PCM driver to start"); 1043 return err; 1044 } 1045 1046 err = pcm_prepare(handle->handle); 1047 1048 return err; 1049} 1050 1051static status_t s_close(alsa_handle_t *handle) 1052{ 1053 int ret; 1054 status_t err = NO_ERROR; 1055 struct pcm *h = handle->rxHandle; 1056 1057 handle->rxHandle = 0; 1058 ALOGV("s_close: handle %p h %p", handle, h); 1059 if (h) { 1060 ALOGV("s_close rxHandle\n"); 1061 err = pcm_close(h); 1062 if(err != NO_ERROR) { 1063 ALOGE("s_close: pcm_close failed for rxHandle with err %d", err); 1064 } 1065 } 1066 1067 h = handle->handle; 1068 handle->handle = 0; 1069 1070 if (h) { 1071 ALOGV("s_close handle h %p\n", h); 1072 err = pcm_close(h); 1073 if(err != NO_ERROR) { 1074 ALOGE("s_close: pcm_close failed for handle with err %d", err); 1075 } 1076 1077 if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_VOICECALL) || 1078 !strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_VOICE)) && 1079 platform_is_Fusion3()) { 1080#ifdef QCOM_CSDCLIENT_ENABLED 1081 if (csd_stop_voice == NULL) { 1082 ALOGE("dlsym:Error:%s Loading csd_client_disable_device", dlerror()); 1083 } else { 1084 err = csd_stop_voice(); 1085 if (err < 0) { 1086 ALOGE("s_close: csd_client error %d\n", err); 1087 } 1088 } 1089#endif 1090 } 1091 1092 disableDevice(handle); 1093 } else if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) || 1094 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) || 1095 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) || 1096 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))){ 1097 disableDevice(handle); 1098 } 1099 1100 return err; 1101} 1102 1103/* 1104 this is same as s_close, but don't discard 1105 the device/mode info. This way we can still 1106 close the device, hit idle and power-save, reopen the pcm 1107 for the same device/mode after resuming 1108*/ 1109static status_t s_standby(alsa_handle_t *handle) 1110{ 1111 int ret; 1112 status_t err = NO_ERROR; 1113 struct pcm *h = handle->rxHandle; 1114 handle->rxHandle = 0; 1115 ALOGV("s_standby: handle %p h %p", handle, h); 1116 if (h) { 1117 ALOGD("s_standby rxHandle\n"); 1118 err = pcm_close(h); 1119 if(err != NO_ERROR) { 1120 ALOGE("s_standby: pcm_close failed for rxHandle with err %d", err); 1121 } 1122 } 1123 1124 h = handle->handle; 1125 handle->handle = 0; 1126 1127 if (h) { 1128 ALOGV("s_standby handle h %p\n", h); 1129 err = pcm_close(h); 1130 if(err != NO_ERROR) { 1131 ALOGE("s_standby: pcm_close failed for handle with err %d", err); 1132 } 1133 disableDevice(handle); 1134 } else if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) || 1135 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) || 1136 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) || 1137 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) { 1138 disableDevice(handle); 1139 } 1140 1141 return err; 1142} 1143 1144static status_t s_route(alsa_handle_t *handle, uint32_t devices, int mode) 1145{ 1146 status_t status = NO_ERROR; 1147 1148 ALOGD("s_route: devices 0x%x in mode %d", devices, mode); 1149 callMode = mode; 1150 switchDevice(handle, devices, mode); 1151 return status; 1152} 1153 1154int getUseCaseType(const char *useCase) 1155{ 1156 ALOGD("use case is %s\n", useCase); 1157 if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI, 1158 strlen(SND_USE_CASE_VERB_HIFI)) || 1159 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC, 1160 strlen(SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) || 1161 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER, 1162 strlen(SND_USE_CASE_VERB_HIFI_LOW_POWER)) || 1163 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_TUNNEL, 1164 strlen(SND_USE_CASE_VERB_HIFI_TUNNEL)) || 1165 !strncmp(useCase, SND_USE_CASE_VERB_DIGITAL_RADIO, 1166 strlen(SND_USE_CASE_VERB_DIGITAL_RADIO)) || 1167 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC, 1168 strlen(SND_USE_CASE_MOD_PLAY_MUSIC)) || 1169 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC, 1170 strlen(SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) || 1171 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LPA, 1172 strlen(SND_USE_CASE_MOD_PLAY_LPA)) || 1173 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_TUNNEL, 1174 strlen(SND_USE_CASE_MOD_PLAY_TUNNEL)) || 1175 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_FM, 1176 strlen(SND_USE_CASE_MOD_PLAY_FM))) { 1177 return USECASE_TYPE_RX; 1178 } else if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI_REC, 1179 strlen(SND_USE_CASE_VERB_HIFI_REC)) || 1180 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC, 1181 strlen(SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC)) || 1182 !strncmp(useCase, SND_USE_CASE_VERB_FM_REC, 1183 strlen(SND_USE_CASE_VERB_FM_REC)) || 1184 !strncmp(useCase, SND_USE_CASE_VERB_FM_A2DP_REC, 1185 strlen(SND_USE_CASE_VERB_FM_A2DP_REC)) || 1186 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, 1187 strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC)) || 1188 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC, 1189 strlen(SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC)) || 1190 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_FM, 1191 strlen(SND_USE_CASE_MOD_CAPTURE_FM)) || 1192 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM, 1193 strlen(SND_USE_CASE_MOD_CAPTURE_A2DP_FM))) { 1194 return USECASE_TYPE_TX; 1195 } else if (!strncmp(useCase, SND_USE_CASE_VERB_VOICECALL, 1196 strlen(SND_USE_CASE_VERB_VOICECALL)) || 1197 !strncmp(useCase, SND_USE_CASE_VERB_IP_VOICECALL, 1198 strlen(SND_USE_CASE_VERB_IP_VOICECALL)) || 1199 !strncmp(useCase, SND_USE_CASE_VERB_DL_REC, 1200 strlen(SND_USE_CASE_VERB_DL_REC)) || 1201 !strncmp(useCase, SND_USE_CASE_VERB_UL_DL_REC, 1202 strlen(SND_USE_CASE_VERB_UL_DL_REC)) || 1203 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOICE, 1204 strlen(SND_USE_CASE_MOD_PLAY_VOICE)) || 1205 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOIP, 1206 strlen(SND_USE_CASE_MOD_PLAY_VOIP)) || 1207 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL, 1208 strlen(SND_USE_CASE_MOD_CAPTURE_VOICE_DL)) || 1209 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL, 1210 strlen(SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL)) || 1211 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE, 1212 strlen(SND_USE_CASE_MOD_CAPTURE_VOICE)) || 1213 !strncmp(useCase, SND_USE_CASE_VERB_VOLTE, 1214 strlen(SND_USE_CASE_VERB_VOLTE)) || 1215 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOLTE, 1216 strlen(SND_USE_CASE_MOD_PLAY_VOLTE))) { 1217 return (USECASE_TYPE_RX | USECASE_TYPE_TX); 1218 } else { 1219 ALOGE("unknown use case %s\n", useCase); 1220 return 0; 1221 } 1222} 1223 1224static void disableDevice(alsa_handle_t *handle) 1225{ 1226 unsigned usecase_type = 0; 1227 int i, mods_size; 1228 char *useCase; 1229 const char **mods_list; 1230 1231 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase); 1232 if (useCase != NULL) { 1233 if (!strncmp(useCase, handle->useCase, MAX_UC_LEN)) { 1234 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE); 1235 } else { 1236 snd_use_case_set(handle->ucMgr, "_dismod", handle->useCase); 1237 } 1238 free(useCase); 1239 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase); 1240 if (strncmp(useCase, SND_USE_CASE_VERB_INACTIVE, 1241 strlen(SND_USE_CASE_VERB_INACTIVE))) 1242 usecase_type |= getUseCaseType(useCase); 1243 mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list); 1244 ALOGV("Number of modifiers %d\n", mods_size); 1245 if (mods_size) { 1246 for(i = 0; i < mods_size; i++) { 1247 ALOGV("index %d modifier %s\n", i, mods_list[i]); 1248 usecase_type |= getUseCaseType(mods_list[i]); 1249 } 1250 } 1251 ALOGV("usecase_type is %d\n", usecase_type); 1252 if (!(usecase_type & USECASE_TYPE_TX) && (strncmp(curTxUCMDevice, "None", 4))) 1253 snd_use_case_set(handle->ucMgr, "_disdev", curTxUCMDevice); 1254 if (!(usecase_type & USECASE_TYPE_RX) && (strncmp(curRxUCMDevice, "None", 4))) 1255 snd_use_case_set(handle->ucMgr, "_disdev", curRxUCMDevice); 1256 } else { 1257 ALOGE("Invalid state, no valid use case found to disable"); 1258 } 1259 free(useCase); 1260} 1261 1262char *getUCMDevice(uint32_t devices, int input, char *rxDevice) 1263{ 1264 if (!input) { 1265 if (!(mDevSettingsFlag & TTY_OFF) && 1266 (callMode == AudioSystem::MODE_IN_CALL) && 1267 ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) || 1268 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) { 1269#ifdef QCOM_ANC_HEADSET_ENABLED 1270 || 1271 (devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) || 1272 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) { 1273#endif 1274 if (mDevSettingsFlag & TTY_VCO) { 1275 return strdup(SND_USE_CASE_DEV_TTY_HEADSET_RX); 1276 } else if (mDevSettingsFlag & TTY_FULL) { 1277 return strdup(SND_USE_CASE_DEV_TTY_FULL_RX); 1278 } else if (mDevSettingsFlag & TTY_HCO) { 1279 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_RX); /* HANDSET RX */ 1280 } 1281 }else if ((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET) || 1282 (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)) { 1283 return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */ 1284 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) && 1285 ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) || 1286 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) { 1287 if (mDevSettingsFlag & ANC_FLAG) { 1288 return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */ 1289 } else { 1290 return strdup(SND_USE_CASE_DEV_SPEAKER_HEADSET); /* COMBO SPEAKER+HEADSET RX */ 1291 } 1292#ifdef QCOM_ANC_HEADSET_ENABLED 1293 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) && 1294 ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) || 1295 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) { 1296 return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */ 1297 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) && 1298 (devices & AudioSystem::DEVICE_OUT_FM_TX)) { 1299 return strdup(SND_USE_CASE_DEV_SPEAKER_FM_TX); /* COMBO SPEAKER+FM_TX RX */ 1300#endif 1301 } else if (devices & AudioSystem::DEVICE_OUT_EARPIECE) { 1302 if (callMode == AudioSystem::MODE_IN_CALL) { 1303 return strdup(SND_USE_CASE_DEV_VOC_EARPIECE); /* Voice HANDSET RX */ 1304 } else 1305 return strdup(SND_USE_CASE_DEV_EARPIECE); /* HANDSET RX */ 1306 } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) { 1307 if (callMode == AudioSystem::MODE_IN_CALL) { 1308 return strdup(SND_USE_CASE_DEV_VOC_SPEAKER); /* Voice SPEAKER RX */ 1309 } else 1310 return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */ 1311 } else if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) || 1312 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) { 1313 if (mDevSettingsFlag & ANC_FLAG) { 1314 if (callMode == AudioSystem::MODE_IN_CALL) { 1315 return strdup(SND_USE_CASE_DEV_VOC_ANC_HEADSET); /* Voice ANC HEADSET RX */ 1316 } else 1317 return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */ 1318 } else { 1319 if (callMode == AudioSystem::MODE_IN_CALL) { 1320 return strdup(SND_USE_CASE_DEV_VOC_HEADPHONE); /* Voice HEADSET RX */ 1321 } else 1322 return strdup(SND_USE_CASE_DEV_HEADPHONES); /* HEADSET RX */ 1323 } 1324#ifdef QCOM_ANC_HEADSET_ENABLED 1325 } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) || 1326 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE)) { 1327 if (callMode == AudioSystem::MODE_IN_CALL) { 1328 return strdup(SND_USE_CASE_DEV_VOC_ANC_HEADSET); /* Voice ANC HEADSET RX */ 1329 } else 1330 return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */ 1331#endif 1332 } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) || 1333 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) || 1334 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT)) { 1335 if (btsco_samplerate == BTSCO_RATE_16KHZ) 1336 return strdup(SND_USE_CASE_DEV_BTSCO_WB_RX); /* BTSCO RX*/ 1337 else 1338 return strdup(SND_USE_CASE_DEV_BTSCO_NB_RX); /* BTSCO RX*/ 1339 } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP) || 1340 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES) || 1341#ifdef QCOM_VOIP_ENABLED 1342 (devices & AudioSystem::DEVICE_OUT_DIRECTOUTPUT) || 1343#endif 1344 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) { 1345 /* Nothing to be done, use current active device */ 1346 if (strncmp(curRxUCMDevice, "None", 4)) { 1347 return strdup(curRxUCMDevice); 1348 } 1349 } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) { 1350 return strdup(SND_USE_CASE_DEV_HDMI); /* HDMI RX */ 1351#ifdef QCOM_PROXY_DEVICE_ENABLED 1352 } else if (devices & AudioSystem::DEVICE_OUT_PROXY) { 1353 return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */ 1354#endif 1355#ifdef QCOM_FM_TX_ENABLED 1356 } else if (devices & AudioSystem::DEVICE_OUT_FM_TX) { 1357 return strdup(SND_USE_CASE_DEV_FM_TX); /* FM Tx */ 1358#endif 1359 } else if (devices & AudioSystem::DEVICE_OUT_DEFAULT) { 1360 if (callMode == AudioSystem::MODE_IN_CALL) { 1361 return strdup(SND_USE_CASE_DEV_VOC_SPEAKER); /* Voice SPEAKER RX */ 1362 } else 1363 return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */ 1364 } else { 1365 ALOGD("No valid output device: %u", devices); 1366 } 1367 } else { 1368 if (!(mDevSettingsFlag & TTY_OFF) && 1369 (callMode == AudioSystem::MODE_IN_CALL) && 1370 ((devices & AudioSystem::DEVICE_IN_WIRED_HEADSET))) { 1371#ifdef QCOM_ANC_HEADSET_ENABLED 1372 ||(devices & AudioSystem::DEVICE_IN_ANC_HEADSET))) { 1373#endif 1374 if (mDevSettingsFlag & TTY_HCO) { 1375 return strdup(SND_USE_CASE_DEV_TTY_HEADSET_TX); 1376 } else if (mDevSettingsFlag & TTY_FULL) { 1377 return strdup(SND_USE_CASE_DEV_TTY_FULL_TX); 1378 } else if (mDevSettingsFlag & TTY_VCO) { 1379 if (!strncmp(mic_type, "analog", 6)) { 1380 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_ANALOG_TX); 1381 } else { 1382 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_TX); 1383 } 1384 } 1385 } else if (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) { 1386 if (!strncmp(mic_type, "analog", 6)) { 1387 return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */ 1388 } else { 1389 if (mDevSettingsFlag & DMIC_FLAG) { 1390#ifdef USES_FLUENCE_INCALL 1391 if(callMode == AudioSystem::MODE_IN_CALL) { 1392 if (fluence_mode == FLUENCE_MODE_ENDFIRE) { 1393 return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */ 1394 } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) { 1395 return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */ 1396 } else { 1397 return strdup(SND_USE_CASE_DEV_HANDSET); /* BUILTIN-MIC TX */ 1398 } 1399 } 1400#else 1401 if (((rxDevice != NULL) && 1402 !strncmp(rxDevice, SND_USE_CASE_DEV_SPEAKER, 1403 (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) || 1404 !strncmp(curRxUCMDevice, SND_USE_CASE_DEV_SPEAKER, 1405 (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) { 1406 if (fluence_mode == FLUENCE_MODE_ENDFIRE) { 1407 return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */ 1408 } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) { 1409 return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */ 1410 } 1411 } else { 1412 if (fluence_mode == FLUENCE_MODE_ENDFIRE) { 1413 return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */ 1414 } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) { 1415 return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */ 1416 } 1417 } 1418#endif 1419 } else if (mDevSettingsFlag & QMIC_FLAG){ 1420 return strdup(SND_USE_CASE_DEV_QUAD_MIC); 1421 } 1422#ifdef QCOM_SSR_ENABLED 1423 else if (mDevSettingsFlag & SSRQMIC_FLAG){ 1424 ALOGV("return SSRQMIC_FLAG: 0x%x devices:0x%x",mDevSettingsFlag,devices); 1425 // Mapping for quad mic input device. 1426 return strdup(SND_USE_CASE_DEV_SSR_QUAD_MIC); /* SSR Quad MIC */ 1427 } 1428#endif 1429#ifdef SEPERATED_AUDIO_INPUT 1430 if(input_source == AUDIO_SOURCE_VOICE_RECOGNITION) { 1431 return strdup(SND_USE_CASE_DEV_VOICE_RECOGNITION ); /* VOICE RECOGNITION TX */ 1432 } else if(input_source == AUDIO_SOURCE_CAMCORDER) { 1433 return strdup(SND_USE_CASE_DEV_CAMCORDER_TX ); /* CAMCORDER TX */ 1434 } 1435#endif 1436 else { 1437 return strdup(SND_USE_CASE_DEV_HANDSET); /* BUILTIN-MIC TX */ 1438 } 1439 } 1440 } else if (devices & AudioSystem::DEVICE_IN_AUX_DIGITAL) { 1441 return strdup(SND_USE_CASE_DEV_HDMI_TX); /* HDMI TX */ 1442#ifdef QCOM_ANC_HEADSET_ENABLED 1443 } else if (devices & AudioSystem::DEVICE_IN_ANC_HEADSET) { 1444 return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */ 1445#endif 1446 } else if (devices & AudioSystem::DEVICE_IN_WIRED_HEADSET) { 1447 if (callMode == AudioSystem::MODE_IN_CALL) { 1448 return strdup(SND_USE_CASE_DEV_VOC_HEADSET); /* Voice HEADSET TX */ 1449 } else 1450 return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */ 1451 } else if (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 1452 if (btsco_samplerate == BTSCO_RATE_16KHZ) 1453 return strdup(SND_USE_CASE_DEV_BTSCO_WB_TX); /* BTSCO TX*/ 1454 else 1455 return strdup(SND_USE_CASE_DEV_BTSCO_NB_TX); /* BTSCO TX*/ 1456#ifdef QCOM_USBAUDIO_ENABLED 1457 } else if ((devices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) || 1458 (devices & AudioSystem::DEVICE_IN_PROXY)) { 1459 return strdup(SND_USE_CASE_DEV_PROXY_TX); /* PROXY TX */ 1460#endif 1461 } else if ((devices & AudioSystem::DEVICE_IN_COMMUNICATION) || 1462 (devices & AudioSystem::DEVICE_IN_VOICE_CALL)) { 1463 /* Nothing to be done, use current active device */ 1464 if (strncmp(curTxUCMDevice, "None", 4)) { 1465 return strdup(curTxUCMDevice); 1466 } 1467#ifdef QCOM_FM_ENABLED 1468 } else if ((devices & AudioSystem::DEVICE_IN_FM_RX) || 1469 (devices & AudioSystem::DEVICE_IN_FM_RX_A2DP)) { 1470 /* Nothing to be done, use current tx device or set dummy device */ 1471 if (strncmp(curTxUCMDevice, "None", 4)) { 1472 return strdup(curTxUCMDevice); 1473 } else { 1474 return strdup(SND_USE_CASE_DEV_DUMMY_TX); 1475 } 1476#endif 1477 } else if ((devices & AudioSystem::DEVICE_IN_AMBIENT) || 1478 (devices & AudioSystem::DEVICE_IN_BACK_MIC)) { 1479 ALOGI("No proper mapping found with UCM device list, setting default"); 1480 if (!strncmp(mic_type, "analog", 6)) { 1481 return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */ 1482 } else { 1483 if (callMode == AudioSystem::MODE_IN_CALL) { 1484 return strdup(SND_USE_CASE_DEV_VOC_LINE); /* Voice BUILTIN-MIC TX */ 1485 } else 1486 return strdup(SND_USE_CASE_DEV_LINE); /* BUILTIN-MIC TX */ 1487 } 1488 } else { 1489 ALOGD("No valid input device: %u", devices); 1490 } 1491 } 1492 return NULL; 1493} 1494 1495void s_set_voice_volume(int vol) 1496{ 1497 int err = 0; 1498 ALOGV("s_set_voice_volume: volume %d", vol); 1499 ALSAControl control("/dev/snd/controlC0"); 1500 control.set("Voice Rx Volume", vol, 0); 1501 1502 if (platform_is_Fusion3()) { 1503#ifdef QCOM_CSDCLIENT_ENABLED 1504 if (csd_volume == NULL) { 1505 ALOGE("dlsym:Error:%s Loading csd_client_volume", dlerror()); 1506 } else { 1507 err = csd_volume(vol); 1508 if (err < 0) { 1509 ALOGE("s_set_voice_volume: csd_client error %d", err); 1510 } 1511 } 1512#endif 1513 } 1514} 1515 1516void s_set_volte_volume(int vol) 1517{ 1518 ALOGV("s_set_volte_volume: volume %d", vol); 1519 ALSAControl control("/dev/snd/controlC0"); 1520 control.set("VoLTE Rx Volume", vol, 0); 1521} 1522 1523 1524void s_set_voip_volume(int vol) 1525{ 1526 ALOGV("s_set_voip_volume: volume %d", vol); 1527 ALSAControl control("/dev/snd/controlC0"); 1528 control.set("Voip Rx Volume", vol, 0); 1529} 1530void s_set_mic_mute(int state) 1531{ 1532 int err = 0; 1533 ALOGV("s_set_mic_mute: state %d", state); 1534 ALSAControl control("/dev/snd/controlC0"); 1535 control.set("Voice Tx Mute", state, 0); 1536 1537 if (platform_is_Fusion3()) { 1538#ifdef QCOM_CSDCLIENT_ENABLED 1539 if (csd_mic_mute == NULL) { 1540 ALOGE("dlsym:Error:%s Loading csd_mic_mute", dlerror()); 1541 } else { 1542 err=csd_mic_mute(state); 1543 if (err < 0) { 1544 ALOGE("s_set_mic_mute: csd_client error %d", err); 1545 } 1546 } 1547#endif 1548 } 1549} 1550void s_set_volte_mic_mute(int state) 1551{ 1552 ALOGV("s_set_volte_mic_mute: state %d", state); 1553 ALSAControl control("/dev/snd/controlC0"); 1554 control.set("VoLTE Tx Mute", state, 0); 1555} 1556 1557void s_set_voip_mic_mute(int state) 1558{ 1559 ALOGV("s_set_voip_mic_mute: state %d", state); 1560 ALSAControl control("/dev/snd/controlC0"); 1561 control.set("Voip Tx Mute", state, 0); 1562} 1563 1564void s_set_voip_config(int mode, int rate) 1565{ 1566 ALOGV("s_set_voip_config: mode %d,rate %d", mode, rate); 1567 ALSAControl control("/dev/snd/controlC0"); 1568 char** setValues; 1569 setValues = (char**)malloc(2*sizeof(char*)); 1570 if (setValues == NULL) { 1571 return; 1572 } 1573 setValues[0] = (char*)malloc(4*sizeof(char)); 1574 if (setValues[0] == NULL) { 1575 free(setValues); 1576 return; 1577 } 1578 1579 setValues[1] = (char*)malloc(8*sizeof(char)); 1580 if (setValues[1] == NULL) { 1581 free(setValues); 1582 free(setValues[0]); 1583 return; 1584 } 1585 1586 sprintf(setValues[0], "%d",mode); 1587 sprintf(setValues[1], "%d",rate); 1588 1589 control.setext("Voip Mode Rate Config", 2, setValues); 1590 free(setValues[1]); 1591 free(setValues[0]); 1592 free(setValues); 1593 return; 1594} 1595 1596void s_set_btsco_rate(int rate) 1597{ 1598 btsco_samplerate = rate; 1599} 1600 1601void s_enable_wide_voice(bool flag) 1602{ 1603 int err = 0; 1604 1605 ALOGV("s_enable_wide_voice: flag %d", flag); 1606 ALSAControl control("/dev/snd/controlC0"); 1607 if(flag == true) { 1608 control.set("Widevoice Enable", 1, 0); 1609 } else { 1610 control.set("Widevoice Enable", 0, 0); 1611 } 1612 1613 if (platform_is_Fusion3()) { 1614#ifdef QCOM_CSDCLIENT_ENABLED 1615 if (csd_wide_voice == NULL) { 1616 ALOGE("dlsym:Error:%s Loading csd_wide_voice", dlerror()); 1617 } else { 1618 err = csd_wide_voice(flag); 1619 if (err < 0) { 1620 ALOGE("enableWideVoice: csd_client_wide_voice error %d", err); 1621 } 1622 } 1623#endif 1624 } 1625} 1626 1627void s_set_voc_rec_mode(uint8_t mode) 1628{ 1629 ALOGV("s_set_voc_rec_mode: mode %d", mode); 1630 ALSAControl control("/dev/snd/controlC0"); 1631 control.set("Incall Rec Mode", mode, 0); 1632} 1633 1634void s_enable_fens(bool flag) 1635{ 1636 int err = 0; 1637 1638 ALOGV("s_enable_fens: flag %d", flag); 1639 ALSAControl control("/dev/snd/controlC0"); 1640 if(flag == true) { 1641 control.set("FENS Enable", 1, 0); 1642 } else { 1643 control.set("FENS Enable", 0, 0); 1644 } 1645 1646 if (platform_is_Fusion3()) { 1647#ifdef QCOM_CSDCLIENT_ENABLED 1648 if (csd_fens == NULL) { 1649 ALOGE("dlsym:Error:%s Loading csd_fens", dlerror()); 1650 } else { 1651 err = csd_fens(flag); 1652 if (err < 0) { 1653 ALOGE("s_enable_fens: csd_client error %d", err); 1654 } 1655 } 1656#endif 1657 } 1658} 1659 1660void s_enable_slow_talk(bool flag) 1661{ 1662 int err = 0; 1663 1664 ALOGV("s_enable_slow_talk: flag %d", flag); 1665 ALSAControl control("/dev/snd/controlC0"); 1666 if(flag == true) { 1667 control.set("Slowtalk Enable", 1, 0); 1668 } else { 1669 control.set("Slowtalk Enable", 0, 0); 1670 } 1671 1672 if (platform_is_Fusion3()) { 1673#ifdef QCOM_CSDCLIENT_ENABLED 1674 if (csd_slow_talk == NULL) { 1675 ALOGE("dlsym:Error:%s Loading csd_slow_talk", dlerror()); 1676 } else { 1677 err = csd_slow_talk(flag); 1678 if (err < 0) { 1679 ALOGE("s_enable_slow_talk: csd_client error %d", err); 1680 } 1681 } 1682#endif 1683 } 1684} 1685 1686void s_set_flags(uint32_t flags) 1687{ 1688 ALOGV("s_set_flags: flags %d", flags); 1689 mDevSettingsFlag = flags; 1690} 1691 1692static status_t s_set_compressed_vol(int value) 1693{ 1694 status_t err = NO_ERROR; 1695 1696 ALSAControl control("/dev/snd/controlC0"); 1697 control.set("COMPRESSED RX Volume",value,0); 1698 1699 return err; 1700} 1701 1702#ifdef SEPERATED_AUDIO_INPUT 1703void s_setInput(int input) 1704{ 1705 input_source = input; 1706 ALOGD("s_setInput() : input_source = %d",input_source); 1707} 1708#endif 1709 1710#ifdef QCOM_CSDCLIENT_ENABLED 1711static void s_set_csd_handle(void* handle) 1712{ 1713 csd_handle = static_cast<void*>(handle); 1714 ALOGI("%s csd_handle: %p", __func__, csd_handle); 1715 1716 csd_disable_device = (int (*)())::dlsym(csd_handle,"csd_client_disable_device"); 1717 csd_enable_device = (int (*)(int,int,uint32_t))::dlsym(csd_handle,"csd_client_enable_device"); 1718 csd_start_voice = (int (*)())::dlsym(csd_handle,"csd_client_start_voice"); 1719 csd_stop_voice = (int (*)())::dlsym(csd_handle,"csd_client_stop_voice"); 1720 csd_volume = (int (*)(int))::dlsym(csd_handle,"csd_client_volume"); 1721 csd_mic_mute = (int (*)(int))::dlsym(csd_handle,"csd_client_mic_mute"); 1722 csd_wide_voice = (int (*)(uint8_t))::dlsym(csd_handle,"csd_client_wide_voice"); 1723 csd_fens = (int (*)(uint8_t))::dlsym(csd_handle,"csd_client_fens"); 1724 csd_slow_talk = (int (*)(uint8_t))::dlsym(csd_handle,"csd_client_slow_talk"); 1725} 1726#endif 1727 1728} 1729