blob: 0fd9f83e6f85185872e0d604a8d8c902cac17302 [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>
Ajay Dudani9746c472012-06-18 16:01:16 -070027#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -070028extern "C" {
29#include "csd_client.h"
30}
Iliyan Malchev4113f342012-06-11 14:39:47 -070031#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -070032
33#ifndef ALSA_DEFAULT_SAMPLE_RATE
34#define ALSA_DEFAULT_SAMPLE_RATE 44100 // in Hz
35#endif
36
37#define BTSCO_RATE_16KHZ 16000
38#define USECASE_TYPE_RX 1
39#define USECASE_TYPE_TX 2
40
41namespace android_audio_legacy
42{
43
44static int s_device_open(const hw_module_t*, const char*, hw_device_t**);
45static int s_device_close(hw_device_t*);
46static status_t s_init(alsa_device_t *, ALSAHandleList &);
47static status_t s_open(alsa_handle_t *);
48static status_t s_close(alsa_handle_t *);
49static status_t s_standby(alsa_handle_t *);
50static status_t s_route(alsa_handle_t *, uint32_t, int);
51static status_t s_start_voice_call(alsa_handle_t *);
52static status_t s_start_voip_call(alsa_handle_t *);
53static status_t s_start_fm(alsa_handle_t *);
54static void s_set_voice_volume(int);
55static void s_set_voip_volume(int);
56static void s_set_mic_mute(int);
57static void s_set_voip_mic_mute(int);
58static void s_set_voip_config(int, int);
59static status_t s_set_fm_vol(int);
60static void s_set_btsco_rate(int);
61static status_t s_set_lpa_vol(int);
62static void s_enable_wide_voice(bool flag);
63static void s_enable_fens(bool flag);
64static void s_set_flags(uint32_t flags);
65static status_t s_set_compressed_vol(int);
66static void s_enable_slow_talk(bool flag);
67static void s_set_voc_rec_mode(uint8_t mode);
68static void s_set_volte_mic_mute(int state);
69static void s_set_volte_volume(int vol);
ty.lee74060de2012-08-02 00:47:00 +090070#ifdef SEPERATED_AUDIO_INPUT
71static void s_setInput(int);
72
73static int input_source;
74#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -070075
76static char mic_type[25];
77static char curRxUCMDevice[50];
78static char curTxUCMDevice[50];
79static int fluence_mode;
80static int fmVolume;
ty.lee924f7982012-08-01 23:15:30 +090081#ifdef USES_FLUENCE_INCALL
82static uint32_t mDevSettingsFlag = TTY_OFF | DMIC_FLAG;
83#else
Iliyan Malchev4765c432012-06-11 14:36:16 -070084static uint32_t mDevSettingsFlag = TTY_OFF;
ty.lee924f7982012-08-01 23:15:30 +090085#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -070086static int btsco_samplerate = 8000;
87static bool pflag = false;
88static ALSAUseCaseList mUseCaseList;
89
90static hw_module_methods_t s_module_methods = {
91 open : s_device_open
92};
93
Iliyan Malchev4113f342012-06-11 14:39:47 -070094extern "C" hw_module_t HAL_MODULE_INFO_SYM = {
Iliyan Malchev4765c432012-06-11 14:36:16 -070095 tag : HARDWARE_MODULE_TAG,
96 version_major : 1,
97 version_minor : 0,
98 id : ALSA_HARDWARE_MODULE_ID,
99 name : "QCOM ALSA module",
100 author : "QuIC Inc",
101 methods : &s_module_methods,
102 dso : 0,
103 reserved : {0,},
104};
105
106static int s_device_open(const hw_module_t* module, const char* name,
107 hw_device_t** device)
108{
109 char value[128];
110 alsa_device_t *dev;
111 dev = (alsa_device_t *) malloc(sizeof(*dev));
112 if (!dev) return -ENOMEM;
113
114 memset(dev, 0, sizeof(*dev));
115
116 /* initialize the procs */
117 dev->common.tag = HARDWARE_DEVICE_TAG;
118 dev->common.version = 0;
119 dev->common.module = (hw_module_t *) module;
120 dev->common.close = s_device_close;
121 dev->init = s_init;
122 dev->open = s_open;
123 dev->close = s_close;
124 dev->route = s_route;
125 dev->standby = s_standby;
126 dev->startVoiceCall = s_start_voice_call;
127 dev->startVoipCall = s_start_voip_call;
128 dev->startFm = s_start_fm;
129 dev->setVoiceVolume = s_set_voice_volume;
130 dev->setVoipVolume = s_set_voip_volume;
131 dev->setMicMute = s_set_mic_mute;
132 dev->setVoipMicMute = s_set_voip_mic_mute;
133 dev->setVoipConfig = s_set_voip_config;
134 dev->setFmVolume = s_set_fm_vol;
135 dev->setBtscoRate = s_set_btsco_rate;
136 dev->setLpaVolume = s_set_lpa_vol;
137 dev->enableWideVoice = s_enable_wide_voice;
138 dev->enableFENS = s_enable_fens;
139 dev->setFlags = s_set_flags;
140 dev->setCompressedVolume = s_set_compressed_vol;
141 dev->enableSlowTalk = s_enable_slow_talk;
142 dev->setVocRecMode = s_set_voc_rec_mode;
143 dev->setVoLTEMicMute = s_set_volte_mic_mute;
144 dev->setVoLTEVolume = s_set_volte_volume;
ty.lee74060de2012-08-02 00:47:00 +0900145#ifdef SEPERATED_AUDIO_INPUT
146 dev->setInput = s_setInput;
147#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700148
149 *device = &dev->common;
150
151 property_get("persist.audio.handset.mic",value,"0");
152 strlcpy(mic_type, value, sizeof(mic_type));
153 property_get("persist.audio.fluence.mode",value,"0");
154 if (!strcmp("broadside", value)) {
155 fluence_mode = FLUENCE_MODE_BROADSIDE;
156 } else {
157 fluence_mode = FLUENCE_MODE_ENDFIRE;
158 }
159 strlcpy(curRxUCMDevice, "None", sizeof(curRxUCMDevice));
160 strlcpy(curTxUCMDevice, "None", sizeof(curTxUCMDevice));
Ajay Dudani86c852b2012-07-19 15:28:45 -0700161#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -0700162 ALOGD("ALSA module opened");
Ajay Dudani86c852b2012-07-19 15:28:45 -0700163#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700164
165 return 0;
166}
167
168static int s_device_close(hw_device_t* device)
169{
170 free(device);
171 device = NULL;
172 return 0;
173}
174
175// ----------------------------------------------------------------------------
176
177static const int DEFAULT_SAMPLE_RATE = ALSA_DEFAULT_SAMPLE_RATE;
178
179static void switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode);
180static char *getUCMDevice(uint32_t devices, int input, char *rxDevice);
181static void disableDevice(alsa_handle_t *handle);
182int getUseCaseType(const char *useCase);
183
184static int callMode = AudioSystem::MODE_NORMAL;
185// ----------------------------------------------------------------------------
186
187bool platform_is_Fusion3()
188{
189 char platform[128], baseband[128];
190 property_get("ro.board.platform", platform, "");
191 property_get("ro.baseband", baseband, "");
192 if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband))
193 return true;
194 else
195 return false;
196}
197
198int deviceName(alsa_handle_t *handle, unsigned flags, char **value)
199{
200 int ret = 0;
201 char ident[70];
202
203 if (flags & PCM_IN) {
204 strlcpy(ident, "CapturePCM/", sizeof(ident));
205 } else {
206 strlcpy(ident, "PlaybackPCM/", sizeof(ident));
207 }
208 strlcat(ident, handle->useCase, sizeof(ident));
209 ret = snd_use_case_get(handle->ucMgr, ident, (const char **)value);
Ajay Dudani8a9785b2012-09-10 23:28:45 -0700210#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -0700211 ALOGD("Device value returned is %s", (*value));
Ajay Dudani8a9785b2012-09-10 23:28:45 -0700212#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700213 return ret;
214}
215
216status_t setHardwareParams(alsa_handle_t *handle)
217{
218 struct snd_pcm_hw_params *params;
219 unsigned long bufferSize, reqBuffSize;
220 unsigned int periodTime, bufferTime;
221 unsigned int requestedRate = handle->sampleRate;
222 int status = 0;
223 int channels = handle->channels;
224 snd_pcm_format_t format = SNDRV_PCM_FORMAT_S16_LE;
225
226 params = (snd_pcm_hw_params*) calloc(1, sizeof(struct snd_pcm_hw_params));
227 if (!params) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700228 ALOGE("Failed to allocate ALSA hardware parameters!");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700229 return NO_INIT;
230 }
231
232 reqBuffSize = handle->bufferSize;
Ajay Dudani86c852b2012-07-19 15:28:45 -0700233#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -0700234 ALOGD("setHardwareParams: reqBuffSize %d channels %d sampleRate %d",
Iliyan Malchev4765c432012-06-11 14:36:16 -0700235 (int) reqBuffSize, handle->channels, handle->sampleRate);
Ajay Dudani86c852b2012-07-19 15:28:45 -0700236#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700237
Ajay Dudani9746c472012-06-18 16:01:16 -0700238#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700239 if (channels == 6) {
240 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
241 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700242 ALOGV("HWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700243 channels = 4;
244 reqBuffSize = DEFAULT_IN_BUFFER_SIZE;
245 }
246 }
247#endif
248
249 param_init(params);
250 param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS,
251 SNDRV_PCM_ACCESS_RW_INTERLEAVED);
252 if (handle->format != SNDRV_PCM_FORMAT_S16_LE) {
Ajay Dudani9746c472012-06-18 16:01:16 -0700253 if (handle->format == AudioSystem::AMR_NB
254 || handle->format == AudioSystem::AMR_WB
255#ifdef QCOM_QCHAT_ENABLED
256 || handle->format == AudioSystem::EVRC
257 || handle->format == AudioSystem::EVRCB
258 || handle->format == AudioSystem::EVRCWB
259#endif
260 )
Iliyan Malchev4765c432012-06-11 14:36:16 -0700261 format = SNDRV_PCM_FORMAT_SPECIAL;
262 }
263 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
264 format);
265 param_set_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT,
266 SNDRV_PCM_SUBFORMAT_STD);
267 param_set_min(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, reqBuffSize);
268 param_set_int(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 16);
269 param_set_int(params, SNDRV_PCM_HW_PARAM_FRAME_BITS,
270 channels * 16);
271 param_set_int(params, SNDRV_PCM_HW_PARAM_CHANNELS,
272 channels);
273 param_set_int(params, SNDRV_PCM_HW_PARAM_RATE, handle->sampleRate);
274 param_set_hw_refine(handle->handle, params);
275
276 if (param_set_hw_params(handle->handle, params)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700277 ALOGE("cannot set hw params");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700278 return NO_INIT;
279 }
280 param_dump(params);
281
282 handle->handle->buffer_size = pcm_buffer_size(params);
283 handle->handle->period_size = pcm_period_size(params);
284 handle->handle->period_cnt = handle->handle->buffer_size/handle->handle->period_size;
Ajay Dudani86c852b2012-07-19 15:28:45 -0700285#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -0700286 ALOGD("setHardwareParams: buffer_size %d, period_size %d, period_cnt %d",
Iliyan Malchev4765c432012-06-11 14:36:16 -0700287 handle->handle->buffer_size, handle->handle->period_size,
288 handle->handle->period_cnt);
Ajay Dudani86c852b2012-07-19 15:28:45 -0700289#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700290 handle->handle->rate = handle->sampleRate;
291 handle->handle->channels = handle->channels;
292 handle->periodSize = handle->handle->period_size;
293 if (strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC) &&
294 strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC) &&
295 (6 != handle->channels)) {
296 //Do not update buffersize for 5.1 recording
297 handle->bufferSize = handle->handle->period_size;
298 }
299
300 return NO_ERROR;
301}
302
303status_t setSoftwareParams(alsa_handle_t *handle)
304{
305 struct snd_pcm_sw_params* params;
306 struct pcm* pcm = handle->handle;
307
308 unsigned long periodSize = pcm->period_size;
309 int channels = handle->channels;
310
311 params = (snd_pcm_sw_params*) calloc(1, sizeof(struct snd_pcm_sw_params));
312 if (!params) {
313 LOG_ALWAYS_FATAL("Failed to allocate ALSA software parameters!");
314 return NO_INIT;
315 }
316
Ajay Dudani9746c472012-06-18 16:01:16 -0700317#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700318 if (channels == 6) {
319 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
320 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700321 ALOGV("SWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700322 channels = 4;
323 }
324 }
325#endif
326
327 // Get the current software parameters
328 params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
329 params->period_step = 1;
330 if(((!strcmp(handle->useCase,SND_USE_CASE_MOD_PLAY_VOIP)) ||
331 (!strcmp(handle->useCase,SND_USE_CASE_VERB_IP_VOICECALL)))){
Iliyan Malchev4113f342012-06-11 14:39:47 -0700332 ALOGV("setparam: start & stop threshold for Voip ");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700333 params->avail_min = handle->channels - 1 ? periodSize/4 : periodSize/2;
334 params->start_threshold = periodSize/2;
335 params->stop_threshold = INT_MAX;
336 } else {
337 params->avail_min = periodSize/2;
338 params->start_threshold = channels * (periodSize/4);
339 params->stop_threshold = INT_MAX;
340 }
341 params->silence_threshold = 0;
342 params->silence_size = 0;
343
344 if (param_set_sw_params(handle->handle, params)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700345 ALOGE("cannot set sw params");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700346 return NO_INIT;
347 }
348 return NO_ERROR;
349}
350
351void switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode)
352{
353 const char **mods_list;
354 use_case_t useCaseNode;
355 unsigned usecase_type = 0;
356 bool inCallDevSwitch = false;
357 char *rxDevice, *txDevice, ident[70], *use_case = NULL;
358 int err = 0, index, mods_size;
359 int rx_dev_id, tx_dev_id;
Iliyan Malchev4113f342012-06-11 14:39:47 -0700360 ALOGV("%s: device %d", __FUNCTION__, devices);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700361
362 if ((mode == AudioSystem::MODE_IN_CALL) || (mode == AudioSystem::MODE_IN_COMMUNICATION)) {
363 if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
364 (devices & AudioSystem::DEVICE_IN_WIRED_HEADSET)) {
365 devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADSET |
366 AudioSystem::DEVICE_IN_WIRED_HEADSET);
367 } else if (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
368 devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADPHONE |
369 AudioSystem::DEVICE_IN_BUILTIN_MIC);
370 } else if ((devices & AudioSystem::DEVICE_OUT_EARPIECE) ||
371 (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC)) {
372 devices = devices | (AudioSystem::DEVICE_IN_BUILTIN_MIC |
373 AudioSystem::DEVICE_OUT_EARPIECE);
374 } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) {
ty.lee10dfa852012-08-01 21:09:45 +0900375 devices = devices | (AudioSystem::DEVICE_IN_BACK_MIC |
Iliyan Malchev4765c432012-06-11 14:36:16 -0700376 AudioSystem::DEVICE_OUT_SPEAKER);
377 } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) ||
378 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
379 (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
380 devices = devices | (AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET |
381 AudioSystem::DEVICE_OUT_BLUETOOTH_SCO);
Ajay Dudani9746c472012-06-18 16:01:16 -0700382#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700383 } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
384 (devices & AudioSystem::DEVICE_IN_ANC_HEADSET)) {
385 devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADSET |
386 AudioSystem::DEVICE_IN_ANC_HEADSET);
387 } else if (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE) {
388 devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADPHONE |
389 AudioSystem::DEVICE_IN_BUILTIN_MIC);
390#endif
391 } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
392 devices = devices | (AudioSystem::DEVICE_OUT_AUX_DIGITAL |
393 AudioSystem::DEVICE_IN_AUX_DIGITAL);
Ajay Dudani9746c472012-06-18 16:01:16 -0700394#ifdef QCOM_PROXY_DEVICE_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700395 } else if ((devices & AudioSystem::DEVICE_OUT_PROXY) ||
396 (devices & AudioSystem::DEVICE_IN_PROXY)) {
397 devices = devices | (AudioSystem::DEVICE_OUT_PROXY |
398 AudioSystem::DEVICE_IN_PROXY);
399#endif
400 }
401 }
Ajay Dudani9746c472012-06-18 16:01:16 -0700402#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700403 if ((devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) && ( 6 == handle->channels)) {
404 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
405 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700406 ALOGV(" switchDevice , use ssr devices for channels:%d usecase:%s",handle->channels,handle->useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700407 s_set_flags(SSRQMIC_FLAG);
408 }
409 }
410#endif
411
412 rxDevice = getUCMDevice(devices & AudioSystem::DEVICE_OUT_ALL, 0, NULL);
413 txDevice = getUCMDevice(devices & AudioSystem::DEVICE_IN_ALL, 1, rxDevice);
414
415 if (rxDevice != NULL) {
416 if ((handle->handle) && (((!strncmp(rxDevice, DEVICE_SPEAKER_HEADSET, strlen(DEVICE_SPEAKER_HEADSET))) &&
417 ((!strncmp(curRxUCMDevice, DEVICE_HEADPHONES, strlen(DEVICE_HEADPHONES))) ||
418 (!strncmp(curRxUCMDevice, DEVICE_HEADSET, strlen(DEVICE_HEADSET))))) ||
419 (((!strncmp(curRxUCMDevice, DEVICE_SPEAKER_HEADSET, strlen(DEVICE_SPEAKER_HEADSET))) &&
420 ((!strncmp(rxDevice, DEVICE_HEADPHONES, strlen(DEVICE_HEADPHONES))) ||
421 (!strncmp(rxDevice, DEVICE_HEADSET, strlen(DEVICE_HEADSET))))))) &&
422 ((!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI, strlen(SND_USE_CASE_VERB_HIFI))) ||
423 (!strncmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC, strlen(SND_USE_CASE_MOD_PLAY_MUSIC))))) {
424 pcm_close(handle->handle);
425 handle->handle=NULL;
426 handle->rxHandle=NULL;
427 pflag = true;
428 }
429 }
430
431 if ((rxDevice != NULL) && (txDevice != NULL)) {
432 if (((strncmp(rxDevice, curRxUCMDevice, MAX_STR_LEN)) ||
433 (strncmp(txDevice, curTxUCMDevice, MAX_STR_LEN))) && (mode == AudioSystem::MODE_IN_CALL))
434 inCallDevSwitch = true;
435 }
Ajay Dudani91bf8912012-08-20 18:48:13 -0700436
437#ifdef QCOM_CSDCLIENT_ENABLED
438 if (mode == AudioSystem::MODE_IN_CALL && platform_is_Fusion3() && (inCallDevSwitch == true)) {
439 err = csd_client_disable_device();
440 if (err < 0)
441 {
442 ALOGE("csd_client_disable_device, failed, error %d", err);
443 }
444 }
445#endif
446
Iliyan Malchev4765c432012-06-11 14:36:16 -0700447 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&use_case);
448 mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
449 if (rxDevice != NULL) {
450 if ((strncmp(curRxUCMDevice, "None", 4)) &&
451 ((strncmp(rxDevice, curRxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
452 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
453 strlen(SND_USE_CASE_VERB_INACTIVE)))) {
454 usecase_type = getUseCaseType(use_case);
455 if (usecase_type & USECASE_TYPE_RX) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700456 ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700457 strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
458 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
459 mUseCaseList.push_front(useCaseNode);
460 }
461 }
462 if (mods_size) {
463 for(index = 0; index < mods_size; index++) {
464 usecase_type = getUseCaseType(mods_list[index]);
465 if (usecase_type & USECASE_TYPE_RX) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700466 ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700467 strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
468 snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
469 mUseCaseList.push_back(useCaseNode);
470 }
471 }
472 }
473 snd_use_case_set(handle->ucMgr, "_disdev", curRxUCMDevice);
474 }
475 }
476 if (txDevice != NULL) {
477 if ((strncmp(curTxUCMDevice, "None", 4)) &&
478 ((strncmp(txDevice, curTxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
479 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
480 strlen(SND_USE_CASE_VERB_INACTIVE)))) {
481 usecase_type = getUseCaseType(use_case);
482 if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700483 ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700484 strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
485 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
486 mUseCaseList.push_front(useCaseNode);
487 }
488 }
489 if (mods_size) {
490 for(index = 0; index < mods_size; index++) {
491 usecase_type = getUseCaseType(mods_list[index]);
492 if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700493 ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700494 strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
495 snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
496 mUseCaseList.push_back(useCaseNode);
497 }
498 }
499 }
500 snd_use_case_set(handle->ucMgr, "_disdev", curTxUCMDevice);
501 }
502 }
Iliyan Malchev4113f342012-06-11 14:39:47 -0700503 ALOGV("%s,rxDev:%s, txDev:%s, curRxDev:%s, curTxDev:%s\n", __FUNCTION__, rxDevice, txDevice, curRxUCMDevice, curTxUCMDevice);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700504
505 if (rxDevice != NULL) {
506 snd_use_case_set(handle->ucMgr, "_enadev", rxDevice);
507 strlcpy(curRxUCMDevice, rxDevice, sizeof(curRxUCMDevice));
Ajay Dudani9746c472012-06-18 16:01:16 -0700508#ifdef QCOM_FM_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700509 if (devices & AudioSystem::DEVICE_OUT_FM)
510 s_set_fm_vol(fmVolume);
511#endif
512 }
513 if (txDevice != NULL) {
514 snd_use_case_set(handle->ucMgr, "_enadev", txDevice);
515 strlcpy(curTxUCMDevice, txDevice, sizeof(curTxUCMDevice));
516 }
517 for(ALSAUseCaseList::iterator it = mUseCaseList.begin(); it != mUseCaseList.end(); ++it) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700518 ALOGD("Route use case %s\n", it->useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700519 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
520 strlen(SND_USE_CASE_VERB_INACTIVE))) && (!strncmp(use_case, it->useCase, MAX_UC_LEN))) {
521 snd_use_case_set(handle->ucMgr, "_verb", it->useCase);
522 } else {
523 snd_use_case_set(handle->ucMgr, "_enamod", it->useCase);
524 }
525 }
526 if (!mUseCaseList.empty())
527 mUseCaseList.clear();
528 if (use_case != NULL) {
529 free(use_case);
530 use_case = NULL;
531 }
Ajay Dudani8a9785b2012-09-10 23:28:45 -0700532#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -0700533 ALOGD("switchDevice: curTxUCMDevivce %s curRxDevDevice %s", curTxUCMDevice, curRxUCMDevice);
Ajay Dudani8a9785b2012-09-10 23:28:45 -0700534#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700535
536 if (mode == AudioSystem::MODE_IN_CALL && platform_is_Fusion3() && (inCallDevSwitch == true)) {
537 /* get tx acdb id */
538 memset(&ident,0,sizeof(ident));
539 strlcpy(ident, "ACDBID/", sizeof(ident));
540 strlcat(ident, curTxUCMDevice, sizeof(ident));
541 tx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
542
543 /* get rx acdb id */
544 memset(&ident,0,sizeof(ident));
545 strlcpy(ident, "ACDBID/", sizeof(ident));
546 strlcat(ident, curRxUCMDevice, sizeof(ident));
547 rx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
548
ehgrace.kim91e9fad2012-07-02 18:27:28 -0700549 if (((rx_dev_id == DEVICE_SPEAKER_MONO_RX_ACDB_ID ) || (rx_dev_id == DEVICE_SPEAKER_STEREO_RX_ACDB_ID ))
550 && tx_dev_id == DEVICE_HANDSET_TX_ACDB_ID) {
Iliyan Malchev4765c432012-06-11 14:36:16 -0700551 tx_dev_id = DEVICE_SPEAKER_TX_ACDB_ID;
552 }
553
Ajay Dudani9746c472012-06-18 16:01:16 -0700554#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4113f342012-06-11 14:39:47 -0700555 ALOGV("rx_dev_id=%d, tx_dev_id=%d\n", rx_dev_id, tx_dev_id);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700556 err = csd_client_enable_device(rx_dev_id, tx_dev_id, mDevSettingsFlag);
557 if (err < 0)
558 {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700559 ALOGE("csd_client_disable_device failed, error %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700560 }
Iliyan Malchev4113f342012-06-11 14:39:47 -0700561#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700562 }
563
564 if (rxDevice != NULL) {
565 if (pflag && (((!strncmp(rxDevice, DEVICE_SPEAKER_HEADSET, strlen(DEVICE_SPEAKER_HEADSET))) &&
566 ((!strncmp(curRxUCMDevice, DEVICE_HEADPHONES, strlen(DEVICE_HEADPHONES))) ||
567 (!strncmp(curRxUCMDevice, DEVICE_HEADSET, strlen(DEVICE_HEADSET))))) ||
568 (((!strncmp(curRxUCMDevice, DEVICE_SPEAKER_HEADSET, strlen(DEVICE_SPEAKER_HEADSET))) &&
569 ((!strncmp(rxDevice, DEVICE_HEADPHONES, strlen(DEVICE_HEADPHONES))) ||
570 (!strncmp(rxDevice, DEVICE_HEADSET, strlen(DEVICE_HEADSET))))))) &&
571 ((!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI, strlen(SND_USE_CASE_VERB_HIFI))) ||
572 (!strncmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC, strlen(SND_USE_CASE_MOD_PLAY_MUSIC))))) {
573 s_open(handle);
574 pflag = false;
575 }
576 }
577
578 if (rxDevice != NULL) {
579 free(rxDevice);
580 rxDevice = NULL;
581 }
582 if (txDevice != NULL) {
583 free(txDevice);
584 txDevice = NULL;
585 }
586}
587
588// ----------------------------------------------------------------------------
589
590static status_t s_init(alsa_device_t *module, ALSAHandleList &list)
591{
Ajay Dudani86c852b2012-07-19 15:28:45 -0700592#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -0700593 ALOGD("s_init: Initializing devices for ALSA module");
Ajay Dudani86c852b2012-07-19 15:28:45 -0700594#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700595
596 list.clear();
597
598 return NO_ERROR;
599}
600
601static status_t s_open(alsa_handle_t *handle)
602{
603 char *devName;
604 unsigned flags = 0;
605 int err = NO_ERROR;
606
607 /* No need to call s_close for LPA as pcm device open and close is handled by LPAPlayer in stagefright */
608 if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) || (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA))
609 ||(!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) || (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
Ajay Dudani8a9785b2012-09-10 23:28:45 -0700610#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -0700611 ALOGD("s_open: Opening LPA /Tunnel playback");
Ajay Dudani8a9785b2012-09-10 23:28:45 -0700612#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700613 return NO_ERROR;
614 }
615
616 s_close(handle);
617
Ajay Dudani86c852b2012-07-19 15:28:45 -0700618#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -0700619 ALOGD("s_open: handle %p", handle);
Ajay Dudani86c852b2012-07-19 15:28:45 -0700620#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700621
622 // ASoC multicomponent requires a valid path (frontend/backend) for
623 // the device to be opened
624
625 // The PCM stream is opened in blocking mode, per ALSA defaults. The
626 // AudioFlinger seems to assume blocking mode too, so asynchronous mode
627 // should not be used.
SathishKumar Mani88613382012-08-13 18:40:18 -0700628 if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
629 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
630 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
631 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
632 ALOGV("LPA/tunnel use case");
633 flags |= PCM_MMAP;
634 flags |= DEBUG_ON;
635 } else if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI)) ||
636 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) ||
637 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -0700638 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC))) {
SathishKumar Mani88613382012-08-13 18:40:18 -0700639 ALOGV("Music case");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700640 flags = PCM_OUT;
641 } else {
642 flags = PCM_IN;
643 }
644 if (handle->channels == 1) {
645 flags |= PCM_MONO;
646 }
Ajay Dudani9746c472012-06-18 16:01:16 -0700647#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700648 else if (handle->channels == 4 ) {
649 flags |= PCM_QUAD;
650 } else if (handle->channels == 6 ) {
651 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
652 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
653 flags |= PCM_QUAD;
654 } else {
655 flags |= PCM_5POINT1;
656 }
657 }
658#endif
659 else {
660 flags |= PCM_STEREO;
661 }
662 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700663 ALOGE("Failed to get pcm device node: %s", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700664 return NO_INIT;
665 }
666 if (devName != NULL) {
667 handle->handle = pcm_open(flags, (char*)devName);
668 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700669 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700670 return NO_INIT;
671 }
672
673 if (!handle->handle) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700674 ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700675 free(devName);
676 return NO_INIT;
677 }
678
679 handle->handle->flags = flags;
680 err = setHardwareParams(handle);
681
682 if (err == NO_ERROR) {
683 err = setSoftwareParams(handle);
684 }
685
686 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700687 ALOGE("Set HW/SW params failed: Closing the pcm stream");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700688 s_standby(handle);
689 }
690
691 free(devName);
692 return NO_ERROR;
693}
694
695static status_t s_start_voip_call(alsa_handle_t *handle)
696{
697
698 char* devName;
699 char* devName1;
700 unsigned flags = 0;
701 int err = NO_ERROR;
702 uint8_t voc_pkt[VOIP_BUFFER_MAX_SIZE];
703
704 s_close(handle);
705 flags = PCM_OUT;
706 flags |= PCM_MONO;
Iliyan Malchev4113f342012-06-11 14:39:47 -0700707 ALOGV("s_open:s_start_voip_call handle %p", handle);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700708
709 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700710 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700711 return NO_INIT;
712 }
713
714 if (devName != NULL) {
715 handle->handle = pcm_open(flags, (char*)devName);
716 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700717 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700718 return NO_INIT;
719 }
720
721 if (!handle->handle) {
722 free(devName);
Iliyan Malchev4113f342012-06-11 14:39:47 -0700723 ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700724 return NO_INIT;
725 }
726
727 if (!pcm_ready(handle->handle)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700728 ALOGE(" pcm ready failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700729 }
730
731 handle->handle->flags = flags;
732 err = setHardwareParams(handle);
733
734 if (err == NO_ERROR) {
735 err = setSoftwareParams(handle);
736 }
737
738 err = pcm_prepare(handle->handle);
739 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700740 ALOGE("DEVICE_OUT_DIRECTOUTPUT: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700741 }
742
743 /* first write required start dsp */
744 memset(&voc_pkt,0,sizeof(voc_pkt));
745 pcm_write(handle->handle,&voc_pkt,handle->handle->period_size);
746 handle->rxHandle = handle->handle;
747 free(devName);
Iliyan Malchev4113f342012-06-11 14:39:47 -0700748 ALOGV("s_open: DEVICE_IN_COMMUNICATION ");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700749 flags = PCM_IN;
750 flags |= PCM_MONO;
751 handle->handle = 0;
752
753 if (deviceName(handle, flags, &devName1) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700754 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700755 return NO_INIT;
756 }
757 if (devName != NULL) {
758 handle->handle = pcm_open(flags, (char*)devName1);
759 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700760 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700761 return NO_INIT;
762 }
763
764 if (!handle->handle) {
765 free(devName);
Iliyan Malchev4113f342012-06-11 14:39:47 -0700766 ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700767 return NO_INIT;
768 }
769
770 if (!pcm_ready(handle->handle)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700771 ALOGE(" pcm ready in failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700772 }
773
774 handle->handle->flags = flags;
775
776 err = setHardwareParams(handle);
777
778 if (err == NO_ERROR) {
779 err = setSoftwareParams(handle);
780 }
781
782
783 err = pcm_prepare(handle->handle);
784 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700785 ALOGE("DEVICE_IN_COMMUNICATION: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700786 }
787
788 /* first read required start dsp */
789 memset(&voc_pkt,0,sizeof(voc_pkt));
790 pcm_read(handle->handle,&voc_pkt,handle->handle->period_size);
791 return NO_ERROR;
792}
793
794static status_t s_start_voice_call(alsa_handle_t *handle)
795{
796 char* devName;
797 unsigned flags = 0;
798 int err = NO_ERROR;
799
Ajay Dudani86c852b2012-07-19 15:28:45 -0700800#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -0700801 ALOGD("s_start_voice_call: handle %p", handle);
Ajay Dudani86c852b2012-07-19 15:28:45 -0700802#endif
803
Iliyan Malchev4765c432012-06-11 14:36:16 -0700804 // ASoC multicomponent requires a valid path (frontend/backend) for
805 // the device to be opened
806
807 flags = PCM_OUT | PCM_MONO;
808 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700809 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700810 return NO_INIT;
811 }
812 if (devName != NULL) {
813 handle->handle = pcm_open(flags, (char*)devName);
814 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700815 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700816 return NO_INIT;
817 }
818 if (!handle->handle) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700819 ALOGE("s_start_voicecall: could not open PCM device");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700820 goto Error;
821 }
822
823 handle->handle->flags = flags;
824 err = setHardwareParams(handle);
825 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700826 ALOGE("s_start_voice_call: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700827 goto Error;
828 }
829
830 err = setSoftwareParams(handle);
831 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700832 ALOGE("s_start_voice_call: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700833 goto Error;
834 }
835
836 err = pcm_prepare(handle->handle);
837 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700838 ALOGE("s_start_voice_call: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700839 goto Error;
840 }
841
842 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700843 ALOGE("s_start_voice_call:SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700844 goto Error;
845 }
846
847 // Store the PCM playback device pointer in rxHandle
848 handle->rxHandle = handle->handle;
849 free(devName);
850
851 // Open PCM capture device
852 flags = PCM_IN | PCM_MONO;
853 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700854 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700855 goto Error;
856 }
857 if (devName != NULL) {
858 handle->handle = pcm_open(flags, (char*)devName);
859 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700860 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700861 return NO_INIT;
862 }
863 if (!handle->handle) {
864 free(devName);
865 goto Error;
866 }
867
868 handle->handle->flags = flags;
869 err = setHardwareParams(handle);
870 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700871 ALOGE("s_start_voice_call: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700872 goto Error;
873 }
874
875 err = setSoftwareParams(handle);
876 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700877 ALOGE("s_start_voice_call: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700878 goto Error;
879 }
880
881 err = pcm_prepare(handle->handle);
882 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700883 ALOGE("s_start_voice_call: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700884 goto Error;
885 }
886
887 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700888 ALOGE("s_start_voice_call:SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700889 goto Error;
890 }
891
892 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -0700893#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700894 err = csd_client_start_voice();
895 if (err < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700896 ALOGE("s_start_voice_call: csd_client error %d\n", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700897 goto Error;
898 }
Iliyan Malchev4113f342012-06-11 14:39:47 -0700899#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700900 }
901
902 free(devName);
903 return NO_ERROR;
904
905Error:
Iliyan Malchev4113f342012-06-11 14:39:47 -0700906 ALOGE("s_start_voice_call: Failed to initialize ALSA device '%s'", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700907 free(devName);
908 s_close(handle);
909 return NO_INIT;
910}
911
912static status_t s_start_fm(alsa_handle_t *handle)
913{
914 char *devName;
915 unsigned flags = 0;
916 int err = NO_ERROR;
917
SathishKumar Mani0a019912012-09-11 12:33:11 -0700918 ALOGD("s_start_fm: handle %p", handle);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700919
920 // ASoC multicomponent requires a valid path (frontend/backend) for
921 // the device to be opened
922
923 flags = PCM_OUT | PCM_STEREO;
924 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700925 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700926 goto Error;
927 }
928 if (devName != NULL) {
929 handle->handle = pcm_open(flags, (char*)devName);
930 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700931 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700932 return NO_INIT;
933 }
934 if (!handle->handle) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700935 ALOGE("s_start_fm: could not open PCM device");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700936 goto Error;
937 }
938
939 handle->handle->flags = flags;
940 err = setHardwareParams(handle);
941 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700942 ALOGE("s_start_fm: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700943 goto Error;
944 }
945
946 err = setSoftwareParams(handle);
947 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700948 ALOGE("s_start_fm: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700949 goto Error;
950 }
951
952 err = pcm_prepare(handle->handle);
953 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700954 ALOGE("s_start_fm: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700955 goto Error;
956 }
957
958 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700959 ALOGE("s_start_fm: SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700960 goto Error;
961 }
962
963 // Store the PCM playback device pointer in rxHandle
964 handle->rxHandle = handle->handle;
965 free(devName);
966
967 // Open PCM capture device
968 flags = PCM_IN | PCM_STEREO;
969 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700970 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700971 goto Error;
972 }
973 if (devName != NULL) {
974 handle->handle = pcm_open(flags, (char*)devName);
975 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700976 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700977 return NO_INIT;
978 }
979 if (!handle->handle) {
980 goto Error;
981 }
982
983 handle->handle->flags = flags;
984 err = setHardwareParams(handle);
985 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700986 ALOGE("s_start_fm: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700987 goto Error;
988 }
989
990 err = setSoftwareParams(handle);
991 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700992 ALOGE("s_start_fm: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700993 goto Error;
994 }
995
996 err = pcm_prepare(handle->handle);
997 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700998 ALOGE("s_start_fm: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700999 goto Error;
1000 }
1001
1002 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001003 ALOGE("s_start_fm: SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001004 goto Error;
1005 }
1006
1007 s_set_fm_vol(fmVolume);
1008 free(devName);
1009 return NO_ERROR;
1010
1011Error:
1012 free(devName);
1013 s_close(handle);
1014 return NO_INIT;
1015}
1016
1017static status_t s_set_fm_vol(int value)
1018{
1019 status_t err = NO_ERROR;
1020
1021 ALSAControl control("/dev/snd/controlC0");
1022 control.set("Internal FM RX Volume",value,0);
1023 fmVolume = value;
1024
1025 return err;
1026}
1027
1028static status_t s_set_lpa_vol(int value)
1029{
1030 status_t err = NO_ERROR;
1031
1032 ALSAControl control("/dev/snd/controlC0");
1033 control.set("LPA RX Volume",value,0);
1034
1035 return err;
1036}
1037
1038static status_t s_start(alsa_handle_t *handle)
1039{
1040 status_t err = NO_ERROR;
1041
1042 if(!handle->handle) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001043 ALOGE("No active PCM driver to start");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001044 return err;
1045 }
1046
1047 err = pcm_prepare(handle->handle);
1048
1049 return err;
1050}
1051
1052static status_t s_close(alsa_handle_t *handle)
1053{
1054 int ret;
1055 status_t err = NO_ERROR;
1056 struct pcm *h = handle->rxHandle;
1057
1058 handle->rxHandle = 0;
Ajay Dudani86c852b2012-07-19 15:28:45 -07001059#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001060 ALOGD("s_close: handle %p h %p", handle, h);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001061#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001062 if (h) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001063 ALOGV("s_close rxHandle\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001064 err = pcm_close(h);
1065 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001066 ALOGE("s_close: pcm_close failed for rxHandle with err %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001067 }
1068 }
1069
1070 h = handle->handle;
1071 handle->handle = 0;
1072
1073 if (h) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001074 ALOGV("s_close handle h %p\n", h);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001075 err = pcm_close(h);
1076 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001077 ALOGE("s_close: pcm_close failed for handle with err %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001078 }
1079
1080 if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_VOICECALL) ||
1081 !strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_VOICE)) &&
1082 platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001083#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001084 err = csd_client_stop_voice();
1085 if (err < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001086 ALOGE("s_close: csd_client error %d\n", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001087 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001088#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001089 }
1090
1091 disableDevice(handle);
1092 } else if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
1093 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
1094 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
1095 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))){
1096 disableDevice(handle);
1097 }
1098
1099 return err;
1100}
1101
1102/*
1103 this is same as s_close, but don't discard
1104 the device/mode info. This way we can still
1105 close the device, hit idle and power-save, reopen the pcm
1106 for the same device/mode after resuming
1107*/
1108static status_t s_standby(alsa_handle_t *handle)
1109{
1110 int ret;
1111 status_t err = NO_ERROR;
1112 struct pcm *h = handle->rxHandle;
1113 handle->rxHandle = 0;
Ajay Dudani86c852b2012-07-19 15:28:45 -07001114#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001115 ALOGD("s_standby: handle %p h %p", handle, h);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001116#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001117 if (h) {
SathishKumar Mani0a019912012-09-11 12:33:11 -07001118 ALOGD("s_standby rxHandle\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001119 err = pcm_close(h);
1120 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001121 ALOGE("s_standby: pcm_close failed for rxHandle with err %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001122 }
1123 }
1124
1125 h = handle->handle;
1126 handle->handle = 0;
1127
1128 if (h) {
Ajay Dudani86c852b2012-07-19 15:28:45 -07001129#if LOCAL_LOGD
1130 ALOGD("s_standby handle h %p\n", h);
1131#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001132 err = pcm_close(h);
1133 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001134 ALOGE("s_standby: pcm_close failed for handle with err %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001135 }
1136 disableDevice(handle);
1137 } else if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
1138 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
1139 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
1140 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
1141 disableDevice(handle);
1142 }
1143
1144 return err;
1145}
1146
1147static status_t s_route(alsa_handle_t *handle, uint32_t devices, int mode)
1148{
1149 status_t status = NO_ERROR;
1150
Ajay Dudani86c852b2012-07-19 15:28:45 -07001151#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001152 ALOGD("s_route: devices 0x%x in mode %d", devices, mode);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001153#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001154 callMode = mode;
1155 switchDevice(handle, devices, mode);
1156 return status;
1157}
1158
1159int getUseCaseType(const char *useCase)
1160{
SathishKumar Mani0a019912012-09-11 12:33:11 -07001161 ALOGD("use case is %s\n", useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001162 if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI,
1163 strlen(SND_USE_CASE_VERB_HIFI)) ||
SathishKumar Mani88613382012-08-13 18:40:18 -07001164 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC,
1165 strlen(SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -07001166 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER,
1167 strlen(SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
1168 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_TUNNEL,
1169 strlen(SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
1170 !strncmp(useCase, SND_USE_CASE_VERB_DIGITAL_RADIO,
1171 strlen(SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
1172 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC,
1173 strlen(SND_USE_CASE_MOD_PLAY_MUSIC)) ||
SathishKumar Mani88613382012-08-13 18:40:18 -07001174 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC,
1175 strlen(SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -07001176 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LPA,
1177 strlen(SND_USE_CASE_MOD_PLAY_LPA)) ||
1178 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_TUNNEL,
1179 strlen(SND_USE_CASE_MOD_PLAY_TUNNEL)) ||
1180 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_FM,
1181 strlen(SND_USE_CASE_MOD_PLAY_FM))) {
1182 return USECASE_TYPE_RX;
1183 } else if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI_REC,
1184 strlen(SND_USE_CASE_VERB_HIFI_REC)) ||
SathishKumar Mani88613382012-08-13 18:40:18 -07001185 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC,
1186 strlen(SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC)) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -07001187 !strncmp(useCase, SND_USE_CASE_VERB_FM_REC,
1188 strlen(SND_USE_CASE_VERB_FM_REC)) ||
1189 !strncmp(useCase, SND_USE_CASE_VERB_FM_A2DP_REC,
1190 strlen(SND_USE_CASE_VERB_FM_A2DP_REC)) ||
1191 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC,
1192 strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC)) ||
SathishKumar Mani88613382012-08-13 18:40:18 -07001193 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC,
1194 strlen(SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC)) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -07001195 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_FM,
1196 strlen(SND_USE_CASE_MOD_CAPTURE_FM)) ||
1197 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM,
1198 strlen(SND_USE_CASE_MOD_CAPTURE_A2DP_FM))) {
1199 return USECASE_TYPE_TX;
1200 } else if (!strncmp(useCase, SND_USE_CASE_VERB_VOICECALL,
1201 strlen(SND_USE_CASE_VERB_VOICECALL)) ||
1202 !strncmp(useCase, SND_USE_CASE_VERB_IP_VOICECALL,
1203 strlen(SND_USE_CASE_VERB_IP_VOICECALL)) ||
1204 !strncmp(useCase, SND_USE_CASE_VERB_DL_REC,
1205 strlen(SND_USE_CASE_VERB_DL_REC)) ||
1206 !strncmp(useCase, SND_USE_CASE_VERB_UL_DL_REC,
1207 strlen(SND_USE_CASE_VERB_UL_DL_REC)) ||
1208 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOICE,
1209 strlen(SND_USE_CASE_MOD_PLAY_VOICE)) ||
1210 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOIP,
1211 strlen(SND_USE_CASE_MOD_PLAY_VOIP)) ||
1212 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
1213 strlen(SND_USE_CASE_MOD_CAPTURE_VOICE_DL)) ||
1214 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
1215 strlen(SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL)) ||
1216 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
1217 strlen(SND_USE_CASE_MOD_CAPTURE_VOICE)) ||
1218 !strncmp(useCase, SND_USE_CASE_VERB_VOLTE,
1219 strlen(SND_USE_CASE_VERB_VOLTE)) ||
1220 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOLTE,
1221 strlen(SND_USE_CASE_MOD_PLAY_VOLTE))) {
1222 return (USECASE_TYPE_RX | USECASE_TYPE_TX);
1223 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001224 ALOGE("unknown use case %s\n", useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001225 return 0;
1226 }
1227}
1228
1229static void disableDevice(alsa_handle_t *handle)
1230{
1231 unsigned usecase_type = 0;
1232 int i, mods_size;
1233 char *useCase;
1234 const char **mods_list;
1235
1236 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
1237 if (useCase != NULL) {
1238 if (!strncmp(useCase, handle->useCase, MAX_UC_LEN)) {
1239 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
1240 } else {
1241 snd_use_case_set(handle->ucMgr, "_dismod", handle->useCase);
1242 }
1243 free(useCase);
1244 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
1245 if (strncmp(useCase, SND_USE_CASE_VERB_INACTIVE,
1246 strlen(SND_USE_CASE_VERB_INACTIVE)))
1247 usecase_type |= getUseCaseType(useCase);
1248 mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001249#if LOCAL_LOGD
1250 ALOGD("Number of modifiers %d\n", mods_size);
1251#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001252 if (mods_size) {
1253 for(i = 0; i < mods_size; i++) {
Ajay Dudani8a9785b2012-09-10 23:28:45 -07001254#if LOCAL_LOGD
1255 ALOGD("index %d modifier %s\n", i, mods_list[i]);
1256#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001257 usecase_type |= getUseCaseType(mods_list[i]);
1258 }
1259 }
Ajay Dudani86c852b2012-07-19 15:28:45 -07001260#if LOCAL_LOGD
1261 ALOGD("usecase_type is %d\n", usecase_type);
1262#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001263 if (!(usecase_type & USECASE_TYPE_TX) && (strncmp(curTxUCMDevice, "None", 4)))
1264 snd_use_case_set(handle->ucMgr, "_disdev", curTxUCMDevice);
1265 if (!(usecase_type & USECASE_TYPE_RX) && (strncmp(curRxUCMDevice, "None", 4)))
1266 snd_use_case_set(handle->ucMgr, "_disdev", curRxUCMDevice);
1267 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001268 ALOGE("Invalid state, no valid use case found to disable");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001269 }
1270 free(useCase);
1271}
1272
1273char *getUCMDevice(uint32_t devices, int input, char *rxDevice)
1274{
1275 if (!input) {
1276 if (!(mDevSettingsFlag & TTY_OFF) &&
1277 (callMode == AudioSystem::MODE_IN_CALL) &&
1278 ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
ty.lee924f7982012-08-01 23:15:30 +09001279 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001280#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001281 ||
1282 (devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
1283 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) {
1284#endif
1285 if (mDevSettingsFlag & TTY_VCO) {
1286 return strdup(SND_USE_CASE_DEV_TTY_HEADSET_RX);
1287 } else if (mDevSettingsFlag & TTY_FULL) {
1288 return strdup(SND_USE_CASE_DEV_TTY_FULL_RX);
1289 } else if (mDevSettingsFlag & TTY_HCO) {
1290 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_RX); /* HANDSET RX */
1291 }
1292 }else if ((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET) ||
1293 (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)) {
1294 return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */
1295 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1296 ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
1297 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
1298 if (mDevSettingsFlag & ANC_FLAG) {
1299 return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
1300 } else {
1301 return strdup(SND_USE_CASE_DEV_SPEAKER_HEADSET); /* COMBO SPEAKER+HEADSET RX */
1302 }
Ajay Dudani9746c472012-06-18 16:01:16 -07001303#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001304 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1305 ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
1306 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) {
1307 return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
1308 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1309 (devices & AudioSystem::DEVICE_OUT_FM_TX)) {
1310 return strdup(SND_USE_CASE_DEV_SPEAKER_FM_TX); /* COMBO SPEAKER+FM_TX RX */
1311#endif
1312 } else if (devices & AudioSystem::DEVICE_OUT_EARPIECE) {
1313 return strdup(SND_USE_CASE_DEV_EARPIECE); /* HANDSET RX */
1314 } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) {
1315 return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
1316 } else if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
1317 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) {
1318 if (mDevSettingsFlag & ANC_FLAG) {
1319 return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */
1320 } else {
1321 return strdup(SND_USE_CASE_DEV_HEADPHONES); /* HEADSET RX */
1322 }
Ajay Dudani9746c472012-06-18 16:01:16 -07001323#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001324 } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
1325 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE)) {
1326 return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */
1327#endif
1328 } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) ||
1329 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
1330 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT)) {
1331 if (btsco_samplerate == BTSCO_RATE_16KHZ)
1332 return strdup(SND_USE_CASE_DEV_BTSCO_WB_RX); /* BTSCO RX*/
1333 else
1334 return strdup(SND_USE_CASE_DEV_BTSCO_NB_RX); /* BTSCO RX*/
1335 } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP) ||
1336 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES) ||
Ajay Dudani9746c472012-06-18 16:01:16 -07001337#ifdef QCOM_VOIP_ENABLED
1338 (devices & AudioSystem::DEVICE_OUT_DIRECTOUTPUT) ||
1339#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001340 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) {
1341 /* Nothing to be done, use current active device */
1342 if (strncmp(curRxUCMDevice, "None", 4)) {
1343 return strdup(curRxUCMDevice);
1344 }
1345 } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
1346 return strdup(SND_USE_CASE_DEV_HDMI); /* HDMI RX */
Ajay Dudani9746c472012-06-18 16:01:16 -07001347#ifdef QCOM_PROXY_DEVICE_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001348 } else if (devices & AudioSystem::DEVICE_OUT_PROXY) {
1349 return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */
Ajay Dudani9746c472012-06-18 16:01:16 -07001350#endif
1351#ifdef QCOM_FM_TX_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001352 } else if (devices & AudioSystem::DEVICE_OUT_FM_TX) {
1353 return strdup(SND_USE_CASE_DEV_FM_TX); /* FM Tx */
1354#endif
1355 } else if (devices & AudioSystem::DEVICE_OUT_DEFAULT) {
1356 return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
1357 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001358 ALOGD("No valid output device: %u", devices);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001359 }
1360 } else {
1361 if (!(mDevSettingsFlag & TTY_OFF) &&
1362 (callMode == AudioSystem::MODE_IN_CALL) &&
ty.lee924f7982012-08-01 23:15:30 +09001363 ((devices & AudioSystem::DEVICE_IN_WIRED_HEADSET))) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001364#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001365 ||(devices & AudioSystem::DEVICE_IN_ANC_HEADSET))) {
1366#endif
1367 if (mDevSettingsFlag & TTY_HCO) {
1368 return strdup(SND_USE_CASE_DEV_TTY_HEADSET_TX);
1369 } else if (mDevSettingsFlag & TTY_FULL) {
1370 return strdup(SND_USE_CASE_DEV_TTY_FULL_TX);
1371 } else if (mDevSettingsFlag & TTY_VCO) {
1372 if (!strncmp(mic_type, "analog", 6)) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001373 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_ANALOG_TX);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001374 } else {
1375 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_TX);
1376 }
1377 }
1378 } else if (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) {
1379 if (!strncmp(mic_type, "analog", 6)) {
1380 return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
1381 } else {
1382 if (mDevSettingsFlag & DMIC_FLAG) {
ty.lee924f7982012-08-01 23:15:30 +09001383#ifdef USES_FLUENCE_INCALL
1384 if(callMode == AudioSystem::MODE_IN_CALL) {
1385 if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
1386 return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
1387 } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
1388 return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
1389 } else {
1390 return strdup(SND_USE_CASE_DEV_HANDSET); /* BUILTIN-MIC TX */
1391 }
1392 }
1393#else
Iliyan Malchev4765c432012-06-11 14:36:16 -07001394 if (((rxDevice != NULL) &&
1395 !strncmp(rxDevice, SND_USE_CASE_DEV_SPEAKER,
1396 (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) ||
1397 !strncmp(curRxUCMDevice, SND_USE_CASE_DEV_SPEAKER,
1398 (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) {
1399 if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
1400 return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
1401 } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
1402 return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
1403 }
1404 } else {
1405 if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
1406 return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
1407 } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
1408 return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
1409 }
1410 }
ty.lee924f7982012-08-01 23:15:30 +09001411#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001412 } else if (mDevSettingsFlag & QMIC_FLAG){
1413 return strdup(SND_USE_CASE_DEV_QUAD_MIC);
ty.lee924f7982012-08-01 23:15:30 +09001414 }
Ajay Dudani9746c472012-06-18 16:01:16 -07001415#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001416 else if (mDevSettingsFlag & SSRQMIC_FLAG){
Iliyan Malchev4113f342012-06-11 14:39:47 -07001417 ALOGV("return SSRQMIC_FLAG: 0x%x devices:0x%x",mDevSettingsFlag,devices);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001418 // Mapping for quad mic input device.
1419 return strdup(SND_USE_CASE_DEV_SSR_QUAD_MIC); /* SSR Quad MIC */
ty.lee924f7982012-08-01 23:15:30 +09001420 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001421#endif
ty.lee74060de2012-08-02 00:47:00 +09001422#ifdef SEPERATED_AUDIO_INPUT
1423 if(input_source == AUDIO_SOURCE_VOICE_RECOGNITION) {
1424 ALOGV("getUCMdevice returned the VOICE_RECOGNITION UCM by input source = %d", input_source);
1425 return strdup(SND_USE_CASE_DEV_VOICE_RECOGNITION ); /* VOICE RECOGNITION TX */
1426 } else if(input_source == AUDIO_SOURCE_CAMCORDER) {
1427 ALOGV("getUCMdevice returned the Camcorder Tx UCM by input source = %d", input_source);
1428 return strdup(SND_USE_CASE_DEV_CAMCORDER_TX ); /* CAMCORDER TX */
1429 }
1430#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001431 else {
ty.lee74060de2012-08-02 00:47:00 +09001432 return strdup(SND_USE_CASE_DEV_HANDSET); /* BUILTIN-MIC TX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001433 }
1434 }
1435 } else if (devices & AudioSystem::DEVICE_IN_AUX_DIGITAL) {
1436 return strdup(SND_USE_CASE_DEV_HDMI_TX); /* HDMI TX */
Ajay Dudani9746c472012-06-18 16:01:16 -07001437#ifdef QCOM_ANC_HEADSET_ENABLED
ehgrace.kim249f87d2012-08-12 20:40:32 -07001438 } else if (devices & AudioSystem::DEVICE_IN_ANC_HEADSET) {
Iliyan Malchev4765c432012-06-11 14:36:16 -07001439 return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */
1440#endif
ehgrace.kim249f87d2012-08-12 20:40:32 -07001441 } else if (devices & AudioSystem::DEVICE_IN_WIRED_HEADSET) {
1442 return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001443 } else if (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
1444 if (btsco_samplerate == BTSCO_RATE_16KHZ)
1445 return strdup(SND_USE_CASE_DEV_BTSCO_WB_TX); /* BTSCO TX*/
1446 else
1447 return strdup(SND_USE_CASE_DEV_BTSCO_NB_TX); /* BTSCO TX*/
Ajay Dudani9746c472012-06-18 16:01:16 -07001448#ifdef QCOM_USBAUDIO_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001449 } else if ((devices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) ||
1450 (devices & AudioSystem::DEVICE_IN_PROXY)) {
1451 return strdup(SND_USE_CASE_DEV_PROXY_TX); /* PROXY TX */
1452#endif
1453 } else if ((devices & AudioSystem::DEVICE_IN_COMMUNICATION) ||
1454 (devices & AudioSystem::DEVICE_IN_VOICE_CALL)) {
1455 /* Nothing to be done, use current active device */
1456 if (strncmp(curTxUCMDevice, "None", 4)) {
1457 return strdup(curTxUCMDevice);
1458 }
Ajay Dudani9746c472012-06-18 16:01:16 -07001459#ifdef QCOM_FM_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001460 } else if ((devices & AudioSystem::DEVICE_IN_FM_RX) ||
1461 (devices & AudioSystem::DEVICE_IN_FM_RX_A2DP)) {
1462 /* Nothing to be done, use current tx device or set dummy device */
1463 if (strncmp(curTxUCMDevice, "None", 4)) {
1464 return strdup(curTxUCMDevice);
1465 } else {
1466 return strdup(SND_USE_CASE_DEV_DUMMY_TX);
1467 }
1468#endif
1469 } else if ((devices & AudioSystem::DEVICE_IN_AMBIENT) ||
1470 (devices & AudioSystem::DEVICE_IN_BACK_MIC)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001471 ALOGI("No proper mapping found with UCM device list, setting default");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001472 if (!strncmp(mic_type, "analog", 6)) {
1473 return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
1474 } else {
1475 return strdup(SND_USE_CASE_DEV_LINE); /* BUILTIN-MIC TX */
1476 }
1477 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001478 ALOGD("No valid input device: %u", devices);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001479 }
1480 }
1481 return NULL;
1482}
1483
1484void s_set_voice_volume(int vol)
1485{
1486 int err = 0;
Ajay Dudani86c852b2012-07-19 15:28:45 -07001487#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001488 ALOGD("s_set_voice_volume: volume %d", vol);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001489#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001490 ALSAControl control("/dev/snd/controlC0");
1491 control.set("Voice Rx Volume", vol, 0);
1492
1493 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001494#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001495 err = csd_client_volume(vol);
1496 if (err < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001497 ALOGE("s_set_voice_volume: csd_client error %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001498 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001499#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001500 }
1501}
1502
1503void s_set_volte_volume(int vol)
1504{
Ajay Dudani86c852b2012-07-19 15:28:45 -07001505#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001506 ALOGD("s_set_volte_volume: volume %d", vol);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001507#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001508 ALSAControl control("/dev/snd/controlC0");
1509 control.set("VoLTE Rx Volume", vol, 0);
1510}
1511
1512
1513void s_set_voip_volume(int vol)
1514{
Ajay Dudani86c852b2012-07-19 15:28:45 -07001515#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001516 ALOGD("s_set_voip_volume: volume %d", vol);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001517#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001518 ALSAControl control("/dev/snd/controlC0");
1519 control.set("Voip Rx Volume", vol, 0);
1520}
1521void s_set_mic_mute(int state)
1522{
1523 int err = 0;
Ajay Dudani86c852b2012-07-19 15:28:45 -07001524#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001525 ALOGD("s_set_mic_mute: state %d", state);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001526#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001527 ALSAControl control("/dev/snd/controlC0");
1528 control.set("Voice Tx Mute", state, 0);
1529
1530 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001531#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001532 err = csd_client_mic_mute(state);
1533 if (err < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001534 ALOGE("s_set_mic_mute: csd_client error %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001535 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001536#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001537 }
1538}
1539void s_set_volte_mic_mute(int state)
1540{
Ajay Dudani86c852b2012-07-19 15:28:45 -07001541#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001542 ALOGD("s_set_volte_mic_mute: state %d", state);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001543#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001544 ALSAControl control("/dev/snd/controlC0");
1545 control.set("VoLTE Tx Mute", state, 0);
1546}
1547
1548void s_set_voip_mic_mute(int state)
1549{
Ajay Dudani86c852b2012-07-19 15:28:45 -07001550#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001551 ALOGD("s_set_voip_mic_mute: state %d", state);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001552#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001553 ALSAControl control("/dev/snd/controlC0");
1554 control.set("Voip Tx Mute", state, 0);
1555}
1556
1557void s_set_voip_config(int mode, int rate)
1558{
Ajay Dudani86c852b2012-07-19 15:28:45 -07001559#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001560 ALOGD("s_set_voip_config: mode %d,rate %d", mode, rate);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001561#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001562 ALSAControl control("/dev/snd/controlC0");
1563 char** setValues;
1564 setValues = (char**)malloc(2*sizeof(char*));
1565 if (setValues == NULL) {
1566 return;
1567 }
1568 setValues[0] = (char*)malloc(4*sizeof(char));
1569 if (setValues[0] == NULL) {
1570 free(setValues);
1571 return;
1572 }
1573
1574 setValues[1] = (char*)malloc(8*sizeof(char));
1575 if (setValues[1] == NULL) {
1576 free(setValues);
1577 free(setValues[0]);
1578 return;
1579 }
1580
1581 sprintf(setValues[0], "%d",mode);
1582 sprintf(setValues[1], "%d",rate);
1583
1584 control.setext("Voip Mode Rate Config", 2, setValues);
1585 free(setValues[1]);
1586 free(setValues[0]);
1587 free(setValues);
1588 return;
1589}
1590
1591void s_set_btsco_rate(int rate)
1592{
1593 btsco_samplerate = rate;
1594}
1595
1596void s_enable_wide_voice(bool flag)
1597{
1598 int err = 0;
1599
Ajay Dudani86c852b2012-07-19 15:28:45 -07001600#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001601 ALOGD("s_enable_wide_voice: flag %d", flag);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001602#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001603 ALSAControl control("/dev/snd/controlC0");
1604 if(flag == true) {
1605 control.set("Widevoice Enable", 1, 0);
1606 } else {
1607 control.set("Widevoice Enable", 0, 0);
1608 }
1609
1610 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001611#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001612 err == csd_client_wide_voice(flag);
1613 if (err < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001614 ALOGE("s_enable_wide_voice: csd_client error %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001615 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001616#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001617 }
1618}
1619
1620void s_set_voc_rec_mode(uint8_t mode)
1621{
Ajay Dudani86c852b2012-07-19 15:28:45 -07001622#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001623 ALOGD("s_set_voc_rec_mode: mode %d", mode);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001624#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001625 ALSAControl control("/dev/snd/controlC0");
1626 control.set("Incall Rec Mode", mode, 0);
1627}
1628
1629void s_enable_fens(bool flag)
1630{
1631 int err = 0;
1632
Ajay Dudani86c852b2012-07-19 15:28:45 -07001633#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001634 ALOGD("s_enable_fens: flag %d", flag);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001635#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001636 ALSAControl control("/dev/snd/controlC0");
1637 if(flag == true) {
1638 control.set("FENS Enable", 1, 0);
1639 } else {
1640 control.set("FENS Enable", 0, 0);
1641 }
1642
1643 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001644#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001645 err = csd_client_fens(flag);
1646 if (err < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001647 ALOGE("s_enable_fens: csd_client error %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001648 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001649#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001650 }
1651}
1652
1653void s_enable_slow_talk(bool flag)
1654{
1655 int err = 0;
1656
Ajay Dudani86c852b2012-07-19 15:28:45 -07001657#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001658 ALOGD("s_enable_slow_talk: flag %d", flag);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001659#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001660 ALSAControl control("/dev/snd/controlC0");
1661 if(flag == true) {
1662 control.set("Slowtalk Enable", 1, 0);
1663 } else {
1664 control.set("Slowtalk Enable", 0, 0);
1665 }
1666
1667 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001668#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001669 err = csd_client_slow_talk(flag);
1670 if (err < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001671 ALOGE("s_enable_slow_talk: csd_client error %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001672 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001673#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001674 }
1675}
1676
1677void s_set_flags(uint32_t flags)
1678{
Iliyan Malchev4113f342012-06-11 14:39:47 -07001679 ALOGV("s_set_flags: flags %d", flags);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001680 mDevSettingsFlag = flags;
1681}
1682
1683static status_t s_set_compressed_vol(int value)
1684{
1685 status_t err = NO_ERROR;
1686
1687 ALSAControl control("/dev/snd/controlC0");
1688 control.set("COMPRESSED RX Volume",value,0);
1689
1690 return err;
1691}
1692
ty.lee74060de2012-08-02 00:47:00 +09001693#ifdef SEPERATED_AUDIO_INPUT
1694void s_setInput(int input)
1695{
1696 input_source = input;
1697 ALOGD("s_setInput() : input_source = %d",input_source);
1698}
1699#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001700}