alsa_default.cpp revision 9746c4758b161e26eec92b1ef1ff1bf0ba0bd268
14765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* alsa_default.cpp
24765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev **
34765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** Copyright 2009 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
199746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#define LOG_TAG "ALSAModule"
204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev//#define LOG_NDEBUG 0
219746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#define LOG_NDDEBUG 0
224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <utils/Log.h>
234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <cutils/properties.h>
244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <linux/ioctl.h>
254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include "AudioHardwareALSA.h"
264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <media/AudioRecord.h>
279746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_CSDCLIENT_ENABLED
284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevextern "C" {
294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include "csd_client.h"
304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
314113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev#endif
324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#ifndef ALSA_DEFAULT_SAMPLE_RATE
344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#define ALSA_DEFAULT_SAMPLE_RATE 44100 // in Hz
354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#define BTSCO_RATE_16KHZ 16000
384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#define USECASE_TYPE_RX 1
394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#define USECASE_TYPE_TX 2
404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevnamespace android_audio_legacy
424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int      s_device_open(const hw_module_t*, const char*, hw_device_t**);
454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int      s_device_close(hw_device_t*);
464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_init(alsa_device_t *, ALSAHandleList &);
474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_open(alsa_handle_t *);
484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_close(alsa_handle_t *);
494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_standby(alsa_handle_t *);
504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_route(alsa_handle_t *, uint32_t, int);
514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_start_voice_call(alsa_handle_t *);
524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_start_voip_call(alsa_handle_t *);
534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_start_fm(alsa_handle_t *);
544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void     s_set_voice_volume(int);
554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void     s_set_voip_volume(int);
564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void     s_set_mic_mute(int);
574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void     s_set_voip_mic_mute(int);
584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void     s_set_voip_config(int, int);
594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_set_fm_vol(int);
604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void     s_set_btsco_rate(int);
614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_set_lpa_vol(int);
624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void     s_enable_wide_voice(bool flag);
634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void     s_enable_fens(bool flag);
644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void     s_set_flags(uint32_t flags);
654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_set_compressed_vol(int);
664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void     s_enable_slow_talk(bool flag);
674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void     s_set_voc_rec_mode(uint8_t mode);
684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void     s_set_volte_mic_mute(int state);
694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void     s_set_volte_volume(int vol);
704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic char mic_type[25];
724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic char curRxUCMDevice[50];
734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic char curTxUCMDevice[50];
744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int fluence_mode;
754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int fmVolume;
764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic uint32_t mDevSettingsFlag = TTY_OFF;
774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int btsco_samplerate = 8000;
784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic bool pflag = false;
794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic ALSAUseCaseList mUseCaseList;
804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic hw_module_methods_t s_module_methods = {
824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    open            : s_device_open
834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev};
844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
854113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchevextern "C" hw_module_t HAL_MODULE_INFO_SYM = {
864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    tag             : HARDWARE_MODULE_TAG,
874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    version_major   : 1,
884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    version_minor   : 0,
894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    id              : ALSA_HARDWARE_MODULE_ID,
904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    name            : "QCOM ALSA module",
914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    author          : "QuIC Inc",
924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    methods         : &s_module_methods,
934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dso             : 0,
944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    reserved        : {0,},
954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev};
964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int s_device_open(const hw_module_t* module, const char* name,
984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        hw_device_t** device)
994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
1004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char value[128];
1014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    alsa_device_t *dev;
1024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev = (alsa_device_t *) malloc(sizeof(*dev));
1034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!dev) return -ENOMEM;
1044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
1054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    memset(dev, 0, sizeof(*dev));
1064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
1074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    /* initialize the procs */
1084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->common.tag = HARDWARE_DEVICE_TAG;
1094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->common.version = 0;
1104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->common.module = (hw_module_t *) module;
1114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->common.close = s_device_close;
1124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->init = s_init;
1134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->open = s_open;
1144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->close = s_close;
1154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->route = s_route;
1164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->standby = s_standby;
1174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->startVoiceCall = s_start_voice_call;
1184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->startVoipCall = s_start_voip_call;
1194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->startFm = s_start_fm;
1204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->setVoiceVolume = s_set_voice_volume;
1214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->setVoipVolume = s_set_voip_volume;
1224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->setMicMute = s_set_mic_mute;
1234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->setVoipMicMute = s_set_voip_mic_mute;
1244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->setVoipConfig = s_set_voip_config;
1254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->setFmVolume = s_set_fm_vol;
1264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->setBtscoRate = s_set_btsco_rate;
1274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->setLpaVolume = s_set_lpa_vol;
1284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->enableWideVoice = s_enable_wide_voice;
1294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->enableFENS = s_enable_fens;
1304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->setFlags = s_set_flags;
1314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->setCompressedVolume = s_set_compressed_vol;
1324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->enableSlowTalk = s_enable_slow_talk;
1334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->setVocRecMode = s_set_voc_rec_mode;
1344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->setVoLTEMicMute = s_set_volte_mic_mute;
1354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev->setVoLTEVolume = s_set_volte_volume;
1364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
1374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    *device = &dev->common;
1384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
1394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    property_get("persist.audio.handset.mic",value,"0");
1404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(mic_type, value, sizeof(mic_type));
1414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    property_get("persist.audio.fluence.mode",value,"0");
1424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!strcmp("broadside", value)) {
1434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        fluence_mode = FLUENCE_MODE_BROADSIDE;
1444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
1454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        fluence_mode = FLUENCE_MODE_ENDFIRE;
1464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
1474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(curRxUCMDevice, "None", sizeof(curRxUCMDevice));
1484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(curTxUCMDevice, "None", sizeof(curTxUCMDevice));
1494113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("ALSA module opened");
1504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
1514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return 0;
1524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
1534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
1544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int s_device_close(hw_device_t* device)
1554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
1564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(device);
1574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    device = NULL;
1584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return 0;
1594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
1604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
1614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// ----------------------------------------------------------------------------
1624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
1634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic const int DEFAULT_SAMPLE_RATE = ALSA_DEFAULT_SAMPLE_RATE;
1644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
1654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode);
1664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic char *getUCMDevice(uint32_t devices, int input, char *rxDevice);
1674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void disableDevice(alsa_handle_t *handle);
1684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint getUseCaseType(const char *useCase);
1694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
1704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int callMode = AudioSystem::MODE_NORMAL;
1714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// ----------------------------------------------------------------------------
1724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
1734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevbool platform_is_Fusion3()
1744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
1754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char platform[128], baseband[128];
1764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    property_get("ro.board.platform", platform, "");
1774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    property_get("ro.baseband", baseband, "");
1784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband))
1794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return true;
1804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    else
1814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return false;
1824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
1834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
1844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint deviceName(alsa_handle_t *handle, unsigned flags, char **value)
1854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
1864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int ret = 0;
1874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char ident[70];
1884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
1894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (flags & PCM_IN) {
1904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcpy(ident, "CapturePCM/", sizeof(ident));
1914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
1924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcpy(ident, "PlaybackPCM/", sizeof(ident));
1934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
1944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcat(ident, handle->useCase, sizeof(ident));
1954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ret = snd_use_case_get(handle->ucMgr, ident, (const char **)value);
1964113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("Device value returned is %s", (*value));
1974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
1984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
1994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
2004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatus_t setHardwareParams(alsa_handle_t *handle)
2014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
2024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    struct snd_pcm_hw_params *params;
2034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    unsigned long bufferSize, reqBuffSize;
2044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    unsigned int periodTime, bufferTime;
2054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    unsigned int requestedRate = handle->sampleRate;
2064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int status = 0;
2074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int channels = handle->channels;
2084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    snd_pcm_format_t format = SNDRV_PCM_FORMAT_S16_LE;
2094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
2104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    params = (snd_pcm_hw_params*) calloc(1, sizeof(struct snd_pcm_hw_params));
2114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!params) {
2124113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("Failed to allocate ALSA hardware parameters!");
2134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return NO_INIT;
2144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
2154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
2164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    reqBuffSize = handle->bufferSize;
2174113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("setHardwareParams: reqBuffSize %d channels %d sampleRate %d",
2184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev         (int) reqBuffSize, handle->channels, handle->sampleRate);
2194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
2209746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_SSR_ENABLED
2214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (channels == 6) {
2224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
2234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
2244113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev            ALOGV("HWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase);
2254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            channels = 4;
2264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            reqBuffSize = DEFAULT_IN_BUFFER_SIZE;
2274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
2284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
2294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
2304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
2314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    param_init(params);
2324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS,
2334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   SNDRV_PCM_ACCESS_RW_INTERLEAVED);
2344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (handle->format != SNDRV_PCM_FORMAT_S16_LE) {
2359746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani        if (handle->format == AudioSystem::AMR_NB
2369746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani            || handle->format == AudioSystem::AMR_WB
2379746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_QCHAT_ENABLED
2389746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani            || handle->format == AudioSystem::EVRC
2399746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani            || handle->format == AudioSystem::EVRCB
2409746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani            || handle->format == AudioSystem::EVRCWB
2419746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#endif
2429746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani            )
2434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev              format = SNDRV_PCM_FORMAT_SPECIAL;
2444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
2454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   format);
2474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    param_set_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT,
2484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   SNDRV_PCM_SUBFORMAT_STD);
2494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    param_set_min(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, reqBuffSize);
2504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    param_set_int(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 16);
2514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    param_set_int(params, SNDRV_PCM_HW_PARAM_FRAME_BITS,
2524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   channels * 16);
2534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    param_set_int(params, SNDRV_PCM_HW_PARAM_CHANNELS,
2544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                  channels);
2554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    param_set_int(params, SNDRV_PCM_HW_PARAM_RATE, handle->sampleRate);
2564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    param_set_hw_refine(handle->handle, params);
2574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
2584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (param_set_hw_params(handle->handle, params)) {
2594113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("cannot set hw params");
2604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return NO_INIT;
2614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
2624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    param_dump(params);
2634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
2644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    handle->handle->buffer_size = pcm_buffer_size(params);
2654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    handle->handle->period_size = pcm_period_size(params);
2664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    handle->handle->period_cnt = handle->handle->buffer_size/handle->handle->period_size;
2674113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("setHardwareParams: buffer_size %d, period_size %d, period_cnt %d",
2684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        handle->handle->buffer_size, handle->handle->period_size,
2694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        handle->handle->period_cnt);
2704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    handle->handle->rate = handle->sampleRate;
2714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    handle->handle->channels = handle->channels;
2724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    handle->periodSize = handle->handle->period_size;
2734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC) &&
2744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC) &&
2754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (6 != handle->channels)) {
2764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        //Do not update buffersize for 5.1 recording
2774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        handle->bufferSize = handle->handle->period_size;
2784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
2794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
2804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return NO_ERROR;
2814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
2824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
2834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatus_t setSoftwareParams(alsa_handle_t *handle)
2844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
2854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    struct snd_pcm_sw_params* params;
2864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    struct pcm* pcm = handle->handle;
2874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
2884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    unsigned long periodSize = pcm->period_size;
2894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int channels = handle->channels;
2904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
2914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    params = (snd_pcm_sw_params*) calloc(1, sizeof(struct snd_pcm_sw_params));
2924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!params) {
2934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        LOG_ALWAYS_FATAL("Failed to allocate ALSA software parameters!");
2944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return NO_INIT;
2954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
2964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
2979746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_SSR_ENABLED
2984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (channels == 6) {
2994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
3004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
3014113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev            ALOGV("SWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase);
3024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            channels = 4;
3034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
3044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
3054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
3064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
3074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    // Get the current software parameters
3084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
3094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    params->period_step = 1;
3104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(((!strcmp(handle->useCase,SND_USE_CASE_MOD_PLAY_VOIP)) ||
3114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (!strcmp(handle->useCase,SND_USE_CASE_VERB_IP_VOICECALL)))){
3124113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev          ALOGV("setparam:  start & stop threshold for Voip ");
3134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev          params->avail_min = handle->channels - 1 ? periodSize/4 : periodSize/2;
3144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev          params->start_threshold = periodSize/2;
3154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev          params->stop_threshold = INT_MAX;
3164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     } else {
3174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev         params->avail_min = periodSize/2;
3184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev         params->start_threshold = channels * (periodSize/4);
3194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev         params->stop_threshold = INT_MAX;
3204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     }
3214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    params->silence_threshold = 0;
3224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    params->silence_size = 0;
3234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
3244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (param_set_sw_params(handle->handle, params)) {
3254113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("cannot set sw params");
3264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return NO_INIT;
3274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
3284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return NO_ERROR;
3294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
3304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
3314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode)
3324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
3334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    const char **mods_list;
3344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    use_case_t useCaseNode;
3354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    unsigned usecase_type = 0;
3364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    bool inCallDevSwitch = false;
3374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *rxDevice, *txDevice, ident[70], *use_case = NULL;
3384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int err = 0, index, mods_size;
3394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int rx_dev_id, tx_dev_id;
3404113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGV("%s: device %d", __FUNCTION__, devices);
3414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
3424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if ((mode == AudioSystem::MODE_IN_CALL)  || (mode == AudioSystem::MODE_IN_COMMUNICATION)) {
3434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
3444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (devices & AudioSystem::DEVICE_IN_WIRED_HEADSET)) {
3454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADSET |
3464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      AudioSystem::DEVICE_IN_WIRED_HEADSET);
3474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
3484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADPHONE |
3494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      AudioSystem::DEVICE_IN_BUILTIN_MIC);
3504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if ((devices & AudioSystem::DEVICE_OUT_EARPIECE) ||
3514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                  (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC)) {
3524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            devices = devices | (AudioSystem::DEVICE_IN_BUILTIN_MIC |
3534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      AudioSystem::DEVICE_OUT_EARPIECE);
3544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) {
3554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            devices = devices | (AudioSystem::DEVICE_IN_BUILTIN_MIC |
3564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                       AudioSystem::DEVICE_OUT_SPEAKER);
3574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) ||
3584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
3594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
3604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            devices = devices | (AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET |
3614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      AudioSystem::DEVICE_OUT_BLUETOOTH_SCO);
3629746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_ANC_HEADSET_ENABLED
3634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
3644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   (devices & AudioSystem::DEVICE_IN_ANC_HEADSET)) {
3654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADSET |
3664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      AudioSystem::DEVICE_IN_ANC_HEADSET);
3674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE) {
3684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADPHONE |
3694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      AudioSystem::DEVICE_IN_BUILTIN_MIC);
3704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
3714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
3724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            devices = devices | (AudioSystem::DEVICE_OUT_AUX_DIGITAL |
3734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      AudioSystem::DEVICE_IN_AUX_DIGITAL);
3749746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_PROXY_DEVICE_ENABLED
3754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if ((devices & AudioSystem::DEVICE_OUT_PROXY) ||
3764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                  (devices & AudioSystem::DEVICE_IN_PROXY)) {
3774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            devices = devices | (AudioSystem::DEVICE_OUT_PROXY |
3784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      AudioSystem::DEVICE_IN_PROXY);
3794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
3804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
3814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
3829746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_SSR_ENABLED
3834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if ((devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) && ( 6 == handle->channels)) {
3844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
3854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
3864113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev            ALOGV(" switchDevice , use ssr devices for channels:%d usecase:%s",handle->channels,handle->useCase);
3874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            s_set_flags(SSRQMIC_FLAG);
3884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
3894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
3904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
3914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
3924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    rxDevice = getUCMDevice(devices & AudioSystem::DEVICE_OUT_ALL, 0, NULL);
3934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    txDevice = getUCMDevice(devices & AudioSystem::DEVICE_IN_ALL, 1, rxDevice);
3944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
3954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (rxDevice != NULL) {
3964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if ((handle->handle) && (((!strncmp(rxDevice, DEVICE_SPEAKER_HEADSET, strlen(DEVICE_SPEAKER_HEADSET))) &&
3974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ((!strncmp(curRxUCMDevice, DEVICE_HEADPHONES, strlen(DEVICE_HEADPHONES))) ||
3984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (!strncmp(curRxUCMDevice, DEVICE_HEADSET, strlen(DEVICE_HEADSET))))) ||
3994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (((!strncmp(curRxUCMDevice, DEVICE_SPEAKER_HEADSET, strlen(DEVICE_SPEAKER_HEADSET))) &&
4004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ((!strncmp(rxDevice, DEVICE_HEADPHONES, strlen(DEVICE_HEADPHONES))) ||
4014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (!strncmp(rxDevice, DEVICE_HEADSET, strlen(DEVICE_HEADSET))))))) &&
4024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ((!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI, strlen(SND_USE_CASE_VERB_HIFI))) ||
4034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (!strncmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC, strlen(SND_USE_CASE_MOD_PLAY_MUSIC))))) {
4044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            pcm_close(handle->handle);
4054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            handle->handle=NULL;
4064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            handle->rxHandle=NULL;
4074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            pflag = true;
4084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
4094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
4104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
4114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if ((rxDevice != NULL) && (txDevice != NULL)) {
4124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (((strncmp(rxDevice, curRxUCMDevice, MAX_STR_LEN)) ||
4134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             (strncmp(txDevice, curTxUCMDevice, MAX_STR_LEN))) && (mode == AudioSystem::MODE_IN_CALL))
4144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            inCallDevSwitch = true;
4154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
4164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    snd_use_case_get(handle->ucMgr, "_verb", (const char **)&use_case);
4174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
4184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (rxDevice != NULL) {
4194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if ((strncmp(curRxUCMDevice, "None", 4)) &&
4204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ((strncmp(rxDevice, curRxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
4214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
4224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                strlen(SND_USE_CASE_VERB_INACTIVE)))) {
4234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                usecase_type = getUseCaseType(use_case);
4244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (usecase_type & USECASE_TYPE_RX) {
4254113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev                    ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
4264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
4274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
4284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    mUseCaseList.push_front(useCaseNode);
4294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
4304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
4314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (mods_size) {
4324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                for(index = 0; index < mods_size; index++) {
4334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    usecase_type = getUseCaseType(mods_list[index]);
4344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if (usecase_type & USECASE_TYPE_RX) {
4354113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev                        ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
4364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
4374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
4384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        mUseCaseList.push_back(useCaseNode);
4394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
4404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
4414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
4424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_use_case_set(handle->ucMgr, "_disdev", curRxUCMDevice);
4434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
4444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
4454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (txDevice != NULL) {
4464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if ((strncmp(curTxUCMDevice, "None", 4)) &&
4474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ((strncmp(txDevice, curTxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
4484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
4494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                strlen(SND_USE_CASE_VERB_INACTIVE)))) {
4504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                usecase_type = getUseCaseType(use_case);
4514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
4524113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev                    ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
4534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
4544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
4554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    mUseCaseList.push_front(useCaseNode);
4564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
4574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
4584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (mods_size) {
4594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                for(index = 0; index < mods_size; index++) {
4604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    usecase_type = getUseCaseType(mods_list[index]);
4614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
4624113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev                        ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
4634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
4644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
4654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        mUseCaseList.push_back(useCaseNode);
4664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
4674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
4684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
4694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_use_case_set(handle->ucMgr, "_disdev", curTxUCMDevice);
4704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev       }
4714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
4724113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGV("%s,rxDev:%s, txDev:%s, curRxDev:%s, curTxDev:%s\n", __FUNCTION__, rxDevice, txDevice, curRxUCMDevice, curTxUCMDevice);
4739746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_CSDCLIENT_ENABLED
4744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (mode == AudioSystem::MODE_IN_CALL && platform_is_Fusion3() && (inCallDevSwitch == true)) {
4754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        err = csd_client_disable_device();
4764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (err < 0)
4774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        {
4784113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev            ALOGE("csd_client_disable_device, failed, error %d", err);
4794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
4804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
4814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
4824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
4834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (rxDevice != NULL) {
4844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        snd_use_case_set(handle->ucMgr, "_enadev", rxDevice);
4854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcpy(curRxUCMDevice, rxDevice, sizeof(curRxUCMDevice));
4869746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_FM_ENABLED
4874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (devices & AudioSystem::DEVICE_OUT_FM)
4884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            s_set_fm_vol(fmVolume);
4894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
4904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
4914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (txDevice != NULL) {
4924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev       snd_use_case_set(handle->ucMgr, "_enadev", txDevice);
4934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev       strlcpy(curTxUCMDevice, txDevice, sizeof(curTxUCMDevice));
4944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
4954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    for(ALSAUseCaseList::iterator it = mUseCaseList.begin(); it != mUseCaseList.end(); ++it) {
4964113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGD("Route use case %s\n", it->useCase);
4974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
4984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_VERB_INACTIVE))) && (!strncmp(use_case, it->useCase, MAX_UC_LEN))) {
4994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_use_case_set(handle->ucMgr, "_verb", it->useCase);
5004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
5014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_use_case_set(handle->ucMgr, "_enamod", it->useCase);
5024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
5034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
5044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!mUseCaseList.empty())
5054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        mUseCaseList.clear();
5064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (use_case != NULL) {
5074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        free(use_case);
5084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        use_case = NULL;
5094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
5104113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("switchDevice: curTxUCMDevivce %s curRxDevDevice %s", curTxUCMDevice, curRxUCMDevice);
5114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
5124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (mode == AudioSystem::MODE_IN_CALL && platform_is_Fusion3() && (inCallDevSwitch == true)) {
5134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        /* get tx acdb id */
5144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        memset(&ident,0,sizeof(ident));
5154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcpy(ident, "ACDBID/", sizeof(ident));
5164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcat(ident, curTxUCMDevice, sizeof(ident));
5174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        tx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
5184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
5194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev       /* get rx acdb id */
5204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        memset(&ident,0,sizeof(ident));
5214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcpy(ident, "ACDBID/", sizeof(ident));
5224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcat(ident, curRxUCMDevice, sizeof(ident));
5234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        rx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
5244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
5254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (rx_dev_id == DEVICE_SPEAKER_RX_ACDB_ID && tx_dev_id == DEVICE_HANDSET_TX_ACDB_ID) {
5264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            tx_dev_id = DEVICE_SPEAKER_TX_ACDB_ID;
5274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
5284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
5299746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_CSDCLIENT_ENABLED
5304113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGV("rx_dev_id=%d, tx_dev_id=%d\n", rx_dev_id, tx_dev_id);
5314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        err = csd_client_enable_device(rx_dev_id, tx_dev_id, mDevSettingsFlag);
5324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (err < 0)
5334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        {
5344113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev            ALOGE("csd_client_disable_device failed, error %d", err);
5354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
5364113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev#endif
5374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
5384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
5394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (rxDevice != NULL) {
5404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (pflag && (((!strncmp(rxDevice, DEVICE_SPEAKER_HEADSET, strlen(DEVICE_SPEAKER_HEADSET))) &&
5414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ((!strncmp(curRxUCMDevice, DEVICE_HEADPHONES, strlen(DEVICE_HEADPHONES))) ||
5424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (!strncmp(curRxUCMDevice, DEVICE_HEADSET, strlen(DEVICE_HEADSET))))) ||
5434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (((!strncmp(curRxUCMDevice, DEVICE_SPEAKER_HEADSET, strlen(DEVICE_SPEAKER_HEADSET))) &&
5444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ((!strncmp(rxDevice, DEVICE_HEADPHONES, strlen(DEVICE_HEADPHONES))) ||
5454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (!strncmp(rxDevice, DEVICE_HEADSET, strlen(DEVICE_HEADSET))))))) &&
5464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ((!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI, strlen(SND_USE_CASE_VERB_HIFI))) ||
5474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (!strncmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC, strlen(SND_USE_CASE_MOD_PLAY_MUSIC))))) {
5484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            s_open(handle);
5494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            pflag = false;
5504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
5514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
5524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
5534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (rxDevice != NULL) {
5544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        free(rxDevice);
5554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        rxDevice = NULL;
5564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
5574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (txDevice != NULL) {
5584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        free(txDevice);
5594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        txDevice = NULL;
5604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
5614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
5624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
5634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// ----------------------------------------------------------------------------
5644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
5654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_init(alsa_device_t *module, ALSAHandleList &list)
5664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
5674113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("s_init: Initializing devices for ALSA module");
5684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
5694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list.clear();
5704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
5714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return NO_ERROR;
5724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
5734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
5744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_open(alsa_handle_t *handle)
5754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
5764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *devName;
5774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    unsigned flags = 0;
5784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int err = NO_ERROR;
5794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
5804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    /* No need to call s_close for LPA as pcm device open and close is handled by LPAPlayer in stagefright */
5814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) || (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA))
5824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ||(!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) || (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
5834113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGD("s_open: Opening LPA /Tunnel playback");
5844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return NO_ERROR;
5854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
5864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
5874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    s_close(handle);
5884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
5894113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("s_open: handle %p", handle);
5904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
5914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    // ASoC multicomponent requires a valid path (frontend/backend) for
5924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    // the device to be opened
5934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
5944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    // The PCM stream is opened in blocking mode, per ALSA defaults.  The
5954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    // AudioFlinger seems to assume blocking mode too, so asynchronous mode
5964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    // should not be used.
5974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI)) ||
5984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC))) {
5994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        flags = PCM_OUT;
6004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
6014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        flags = PCM_IN;
6024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
6034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (handle->channels == 1) {
6044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        flags |= PCM_MONO;
6054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
6069746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_SSR_ENABLED
6074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    else if (handle->channels == 4 ) {
6084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        flags |= PCM_QUAD;
6094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (handle->channels == 6 ) {
6104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
6114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
6124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            flags |= PCM_QUAD;
6134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
6144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            flags |= PCM_5POINT1;
6154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
6164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
6174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
6184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    else {
6194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        flags |= PCM_STEREO;
6204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
6214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (deviceName(handle, flags, &devName) < 0) {
6224113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("Failed to get pcm device node: %s", devName);
6234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return NO_INIT;
6244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
6254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (devName != NULL) {
6264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        handle->handle = pcm_open(flags, (char*)devName);
6274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
6284113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("Failed to get pcm device node");
6294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return NO_INIT;
6304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
6314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
6324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!handle->handle) {
6334113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
6344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        free(devName);
6354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return NO_INIT;
6364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
6374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
6384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    handle->handle->flags = flags;
6394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    err = setHardwareParams(handle);
6404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
6414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (err == NO_ERROR) {
6424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        err = setSoftwareParams(handle);
6434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
6444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
6454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(err != NO_ERROR) {
6464113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("Set HW/SW params failed: Closing the pcm stream");
6474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        s_standby(handle);
6484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
6494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
6504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(devName);
6514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return NO_ERROR;
6524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
6534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
6544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_start_voip_call(alsa_handle_t *handle)
6554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
6564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
6574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char* devName;
6584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char* devName1;
6594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    unsigned flags = 0;
6604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int err = NO_ERROR;
6614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    uint8_t voc_pkt[VOIP_BUFFER_MAX_SIZE];
6624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
6634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    s_close(handle);
6644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    flags = PCM_OUT;
6654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    flags |= PCM_MONO;
6664113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGV("s_open:s_start_voip_call  handle %p", handle);
6674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
6684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (deviceName(handle, flags, &devName) < 0) {
6694113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev         ALOGE("Failed to get pcm device node");
6704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev         return NO_INIT;
6714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
6724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
6734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (devName != NULL) {
6744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        handle->handle = pcm_open(flags, (char*)devName);
6754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
6764113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev         ALOGE("Failed to get pcm device node");
6774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev         return NO_INIT;
6784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
6794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
6804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     if (!handle->handle) {
6814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev          free(devName);
6824113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev          ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
6834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev          return NO_INIT;
6844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     }
6854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
6864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     if (!pcm_ready(handle->handle)) {
6874113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev         ALOGE(" pcm ready failed");
6884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     }
6894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
6904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     handle->handle->flags = flags;
6914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     err = setHardwareParams(handle);
6924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
6934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     if (err == NO_ERROR) {
6944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev         err = setSoftwareParams(handle);
6954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     }
6964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
6974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     err = pcm_prepare(handle->handle);
6984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     if(err != NO_ERROR) {
6994113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev         ALOGE("DEVICE_OUT_DIRECTOUTPUT: pcm_prepare failed");
7004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     }
7014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     /* first write required start dsp */
7034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     memset(&voc_pkt,0,sizeof(voc_pkt));
7044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     pcm_write(handle->handle,&voc_pkt,handle->handle->period_size);
7054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     handle->rxHandle = handle->handle;
7064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     free(devName);
7074113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev     ALOGV("s_open: DEVICE_IN_COMMUNICATION ");
7084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     flags = PCM_IN;
7094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     flags |= PCM_MONO;
7104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     handle->handle = 0;
7114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     if (deviceName(handle, flags, &devName1) < 0) {
7134113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("Failed to get pcm device node");
7144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return NO_INIT;
7154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     }
7164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (devName != NULL) {
7174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        handle->handle = pcm_open(flags, (char*)devName1);
7184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
7194113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev         ALOGE("Failed to get pcm device node");
7204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev         return NO_INIT;
7214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
7224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     if (!handle->handle) {
7244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev         free(devName);
7254113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev         ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
7264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev         return NO_INIT;
7274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     }
7284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     if (!pcm_ready(handle->handle)) {
7304113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE(" pcm ready in failed");
7314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     }
7324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     handle->handle->flags = flags;
7344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     err = setHardwareParams(handle);
7364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     if (err == NO_ERROR) {
7384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev         err = setSoftwareParams(handle);
7394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     }
7404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     err = pcm_prepare(handle->handle);
7434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     if(err != NO_ERROR) {
7444113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev         ALOGE("DEVICE_IN_COMMUNICATION: pcm_prepare failed");
7454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     }
7464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     /* first read required start dsp */
7484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     memset(&voc_pkt,0,sizeof(voc_pkt));
7494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     pcm_read(handle->handle,&voc_pkt,handle->handle->period_size);
7504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     return NO_ERROR;
7514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
7524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_start_voice_call(alsa_handle_t *handle)
7544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
7554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char* devName;
7564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    unsigned flags = 0;
7574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int err = NO_ERROR;
7584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7594113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("s_start_voice_call: handle %p", handle);
7604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    // ASoC multicomponent requires a valid path (frontend/backend) for
7614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    // the device to be opened
7624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    flags = PCM_OUT | PCM_MONO;
7644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (deviceName(handle, flags, &devName) < 0) {
7654113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("Failed to get pcm device node");
7664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return NO_INIT;
7674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
7684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (devName != NULL) {
7694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        handle->handle = pcm_open(flags, (char*)devName);
7704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
7714113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev         ALOGE("Failed to get pcm device node");
7724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev         return NO_INIT;
7734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
7744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!handle->handle) {
7754113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_start_voicecall: could not open PCM device");
7764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
7774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
7784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    handle->handle->flags = flags;
7804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    err = setHardwareParams(handle);
7814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(err != NO_ERROR) {
7824113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_start_voice_call: setHardwareParams failed");
7834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
7844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
7854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    err = setSoftwareParams(handle);
7874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(err != NO_ERROR) {
7884113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_start_voice_call: setSoftwareParams failed");
7894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
7904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
7914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    err = pcm_prepare(handle->handle);
7934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(err != NO_ERROR) {
7944113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_start_voice_call: pcm_prepare failed");
7954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
7964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
7974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
7994113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_start_voice_call:SNDRV_PCM_IOCTL_START failed\n");
8004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
8014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
8024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
8034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    // Store the PCM playback device pointer in rxHandle
8044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    handle->rxHandle = handle->handle;
8054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(devName);
8064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
8074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    // Open PCM capture device
8084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    flags = PCM_IN | PCM_MONO;
8094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (deviceName(handle, flags, &devName) < 0) {
8104113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("Failed to get pcm device node");
8114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
8124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
8134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (devName != NULL) {
8144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        handle->handle = pcm_open(flags, (char*)devName);
8154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
8164113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev         ALOGE("Failed to get pcm device node");
8174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev         return NO_INIT;
8184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
8194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!handle->handle) {
8204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        free(devName);
8214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
8224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
8234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
8244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    handle->handle->flags = flags;
8254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    err = setHardwareParams(handle);
8264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(err != NO_ERROR) {
8274113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_start_voice_call: setHardwareParams failed");
8284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
8294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
8304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
8314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    err = setSoftwareParams(handle);
8324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(err != NO_ERROR) {
8334113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_start_voice_call: setSoftwareParams failed");
8344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
8354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
8364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
8374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    err = pcm_prepare(handle->handle);
8384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(err != NO_ERROR) {
8394113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_start_voice_call: pcm_prepare failed");
8404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
8414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
8424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
8434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
8444113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_start_voice_call:SNDRV_PCM_IOCTL_START failed\n");
8454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
8464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
8474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
8484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (platform_is_Fusion3()) {
8499746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_CSDCLIENT_ENABLED
8504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        err = csd_client_start_voice();
8514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (err < 0) {
8524113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev            ALOGE("s_start_voice_call: csd_client error %d\n", err);
8534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            goto Error;
8544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
8554113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev#endif
8564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
8574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
8584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(devName);
8594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return NO_ERROR;
8604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
8614765c439491ddda3de658e62cc4a64d10e726b34Iliyan MalchevError:
8624113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGE("s_start_voice_call: Failed to initialize ALSA device '%s'", devName);
8634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(devName);
8644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    s_close(handle);
8654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return NO_INIT;
8664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
8674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
8684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_start_fm(alsa_handle_t *handle)
8694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
8704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *devName;
8714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    unsigned flags = 0;
8724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int err = NO_ERROR;
8734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
8744113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGE("s_start_fm: handle %p", handle);
8754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
8764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    // ASoC multicomponent requires a valid path (frontend/backend) for
8774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    // the device to be opened
8784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
8794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    flags = PCM_OUT | PCM_STEREO;
8804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (deviceName(handle, flags, &devName) < 0) {
8814113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("Failed to get pcm device node");
8824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
8834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
8844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (devName != NULL) {
8854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        handle->handle = pcm_open(flags, (char*)devName);
8864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
8874113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev         ALOGE("Failed to get pcm device node");
8884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev         return NO_INIT;
8894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
8904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!handle->handle) {
8914113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_start_fm: could not open PCM device");
8924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
8934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
8944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
8954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    handle->handle->flags = flags;
8964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    err = setHardwareParams(handle);
8974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(err != NO_ERROR) {
8984113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_start_fm: setHardwareParams failed");
8994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
9004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
9014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    err = setSoftwareParams(handle);
9034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(err != NO_ERROR) {
9044113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_start_fm: setSoftwareParams failed");
9054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
9064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
9074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    err = pcm_prepare(handle->handle);
9094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(err != NO_ERROR) {
9104113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_start_fm: setSoftwareParams failed");
9114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
9124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
9134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
9154113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_start_fm: SNDRV_PCM_IOCTL_START failed\n");
9164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
9174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
9184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    // Store the PCM playback device pointer in rxHandle
9204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    handle->rxHandle = handle->handle;
9214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(devName);
9224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    // Open PCM capture device
9244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    flags = PCM_IN | PCM_STEREO;
9254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (deviceName(handle, flags, &devName) < 0) {
9264113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("Failed to get pcm device node");
9274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
9284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
9294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (devName != NULL) {
9304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        handle->handle = pcm_open(flags, (char*)devName);
9314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
9324113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev         ALOGE("Failed to get pcm device node");
9334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev         return NO_INIT;
9344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
9354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!handle->handle) {
9364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
9374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
9384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    handle->handle->flags = flags;
9404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    err = setHardwareParams(handle);
9414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(err != NO_ERROR) {
9424113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_start_fm: setHardwareParams failed");
9434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
9444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
9454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    err = setSoftwareParams(handle);
9474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(err != NO_ERROR) {
9484113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_start_fm: setSoftwareParams failed");
9494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
9504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
9514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    err = pcm_prepare(handle->handle);
9534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(err != NO_ERROR) {
9544113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_start_fm: pcm_prepare failed");
9554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
9564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
9574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
9594113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_start_fm: SNDRV_PCM_IOCTL_START failed\n");
9604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        goto Error;
9614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
9624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    s_set_fm_vol(fmVolume);
9644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(devName);
9654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return NO_ERROR;
9664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9674765c439491ddda3de658e62cc4a64d10e726b34Iliyan MalchevError:
9684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(devName);
9694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    s_close(handle);
9704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return NO_INIT;
9714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
9724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_set_fm_vol(int value)
9744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
9754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    status_t err = NO_ERROR;
9764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALSAControl control("/dev/snd/controlC0");
9784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    control.set("Internal FM RX Volume",value,0);
9794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    fmVolume = value;
9804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return err;
9824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
9834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_set_lpa_vol(int value)
9854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
9864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    status_t err = NO_ERROR;
9874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALSAControl control("/dev/snd/controlC0");
9894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    control.set("LPA RX Volume",value,0);
9904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return err;
9924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
9934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_start(alsa_handle_t *handle)
9954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
9964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    status_t err = NO_ERROR;
9974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(!handle->handle) {
9994113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("No active PCM driver to start");
10004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return err;
10014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
10024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
10034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    err = pcm_prepare(handle->handle);
10044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
10054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return err;
10064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
10074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
10084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_close(alsa_handle_t *handle)
10094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
10104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int ret;
10114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    status_t err = NO_ERROR;
10124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     struct pcm *h = handle->rxHandle;
10134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
10144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    handle->rxHandle = 0;
10154113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("s_close: handle %p h %p", handle, h);
10164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (h) {
10174113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGV("s_close rxHandle\n");
10184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        err = pcm_close(h);
10194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(err != NO_ERROR) {
10204113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev            ALOGE("s_close: pcm_close failed for rxHandle with err %d", err);
10214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
10224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
10234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
10244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    h = handle->handle;
10254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    handle->handle = 0;
10264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
10274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (h) {
10284113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev          ALOGV("s_close handle h %p\n", h);
10294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        err = pcm_close(h);
10304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(err != NO_ERROR) {
10314113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev            ALOGE("s_close: pcm_close failed for handle with err %d", err);
10324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
10334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
10344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_VOICECALL) ||
10354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             !strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_VOICE)) &&
10364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            platform_is_Fusion3()) {
10379746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_CSDCLIENT_ENABLED
10384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            err = csd_client_stop_voice();
10394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (err < 0) {
10404113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev                ALOGE("s_close: csd_client error %d\n", err);
10414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
10424113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev#endif
10434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
10444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
10454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        disableDevice(handle);
10464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
10474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev              (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
10484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev              (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
10494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev              (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))){
10504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        disableDevice(handle);
10514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
10524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
10534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return err;
10544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
10554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
10564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/*
10574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    this is same as s_close, but don't discard
10584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    the device/mode info. This way we can still
10594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    close the device, hit idle and power-save, reopen the pcm
10604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    for the same device/mode after resuming
10614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev*/
10624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_standby(alsa_handle_t *handle)
10634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
10644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int ret;
10654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    status_t err = NO_ERROR;
10664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    struct pcm *h = handle->rxHandle;
10674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    handle->rxHandle = 0;
10684113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("s_standby: handle %p h %p", handle, h);
10694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (h) {
10704113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("s_standby  rxHandle\n");
10714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        err = pcm_close(h);
10724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(err != NO_ERROR) {
10734113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev            ALOGE("s_standby: pcm_close failed for rxHandle with err %d", err);
10744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
10754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
10764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
10774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    h = handle->handle;
10784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    handle->handle = 0;
10794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
10804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (h) {
10814113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev          ALOGE("s_standby handle h %p\n", h);
10824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        err = pcm_close(h);
10834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(err != NO_ERROR) {
10844113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev            ALOGE("s_standby: pcm_close failed for handle with err %d", err);
10854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
10864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        disableDevice(handle);
10874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
10884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev              (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
10894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev              (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
10904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev              (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
10914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        disableDevice(handle);
10924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
10934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
10944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return err;
10954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
10964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
10974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_route(alsa_handle_t *handle, uint32_t devices, int mode)
10984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
10994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    status_t status = NO_ERROR;
11004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
11014113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("s_route: devices 0x%x in mode %d", devices, mode);
11024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    callMode = mode;
11034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    switchDevice(handle, devices, mode);
11044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return status;
11054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
11064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
11074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint getUseCaseType(const char *useCase)
11084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
11094113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGE("use case is %s\n", useCase);
11104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI,
11114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev           strlen(SND_USE_CASE_VERB_HIFI)) ||
11124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER,
11134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
11144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_HIFI_TUNNEL,
11154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
11164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_DIGITAL_RADIO,
11174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
11184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC,
11194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_MOD_PLAY_MUSIC)) ||
11204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LPA,
11214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_MOD_PLAY_LPA)) ||
11224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_PLAY_TUNNEL,
11234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_MOD_PLAY_TUNNEL)) ||
11244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_PLAY_FM,
11254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_MOD_PLAY_FM))) {
11264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return USECASE_TYPE_RX;
11274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI_REC,
11284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_VERB_HIFI_REC)) ||
11294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_FM_REC,
11304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_VERB_FM_REC)) ||
11314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_FM_A2DP_REC,
11324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_VERB_FM_A2DP_REC)) ||
11334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC,
11344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC)) ||
11354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_FM,
11364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_MOD_CAPTURE_FM)) ||
11374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM,
11384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_MOD_CAPTURE_A2DP_FM))) {
11394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return USECASE_TYPE_TX;
11404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (!strncmp(useCase, SND_USE_CASE_VERB_VOICECALL,
11414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_VERB_VOICECALL)) ||
11424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_IP_VOICECALL,
11434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_VERB_IP_VOICECALL)) ||
11444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_DL_REC,
11454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_VERB_DL_REC)) ||
11464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_UL_DL_REC,
11474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_VERB_UL_DL_REC)) ||
11484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOICE,
11494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_MOD_PLAY_VOICE)) ||
11504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOIP,
11514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_MOD_PLAY_VOIP)) ||
11524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
11534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_MOD_CAPTURE_VOICE_DL)) ||
11544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
11554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL)) ||
11564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
11574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_MOD_CAPTURE_VOICE)) ||
11584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_VOLTE,
11594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_VERB_VOLTE)) ||
11604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOLTE,
11614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_MOD_PLAY_VOLTE))) {
11624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return (USECASE_TYPE_RX | USECASE_TYPE_TX);
11634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
11644113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("unknown use case %s\n", useCase);
11654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return 0;
11664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
11674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
11684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
11694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void disableDevice(alsa_handle_t *handle)
11704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
11714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    unsigned usecase_type = 0;
11724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int i, mods_size;
11734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *useCase;
11744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    const char **mods_list;
11754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
11764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
11774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (useCase != NULL) {
11784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!strncmp(useCase, handle->useCase, MAX_UC_LEN)) {
11794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
11804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
11814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_use_case_set(handle->ucMgr, "_dismod", handle->useCase);
11824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
11834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        free(useCase);
11844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
11854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (strncmp(useCase, SND_USE_CASE_VERB_INACTIVE,
11864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               strlen(SND_USE_CASE_VERB_INACTIVE)))
11874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            usecase_type |= getUseCaseType(useCase);
11884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
11894113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("Number of modifiers %d\n", mods_size);
11904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (mods_size) {
11914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            for(i = 0; i < mods_size; i++) {
11924113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev                ALOGE("index %d modifier %s\n", i, mods_list[i]);
11934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                usecase_type |= getUseCaseType(mods_list[i]);
11944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
11954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
11964113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("usecase_type is %d\n", usecase_type);
11974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!(usecase_type & USECASE_TYPE_TX) && (strncmp(curTxUCMDevice, "None", 4)))
11984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_use_case_set(handle->ucMgr, "_disdev", curTxUCMDevice);
11994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!(usecase_type & USECASE_TYPE_RX) && (strncmp(curRxUCMDevice, "None", 4)))
12004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_use_case_set(handle->ucMgr, "_disdev", curRxUCMDevice);
12014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
12024113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev        ALOGE("Invalid state, no valid use case found to disable");
12034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
12044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(useCase);
12054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
12064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
12074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevchar *getUCMDevice(uint32_t devices, int input, char *rxDevice)
12084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
12094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!input) {
12104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!(mDevSettingsFlag & TTY_OFF) &&
12114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (callMode == AudioSystem::MODE_IN_CALL) &&
12124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
12134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
12149746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_ANC_HEADSET_ENABLED
12154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             ||
12164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             (devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
12174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) {
12184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
12194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             if (mDevSettingsFlag & TTY_VCO) {
12204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 return strdup(SND_USE_CASE_DEV_TTY_HEADSET_RX);
12214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             } else if (mDevSettingsFlag & TTY_FULL) {
12224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 return strdup(SND_USE_CASE_DEV_TTY_FULL_RX);
12234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             } else if (mDevSettingsFlag & TTY_HCO) {
12244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_RX); /* HANDSET RX */
12254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             }
12264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }else if ((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET) ||
12274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                  (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)) {
12284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */
12294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
12304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
12314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
12324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (mDevSettingsFlag & ANC_FLAG) {
12334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
12344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
12354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return strdup(SND_USE_CASE_DEV_SPEAKER_HEADSET); /* COMBO SPEAKER+HEADSET RX */
12364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
12379746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_ANC_HEADSET_ENABLED
12384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
12394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
12404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) {
12414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
12424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
12434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 (devices & AudioSystem::DEVICE_OUT_FM_TX)) {
12444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return strdup(SND_USE_CASE_DEV_SPEAKER_FM_TX); /* COMBO SPEAKER+FM_TX RX */
12454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
12464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (devices & AudioSystem::DEVICE_OUT_EARPIECE) {
12474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return strdup(SND_USE_CASE_DEV_EARPIECE); /* HANDSET RX */
12484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) {
12494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
12504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
12514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) {
12524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (mDevSettingsFlag & ANC_FLAG) {
12534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */
12544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
12554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return strdup(SND_USE_CASE_DEV_HEADPHONES); /* HEADSET RX */
12564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
12579746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_ANC_HEADSET_ENABLED
12584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
12594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE)) {
12604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */
12614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
12624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) ||
12634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                  (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
12644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                  (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT)) {
12654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (btsco_samplerate == BTSCO_RATE_16KHZ)
12664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return strdup(SND_USE_CASE_DEV_BTSCO_WB_RX); /* BTSCO RX*/
12674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            else
12684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return strdup(SND_USE_CASE_DEV_BTSCO_NB_RX); /* BTSCO RX*/
12694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP) ||
12704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES) ||
12719746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_VOIP_ENABLED
12729746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                   (devices & AudioSystem::DEVICE_OUT_DIRECTOUTPUT) ||
12739746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#endif
12744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) {
12754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            /* Nothing to be done, use current active device */
12764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (strncmp(curRxUCMDevice, "None", 4)) {
12774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return strdup(curRxUCMDevice);
12784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
12794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
12804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return strdup(SND_USE_CASE_DEV_HDMI); /* HDMI RX */
12819746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_PROXY_DEVICE_ENABLED
12824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (devices & AudioSystem::DEVICE_OUT_PROXY) {
12834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */
12849746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#endif
12859746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_FM_TX_ENABLED
12864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (devices & AudioSystem::DEVICE_OUT_FM_TX) {
12874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return strdup(SND_USE_CASE_DEV_FM_TX); /* FM Tx */
12884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
12894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (devices & AudioSystem::DEVICE_OUT_DEFAULT) {
12904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
12914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
12924113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev            ALOGD("No valid output device: %u", devices);
12934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
12944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
12954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!(mDevSettingsFlag & TTY_OFF) &&
12964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (callMode == AudioSystem::MODE_IN_CALL) &&
12974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ((devices & AudioSystem::DEVICE_IN_WIRED_HEADSET))) {
12989746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_ANC_HEADSET_ENABLED
12994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ||(devices & AudioSystem::DEVICE_IN_ANC_HEADSET))) {
13004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
13014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             if (mDevSettingsFlag & TTY_HCO) {
13024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 return strdup(SND_USE_CASE_DEV_TTY_HEADSET_TX);
13034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             } else if (mDevSettingsFlag & TTY_FULL) {
13044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 return strdup(SND_USE_CASE_DEV_TTY_FULL_TX);
13054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             } else if (mDevSettingsFlag & TTY_VCO) {
13064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 if (!strncmp(mic_type, "analog", 6)) {
13079746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                     return strdup(SND_USE_CASE_DEV_TTY_HANDSET_ANALOG_TX);
13084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 } else {
13094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                     return strdup(SND_USE_CASE_DEV_TTY_HANDSET_TX);
13104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 }
13114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             }
13124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) {
13134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (!strncmp(mic_type, "analog", 6)) {
13144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
13154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
13164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (mDevSettingsFlag & DMIC_FLAG) {
13174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if (((rxDevice != NULL) &&
13184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        !strncmp(rxDevice, SND_USE_CASE_DEV_SPEAKER,
13194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) ||
13204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        !strncmp(curRxUCMDevice, SND_USE_CASE_DEV_SPEAKER,
13214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) {
13224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
13234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
13244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
13254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
13264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        }
13274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    } else {
13284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
13294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
13304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
13314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
13324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        }
13334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
13344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                } else if (mDevSettingsFlag & QMIC_FLAG){
13354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    return strdup(SND_USE_CASE_DEV_QUAD_MIC);
13364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
13379746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_SSR_ENABLED
13384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                else if (mDevSettingsFlag & SSRQMIC_FLAG){
13394113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev                    ALOGV("return SSRQMIC_FLAG: 0x%x devices:0x%x",mDevSettingsFlag,devices);
13404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    // Mapping for quad mic input device.
13414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    return strdup(SND_USE_CASE_DEV_SSR_QUAD_MIC); /* SSR Quad MIC */
13424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
13434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
13444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                else {
13454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    return strdup(SND_USE_CASE_DEV_LINE); /* BUILTIN-MIC TX */
13464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
13474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
13484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (devices & AudioSystem::DEVICE_IN_AUX_DIGITAL) {
13494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return strdup(SND_USE_CASE_DEV_HDMI_TX); /* HDMI TX */
13509746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_ANC_HEADSET_ENABLED
13514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if ((devices & AudioSystem::DEVICE_IN_WIRED_HEADSET) ||
13524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   (devices & AudioSystem::DEVICE_IN_ANC_HEADSET)) {
13534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */
13544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
13554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
13564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             if (btsco_samplerate == BTSCO_RATE_16KHZ)
13574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 return strdup(SND_USE_CASE_DEV_BTSCO_WB_TX); /* BTSCO TX*/
13584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             else
13594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 return strdup(SND_USE_CASE_DEV_BTSCO_NB_TX); /* BTSCO TX*/
13609746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_USBAUDIO_ENABLED
13614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if ((devices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) ||
13624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   (devices & AudioSystem::DEVICE_IN_PROXY)) {
13634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return strdup(SND_USE_CASE_DEV_PROXY_TX); /* PROXY TX */
13644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
13654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if ((devices & AudioSystem::DEVICE_IN_COMMUNICATION) ||
13664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   (devices & AudioSystem::DEVICE_IN_VOICE_CALL)) {
13674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            /* Nothing to be done, use current active device */
13684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (strncmp(curTxUCMDevice, "None", 4)) {
13694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return strdup(curTxUCMDevice);
13704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
13719746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_FM_ENABLED
13724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if ((devices & AudioSystem::DEVICE_IN_FM_RX) ||
13734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   (devices & AudioSystem::DEVICE_IN_FM_RX_A2DP)) {
13744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            /* Nothing to be done, use current tx device or set dummy device */
13754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (strncmp(curTxUCMDevice, "None", 4)) {
13764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return strdup(curTxUCMDevice);
13774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
13784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return strdup(SND_USE_CASE_DEV_DUMMY_TX);
13794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
13804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
13814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if ((devices & AudioSystem::DEVICE_IN_AMBIENT) ||
13824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   (devices & AudioSystem::DEVICE_IN_BACK_MIC)) {
13834113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev            ALOGI("No proper mapping found with UCM device list, setting default");
13844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (!strncmp(mic_type, "analog", 6)) {
13854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
13864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
13874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return strdup(SND_USE_CASE_DEV_LINE); /* BUILTIN-MIC TX */
13884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
13894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
13904113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev            ALOGD("No valid input device: %u", devices);
13914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
13924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
13934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return NULL;
13944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
13954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
13964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid s_set_voice_volume(int vol)
13974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
13984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int err = 0;
13994113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("s_set_voice_volume: volume %d", vol);
14004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALSAControl control("/dev/snd/controlC0");
14014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    control.set("Voice Rx Volume", vol, 0);
14024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
14034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (platform_is_Fusion3()) {
14049746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_CSDCLIENT_ENABLED
14054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        err = csd_client_volume(vol);
14064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (err < 0) {
14074113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev            ALOGE("s_set_voice_volume: csd_client error %d", err);
14084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
14094113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev#endif
14104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
14114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
14124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
14134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid s_set_volte_volume(int vol)
14144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
14154113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("s_set_volte_volume: volume %d", vol);
14164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALSAControl control("/dev/snd/controlC0");
14174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    control.set("VoLTE Rx Volume", vol, 0);
14184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
14194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
14204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
14214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid s_set_voip_volume(int vol)
14224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
14234113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("s_set_voip_volume: volume %d", vol);
14244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALSAControl control("/dev/snd/controlC0");
14254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    control.set("Voip Rx Volume", vol, 0);
14264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
14274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid s_set_mic_mute(int state)
14284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
14294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int err = 0;
14304113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("s_set_mic_mute: state %d", state);
14314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALSAControl control("/dev/snd/controlC0");
14324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    control.set("Voice Tx Mute", state, 0);
14334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
14344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (platform_is_Fusion3()) {
14359746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_CSDCLIENT_ENABLED
14364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        err = csd_client_mic_mute(state);
14374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (err < 0) {
14384113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev            ALOGE("s_set_mic_mute: csd_client error %d", err);
14394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
14404113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev#endif
14414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
14424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
14434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid s_set_volte_mic_mute(int state)
14444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
14454113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("s_set_volte_mic_mute: state %d", state);
14464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALSAControl control("/dev/snd/controlC0");
14474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    control.set("VoLTE Tx Mute", state, 0);
14484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
14494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
14504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid s_set_voip_mic_mute(int state)
14514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
14524113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("s_set_voip_mic_mute: state %d", state);
14534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALSAControl control("/dev/snd/controlC0");
14544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    control.set("Voip Tx Mute", state, 0);
14554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
14564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
14574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid s_set_voip_config(int mode, int rate)
14584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
14594113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("s_set_voip_config: mode %d,rate %d", mode, rate);
14604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALSAControl control("/dev/snd/controlC0");
14614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char** setValues;
14624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    setValues = (char**)malloc(2*sizeof(char*));
14634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (setValues == NULL) {
14644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev          return;
14654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
14664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    setValues[0] = (char*)malloc(4*sizeof(char));
14674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (setValues[0] == NULL) {
14684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev          free(setValues);
14694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev          return;
14704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
14714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
14724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    setValues[1] = (char*)malloc(8*sizeof(char));
14734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (setValues[1] == NULL) {
14744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev          free(setValues);
14754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev          free(setValues[0]);
14764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev          return;
14774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
14784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
14794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    sprintf(setValues[0], "%d",mode);
14804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    sprintf(setValues[1], "%d",rate);
14814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
14824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    control.setext("Voip Mode Rate Config", 2, setValues);
14834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(setValues[1]);
14844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(setValues[0]);
14854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(setValues);
14864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return;
14874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
14884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
14894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid s_set_btsco_rate(int rate)
14904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
14914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    btsco_samplerate = rate;
14924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
14934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
14944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid s_enable_wide_voice(bool flag)
14954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
14964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int err = 0;
14974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
14984113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("s_enable_wide_voice: flag %d", flag);
14994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALSAControl control("/dev/snd/controlC0");
15004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(flag == true) {
15014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        control.set("Widevoice Enable", 1, 0);
15024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
15034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        control.set("Widevoice Enable", 0, 0);
15044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
15054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
15064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (platform_is_Fusion3()) {
15079746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_CSDCLIENT_ENABLED
15084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        err == csd_client_wide_voice(flag);
15094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (err < 0) {
15104113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev            ALOGE("s_enable_wide_voice: csd_client error %d", err);
15114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
15124113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev#endif
15134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
15144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
15154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
15164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid s_set_voc_rec_mode(uint8_t mode)
15174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
15184113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("s_set_voc_rec_mode: mode %d", mode);
15194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALSAControl control("/dev/snd/controlC0");
15204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    control.set("Incall Rec Mode", mode, 0);
15214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
15224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
15234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid s_enable_fens(bool flag)
15244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
15254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int err = 0;
15264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
15274113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("s_enable_fens: flag %d", flag);
15284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALSAControl control("/dev/snd/controlC0");
15294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(flag == true) {
15304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        control.set("FENS Enable", 1, 0);
15314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
15324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        control.set("FENS Enable", 0, 0);
15334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
15344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
15354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (platform_is_Fusion3()) {
15369746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_CSDCLIENT_ENABLED
15374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        err = csd_client_fens(flag);
15384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (err < 0) {
15394113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev            ALOGE("s_enable_fens: csd_client error %d", err);
15404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
15414113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev#endif
15424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
15434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
15444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
15454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid s_enable_slow_talk(bool flag)
15464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
15474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int err = 0;
15484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
15494113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGD("s_enable_slow_talk: flag %d", flag);
15504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALSAControl control("/dev/snd/controlC0");
15514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(flag == true) {
15524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        control.set("Slowtalk Enable", 1, 0);
15534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
15544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        control.set("Slowtalk Enable", 0, 0);
15554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
15564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
15574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (platform_is_Fusion3()) {
15589746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_CSDCLIENT_ENABLED
15594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        err = csd_client_slow_talk(flag);
15604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (err < 0) {
15614113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev            ALOGE("s_enable_slow_talk: csd_client error %d", err);
15624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
15634113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev#endif
15644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
15654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
15664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
15674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid s_set_flags(uint32_t flags)
15684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
15694113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev    ALOGV("s_set_flags: flags %d", flags);
15704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    mDevSettingsFlag = flags;
15714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
15724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
15734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic status_t s_set_compressed_vol(int value)
15744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
15754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    status_t err = NO_ERROR;
15764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
15774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALSAControl control("/dev/snd/controlC0");
15784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    control.set("COMPRESSED RX Volume",value,0);
15794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
15804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return err;
15814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
15824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
15834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
1584