blob: ea8ad2f03ffbf7cf128a50218332b12af04c1ab9 [file] [log] [blame]
Iliyan Malchev4765c432012-06-11 14:36:16 -07001/* alsa_default.cpp
2 **
3 ** Copyright 2009 Wind River Systems
4 ** Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
5 **
6 ** Licensed under the Apache License, Version 2.0 (the "License");
7 ** you may not use this file except in compliance with the License.
8 ** You may obtain a copy of the License at
9 **
10 ** http://www.apache.org/licenses/LICENSE-2.0
11 **
12 ** Unless required by applicable law or agreed to in writing, software
13 ** distributed under the License is distributed on an "AS IS" BASIS,
14 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 ** See the License for the specific language governing permissions and
16 ** limitations under the License.
17 */
18
Ajay Dudani9746c472012-06-18 16:01:16 -070019#define LOG_TAG "ALSAModule"
Iliyan Malchev4765c432012-06-11 14:36:16 -070020//#define LOG_NDEBUG 0
Ajay Dudani9746c472012-06-18 16:01:16 -070021#define LOG_NDDEBUG 0
Iliyan Malchev4765c432012-06-11 14:36:16 -070022#include <utils/Log.h>
23#include <cutils/properties.h>
24#include <linux/ioctl.h>
25#include "AudioHardwareALSA.h"
26#include <media/AudioRecord.h>
SathishKumar Mani5ff7a022012-09-14 11:36:35 -070027#include <dlfcn.h>
Ajay Dudani9746c472012-06-18 16:01:16 -070028#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -070029extern "C" {
SathishKumar Mani5ff7a022012-09-14 11:36:35 -070030static int (*csd_disable_device)();
31static int (*csd_enable_device)(int, int, uint32_t);
32static int (*csd_volume)(int);
33static int (*csd_mic_mute)(int);
34static int (*csd_wide_voice)(uint8_t);
35static int (*csd_slow_talk)(uint8_t);
36static int (*csd_fens)(uint8_t);
37static int (*csd_start_voice)();
38static int (*csd_stop_voice)();
Iliyan Malchev4765c432012-06-11 14:36:16 -070039}
Iliyan Malchev4113f342012-06-11 14:39:47 -070040#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -070041
42#ifndef ALSA_DEFAULT_SAMPLE_RATE
43#define ALSA_DEFAULT_SAMPLE_RATE 44100 // in Hz
44#endif
45
46#define BTSCO_RATE_16KHZ 16000
47#define USECASE_TYPE_RX 1
48#define USECASE_TYPE_TX 2
49
50namespace android_audio_legacy
51{
52
53static int s_device_open(const hw_module_t*, const char*, hw_device_t**);
54static int s_device_close(hw_device_t*);
55static status_t s_init(alsa_device_t *, ALSAHandleList &);
56static status_t s_open(alsa_handle_t *);
57static status_t s_close(alsa_handle_t *);
58static status_t s_standby(alsa_handle_t *);
59static status_t s_route(alsa_handle_t *, uint32_t, int);
60static status_t s_start_voice_call(alsa_handle_t *);
61static status_t s_start_voip_call(alsa_handle_t *);
62static status_t s_start_fm(alsa_handle_t *);
63static void s_set_voice_volume(int);
64static void s_set_voip_volume(int);
65static void s_set_mic_mute(int);
66static void s_set_voip_mic_mute(int);
67static void s_set_voip_config(int, int);
68static status_t s_set_fm_vol(int);
69static void s_set_btsco_rate(int);
70static status_t s_set_lpa_vol(int);
71static void s_enable_wide_voice(bool flag);
72static void s_enable_fens(bool flag);
73static void s_set_flags(uint32_t flags);
74static status_t s_set_compressed_vol(int);
75static void s_enable_slow_talk(bool flag);
76static void s_set_voc_rec_mode(uint8_t mode);
77static void s_set_volte_mic_mute(int state);
78static void s_set_volte_volume(int vol);
ty.lee74060de2012-08-02 00:47:00 +090079#ifdef SEPERATED_AUDIO_INPUT
80static void s_setInput(int);
81
82static int input_source;
83#endif
SathishKumar Mani5ff7a022012-09-14 11:36:35 -070084#ifdef QCOM_CSDCLIENT_ENABLED
85static void s_set_csd_handle(void*);
86#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -070087
88static char mic_type[25];
89static char curRxUCMDevice[50];
90static char curTxUCMDevice[50];
91static int fluence_mode;
92static int fmVolume;
ty.lee924f7982012-08-01 23:15:30 +090093#ifdef USES_FLUENCE_INCALL
94static uint32_t mDevSettingsFlag = TTY_OFF | DMIC_FLAG;
95#else
Iliyan Malchev4765c432012-06-11 14:36:16 -070096static uint32_t mDevSettingsFlag = TTY_OFF;
ty.lee924f7982012-08-01 23:15:30 +090097#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -070098static int btsco_samplerate = 8000;
99static bool pflag = false;
100static ALSAUseCaseList mUseCaseList;
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700101static void *csd_handle;
Iliyan Malchev4765c432012-06-11 14:36:16 -0700102
103static hw_module_methods_t s_module_methods = {
104 open : s_device_open
105};
106
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700107extern "C" {
108hw_module_t HAL_MODULE_INFO_SYM = {
Iliyan Malchev4765c432012-06-11 14:36:16 -0700109 tag : HARDWARE_MODULE_TAG,
110 version_major : 1,
111 version_minor : 0,
112 id : ALSA_HARDWARE_MODULE_ID,
113 name : "QCOM ALSA module",
114 author : "QuIC Inc",
115 methods : &s_module_methods,
116 dso : 0,
117 reserved : {0,},
118};
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700119}
Iliyan Malchev4765c432012-06-11 14:36:16 -0700120
121static int s_device_open(const hw_module_t* module, const char* name,
122 hw_device_t** device)
123{
124 char value[128];
125 alsa_device_t *dev;
126 dev = (alsa_device_t *) malloc(sizeof(*dev));
127 if (!dev) return -ENOMEM;
128
129 memset(dev, 0, sizeof(*dev));
130
131 /* initialize the procs */
132 dev->common.tag = HARDWARE_DEVICE_TAG;
133 dev->common.version = 0;
134 dev->common.module = (hw_module_t *) module;
135 dev->common.close = s_device_close;
136 dev->init = s_init;
137 dev->open = s_open;
138 dev->close = s_close;
139 dev->route = s_route;
140 dev->standby = s_standby;
141 dev->startVoiceCall = s_start_voice_call;
142 dev->startVoipCall = s_start_voip_call;
143 dev->startFm = s_start_fm;
144 dev->setVoiceVolume = s_set_voice_volume;
145 dev->setVoipVolume = s_set_voip_volume;
146 dev->setMicMute = s_set_mic_mute;
147 dev->setVoipMicMute = s_set_voip_mic_mute;
148 dev->setVoipConfig = s_set_voip_config;
149 dev->setFmVolume = s_set_fm_vol;
150 dev->setBtscoRate = s_set_btsco_rate;
151 dev->setLpaVolume = s_set_lpa_vol;
152 dev->enableWideVoice = s_enable_wide_voice;
153 dev->enableFENS = s_enable_fens;
154 dev->setFlags = s_set_flags;
155 dev->setCompressedVolume = s_set_compressed_vol;
156 dev->enableSlowTalk = s_enable_slow_talk;
157 dev->setVocRecMode = s_set_voc_rec_mode;
158 dev->setVoLTEMicMute = s_set_volte_mic_mute;
159 dev->setVoLTEVolume = s_set_volte_volume;
ty.lee74060de2012-08-02 00:47:00 +0900160#ifdef SEPERATED_AUDIO_INPUT
161 dev->setInput = s_setInput;
162#endif
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700163#ifdef QCOM_CSDCLIENT_ENABLED
164 dev->setCsdHandle = s_set_csd_handle;
165#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700166 *device = &dev->common;
167
168 property_get("persist.audio.handset.mic",value,"0");
169 strlcpy(mic_type, value, sizeof(mic_type));
170 property_get("persist.audio.fluence.mode",value,"0");
171 if (!strcmp("broadside", value)) {
172 fluence_mode = FLUENCE_MODE_BROADSIDE;
173 } else {
174 fluence_mode = FLUENCE_MODE_ENDFIRE;
175 }
176 strlcpy(curRxUCMDevice, "None", sizeof(curRxUCMDevice));
177 strlcpy(curTxUCMDevice, "None", sizeof(curTxUCMDevice));
SathishKumar Mani9efed762012-09-18 18:52:48 -0700178 ALOGV("ALSA module opened");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700179
180 return 0;
181}
182
183static int s_device_close(hw_device_t* device)
184{
185 free(device);
186 device = NULL;
187 return 0;
188}
189
190// ----------------------------------------------------------------------------
191
192static const int DEFAULT_SAMPLE_RATE = ALSA_DEFAULT_SAMPLE_RATE;
193
194static void switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode);
195static char *getUCMDevice(uint32_t devices, int input, char *rxDevice);
196static void disableDevice(alsa_handle_t *handle);
197int getUseCaseType(const char *useCase);
198
199static int callMode = AudioSystem::MODE_NORMAL;
200// ----------------------------------------------------------------------------
201
202bool platform_is_Fusion3()
203{
204 char platform[128], baseband[128];
205 property_get("ro.board.platform", platform, "");
206 property_get("ro.baseband", baseband, "");
207 if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband))
208 return true;
209 else
210 return false;
211}
212
213int deviceName(alsa_handle_t *handle, unsigned flags, char **value)
214{
215 int ret = 0;
216 char ident[70];
217
218 if (flags & PCM_IN) {
219 strlcpy(ident, "CapturePCM/", sizeof(ident));
220 } else {
221 strlcpy(ident, "PlaybackPCM/", sizeof(ident));
222 }
223 strlcat(ident, handle->useCase, sizeof(ident));
224 ret = snd_use_case_get(handle->ucMgr, ident, (const char **)value);
Iliyan Malchev4113f342012-06-11 14:39:47 -0700225 ALOGD("Device value returned is %s", (*value));
Iliyan Malchev4765c432012-06-11 14:36:16 -0700226 return ret;
227}
228
229status_t setHardwareParams(alsa_handle_t *handle)
230{
231 struct snd_pcm_hw_params *params;
232 unsigned long bufferSize, reqBuffSize;
233 unsigned int periodTime, bufferTime;
234 unsigned int requestedRate = handle->sampleRate;
235 int status = 0;
236 int channels = handle->channels;
237 snd_pcm_format_t format = SNDRV_PCM_FORMAT_S16_LE;
238
239 params = (snd_pcm_hw_params*) calloc(1, sizeof(struct snd_pcm_hw_params));
240 if (!params) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700241 ALOGE("Failed to allocate ALSA hardware parameters!");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700242 return NO_INIT;
243 }
244
245 reqBuffSize = handle->bufferSize;
Iliyan Malchev4113f342012-06-11 14:39:47 -0700246 ALOGD("setHardwareParams: reqBuffSize %d channels %d sampleRate %d",
Iliyan Malchev4765c432012-06-11 14:36:16 -0700247 (int) reqBuffSize, handle->channels, handle->sampleRate);
248
Ajay Dudani9746c472012-06-18 16:01:16 -0700249#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700250 if (channels == 6) {
251 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
252 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700253 ALOGV("HWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700254 channels = 4;
255 reqBuffSize = DEFAULT_IN_BUFFER_SIZE;
256 }
257 }
258#endif
259
260 param_init(params);
261 param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS,
262 SNDRV_PCM_ACCESS_RW_INTERLEAVED);
263 if (handle->format != SNDRV_PCM_FORMAT_S16_LE) {
Ajay Dudani9746c472012-06-18 16:01:16 -0700264 if (handle->format == AudioSystem::AMR_NB
265 || handle->format == AudioSystem::AMR_WB
266#ifdef QCOM_QCHAT_ENABLED
267 || handle->format == AudioSystem::EVRC
268 || handle->format == AudioSystem::EVRCB
269 || handle->format == AudioSystem::EVRCWB
270#endif
271 )
Iliyan Malchev4765c432012-06-11 14:36:16 -0700272 format = SNDRV_PCM_FORMAT_SPECIAL;
273 }
274 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
275 format);
276 param_set_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT,
277 SNDRV_PCM_SUBFORMAT_STD);
278 param_set_min(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, reqBuffSize);
279 param_set_int(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 16);
280 param_set_int(params, SNDRV_PCM_HW_PARAM_FRAME_BITS,
281 channels * 16);
282 param_set_int(params, SNDRV_PCM_HW_PARAM_CHANNELS,
283 channels);
284 param_set_int(params, SNDRV_PCM_HW_PARAM_RATE, handle->sampleRate);
285 param_set_hw_refine(handle->handle, params);
286
287 if (param_set_hw_params(handle->handle, params)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700288 ALOGE("cannot set hw params");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700289 return NO_INIT;
290 }
291 param_dump(params);
292
293 handle->handle->buffer_size = pcm_buffer_size(params);
294 handle->handle->period_size = pcm_period_size(params);
295 handle->handle->period_cnt = handle->handle->buffer_size/handle->handle->period_size;
Iliyan Malchev4113f342012-06-11 14:39:47 -0700296 ALOGD("setHardwareParams: buffer_size %d, period_size %d, period_cnt %d",
Iliyan Malchev4765c432012-06-11 14:36:16 -0700297 handle->handle->buffer_size, handle->handle->period_size,
298 handle->handle->period_cnt);
299 handle->handle->rate = handle->sampleRate;
300 handle->handle->channels = handle->channels;
301 handle->periodSize = handle->handle->period_size;
302 if (strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC) &&
303 strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC) &&
304 (6 != handle->channels)) {
305 //Do not update buffersize for 5.1 recording
306 handle->bufferSize = handle->handle->period_size;
307 }
308
309 return NO_ERROR;
310}
311
312status_t setSoftwareParams(alsa_handle_t *handle)
313{
314 struct snd_pcm_sw_params* params;
315 struct pcm* pcm = handle->handle;
316
317 unsigned long periodSize = pcm->period_size;
318 int channels = handle->channels;
319
320 params = (snd_pcm_sw_params*) calloc(1, sizeof(struct snd_pcm_sw_params));
321 if (!params) {
322 LOG_ALWAYS_FATAL("Failed to allocate ALSA software parameters!");
323 return NO_INIT;
324 }
325
Ajay Dudani9746c472012-06-18 16:01:16 -0700326#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700327 if (channels == 6) {
328 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
329 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700330 ALOGV("SWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700331 channels = 4;
332 }
333 }
334#endif
335
336 // Get the current software parameters
337 params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
338 params->period_step = 1;
339 if(((!strcmp(handle->useCase,SND_USE_CASE_MOD_PLAY_VOIP)) ||
340 (!strcmp(handle->useCase,SND_USE_CASE_VERB_IP_VOICECALL)))){
Iliyan Malchev4113f342012-06-11 14:39:47 -0700341 ALOGV("setparam: start & stop threshold for Voip ");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700342 params->avail_min = handle->channels - 1 ? periodSize/4 : periodSize/2;
343 params->start_threshold = periodSize/2;
344 params->stop_threshold = INT_MAX;
345 } else {
346 params->avail_min = periodSize/2;
347 params->start_threshold = channels * (periodSize/4);
348 params->stop_threshold = INT_MAX;
349 }
350 params->silence_threshold = 0;
351 params->silence_size = 0;
352
353 if (param_set_sw_params(handle->handle, params)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700354 ALOGE("cannot set sw params");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700355 return NO_INIT;
356 }
357 return NO_ERROR;
358}
359
360void switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode)
361{
362 const char **mods_list;
363 use_case_t useCaseNode;
364 unsigned usecase_type = 0;
365 bool inCallDevSwitch = false;
366 char *rxDevice, *txDevice, ident[70], *use_case = NULL;
367 int err = 0, index, mods_size;
368 int rx_dev_id, tx_dev_id;
SathishKumar Mani9efed762012-09-18 18:52:48 -0700369 ALOGD("%s: device %d mode:%d", __FUNCTION__, devices, mode);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700370
371 if ((mode == AudioSystem::MODE_IN_CALL) || (mode == AudioSystem::MODE_IN_COMMUNICATION)) {
372 if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
373 (devices & AudioSystem::DEVICE_IN_WIRED_HEADSET)) {
374 devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADSET |
375 AudioSystem::DEVICE_IN_WIRED_HEADSET);
376 } else if (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
377 devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADPHONE |
378 AudioSystem::DEVICE_IN_BUILTIN_MIC);
SathishKumar Manic669c272012-09-21 20:12:08 -0700379 } else if (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) {
380 if (mode == AudioSystem::MODE_IN_CALL) {
381 devices |= AudioSystem::DEVICE_OUT_EARPIECE;
382 }
383 } else if (devices & AudioSystem::DEVICE_OUT_EARPIECE) {
384 devices = devices | AudioSystem::DEVICE_IN_BUILTIN_MIC;
Iliyan Malchev4765c432012-06-11 14:36:16 -0700385 } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) {
ty.lee10dfa852012-08-01 21:09:45 +0900386 devices = devices | (AudioSystem::DEVICE_IN_BACK_MIC |
Iliyan Malchev4765c432012-06-11 14:36:16 -0700387 AudioSystem::DEVICE_OUT_SPEAKER);
388 } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) ||
389 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
390 (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
391 devices = devices | (AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET |
392 AudioSystem::DEVICE_OUT_BLUETOOTH_SCO);
Ajay Dudani9746c472012-06-18 16:01:16 -0700393#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700394 } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
395 (devices & AudioSystem::DEVICE_IN_ANC_HEADSET)) {
396 devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADSET |
397 AudioSystem::DEVICE_IN_ANC_HEADSET);
398 } else if (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE) {
399 devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADPHONE |
400 AudioSystem::DEVICE_IN_BUILTIN_MIC);
401#endif
402 } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
403 devices = devices | (AudioSystem::DEVICE_OUT_AUX_DIGITAL |
404 AudioSystem::DEVICE_IN_AUX_DIGITAL);
Ajay Dudani9746c472012-06-18 16:01:16 -0700405#ifdef QCOM_PROXY_DEVICE_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700406 } else if ((devices & AudioSystem::DEVICE_OUT_PROXY) ||
407 (devices & AudioSystem::DEVICE_IN_PROXY)) {
408 devices = devices | (AudioSystem::DEVICE_OUT_PROXY |
409 AudioSystem::DEVICE_IN_PROXY);
410#endif
411 }
412 }
Ajay Dudani9746c472012-06-18 16:01:16 -0700413#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700414 if ((devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) && ( 6 == handle->channels)) {
415 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
416 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700417 ALOGV(" switchDevice , use ssr devices for channels:%d usecase:%s",handle->channels,handle->useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700418 s_set_flags(SSRQMIC_FLAG);
419 }
420 }
421#endif
422
423 rxDevice = getUCMDevice(devices & AudioSystem::DEVICE_OUT_ALL, 0, NULL);
424 txDevice = getUCMDevice(devices & AudioSystem::DEVICE_IN_ALL, 1, rxDevice);
425
Iliyan Malchev4765c432012-06-11 14:36:16 -0700426 if ((rxDevice != NULL) && (txDevice != NULL)) {
427 if (((strncmp(rxDevice, curRxUCMDevice, MAX_STR_LEN)) ||
SathishKumar Manic669c272012-09-21 20:12:08 -0700428 (strncmp(txDevice, curTxUCMDevice, MAX_STR_LEN))) &&
429 ((mode == AudioSystem::MODE_IN_CALL) ||
430 (mode == AudioSystem::MODE_IN_COMMUNICATION)))
Iliyan Malchev4765c432012-06-11 14:36:16 -0700431 inCallDevSwitch = true;
432 }
Ajay Dudani91bf8912012-08-20 18:48:13 -0700433
434#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Manic669c272012-09-21 20:12:08 -0700435 if (platform_is_Fusion3() && (inCallDevSwitch == true)) {
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700436 if (csd_disable_device == NULL) {
437 ALOGE("dlsym:Error:%s Loading csd_client_disable_device", dlerror());
438 } else {
439 err = csd_disable_device();
440 if (err < 0)
441 {
442 ALOGE("csd_client_disable_device, failed, error %d", err);
443 }
Ajay Dudani91bf8912012-08-20 18:48:13 -0700444 }
445 }
446#endif
447
Iliyan Malchev4765c432012-06-11 14:36:16 -0700448 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&use_case);
449 mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
450 if (rxDevice != NULL) {
451 if ((strncmp(curRxUCMDevice, "None", 4)) &&
452 ((strncmp(rxDevice, curRxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
453 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
454 strlen(SND_USE_CASE_VERB_INACTIVE)))) {
455 usecase_type = getUseCaseType(use_case);
456 if (usecase_type & USECASE_TYPE_RX) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700457 ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700458 strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
459 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
460 mUseCaseList.push_front(useCaseNode);
461 }
462 }
463 if (mods_size) {
464 for(index = 0; index < mods_size; index++) {
465 usecase_type = getUseCaseType(mods_list[index]);
466 if (usecase_type & USECASE_TYPE_RX) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700467 ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700468 strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
469 snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
470 mUseCaseList.push_back(useCaseNode);
471 }
472 }
473 }
474 snd_use_case_set(handle->ucMgr, "_disdev", curRxUCMDevice);
475 }
476 }
477 if (txDevice != NULL) {
478 if ((strncmp(curTxUCMDevice, "None", 4)) &&
479 ((strncmp(txDevice, curTxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
480 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
481 strlen(SND_USE_CASE_VERB_INACTIVE)))) {
482 usecase_type = getUseCaseType(use_case);
483 if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700484 ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700485 strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
486 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
487 mUseCaseList.push_front(useCaseNode);
488 }
489 }
490 if (mods_size) {
491 for(index = 0; index < mods_size; index++) {
492 usecase_type = getUseCaseType(mods_list[index]);
493 if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700494 ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700495 strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
496 snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
497 mUseCaseList.push_back(useCaseNode);
498 }
499 }
500 }
501 snd_use_case_set(handle->ucMgr, "_disdev", curTxUCMDevice);
502 }
503 }
SathishKumar Mani9efed762012-09-18 18:52:48 -0700504 ALOGD("%s,rxDev:%s, txDev:%s, curRxDev:%s, curTxDev:%s\n", __FUNCTION__, rxDevice, txDevice, curRxUCMDevice, curTxUCMDevice);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700505
506 if (rxDevice != NULL) {
507 snd_use_case_set(handle->ucMgr, "_enadev", rxDevice);
508 strlcpy(curRxUCMDevice, rxDevice, sizeof(curRxUCMDevice));
Ajay Dudani9746c472012-06-18 16:01:16 -0700509#ifdef QCOM_FM_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700510 if (devices & AudioSystem::DEVICE_OUT_FM)
511 s_set_fm_vol(fmVolume);
512#endif
513 }
514 if (txDevice != NULL) {
515 snd_use_case_set(handle->ucMgr, "_enadev", txDevice);
516 strlcpy(curTxUCMDevice, txDevice, sizeof(curTxUCMDevice));
517 }
518 for(ALSAUseCaseList::iterator it = mUseCaseList.begin(); it != mUseCaseList.end(); ++it) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700519 ALOGD("Route use case %s\n", it->useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700520 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
521 strlen(SND_USE_CASE_VERB_INACTIVE))) && (!strncmp(use_case, it->useCase, MAX_UC_LEN))) {
522 snd_use_case_set(handle->ucMgr, "_verb", it->useCase);
523 } else {
524 snd_use_case_set(handle->ucMgr, "_enamod", it->useCase);
525 }
526 }
527 if (!mUseCaseList.empty())
528 mUseCaseList.clear();
529 if (use_case != NULL) {
530 free(use_case);
531 use_case = NULL;
532 }
Iliyan Malchev4113f342012-06-11 14:39:47 -0700533 ALOGD("switchDevice: curTxUCMDevivce %s curRxDevDevice %s", curTxUCMDevice, curRxUCMDevice);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700534
SathishKumar Manic669c272012-09-21 20:12:08 -0700535 if (platform_is_Fusion3() && (inCallDevSwitch == true)) {
Iliyan Malchev4765c432012-06-11 14:36:16 -0700536 /* get tx acdb id */
537 memset(&ident,0,sizeof(ident));
538 strlcpy(ident, "ACDBID/", sizeof(ident));
539 strlcat(ident, curTxUCMDevice, sizeof(ident));
540 tx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
541
542 /* get rx acdb id */
543 memset(&ident,0,sizeof(ident));
544 strlcpy(ident, "ACDBID/", sizeof(ident));
545 strlcat(ident, curRxUCMDevice, sizeof(ident));
546 rx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
547
ehgrace.kim91e9fad2012-07-02 18:27:28 -0700548 if (((rx_dev_id == DEVICE_SPEAKER_MONO_RX_ACDB_ID ) || (rx_dev_id == DEVICE_SPEAKER_STEREO_RX_ACDB_ID ))
549 && tx_dev_id == DEVICE_HANDSET_TX_ACDB_ID) {
Iliyan Malchev4765c432012-06-11 14:36:16 -0700550 tx_dev_id = DEVICE_SPEAKER_TX_ACDB_ID;
551 }
552
Ajay Dudani9746c472012-06-18 16:01:16 -0700553#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4113f342012-06-11 14:39:47 -0700554 ALOGV("rx_dev_id=%d, tx_dev_id=%d\n", rx_dev_id, tx_dev_id);
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700555 if (csd_enable_device == NULL) {
556 ALOGE("dlsym:Error:%s Loading csd_client_enable_device", dlerror());
557 } else {
558 err = csd_enable_device(rx_dev_id, tx_dev_id, mDevSettingsFlag);
559 if (err < 0)
560 {
561 ALOGE("csd_client_disable_device failed, error %d", err);
562 }
Iliyan Malchev4765c432012-06-11 14:36:16 -0700563 }
Iliyan Malchev4113f342012-06-11 14:39:47 -0700564#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700565 }
566
567 if (rxDevice != NULL) {
568 if (pflag && (((!strncmp(rxDevice, DEVICE_SPEAKER_HEADSET, strlen(DEVICE_SPEAKER_HEADSET))) &&
569 ((!strncmp(curRxUCMDevice, DEVICE_HEADPHONES, strlen(DEVICE_HEADPHONES))) ||
570 (!strncmp(curRxUCMDevice, DEVICE_HEADSET, strlen(DEVICE_HEADSET))))) ||
571 (((!strncmp(curRxUCMDevice, DEVICE_SPEAKER_HEADSET, strlen(DEVICE_SPEAKER_HEADSET))) &&
572 ((!strncmp(rxDevice, DEVICE_HEADPHONES, strlen(DEVICE_HEADPHONES))) ||
573 (!strncmp(rxDevice, DEVICE_HEADSET, strlen(DEVICE_HEADSET))))))) &&
574 ((!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI, strlen(SND_USE_CASE_VERB_HIFI))) ||
575 (!strncmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC, strlen(SND_USE_CASE_MOD_PLAY_MUSIC))))) {
576 s_open(handle);
577 pflag = false;
578 }
579 }
580
581 if (rxDevice != NULL) {
582 free(rxDevice);
583 rxDevice = NULL;
584 }
585 if (txDevice != NULL) {
586 free(txDevice);
587 txDevice = NULL;
588 }
589}
590
591// ----------------------------------------------------------------------------
592
593static status_t s_init(alsa_device_t *module, ALSAHandleList &list)
594{
SathishKumar Mani9efed762012-09-18 18:52:48 -0700595 ALOGV("s_init: Initializing devices for ALSA module");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700596
597 list.clear();
598
599 return NO_ERROR;
600}
601
602static status_t s_open(alsa_handle_t *handle)
603{
604 char *devName;
605 unsigned flags = 0;
606 int err = NO_ERROR;
607
608 /* No need to call s_close for LPA as pcm device open and close is handled by LPAPlayer in stagefright */
609 if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) || (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA))
610 ||(!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) || (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
SathishKumar Mani9efed762012-09-18 18:52:48 -0700611 ALOGV("s_open: Opening LPA /Tunnel playback");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700612 return NO_ERROR;
613 }
614
615 s_close(handle);
616
SathishKumar Mani9efed762012-09-18 18:52:48 -0700617 ALOGV("s_open: handle %p", handle);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700618
619 // ASoC multicomponent requires a valid path (frontend/backend) for
620 // the device to be opened
621
622 // The PCM stream is opened in blocking mode, per ALSA defaults. The
623 // AudioFlinger seems to assume blocking mode too, so asynchronous mode
624 // should not be used.
SathishKumar Mani88613382012-08-13 18:40:18 -0700625 if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
626 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
627 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
628 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
629 ALOGV("LPA/tunnel use case");
630 flags |= PCM_MMAP;
631 flags |= DEBUG_ON;
632 } else if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI)) ||
633 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) ||
634 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -0700635 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC))) {
SathishKumar Mani88613382012-08-13 18:40:18 -0700636 ALOGV("Music case");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700637 flags = PCM_OUT;
638 } else {
639 flags = PCM_IN;
640 }
641 if (handle->channels == 1) {
642 flags |= PCM_MONO;
SathishKumar Manie42406e2012-08-29 16:25:54 -0700643 }
Ajay Dudani9746c472012-06-18 16:01:16 -0700644#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700645 else if (handle->channels == 4 ) {
646 flags |= PCM_QUAD;
647 } else if (handle->channels == 6 ) {
648 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
649 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
650 flags |= PCM_QUAD;
651 } else {
652 flags |= PCM_5POINT1;
653 }
SathishKumar Manie42406e2012-08-29 16:25:54 -0700654 }
Iliyan Malchev4765c432012-06-11 14:36:16 -0700655#endif
656 else {
657 flags |= PCM_STEREO;
658 }
659 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700660 ALOGE("Failed to get pcm device node: %s", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700661 return NO_INIT;
662 }
663 if (devName != NULL) {
664 handle->handle = pcm_open(flags, (char*)devName);
665 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700666 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700667 return NO_INIT;
668 }
669
670 if (!handle->handle) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700671 ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700672 free(devName);
673 return NO_INIT;
674 }
675
676 handle->handle->flags = flags;
677 err = setHardwareParams(handle);
678
679 if (err == NO_ERROR) {
680 err = setSoftwareParams(handle);
681 }
682
683 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700684 ALOGE("Set HW/SW params failed: Closing the pcm stream");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700685 s_standby(handle);
686 }
687
688 free(devName);
689 return NO_ERROR;
690}
691
692static status_t s_start_voip_call(alsa_handle_t *handle)
693{
694
695 char* devName;
696 char* devName1;
697 unsigned flags = 0;
698 int err = NO_ERROR;
699 uint8_t voc_pkt[VOIP_BUFFER_MAX_SIZE];
700
701 s_close(handle);
702 flags = PCM_OUT;
703 flags |= PCM_MONO;
Iliyan Malchev4113f342012-06-11 14:39:47 -0700704 ALOGV("s_open:s_start_voip_call handle %p", handle);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700705
706 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700707 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700708 return NO_INIT;
709 }
710
711 if (devName != NULL) {
712 handle->handle = pcm_open(flags, (char*)devName);
713 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700714 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700715 return NO_INIT;
716 }
717
718 if (!handle->handle) {
719 free(devName);
Iliyan Malchev4113f342012-06-11 14:39:47 -0700720 ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700721 return NO_INIT;
722 }
723
724 if (!pcm_ready(handle->handle)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700725 ALOGE(" pcm ready failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700726 }
727
728 handle->handle->flags = flags;
729 err = setHardwareParams(handle);
730
731 if (err == NO_ERROR) {
732 err = setSoftwareParams(handle);
733 }
734
735 err = pcm_prepare(handle->handle);
736 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700737 ALOGE("DEVICE_OUT_DIRECTOUTPUT: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700738 }
739
740 /* first write required start dsp */
741 memset(&voc_pkt,0,sizeof(voc_pkt));
742 pcm_write(handle->handle,&voc_pkt,handle->handle->period_size);
743 handle->rxHandle = handle->handle;
744 free(devName);
Iliyan Malchev4113f342012-06-11 14:39:47 -0700745 ALOGV("s_open: DEVICE_IN_COMMUNICATION ");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700746 flags = PCM_IN;
747 flags |= PCM_MONO;
748 handle->handle = 0;
749
750 if (deviceName(handle, flags, &devName1) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700751 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700752 return NO_INIT;
753 }
754 if (devName != NULL) {
755 handle->handle = pcm_open(flags, (char*)devName1);
756 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700757 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700758 return NO_INIT;
759 }
760
761 if (!handle->handle) {
762 free(devName);
Iliyan Malchev4113f342012-06-11 14:39:47 -0700763 ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700764 return NO_INIT;
765 }
766
767 if (!pcm_ready(handle->handle)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700768 ALOGE(" pcm ready in failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700769 }
770
771 handle->handle->flags = flags;
772
773 err = setHardwareParams(handle);
774
775 if (err == NO_ERROR) {
776 err = setSoftwareParams(handle);
777 }
778
779
780 err = pcm_prepare(handle->handle);
781 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700782 ALOGE("DEVICE_IN_COMMUNICATION: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700783 }
784
785 /* first read required start dsp */
786 memset(&voc_pkt,0,sizeof(voc_pkt));
787 pcm_read(handle->handle,&voc_pkt,handle->handle->period_size);
788 return NO_ERROR;
789}
790
791static status_t s_start_voice_call(alsa_handle_t *handle)
792{
793 char* devName;
794 unsigned flags = 0;
795 int err = NO_ERROR;
796
SathishKumar Mani9efed762012-09-18 18:52:48 -0700797 ALOGV("s_start_voice_call: handle %p", handle);
Ajay Dudani86c852b2012-07-19 15:28:45 -0700798
Iliyan Malchev4765c432012-06-11 14:36:16 -0700799 // ASoC multicomponent requires a valid path (frontend/backend) for
800 // the device to be opened
801
802 flags = PCM_OUT | PCM_MONO;
803 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700804 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700805 return NO_INIT;
806 }
807 if (devName != NULL) {
808 handle->handle = pcm_open(flags, (char*)devName);
809 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700810 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700811 return NO_INIT;
812 }
813 if (!handle->handle) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700814 ALOGE("s_start_voicecall: could not open PCM device");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700815 goto Error;
816 }
817
818 handle->handle->flags = flags;
819 err = setHardwareParams(handle);
820 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700821 ALOGE("s_start_voice_call: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700822 goto Error;
823 }
824
825 err = setSoftwareParams(handle);
826 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700827 ALOGE("s_start_voice_call: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700828 goto Error;
829 }
830
831 err = pcm_prepare(handle->handle);
832 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700833 ALOGE("s_start_voice_call: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700834 goto Error;
835 }
836
837 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700838 ALOGE("s_start_voice_call:SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700839 goto Error;
840 }
841
842 // Store the PCM playback device pointer in rxHandle
843 handle->rxHandle = handle->handle;
844 free(devName);
845
846 // Open PCM capture device
847 flags = PCM_IN | PCM_MONO;
848 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700849 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700850 goto Error;
851 }
852 if (devName != NULL) {
853 handle->handle = pcm_open(flags, (char*)devName);
854 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700855 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700856 return NO_INIT;
857 }
858 if (!handle->handle) {
859 free(devName);
860 goto Error;
861 }
862
863 handle->handle->flags = flags;
864 err = setHardwareParams(handle);
865 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700866 ALOGE("s_start_voice_call: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700867 goto Error;
868 }
869
870 err = setSoftwareParams(handle);
871 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700872 ALOGE("s_start_voice_call: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700873 goto Error;
874 }
875
876 err = pcm_prepare(handle->handle);
877 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700878 ALOGE("s_start_voice_call: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700879 goto Error;
880 }
881
882 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700883 ALOGE("s_start_voice_call:SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700884 goto Error;
885 }
886
887 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -0700888#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700889 if (csd_start_voice == NULL) {
890 ALOGE("dlsym:Error:%s Loading csd_client_start_voice", dlerror());
891 } else {
892 err = csd_start_voice();
893 if (err < 0){
894 ALOGE("s_start_voice_call: csd_client error %d\n", err);
895 goto Error;
896 }
Iliyan Malchev4765c432012-06-11 14:36:16 -0700897 }
Iliyan Malchev4113f342012-06-11 14:39:47 -0700898#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700899 }
900
901 free(devName);
902 return NO_ERROR;
903
904Error:
Iliyan Malchev4113f342012-06-11 14:39:47 -0700905 ALOGE("s_start_voice_call: Failed to initialize ALSA device '%s'", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700906 free(devName);
907 s_close(handle);
908 return NO_INIT;
909}
910
911static status_t s_start_fm(alsa_handle_t *handle)
912{
913 char *devName;
914 unsigned flags = 0;
915 int err = NO_ERROR;
916
SathishKumar Mani9efed762012-09-18 18:52:48 -0700917 ALOGV("s_start_fm: handle %p", handle);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700918
919 // ASoC multicomponent requires a valid path (frontend/backend) for
920 // the device to be opened
921
922 flags = PCM_OUT | PCM_STEREO;
923 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700924 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700925 goto Error;
926 }
927 if (devName != NULL) {
928 handle->handle = pcm_open(flags, (char*)devName);
929 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700930 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700931 return NO_INIT;
932 }
933 if (!handle->handle) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700934 ALOGE("s_start_fm: could not open PCM device");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700935 goto Error;
936 }
937
938 handle->handle->flags = flags;
939 err = setHardwareParams(handle);
940 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700941 ALOGE("s_start_fm: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700942 goto Error;
943 }
944
945 err = setSoftwareParams(handle);
946 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700947 ALOGE("s_start_fm: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700948 goto Error;
949 }
950
951 err = pcm_prepare(handle->handle);
952 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700953 ALOGE("s_start_fm: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700954 goto Error;
955 }
956
957 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700958 ALOGE("s_start_fm: SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700959 goto Error;
960 }
961
962 // Store the PCM playback device pointer in rxHandle
963 handle->rxHandle = handle->handle;
964 free(devName);
965
966 // Open PCM capture device
967 flags = PCM_IN | PCM_STEREO;
968 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700969 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700970 goto Error;
971 }
972 if (devName != NULL) {
973 handle->handle = pcm_open(flags, (char*)devName);
974 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700975 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700976 return NO_INIT;
977 }
978 if (!handle->handle) {
979 goto Error;
980 }
981
982 handle->handle->flags = flags;
983 err = setHardwareParams(handle);
984 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700985 ALOGE("s_start_fm: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700986 goto Error;
987 }
988
989 err = setSoftwareParams(handle);
990 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700991 ALOGE("s_start_fm: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700992 goto Error;
993 }
994
995 err = pcm_prepare(handle->handle);
996 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700997 ALOGE("s_start_fm: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700998 goto Error;
999 }
1000
1001 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001002 ALOGE("s_start_fm: SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001003 goto Error;
1004 }
1005
1006 s_set_fm_vol(fmVolume);
1007 free(devName);
1008 return NO_ERROR;
1009
1010Error:
1011 free(devName);
1012 s_close(handle);
1013 return NO_INIT;
1014}
1015
1016static status_t s_set_fm_vol(int value)
1017{
1018 status_t err = NO_ERROR;
1019
1020 ALSAControl control("/dev/snd/controlC0");
1021 control.set("Internal FM RX Volume",value,0);
1022 fmVolume = value;
1023
1024 return err;
1025}
1026
1027static status_t s_set_lpa_vol(int value)
1028{
1029 status_t err = NO_ERROR;
1030
1031 ALSAControl control("/dev/snd/controlC0");
1032 control.set("LPA RX Volume",value,0);
1033
1034 return err;
1035}
1036
1037static status_t s_start(alsa_handle_t *handle)
1038{
1039 status_t err = NO_ERROR;
1040
1041 if(!handle->handle) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001042 ALOGE("No active PCM driver to start");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001043 return err;
1044 }
1045
1046 err = pcm_prepare(handle->handle);
1047
1048 return err;
1049}
1050
1051static status_t s_close(alsa_handle_t *handle)
1052{
1053 int ret;
1054 status_t err = NO_ERROR;
1055 struct pcm *h = handle->rxHandle;
1056
1057 handle->rxHandle = 0;
SathishKumar Mani9efed762012-09-18 18:52:48 -07001058 ALOGV("s_close: handle %p h %p", handle, h);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001059 if (h) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001060 ALOGV("s_close rxHandle\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001061 err = pcm_close(h);
1062 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001063 ALOGE("s_close: pcm_close failed for rxHandle with err %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001064 }
1065 }
1066
1067 h = handle->handle;
1068 handle->handle = 0;
1069
1070 if (h) {
SathishKumar Mani9efed762012-09-18 18:52:48 -07001071 ALOGV("s_close handle h %p\n", h);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001072 err = pcm_close(h);
1073 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001074 ALOGE("s_close: pcm_close failed for handle with err %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001075 }
1076
1077 if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_VOICECALL) ||
1078 !strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_VOICE)) &&
1079 platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001080#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001081 if (csd_stop_voice == NULL) {
1082 ALOGE("dlsym:Error:%s Loading csd_client_disable_device", dlerror());
1083 } else {
1084 err = csd_stop_voice();
1085 if (err < 0) {
1086 ALOGE("s_close: csd_client error %d\n", err);
1087 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001088 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001089#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001090 }
1091
1092 disableDevice(handle);
1093 } else if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
1094 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
1095 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
1096 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))){
1097 disableDevice(handle);
1098 }
1099
1100 return err;
1101}
1102
1103/*
1104 this is same as s_close, but don't discard
1105 the device/mode info. This way we can still
1106 close the device, hit idle and power-save, reopen the pcm
1107 for the same device/mode after resuming
1108*/
1109static status_t s_standby(alsa_handle_t *handle)
1110{
1111 int ret;
SathishKumar Manie42406e2012-08-29 16:25:54 -07001112 status_t err = NO_ERROR;
Iliyan Malchev4765c432012-06-11 14:36:16 -07001113 struct pcm *h = handle->rxHandle;
1114 handle->rxHandle = 0;
SathishKumar Mani9efed762012-09-18 18:52:48 -07001115 ALOGV("s_standby: handle %p h %p", handle, h);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001116 if (h) {
SathishKumar Mani0a019912012-09-11 12:33:11 -07001117 ALOGD("s_standby rxHandle\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001118 err = pcm_close(h);
1119 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001120 ALOGE("s_standby: pcm_close failed for rxHandle with err %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001121 }
1122 }
1123
1124 h = handle->handle;
1125 handle->handle = 0;
1126
1127 if (h) {
SathishKumar Mani9efed762012-09-18 18:52:48 -07001128 ALOGV("s_standby handle h %p\n", h);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001129 err = pcm_close(h);
1130 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001131 ALOGE("s_standby: pcm_close failed for handle with err %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001132 }
1133 disableDevice(handle);
1134 } else if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
1135 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
1136 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
1137 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
1138 disableDevice(handle);
1139 }
1140
1141 return err;
1142}
1143
1144static status_t s_route(alsa_handle_t *handle, uint32_t devices, int mode)
1145{
1146 status_t status = NO_ERROR;
1147
Iliyan Malchev4113f342012-06-11 14:39:47 -07001148 ALOGD("s_route: devices 0x%x in mode %d", devices, mode);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001149 callMode = mode;
1150 switchDevice(handle, devices, mode);
1151 return status;
1152}
1153
1154int getUseCaseType(const char *useCase)
1155{
SathishKumar Mani0a019912012-09-11 12:33:11 -07001156 ALOGD("use case is %s\n", useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001157 if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI,
1158 strlen(SND_USE_CASE_VERB_HIFI)) ||
SathishKumar Mani88613382012-08-13 18:40:18 -07001159 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC,
1160 strlen(SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -07001161 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER,
1162 strlen(SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
1163 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_TUNNEL,
1164 strlen(SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
1165 !strncmp(useCase, SND_USE_CASE_VERB_DIGITAL_RADIO,
1166 strlen(SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
1167 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC,
1168 strlen(SND_USE_CASE_MOD_PLAY_MUSIC)) ||
SathishKumar Mani88613382012-08-13 18:40:18 -07001169 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC,
1170 strlen(SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -07001171 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LPA,
1172 strlen(SND_USE_CASE_MOD_PLAY_LPA)) ||
1173 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_TUNNEL,
1174 strlen(SND_USE_CASE_MOD_PLAY_TUNNEL)) ||
1175 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_FM,
1176 strlen(SND_USE_CASE_MOD_PLAY_FM))) {
1177 return USECASE_TYPE_RX;
1178 } else if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI_REC,
1179 strlen(SND_USE_CASE_VERB_HIFI_REC)) ||
SathishKumar Mani88613382012-08-13 18:40:18 -07001180 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC,
1181 strlen(SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC)) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -07001182 !strncmp(useCase, SND_USE_CASE_VERB_FM_REC,
1183 strlen(SND_USE_CASE_VERB_FM_REC)) ||
1184 !strncmp(useCase, SND_USE_CASE_VERB_FM_A2DP_REC,
1185 strlen(SND_USE_CASE_VERB_FM_A2DP_REC)) ||
1186 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC,
1187 strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC)) ||
SathishKumar Mani88613382012-08-13 18:40:18 -07001188 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC,
1189 strlen(SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC)) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -07001190 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_FM,
1191 strlen(SND_USE_CASE_MOD_CAPTURE_FM)) ||
1192 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM,
1193 strlen(SND_USE_CASE_MOD_CAPTURE_A2DP_FM))) {
1194 return USECASE_TYPE_TX;
1195 } else if (!strncmp(useCase, SND_USE_CASE_VERB_VOICECALL,
1196 strlen(SND_USE_CASE_VERB_VOICECALL)) ||
1197 !strncmp(useCase, SND_USE_CASE_VERB_IP_VOICECALL,
1198 strlen(SND_USE_CASE_VERB_IP_VOICECALL)) ||
1199 !strncmp(useCase, SND_USE_CASE_VERB_DL_REC,
1200 strlen(SND_USE_CASE_VERB_DL_REC)) ||
1201 !strncmp(useCase, SND_USE_CASE_VERB_UL_DL_REC,
1202 strlen(SND_USE_CASE_VERB_UL_DL_REC)) ||
1203 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOICE,
1204 strlen(SND_USE_CASE_MOD_PLAY_VOICE)) ||
1205 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOIP,
1206 strlen(SND_USE_CASE_MOD_PLAY_VOIP)) ||
1207 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
1208 strlen(SND_USE_CASE_MOD_CAPTURE_VOICE_DL)) ||
1209 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
1210 strlen(SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL)) ||
1211 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
1212 strlen(SND_USE_CASE_MOD_CAPTURE_VOICE)) ||
1213 !strncmp(useCase, SND_USE_CASE_VERB_VOLTE,
1214 strlen(SND_USE_CASE_VERB_VOLTE)) ||
1215 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOLTE,
1216 strlen(SND_USE_CASE_MOD_PLAY_VOLTE))) {
1217 return (USECASE_TYPE_RX | USECASE_TYPE_TX);
1218 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001219 ALOGE("unknown use case %s\n", useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001220 return 0;
1221 }
1222}
1223
1224static void disableDevice(alsa_handle_t *handle)
1225{
1226 unsigned usecase_type = 0;
1227 int i, mods_size;
1228 char *useCase;
1229 const char **mods_list;
1230
1231 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
1232 if (useCase != NULL) {
1233 if (!strncmp(useCase, handle->useCase, MAX_UC_LEN)) {
1234 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
1235 } else {
1236 snd_use_case_set(handle->ucMgr, "_dismod", handle->useCase);
1237 }
1238 free(useCase);
1239 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
1240 if (strncmp(useCase, SND_USE_CASE_VERB_INACTIVE,
1241 strlen(SND_USE_CASE_VERB_INACTIVE)))
1242 usecase_type |= getUseCaseType(useCase);
1243 mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
SathishKumar Mani9efed762012-09-18 18:52:48 -07001244 ALOGV("Number of modifiers %d\n", mods_size);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001245 if (mods_size) {
1246 for(i = 0; i < mods_size; i++) {
SathishKumar Mani9efed762012-09-18 18:52:48 -07001247 ALOGV("index %d modifier %s\n", i, mods_list[i]);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001248 usecase_type |= getUseCaseType(mods_list[i]);
1249 }
1250 }
SathishKumar Mani9efed762012-09-18 18:52:48 -07001251 ALOGV("usecase_type is %d\n", usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001252 if (!(usecase_type & USECASE_TYPE_TX) && (strncmp(curTxUCMDevice, "None", 4)))
1253 snd_use_case_set(handle->ucMgr, "_disdev", curTxUCMDevice);
1254 if (!(usecase_type & USECASE_TYPE_RX) && (strncmp(curRxUCMDevice, "None", 4)))
1255 snd_use_case_set(handle->ucMgr, "_disdev", curRxUCMDevice);
1256 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001257 ALOGE("Invalid state, no valid use case found to disable");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001258 }
1259 free(useCase);
1260}
1261
1262char *getUCMDevice(uint32_t devices, int input, char *rxDevice)
1263{
1264 if (!input) {
1265 if (!(mDevSettingsFlag & TTY_OFF) &&
1266 (callMode == AudioSystem::MODE_IN_CALL) &&
1267 ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
ty.lee924f7982012-08-01 23:15:30 +09001268 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001269#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001270 ||
1271 (devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
1272 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) {
1273#endif
1274 if (mDevSettingsFlag & TTY_VCO) {
1275 return strdup(SND_USE_CASE_DEV_TTY_HEADSET_RX);
1276 } else if (mDevSettingsFlag & TTY_FULL) {
1277 return strdup(SND_USE_CASE_DEV_TTY_FULL_RX);
1278 } else if (mDevSettingsFlag & TTY_HCO) {
1279 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_RX); /* HANDSET RX */
1280 }
1281 }else if ((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET) ||
1282 (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)) {
1283 return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */
1284 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1285 ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
1286 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
1287 if (mDevSettingsFlag & ANC_FLAG) {
1288 return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
1289 } else {
1290 return strdup(SND_USE_CASE_DEV_SPEAKER_HEADSET); /* COMBO SPEAKER+HEADSET RX */
1291 }
Ajay Dudani9746c472012-06-18 16:01:16 -07001292#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001293 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1294 ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
1295 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) {
1296 return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
1297 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1298 (devices & AudioSystem::DEVICE_OUT_FM_TX)) {
1299 return strdup(SND_USE_CASE_DEV_SPEAKER_FM_TX); /* COMBO SPEAKER+FM_TX RX */
1300#endif
1301 } else if (devices & AudioSystem::DEVICE_OUT_EARPIECE) {
ty.lee925596f2012-09-12 18:23:59 +09001302 if (callMode == AudioSystem::MODE_IN_CALL) {
1303 return strdup(SND_USE_CASE_DEV_VOC_EARPIECE); /* Voice HANDSET RX */
1304 } else
1305 return strdup(SND_USE_CASE_DEV_EARPIECE); /* HANDSET RX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001306 } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) {
ty.lee925596f2012-09-12 18:23:59 +09001307 if (callMode == AudioSystem::MODE_IN_CALL) {
1308 return strdup(SND_USE_CASE_DEV_VOC_SPEAKER); /* Voice SPEAKER RX */
1309 } else
1310 return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001311 } else if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
1312 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) {
1313 if (mDevSettingsFlag & ANC_FLAG) {
ty.lee925596f2012-09-12 18:23:59 +09001314 if (callMode == AudioSystem::MODE_IN_CALL) {
1315 return strdup(SND_USE_CASE_DEV_VOC_ANC_HEADSET); /* Voice ANC HEADSET RX */
1316 } else
1317 return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001318 } else {
ty.lee925596f2012-09-12 18:23:59 +09001319 if (callMode == AudioSystem::MODE_IN_CALL) {
1320 return strdup(SND_USE_CASE_DEV_VOC_HEADPHONE); /* Voice HEADSET RX */
1321 } else
1322 return strdup(SND_USE_CASE_DEV_HEADPHONES); /* HEADSET RX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001323 }
Ajay Dudani9746c472012-06-18 16:01:16 -07001324#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001325 } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
1326 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE)) {
ty.lee925596f2012-09-12 18:23:59 +09001327 if (callMode == AudioSystem::MODE_IN_CALL) {
1328 return strdup(SND_USE_CASE_DEV_VOC_ANC_HEADSET); /* Voice ANC HEADSET RX */
1329 } else
1330 return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001331#endif
1332 } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) ||
1333 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
1334 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT)) {
1335 if (btsco_samplerate == BTSCO_RATE_16KHZ)
1336 return strdup(SND_USE_CASE_DEV_BTSCO_WB_RX); /* BTSCO RX*/
1337 else
1338 return strdup(SND_USE_CASE_DEV_BTSCO_NB_RX); /* BTSCO RX*/
1339 } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP) ||
1340 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES) ||
Ajay Dudani9746c472012-06-18 16:01:16 -07001341#ifdef QCOM_VOIP_ENABLED
1342 (devices & AudioSystem::DEVICE_OUT_DIRECTOUTPUT) ||
1343#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001344 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) {
1345 /* Nothing to be done, use current active device */
1346 if (strncmp(curRxUCMDevice, "None", 4)) {
1347 return strdup(curRxUCMDevice);
1348 }
1349 } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
1350 return strdup(SND_USE_CASE_DEV_HDMI); /* HDMI RX */
Ajay Dudani9746c472012-06-18 16:01:16 -07001351#ifdef QCOM_PROXY_DEVICE_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001352 } else if (devices & AudioSystem::DEVICE_OUT_PROXY) {
1353 return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */
Ajay Dudani9746c472012-06-18 16:01:16 -07001354#endif
1355#ifdef QCOM_FM_TX_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001356 } else if (devices & AudioSystem::DEVICE_OUT_FM_TX) {
1357 return strdup(SND_USE_CASE_DEV_FM_TX); /* FM Tx */
1358#endif
1359 } else if (devices & AudioSystem::DEVICE_OUT_DEFAULT) {
ty.lee925596f2012-09-12 18:23:59 +09001360 if (callMode == AudioSystem::MODE_IN_CALL) {
1361 return strdup(SND_USE_CASE_DEV_VOC_SPEAKER); /* Voice SPEAKER RX */
1362 } else
1363 return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001364 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001365 ALOGD("No valid output device: %u", devices);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001366 }
1367 } else {
1368 if (!(mDevSettingsFlag & TTY_OFF) &&
1369 (callMode == AudioSystem::MODE_IN_CALL) &&
ty.lee924f7982012-08-01 23:15:30 +09001370 ((devices & AudioSystem::DEVICE_IN_WIRED_HEADSET))) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001371#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001372 ||(devices & AudioSystem::DEVICE_IN_ANC_HEADSET))) {
1373#endif
1374 if (mDevSettingsFlag & TTY_HCO) {
1375 return strdup(SND_USE_CASE_DEV_TTY_HEADSET_TX);
1376 } else if (mDevSettingsFlag & TTY_FULL) {
1377 return strdup(SND_USE_CASE_DEV_TTY_FULL_TX);
1378 } else if (mDevSettingsFlag & TTY_VCO) {
1379 if (!strncmp(mic_type, "analog", 6)) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001380 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_ANALOG_TX);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001381 } else {
1382 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_TX);
1383 }
1384 }
1385 } else if (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) {
1386 if (!strncmp(mic_type, "analog", 6)) {
1387 return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
1388 } else {
1389 if (mDevSettingsFlag & DMIC_FLAG) {
ty.lee924f7982012-08-01 23:15:30 +09001390#ifdef USES_FLUENCE_INCALL
1391 if(callMode == AudioSystem::MODE_IN_CALL) {
1392 if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
1393 return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
1394 } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
1395 return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
1396 } else {
1397 return strdup(SND_USE_CASE_DEV_HANDSET); /* BUILTIN-MIC TX */
1398 }
1399 }
1400#else
Iliyan Malchev4765c432012-06-11 14:36:16 -07001401 if (((rxDevice != NULL) &&
1402 !strncmp(rxDevice, SND_USE_CASE_DEV_SPEAKER,
1403 (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) ||
1404 !strncmp(curRxUCMDevice, SND_USE_CASE_DEV_SPEAKER,
1405 (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) {
1406 if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
1407 return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
1408 } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
1409 return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
1410 }
1411 } else {
1412 if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
1413 return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
1414 } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
1415 return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
1416 }
1417 }
ty.lee924f7982012-08-01 23:15:30 +09001418#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001419 } else if (mDevSettingsFlag & QMIC_FLAG){
1420 return strdup(SND_USE_CASE_DEV_QUAD_MIC);
ty.lee924f7982012-08-01 23:15:30 +09001421 }
Ajay Dudani9746c472012-06-18 16:01:16 -07001422#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001423 else if (mDevSettingsFlag & SSRQMIC_FLAG){
Iliyan Malchev4113f342012-06-11 14:39:47 -07001424 ALOGV("return SSRQMIC_FLAG: 0x%x devices:0x%x",mDevSettingsFlag,devices);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001425 // Mapping for quad mic input device.
1426 return strdup(SND_USE_CASE_DEV_SSR_QUAD_MIC); /* SSR Quad MIC */
ty.lee924f7982012-08-01 23:15:30 +09001427 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001428#endif
ty.lee74060de2012-08-02 00:47:00 +09001429#ifdef SEPERATED_AUDIO_INPUT
1430 if(input_source == AUDIO_SOURCE_VOICE_RECOGNITION) {
ty.lee74060de2012-08-02 00:47:00 +09001431 return strdup(SND_USE_CASE_DEV_VOICE_RECOGNITION ); /* VOICE RECOGNITION TX */
1432 } else if(input_source == AUDIO_SOURCE_CAMCORDER) {
ty.lee74060de2012-08-02 00:47:00 +09001433 return strdup(SND_USE_CASE_DEV_CAMCORDER_TX ); /* CAMCORDER TX */
1434 }
1435#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001436 else {
ty.lee74060de2012-08-02 00:47:00 +09001437 return strdup(SND_USE_CASE_DEV_HANDSET); /* BUILTIN-MIC TX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001438 }
1439 }
1440 } else if (devices & AudioSystem::DEVICE_IN_AUX_DIGITAL) {
1441 return strdup(SND_USE_CASE_DEV_HDMI_TX); /* HDMI TX */
Ajay Dudani9746c472012-06-18 16:01:16 -07001442#ifdef QCOM_ANC_HEADSET_ENABLED
ehgrace.kim249f87d2012-08-12 20:40:32 -07001443 } else if (devices & AudioSystem::DEVICE_IN_ANC_HEADSET) {
Iliyan Malchev4765c432012-06-11 14:36:16 -07001444 return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */
1445#endif
ehgrace.kim249f87d2012-08-12 20:40:32 -07001446 } else if (devices & AudioSystem::DEVICE_IN_WIRED_HEADSET) {
ty.lee925596f2012-09-12 18:23:59 +09001447 if (callMode == AudioSystem::MODE_IN_CALL) {
1448 return strdup(SND_USE_CASE_DEV_VOC_HEADSET); /* Voice HEADSET TX */
1449 } else
1450 return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001451 } else if (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
1452 if (btsco_samplerate == BTSCO_RATE_16KHZ)
1453 return strdup(SND_USE_CASE_DEV_BTSCO_WB_TX); /* BTSCO TX*/
1454 else
1455 return strdup(SND_USE_CASE_DEV_BTSCO_NB_TX); /* BTSCO TX*/
Ajay Dudani9746c472012-06-18 16:01:16 -07001456#ifdef QCOM_USBAUDIO_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001457 } else if ((devices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) ||
1458 (devices & AudioSystem::DEVICE_IN_PROXY)) {
1459 return strdup(SND_USE_CASE_DEV_PROXY_TX); /* PROXY TX */
1460#endif
1461 } else if ((devices & AudioSystem::DEVICE_IN_COMMUNICATION) ||
1462 (devices & AudioSystem::DEVICE_IN_VOICE_CALL)) {
1463 /* Nothing to be done, use current active device */
1464 if (strncmp(curTxUCMDevice, "None", 4)) {
1465 return strdup(curTxUCMDevice);
1466 }
Ajay Dudani9746c472012-06-18 16:01:16 -07001467#ifdef QCOM_FM_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001468 } else if ((devices & AudioSystem::DEVICE_IN_FM_RX) ||
1469 (devices & AudioSystem::DEVICE_IN_FM_RX_A2DP)) {
1470 /* Nothing to be done, use current tx device or set dummy device */
1471 if (strncmp(curTxUCMDevice, "None", 4)) {
1472 return strdup(curTxUCMDevice);
1473 } else {
1474 return strdup(SND_USE_CASE_DEV_DUMMY_TX);
1475 }
1476#endif
1477 } else if ((devices & AudioSystem::DEVICE_IN_AMBIENT) ||
1478 (devices & AudioSystem::DEVICE_IN_BACK_MIC)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001479 ALOGI("No proper mapping found with UCM device list, setting default");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001480 if (!strncmp(mic_type, "analog", 6)) {
1481 return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
1482 } else {
ty.lee925596f2012-09-12 18:23:59 +09001483 if (callMode == AudioSystem::MODE_IN_CALL) {
1484 return strdup(SND_USE_CASE_DEV_VOC_LINE); /* Voice BUILTIN-MIC TX */
1485 } else
1486 return strdup(SND_USE_CASE_DEV_LINE); /* BUILTIN-MIC TX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001487 }
1488 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001489 ALOGD("No valid input device: %u", devices);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001490 }
1491 }
1492 return NULL;
1493}
1494
1495void s_set_voice_volume(int vol)
1496{
1497 int err = 0;
SathishKumar Mani9efed762012-09-18 18:52:48 -07001498 ALOGV("s_set_voice_volume: volume %d", vol);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001499 ALSAControl control("/dev/snd/controlC0");
1500 control.set("Voice Rx Volume", vol, 0);
1501
1502 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001503#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001504 if (csd_volume == NULL) {
1505 ALOGE("dlsym:Error:%s Loading csd_client_volume", dlerror());
1506 } else {
1507 err = csd_volume(vol);
1508 if (err < 0) {
1509 ALOGE("s_set_voice_volume: csd_client error %d", err);
1510 }
SathishKumar Manie42406e2012-08-29 16:25:54 -07001511 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001512#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001513 }
1514}
1515
1516void s_set_volte_volume(int vol)
1517{
SathishKumar Mani9efed762012-09-18 18:52:48 -07001518 ALOGV("s_set_volte_volume: volume %d", vol);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001519 ALSAControl control("/dev/snd/controlC0");
1520 control.set("VoLTE Rx Volume", vol, 0);
1521}
1522
1523
1524void s_set_voip_volume(int vol)
1525{
SathishKumar Mani9efed762012-09-18 18:52:48 -07001526 ALOGV("s_set_voip_volume: volume %d", vol);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001527 ALSAControl control("/dev/snd/controlC0");
1528 control.set("Voip Rx Volume", vol, 0);
1529}
1530void s_set_mic_mute(int state)
1531{
1532 int err = 0;
SathishKumar Mani9efed762012-09-18 18:52:48 -07001533 ALOGV("s_set_mic_mute: state %d", state);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001534 ALSAControl control("/dev/snd/controlC0");
1535 control.set("Voice Tx Mute", state, 0);
1536
1537 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001538#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001539 if (csd_mic_mute == NULL) {
1540 ALOGE("dlsym:Error:%s Loading csd_mic_mute", dlerror());
1541 } else {
1542 err=csd_mic_mute(state);
1543 if (err < 0) {
1544 ALOGE("s_set_mic_mute: csd_client error %d", err);
1545 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001546 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001547#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001548 }
1549}
1550void s_set_volte_mic_mute(int state)
1551{
SathishKumar Mani9efed762012-09-18 18:52:48 -07001552 ALOGV("s_set_volte_mic_mute: state %d", state);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001553 ALSAControl control("/dev/snd/controlC0");
1554 control.set("VoLTE Tx Mute", state, 0);
1555}
1556
1557void s_set_voip_mic_mute(int state)
1558{
SathishKumar Mani9efed762012-09-18 18:52:48 -07001559 ALOGV("s_set_voip_mic_mute: state %d", state);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001560 ALSAControl control("/dev/snd/controlC0");
1561 control.set("Voip Tx Mute", state, 0);
1562}
1563
1564void s_set_voip_config(int mode, int rate)
1565{
SathishKumar Mani9efed762012-09-18 18:52:48 -07001566 ALOGV("s_set_voip_config: mode %d,rate %d", mode, rate);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001567 ALSAControl control("/dev/snd/controlC0");
1568 char** setValues;
1569 setValues = (char**)malloc(2*sizeof(char*));
1570 if (setValues == NULL) {
1571 return;
1572 }
1573 setValues[0] = (char*)malloc(4*sizeof(char));
1574 if (setValues[0] == NULL) {
1575 free(setValues);
1576 return;
1577 }
1578
1579 setValues[1] = (char*)malloc(8*sizeof(char));
1580 if (setValues[1] == NULL) {
1581 free(setValues);
1582 free(setValues[0]);
1583 return;
1584 }
1585
1586 sprintf(setValues[0], "%d",mode);
1587 sprintf(setValues[1], "%d",rate);
1588
1589 control.setext("Voip Mode Rate Config", 2, setValues);
1590 free(setValues[1]);
1591 free(setValues[0]);
1592 free(setValues);
1593 return;
1594}
1595
1596void s_set_btsco_rate(int rate)
1597{
1598 btsco_samplerate = rate;
1599}
1600
1601void s_enable_wide_voice(bool flag)
1602{
1603 int err = 0;
1604
SathishKumar Mani9efed762012-09-18 18:52:48 -07001605 ALOGV("s_enable_wide_voice: flag %d", flag);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001606 ALSAControl control("/dev/snd/controlC0");
1607 if(flag == true) {
1608 control.set("Widevoice Enable", 1, 0);
1609 } else {
1610 control.set("Widevoice Enable", 0, 0);
1611 }
1612
1613 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001614#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001615 if (csd_wide_voice == NULL) {
1616 ALOGE("dlsym:Error:%s Loading csd_wide_voice", dlerror());
1617 } else {
1618 err = csd_wide_voice(flag);
1619 if (err < 0) {
1620 ALOGE("enableWideVoice: csd_client_wide_voice error %d", err);
1621 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001622 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001623#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001624 }
1625}
1626
1627void s_set_voc_rec_mode(uint8_t mode)
1628{
SathishKumar Mani9efed762012-09-18 18:52:48 -07001629 ALOGV("s_set_voc_rec_mode: mode %d", mode);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001630 ALSAControl control("/dev/snd/controlC0");
1631 control.set("Incall Rec Mode", mode, 0);
1632}
1633
1634void s_enable_fens(bool flag)
1635{
1636 int err = 0;
1637
SathishKumar Mani9efed762012-09-18 18:52:48 -07001638 ALOGV("s_enable_fens: flag %d", flag);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001639 ALSAControl control("/dev/snd/controlC0");
1640 if(flag == true) {
1641 control.set("FENS Enable", 1, 0);
1642 } else {
1643 control.set("FENS Enable", 0, 0);
1644 }
1645
1646 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001647#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001648 if (csd_fens == NULL) {
1649 ALOGE("dlsym:Error:%s Loading csd_fens", dlerror());
1650 } else {
1651 err = csd_fens(flag);
1652 if (err < 0) {
1653 ALOGE("s_enable_fens: csd_client error %d", err);
1654 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001655 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001656#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001657 }
1658}
1659
1660void s_enable_slow_talk(bool flag)
1661{
1662 int err = 0;
1663
SathishKumar Mani9efed762012-09-18 18:52:48 -07001664 ALOGV("s_enable_slow_talk: flag %d", flag);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001665 ALSAControl control("/dev/snd/controlC0");
1666 if(flag == true) {
1667 control.set("Slowtalk Enable", 1, 0);
1668 } else {
1669 control.set("Slowtalk Enable", 0, 0);
1670 }
1671
1672 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001673#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001674 if (csd_slow_talk == NULL) {
1675 ALOGE("dlsym:Error:%s Loading csd_slow_talk", dlerror());
1676 } else {
1677 err = csd_slow_talk(flag);
1678 if (err < 0) {
1679 ALOGE("s_enable_slow_talk: csd_client error %d", err);
1680 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001681 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001682#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001683 }
1684}
1685
1686void s_set_flags(uint32_t flags)
1687{
Iliyan Malchev4113f342012-06-11 14:39:47 -07001688 ALOGV("s_set_flags: flags %d", flags);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001689 mDevSettingsFlag = flags;
1690}
1691
1692static status_t s_set_compressed_vol(int value)
1693{
1694 status_t err = NO_ERROR;
1695
1696 ALSAControl control("/dev/snd/controlC0");
1697 control.set("COMPRESSED RX Volume",value,0);
1698
1699 return err;
1700}
1701
ty.lee74060de2012-08-02 00:47:00 +09001702#ifdef SEPERATED_AUDIO_INPUT
1703void s_setInput(int input)
1704{
1705 input_source = input;
1706 ALOGD("s_setInput() : input_source = %d",input_source);
1707}
1708#endif
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001709
1710#ifdef QCOM_CSDCLIENT_ENABLED
1711static void s_set_csd_handle(void* handle)
1712{
1713 csd_handle = static_cast<void*>(handle);
1714 ALOGI("%s csd_handle: %p", __func__, csd_handle);
1715
1716 csd_disable_device = (int (*)())::dlsym(csd_handle,"csd_client_disable_device");
1717 csd_enable_device = (int (*)(int,int,uint32_t))::dlsym(csd_handle,"csd_client_enable_device");
1718 csd_start_voice = (int (*)())::dlsym(csd_handle,"csd_client_start_voice");
1719 csd_stop_voice = (int (*)())::dlsym(csd_handle,"csd_client_stop_voice");
1720 csd_volume = (int (*)(int))::dlsym(csd_handle,"csd_client_volume");
1721 csd_mic_mute = (int (*)(int))::dlsym(csd_handle,"csd_client_mic_mute");
1722 csd_wide_voice = (int (*)(uint8_t))::dlsym(csd_handle,"csd_client_wide_voice");
1723 csd_fens = (int (*)(uint8_t))::dlsym(csd_handle,"csd_client_fens");
1724 csd_slow_talk = (int (*)(uint8_t))::dlsym(csd_handle,"csd_client_slow_talk");
1725}
1726#endif
1727
Iliyan Malchev4765c432012-06-11 14:36:16 -07001728}