blob: eaa2343a8ec4b7159f9e50df43fa6ddd2fbcda8e [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;
Iliyan Malchev4765c432012-06-11 14:36:16 -0700255 }
256 }
257#endif
258
259 param_init(params);
260 param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS,
261 SNDRV_PCM_ACCESS_RW_INTERLEAVED);
262 if (handle->format != SNDRV_PCM_FORMAT_S16_LE) {
Ajay Dudani9746c472012-06-18 16:01:16 -0700263 if (handle->format == AudioSystem::AMR_NB
264 || handle->format == AudioSystem::AMR_WB
265#ifdef QCOM_QCHAT_ENABLED
266 || handle->format == AudioSystem::EVRC
267 || handle->format == AudioSystem::EVRCB
268 || handle->format == AudioSystem::EVRCWB
269#endif
270 )
Iliyan Malchev4765c432012-06-11 14:36:16 -0700271 format = SNDRV_PCM_FORMAT_SPECIAL;
272 }
273 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
274 format);
275 param_set_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT,
276 SNDRV_PCM_SUBFORMAT_STD);
SathishKumar Mani77780382012-09-21 20:58:33 -0700277 param_set_int(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, reqBuffSize);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700278 param_set_int(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 16);
279 param_set_int(params, SNDRV_PCM_HW_PARAM_FRAME_BITS,
280 channels * 16);
281 param_set_int(params, SNDRV_PCM_HW_PARAM_CHANNELS,
282 channels);
283 param_set_int(params, SNDRV_PCM_HW_PARAM_RATE, handle->sampleRate);
284 param_set_hw_refine(handle->handle, params);
285
286 if (param_set_hw_params(handle->handle, params)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700287 ALOGE("cannot set hw params");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700288 return NO_INIT;
289 }
290 param_dump(params);
291
292 handle->handle->buffer_size = pcm_buffer_size(params);
293 handle->handle->period_size = pcm_period_size(params);
294 handle->handle->period_cnt = handle->handle->buffer_size/handle->handle->period_size;
Iliyan Malchev4113f342012-06-11 14:39:47 -0700295 ALOGD("setHardwareParams: buffer_size %d, period_size %d, period_cnt %d",
Iliyan Malchev4765c432012-06-11 14:36:16 -0700296 handle->handle->buffer_size, handle->handle->period_size,
297 handle->handle->period_cnt);
298 handle->handle->rate = handle->sampleRate;
299 handle->handle->channels = handle->channels;
300 handle->periodSize = handle->handle->period_size;
301 if (strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC) &&
302 strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC) &&
303 (6 != handle->channels)) {
304 //Do not update buffersize for 5.1 recording
305 handle->bufferSize = handle->handle->period_size;
306 }
307
308 return NO_ERROR;
309}
310
311status_t setSoftwareParams(alsa_handle_t *handle)
312{
313 struct snd_pcm_sw_params* params;
314 struct pcm* pcm = handle->handle;
315
316 unsigned long periodSize = pcm->period_size;
317 int channels = handle->channels;
318
319 params = (snd_pcm_sw_params*) calloc(1, sizeof(struct snd_pcm_sw_params));
320 if (!params) {
321 LOG_ALWAYS_FATAL("Failed to allocate ALSA software parameters!");
322 return NO_INIT;
323 }
324
Ajay Dudani9746c472012-06-18 16:01:16 -0700325#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700326 if (channels == 6) {
327 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
328 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700329 ALOGV("SWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700330 channels = 4;
331 }
332 }
333#endif
334
335 // Get the current software parameters
336 params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
337 params->period_step = 1;
338 if(((!strcmp(handle->useCase,SND_USE_CASE_MOD_PLAY_VOIP)) ||
339 (!strcmp(handle->useCase,SND_USE_CASE_VERB_IP_VOICECALL)))){
Iliyan Malchev4113f342012-06-11 14:39:47 -0700340 ALOGV("setparam: start & stop threshold for Voip ");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700341 params->avail_min = handle->channels - 1 ? periodSize/4 : periodSize/2;
342 params->start_threshold = periodSize/2;
343 params->stop_threshold = INT_MAX;
344 } else {
345 params->avail_min = periodSize/2;
346 params->start_threshold = channels * (periodSize/4);
347 params->stop_threshold = INT_MAX;
348 }
349 params->silence_threshold = 0;
350 params->silence_size = 0;
351
352 if (param_set_sw_params(handle->handle, params)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700353 ALOGE("cannot set sw params");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700354 return NO_INIT;
355 }
356 return NO_ERROR;
357}
358
359void switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode)
360{
361 const char **mods_list;
362 use_case_t useCaseNode;
363 unsigned usecase_type = 0;
364 bool inCallDevSwitch = false;
365 char *rxDevice, *txDevice, ident[70], *use_case = NULL;
366 int err = 0, index, mods_size;
367 int rx_dev_id, tx_dev_id;
SathishKumar Mani9efed762012-09-18 18:52:48 -0700368 ALOGD("%s: device %d mode:%d", __FUNCTION__, devices, mode);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700369
370 if ((mode == AudioSystem::MODE_IN_CALL) || (mode == AudioSystem::MODE_IN_COMMUNICATION)) {
371 if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
372 (devices & AudioSystem::DEVICE_IN_WIRED_HEADSET)) {
373 devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADSET |
374 AudioSystem::DEVICE_IN_WIRED_HEADSET);
375 } else if (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
376 devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADPHONE |
377 AudioSystem::DEVICE_IN_BUILTIN_MIC);
SathishKumar Manic669c272012-09-21 20:12:08 -0700378 } else if (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) {
379 if (mode == AudioSystem::MODE_IN_CALL) {
380 devices |= AudioSystem::DEVICE_OUT_EARPIECE;
381 }
382 } else if (devices & AudioSystem::DEVICE_OUT_EARPIECE) {
383 devices = devices | AudioSystem::DEVICE_IN_BUILTIN_MIC;
Iliyan Malchev4765c432012-06-11 14:36:16 -0700384 } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) {
ty.lee10dfa852012-08-01 21:09:45 +0900385 devices = devices | (AudioSystem::DEVICE_IN_BACK_MIC |
Iliyan Malchev4765c432012-06-11 14:36:16 -0700386 AudioSystem::DEVICE_OUT_SPEAKER);
387 } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) ||
388 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
389 (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
390 devices = devices | (AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET |
391 AudioSystem::DEVICE_OUT_BLUETOOTH_SCO);
Ajay Dudani9746c472012-06-18 16:01:16 -0700392#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700393 } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
394 (devices & AudioSystem::DEVICE_IN_ANC_HEADSET)) {
395 devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADSET |
396 AudioSystem::DEVICE_IN_ANC_HEADSET);
397 } else if (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE) {
398 devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADPHONE |
399 AudioSystem::DEVICE_IN_BUILTIN_MIC);
400#endif
401 } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
Sungmin Choi6ebf0aa2012-09-28 16:09:12 -0700402 if (mode == AudioSystem::MODE_IN_CALL)
403 devices = devices | (AudioSystem::DEVICE_IN_BACK_MIC |
404 AudioSystem::DEVICE_OUT_SPEAKER);
405 else
406 devices = devices | (AudioSystem::DEVICE_OUT_AUX_DIGITAL |
407 AudioSystem::DEVICE_IN_BACK_MIC);
Ajay Dudani9746c472012-06-18 16:01:16 -0700408#ifdef QCOM_PROXY_DEVICE_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700409 } else if ((devices & AudioSystem::DEVICE_OUT_PROXY) ||
410 (devices & AudioSystem::DEVICE_IN_PROXY)) {
411 devices = devices | (AudioSystem::DEVICE_OUT_PROXY |
412 AudioSystem::DEVICE_IN_PROXY);
413#endif
414 }
415 }
Ajay Dudani9746c472012-06-18 16:01:16 -0700416#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700417 if ((devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) && ( 6 == handle->channels)) {
418 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
419 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700420 ALOGV(" switchDevice , use ssr devices for channels:%d usecase:%s",handle->channels,handle->useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700421 s_set_flags(SSRQMIC_FLAG);
422 }
423 }
424#endif
425
426 rxDevice = getUCMDevice(devices & AudioSystem::DEVICE_OUT_ALL, 0, NULL);
427 txDevice = getUCMDevice(devices & AudioSystem::DEVICE_IN_ALL, 1, rxDevice);
428
Iliyan Malchev4765c432012-06-11 14:36:16 -0700429 if ((rxDevice != NULL) && (txDevice != NULL)) {
430 if (((strncmp(rxDevice, curRxUCMDevice, MAX_STR_LEN)) ||
SathishKumar Manic669c272012-09-21 20:12:08 -0700431 (strncmp(txDevice, curTxUCMDevice, MAX_STR_LEN))) &&
432 ((mode == AudioSystem::MODE_IN_CALL) ||
433 (mode == AudioSystem::MODE_IN_COMMUNICATION)))
Iliyan Malchev4765c432012-06-11 14:36:16 -0700434 inCallDevSwitch = true;
435 }
Ajay Dudani91bf8912012-08-20 18:48:13 -0700436
437#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Manic669c272012-09-21 20:12:08 -0700438 if (platform_is_Fusion3() && (inCallDevSwitch == true)) {
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700439 if (csd_disable_device == NULL) {
440 ALOGE("dlsym:Error:%s Loading csd_client_disable_device", dlerror());
441 } else {
442 err = csd_disable_device();
443 if (err < 0)
444 {
445 ALOGE("csd_client_disable_device, failed, error %d", err);
446 }
Ajay Dudani91bf8912012-08-20 18:48:13 -0700447 }
448 }
449#endif
450
Iliyan Malchev4765c432012-06-11 14:36:16 -0700451 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&use_case);
452 mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
453 if (rxDevice != NULL) {
454 if ((strncmp(curRxUCMDevice, "None", 4)) &&
455 ((strncmp(rxDevice, curRxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
456 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
457 strlen(SND_USE_CASE_VERB_INACTIVE)))) {
458 usecase_type = getUseCaseType(use_case);
459 if (usecase_type & USECASE_TYPE_RX) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700460 ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700461 strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
462 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
463 mUseCaseList.push_front(useCaseNode);
464 }
465 }
466 if (mods_size) {
467 for(index = 0; index < mods_size; index++) {
468 usecase_type = getUseCaseType(mods_list[index]);
469 if (usecase_type & USECASE_TYPE_RX) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700470 ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700471 strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
472 snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
473 mUseCaseList.push_back(useCaseNode);
474 }
475 }
476 }
477 snd_use_case_set(handle->ucMgr, "_disdev", curRxUCMDevice);
478 }
479 }
480 if (txDevice != NULL) {
481 if ((strncmp(curTxUCMDevice, "None", 4)) &&
482 ((strncmp(txDevice, curTxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
483 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
484 strlen(SND_USE_CASE_VERB_INACTIVE)))) {
485 usecase_type = getUseCaseType(use_case);
486 if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700487 ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700488 strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
489 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
490 mUseCaseList.push_front(useCaseNode);
491 }
492 }
493 if (mods_size) {
494 for(index = 0; index < mods_size; index++) {
495 usecase_type = getUseCaseType(mods_list[index]);
496 if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700497 ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700498 strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
499 snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
500 mUseCaseList.push_back(useCaseNode);
501 }
502 }
503 }
504 snd_use_case_set(handle->ucMgr, "_disdev", curTxUCMDevice);
505 }
506 }
SathishKumar Mani9efed762012-09-18 18:52:48 -0700507 ALOGD("%s,rxDev:%s, txDev:%s, curRxDev:%s, curTxDev:%s\n", __FUNCTION__, rxDevice, txDevice, curRxUCMDevice, curTxUCMDevice);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700508
509 if (rxDevice != NULL) {
510 snd_use_case_set(handle->ucMgr, "_enadev", rxDevice);
511 strlcpy(curRxUCMDevice, rxDevice, sizeof(curRxUCMDevice));
Ajay Dudani9746c472012-06-18 16:01:16 -0700512#ifdef QCOM_FM_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700513 if (devices & AudioSystem::DEVICE_OUT_FM)
514 s_set_fm_vol(fmVolume);
515#endif
516 }
517 if (txDevice != NULL) {
518 snd_use_case_set(handle->ucMgr, "_enadev", txDevice);
519 strlcpy(curTxUCMDevice, txDevice, sizeof(curTxUCMDevice));
520 }
521 for(ALSAUseCaseList::iterator it = mUseCaseList.begin(); it != mUseCaseList.end(); ++it) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700522 ALOGD("Route use case %s\n", it->useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700523 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
524 strlen(SND_USE_CASE_VERB_INACTIVE))) && (!strncmp(use_case, it->useCase, MAX_UC_LEN))) {
525 snd_use_case_set(handle->ucMgr, "_verb", it->useCase);
526 } else {
527 snd_use_case_set(handle->ucMgr, "_enamod", it->useCase);
528 }
529 }
530 if (!mUseCaseList.empty())
531 mUseCaseList.clear();
532 if (use_case != NULL) {
533 free(use_case);
534 use_case = NULL;
535 }
Iliyan Malchev4113f342012-06-11 14:39:47 -0700536 ALOGD("switchDevice: curTxUCMDevivce %s curRxDevDevice %s", curTxUCMDevice, curRxUCMDevice);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700537
SathishKumar Manic669c272012-09-21 20:12:08 -0700538 if (platform_is_Fusion3() && (inCallDevSwitch == true)) {
Iliyan Malchev4765c432012-06-11 14:36:16 -0700539 /* get tx acdb id */
540 memset(&ident,0,sizeof(ident));
541 strlcpy(ident, "ACDBID/", sizeof(ident));
542 strlcat(ident, curTxUCMDevice, sizeof(ident));
543 tx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
544
545 /* get rx acdb id */
546 memset(&ident,0,sizeof(ident));
547 strlcpy(ident, "ACDBID/", sizeof(ident));
548 strlcat(ident, curRxUCMDevice, sizeof(ident));
549 rx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
550
ehgrace.kim91e9fad2012-07-02 18:27:28 -0700551 if (((rx_dev_id == DEVICE_SPEAKER_MONO_RX_ACDB_ID ) || (rx_dev_id == DEVICE_SPEAKER_STEREO_RX_ACDB_ID ))
552 && tx_dev_id == DEVICE_HANDSET_TX_ACDB_ID) {
Iliyan Malchev4765c432012-06-11 14:36:16 -0700553 tx_dev_id = DEVICE_SPEAKER_TX_ACDB_ID;
554 }
555
Ajay Dudani9746c472012-06-18 16:01:16 -0700556#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4113f342012-06-11 14:39:47 -0700557 ALOGV("rx_dev_id=%d, tx_dev_id=%d\n", rx_dev_id, tx_dev_id);
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700558 if (csd_enable_device == NULL) {
559 ALOGE("dlsym:Error:%s Loading csd_client_enable_device", dlerror());
560 } else {
561 err = csd_enable_device(rx_dev_id, tx_dev_id, mDevSettingsFlag);
562 if (err < 0)
563 {
564 ALOGE("csd_client_disable_device failed, error %d", err);
565 }
Iliyan Malchev4765c432012-06-11 14:36:16 -0700566 }
Iliyan Malchev4113f342012-06-11 14:39:47 -0700567#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700568 }
569
570 if (rxDevice != NULL) {
571 if (pflag && (((!strncmp(rxDevice, DEVICE_SPEAKER_HEADSET, strlen(DEVICE_SPEAKER_HEADSET))) &&
572 ((!strncmp(curRxUCMDevice, DEVICE_HEADPHONES, strlen(DEVICE_HEADPHONES))) ||
573 (!strncmp(curRxUCMDevice, DEVICE_HEADSET, strlen(DEVICE_HEADSET))))) ||
574 (((!strncmp(curRxUCMDevice, DEVICE_SPEAKER_HEADSET, strlen(DEVICE_SPEAKER_HEADSET))) &&
575 ((!strncmp(rxDevice, DEVICE_HEADPHONES, strlen(DEVICE_HEADPHONES))) ||
576 (!strncmp(rxDevice, DEVICE_HEADSET, strlen(DEVICE_HEADSET))))))) &&
577 ((!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI, strlen(SND_USE_CASE_VERB_HIFI))) ||
578 (!strncmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC, strlen(SND_USE_CASE_MOD_PLAY_MUSIC))))) {
579 s_open(handle);
580 pflag = false;
581 }
582 }
583
584 if (rxDevice != NULL) {
585 free(rxDevice);
586 rxDevice = NULL;
587 }
588 if (txDevice != NULL) {
589 free(txDevice);
590 txDevice = NULL;
591 }
592}
593
594// ----------------------------------------------------------------------------
595
596static status_t s_init(alsa_device_t *module, ALSAHandleList &list)
597{
SathishKumar Mani9efed762012-09-18 18:52:48 -0700598 ALOGV("s_init: Initializing devices for ALSA module");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700599
600 list.clear();
601
602 return NO_ERROR;
603}
604
605static status_t s_open(alsa_handle_t *handle)
606{
607 char *devName;
608 unsigned flags = 0;
609 int err = NO_ERROR;
610
611 /* No need to call s_close for LPA as pcm device open and close is handled by LPAPlayer in stagefright */
612 if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) || (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA))
613 ||(!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 -0700614 ALOGV("s_open: Opening LPA /Tunnel playback");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700615 return NO_ERROR;
616 }
617
618 s_close(handle);
619
SathishKumar Mani9efed762012-09-18 18:52:48 -0700620 ALOGV("s_open: handle %p", handle);
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;
SathishKumar Manie42406e2012-08-29 16:25:54 -0700646 }
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 }
SathishKumar Manie42406e2012-08-29 16:25:54 -0700657 }
Iliyan Malchev4765c432012-06-11 14:36:16 -0700658#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
SathishKumar Mani9efed762012-09-18 18:52:48 -0700800 ALOGV("s_start_voice_call: handle %p", handle);
Ajay Dudani86c852b2012-07-19 15:28:45 -0700801
Iliyan Malchev4765c432012-06-11 14:36:16 -0700802 // ASoC multicomponent requires a valid path (frontend/backend) for
803 // the device to be opened
804
805 flags = PCM_OUT | PCM_MONO;
806 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700807 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700808 return NO_INIT;
809 }
810 if (devName != NULL) {
811 handle->handle = pcm_open(flags, (char*)devName);
812 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700813 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700814 return NO_INIT;
815 }
816 if (!handle->handle) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700817 ALOGE("s_start_voicecall: could not open PCM device");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700818 goto Error;
819 }
820
821 handle->handle->flags = flags;
822 err = setHardwareParams(handle);
823 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700824 ALOGE("s_start_voice_call: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700825 goto Error;
826 }
827
828 err = setSoftwareParams(handle);
829 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700830 ALOGE("s_start_voice_call: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700831 goto Error;
832 }
833
834 err = pcm_prepare(handle->handle);
835 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700836 ALOGE("s_start_voice_call: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700837 goto Error;
838 }
839
840 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700841 ALOGE("s_start_voice_call:SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700842 goto Error;
843 }
844
845 // Store the PCM playback device pointer in rxHandle
846 handle->rxHandle = handle->handle;
847 free(devName);
848
849 // Open PCM capture device
850 flags = PCM_IN | PCM_MONO;
851 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700852 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700853 goto Error;
854 }
855 if (devName != NULL) {
856 handle->handle = pcm_open(flags, (char*)devName);
857 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700858 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700859 return NO_INIT;
860 }
861 if (!handle->handle) {
862 free(devName);
863 goto Error;
864 }
865
866 handle->handle->flags = flags;
867 err = setHardwareParams(handle);
868 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700869 ALOGE("s_start_voice_call: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700870 goto Error;
871 }
872
873 err = setSoftwareParams(handle);
874 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700875 ALOGE("s_start_voice_call: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700876 goto Error;
877 }
878
879 err = pcm_prepare(handle->handle);
880 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700881 ALOGE("s_start_voice_call: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700882 goto Error;
883 }
884
885 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700886 ALOGE("s_start_voice_call:SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700887 goto Error;
888 }
889
890 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -0700891#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700892 if (csd_start_voice == NULL) {
893 ALOGE("dlsym:Error:%s Loading csd_client_start_voice", dlerror());
894 } else {
895 err = csd_start_voice();
896 if (err < 0){
897 ALOGE("s_start_voice_call: csd_client error %d\n", err);
898 goto Error;
899 }
Iliyan Malchev4765c432012-06-11 14:36:16 -0700900 }
Iliyan Malchev4113f342012-06-11 14:39:47 -0700901#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700902 }
903
904 free(devName);
905 return NO_ERROR;
906
907Error:
Iliyan Malchev4113f342012-06-11 14:39:47 -0700908 ALOGE("s_start_voice_call: Failed to initialize ALSA device '%s'", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700909 free(devName);
910 s_close(handle);
911 return NO_INIT;
912}
913
914static status_t s_start_fm(alsa_handle_t *handle)
915{
916 char *devName;
917 unsigned flags = 0;
918 int err = NO_ERROR;
919
SathishKumar Mani9efed762012-09-18 18:52:48 -0700920 ALOGV("s_start_fm: handle %p", handle);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700921
922 // ASoC multicomponent requires a valid path (frontend/backend) for
923 // the device to be opened
924
925 flags = PCM_OUT | PCM_STEREO;
926 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700927 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700928 goto Error;
929 }
930 if (devName != NULL) {
931 handle->handle = pcm_open(flags, (char*)devName);
932 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700933 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700934 return NO_INIT;
935 }
936 if (!handle->handle) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700937 ALOGE("s_start_fm: could not open PCM device");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700938 goto Error;
939 }
940
941 handle->handle->flags = flags;
942 err = setHardwareParams(handle);
943 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700944 ALOGE("s_start_fm: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700945 goto Error;
946 }
947
948 err = setSoftwareParams(handle);
949 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700950 ALOGE("s_start_fm: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700951 goto Error;
952 }
953
954 err = pcm_prepare(handle->handle);
955 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700956 ALOGE("s_start_fm: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700957 goto Error;
958 }
959
960 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700961 ALOGE("s_start_fm: SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700962 goto Error;
963 }
964
965 // Store the PCM playback device pointer in rxHandle
966 handle->rxHandle = handle->handle;
967 free(devName);
968
969 // Open PCM capture device
970 flags = PCM_IN | PCM_STEREO;
971 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700972 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700973 goto Error;
974 }
975 if (devName != NULL) {
976 handle->handle = pcm_open(flags, (char*)devName);
977 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700978 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700979 return NO_INIT;
980 }
981 if (!handle->handle) {
982 goto Error;
983 }
984
985 handle->handle->flags = flags;
986 err = setHardwareParams(handle);
987 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700988 ALOGE("s_start_fm: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700989 goto Error;
990 }
991
992 err = setSoftwareParams(handle);
993 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700994 ALOGE("s_start_fm: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700995 goto Error;
996 }
997
998 err = pcm_prepare(handle->handle);
999 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001000 ALOGE("s_start_fm: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001001 goto Error;
1002 }
1003
1004 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001005 ALOGE("s_start_fm: SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001006 goto Error;
1007 }
1008
1009 s_set_fm_vol(fmVolume);
1010 free(devName);
1011 return NO_ERROR;
1012
1013Error:
1014 free(devName);
1015 s_close(handle);
1016 return NO_INIT;
1017}
1018
1019static status_t s_set_fm_vol(int value)
1020{
1021 status_t err = NO_ERROR;
1022
1023 ALSAControl control("/dev/snd/controlC0");
1024 control.set("Internal FM RX Volume",value,0);
1025 fmVolume = value;
1026
1027 return err;
1028}
1029
1030static status_t s_set_lpa_vol(int value)
1031{
1032 status_t err = NO_ERROR;
1033
1034 ALSAControl control("/dev/snd/controlC0");
1035 control.set("LPA RX Volume",value,0);
1036
1037 return err;
1038}
1039
1040static status_t s_start(alsa_handle_t *handle)
1041{
1042 status_t err = NO_ERROR;
1043
1044 if(!handle->handle) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001045 ALOGE("No active PCM driver to start");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001046 return err;
1047 }
1048
1049 err = pcm_prepare(handle->handle);
1050
1051 return err;
1052}
1053
1054static status_t s_close(alsa_handle_t *handle)
1055{
1056 int ret;
1057 status_t err = NO_ERROR;
1058 struct pcm *h = handle->rxHandle;
1059
1060 handle->rxHandle = 0;
SathishKumar Mani9efed762012-09-18 18:52:48 -07001061 ALOGV("s_close: handle %p h %p", handle, h);
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) {
SathishKumar Mani9efed762012-09-18 18:52:48 -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
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001084 if (csd_stop_voice == NULL) {
1085 ALOGE("dlsym:Error:%s Loading csd_client_disable_device", dlerror());
1086 } else {
1087 err = csd_stop_voice();
1088 if (err < 0) {
1089 ALOGE("s_close: csd_client error %d\n", err);
1090 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001091 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001092#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001093 }
1094
1095 disableDevice(handle);
1096 } else if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
1097 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
1098 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
1099 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))){
1100 disableDevice(handle);
1101 }
1102
1103 return err;
1104}
1105
1106/*
1107 this is same as s_close, but don't discard
1108 the device/mode info. This way we can still
1109 close the device, hit idle and power-save, reopen the pcm
1110 for the same device/mode after resuming
1111*/
1112static status_t s_standby(alsa_handle_t *handle)
1113{
1114 int ret;
SathishKumar Manie42406e2012-08-29 16:25:54 -07001115 status_t err = NO_ERROR;
Iliyan Malchev4765c432012-06-11 14:36:16 -07001116 struct pcm *h = handle->rxHandle;
1117 handle->rxHandle = 0;
SathishKumar Mani9efed762012-09-18 18:52:48 -07001118 ALOGV("s_standby: handle %p h %p", handle, h);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001119 if (h) {
SathishKumar Mani0a019912012-09-11 12:33:11 -07001120 ALOGD("s_standby rxHandle\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001121 err = pcm_close(h);
1122 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001123 ALOGE("s_standby: pcm_close failed for rxHandle with err %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001124 }
1125 }
1126
1127 h = handle->handle;
1128 handle->handle = 0;
1129
1130 if (h) {
SathishKumar Mani9efed762012-09-18 18:52:48 -07001131 ALOGV("s_standby handle h %p\n", h);
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
Iliyan Malchev4113f342012-06-11 14:39:47 -07001151 ALOGD("s_route: devices 0x%x in mode %d", devices, mode);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001152 callMode = mode;
1153 switchDevice(handle, devices, mode);
1154 return status;
1155}
1156
1157int getUseCaseType(const char *useCase)
1158{
SathishKumar Mani0a019912012-09-11 12:33:11 -07001159 ALOGD("use case is %s\n", useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001160 if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI,
1161 strlen(SND_USE_CASE_VERB_HIFI)) ||
SathishKumar Mani88613382012-08-13 18:40:18 -07001162 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC,
1163 strlen(SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -07001164 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER,
1165 strlen(SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
1166 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_TUNNEL,
1167 strlen(SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
1168 !strncmp(useCase, SND_USE_CASE_VERB_DIGITAL_RADIO,
1169 strlen(SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
1170 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC,
1171 strlen(SND_USE_CASE_MOD_PLAY_MUSIC)) ||
SathishKumar Mani88613382012-08-13 18:40:18 -07001172 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC,
1173 strlen(SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -07001174 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LPA,
1175 strlen(SND_USE_CASE_MOD_PLAY_LPA)) ||
1176 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_TUNNEL,
1177 strlen(SND_USE_CASE_MOD_PLAY_TUNNEL)) ||
1178 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_FM,
1179 strlen(SND_USE_CASE_MOD_PLAY_FM))) {
1180 return USECASE_TYPE_RX;
1181 } else if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI_REC,
1182 strlen(SND_USE_CASE_VERB_HIFI_REC)) ||
SathishKumar Mani88613382012-08-13 18:40:18 -07001183 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC,
1184 strlen(SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC)) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -07001185 !strncmp(useCase, SND_USE_CASE_VERB_FM_REC,
1186 strlen(SND_USE_CASE_VERB_FM_REC)) ||
1187 !strncmp(useCase, SND_USE_CASE_VERB_FM_A2DP_REC,
1188 strlen(SND_USE_CASE_VERB_FM_A2DP_REC)) ||
1189 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC,
1190 strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC)) ||
SathishKumar Mani88613382012-08-13 18:40:18 -07001191 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC,
1192 strlen(SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC)) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -07001193 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_FM,
1194 strlen(SND_USE_CASE_MOD_CAPTURE_FM)) ||
1195 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM,
1196 strlen(SND_USE_CASE_MOD_CAPTURE_A2DP_FM))) {
1197 return USECASE_TYPE_TX;
1198 } else if (!strncmp(useCase, SND_USE_CASE_VERB_VOICECALL,
1199 strlen(SND_USE_CASE_VERB_VOICECALL)) ||
1200 !strncmp(useCase, SND_USE_CASE_VERB_IP_VOICECALL,
1201 strlen(SND_USE_CASE_VERB_IP_VOICECALL)) ||
1202 !strncmp(useCase, SND_USE_CASE_VERB_DL_REC,
1203 strlen(SND_USE_CASE_VERB_DL_REC)) ||
1204 !strncmp(useCase, SND_USE_CASE_VERB_UL_DL_REC,
1205 strlen(SND_USE_CASE_VERB_UL_DL_REC)) ||
1206 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOICE,
1207 strlen(SND_USE_CASE_MOD_PLAY_VOICE)) ||
1208 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOIP,
1209 strlen(SND_USE_CASE_MOD_PLAY_VOIP)) ||
1210 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
1211 strlen(SND_USE_CASE_MOD_CAPTURE_VOICE_DL)) ||
1212 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
1213 strlen(SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL)) ||
1214 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
1215 strlen(SND_USE_CASE_MOD_CAPTURE_VOICE)) ||
1216 !strncmp(useCase, SND_USE_CASE_VERB_VOLTE,
1217 strlen(SND_USE_CASE_VERB_VOLTE)) ||
1218 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOLTE,
1219 strlen(SND_USE_CASE_MOD_PLAY_VOLTE))) {
1220 return (USECASE_TYPE_RX | USECASE_TYPE_TX);
1221 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001222 ALOGE("unknown use case %s\n", useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001223 return 0;
1224 }
1225}
1226
1227static void disableDevice(alsa_handle_t *handle)
1228{
1229 unsigned usecase_type = 0;
1230 int i, mods_size;
1231 char *useCase;
1232 const char **mods_list;
1233
1234 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
1235 if (useCase != NULL) {
1236 if (!strncmp(useCase, handle->useCase, MAX_UC_LEN)) {
1237 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
1238 } else {
1239 snd_use_case_set(handle->ucMgr, "_dismod", handle->useCase);
1240 }
1241 free(useCase);
1242 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
1243 if (strncmp(useCase, SND_USE_CASE_VERB_INACTIVE,
1244 strlen(SND_USE_CASE_VERB_INACTIVE)))
1245 usecase_type |= getUseCaseType(useCase);
1246 mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
SathishKumar Mani9efed762012-09-18 18:52:48 -07001247 ALOGV("Number of modifiers %d\n", mods_size);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001248 if (mods_size) {
1249 for(i = 0; i < mods_size; i++) {
SathishKumar Mani9efed762012-09-18 18:52:48 -07001250 ALOGV("index %d modifier %s\n", i, mods_list[i]);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001251 usecase_type |= getUseCaseType(mods_list[i]);
1252 }
1253 }
SathishKumar Mani9efed762012-09-18 18:52:48 -07001254 ALOGV("usecase_type is %d\n", usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001255 if (!(usecase_type & USECASE_TYPE_TX) && (strncmp(curTxUCMDevice, "None", 4)))
1256 snd_use_case_set(handle->ucMgr, "_disdev", curTxUCMDevice);
1257 if (!(usecase_type & USECASE_TYPE_RX) && (strncmp(curRxUCMDevice, "None", 4)))
1258 snd_use_case_set(handle->ucMgr, "_disdev", curRxUCMDevice);
1259 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001260 ALOGE("Invalid state, no valid use case found to disable");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001261 }
1262 free(useCase);
1263}
1264
1265char *getUCMDevice(uint32_t devices, int input, char *rxDevice)
1266{
1267 if (!input) {
1268 if (!(mDevSettingsFlag & TTY_OFF) &&
1269 (callMode == AudioSystem::MODE_IN_CALL) &&
1270 ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
ty.lee924f7982012-08-01 23:15:30 +09001271 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001272#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001273 ||
1274 (devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
1275 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) {
1276#endif
1277 if (mDevSettingsFlag & TTY_VCO) {
1278 return strdup(SND_USE_CASE_DEV_TTY_HEADSET_RX);
1279 } else if (mDevSettingsFlag & TTY_FULL) {
1280 return strdup(SND_USE_CASE_DEV_TTY_FULL_RX);
1281 } else if (mDevSettingsFlag & TTY_HCO) {
1282 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_RX); /* HANDSET RX */
1283 }
1284 }else if ((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET) ||
1285 (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)) {
1286 return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */
1287 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1288 ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
1289 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
1290 if (mDevSettingsFlag & ANC_FLAG) {
1291 return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
1292 } else {
1293 return strdup(SND_USE_CASE_DEV_SPEAKER_HEADSET); /* COMBO SPEAKER+HEADSET RX */
1294 }
Ajay Dudani9746c472012-06-18 16:01:16 -07001295#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001296 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1297 ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
1298 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) {
1299 return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
1300 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1301 (devices & AudioSystem::DEVICE_OUT_FM_TX)) {
1302 return strdup(SND_USE_CASE_DEV_SPEAKER_FM_TX); /* COMBO SPEAKER+FM_TX RX */
1303#endif
1304 } else if (devices & AudioSystem::DEVICE_OUT_EARPIECE) {
ty.lee925596f2012-09-12 18:23:59 +09001305 if (callMode == AudioSystem::MODE_IN_CALL) {
1306 return strdup(SND_USE_CASE_DEV_VOC_EARPIECE); /* Voice HANDSET RX */
1307 } else
1308 return strdup(SND_USE_CASE_DEV_EARPIECE); /* HANDSET RX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001309 } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) {
ty.lee925596f2012-09-12 18:23:59 +09001310 if (callMode == AudioSystem::MODE_IN_CALL) {
1311 return strdup(SND_USE_CASE_DEV_VOC_SPEAKER); /* Voice SPEAKER RX */
1312 } else
1313 return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001314 } else if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
1315 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) {
1316 if (mDevSettingsFlag & ANC_FLAG) {
ty.lee925596f2012-09-12 18:23:59 +09001317 if (callMode == AudioSystem::MODE_IN_CALL) {
1318 return strdup(SND_USE_CASE_DEV_VOC_ANC_HEADSET); /* Voice ANC HEADSET RX */
1319 } else
1320 return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001321 } else {
ty.lee925596f2012-09-12 18:23:59 +09001322 if (callMode == AudioSystem::MODE_IN_CALL) {
1323 return strdup(SND_USE_CASE_DEV_VOC_HEADPHONE); /* Voice HEADSET RX */
1324 } else
1325 return strdup(SND_USE_CASE_DEV_HEADPHONES); /* HEADSET RX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001326 }
Ajay Dudani9746c472012-06-18 16:01:16 -07001327#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001328 } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
1329 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE)) {
ty.lee925596f2012-09-12 18:23:59 +09001330 if (callMode == AudioSystem::MODE_IN_CALL) {
1331 return strdup(SND_USE_CASE_DEV_VOC_ANC_HEADSET); /* Voice ANC HEADSET RX */
1332 } else
1333 return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001334#endif
1335 } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) ||
1336 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
1337 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT)) {
1338 if (btsco_samplerate == BTSCO_RATE_16KHZ)
1339 return strdup(SND_USE_CASE_DEV_BTSCO_WB_RX); /* BTSCO RX*/
1340 else
1341 return strdup(SND_USE_CASE_DEV_BTSCO_NB_RX); /* BTSCO RX*/
1342 } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP) ||
1343 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES) ||
Ajay Dudani9746c472012-06-18 16:01:16 -07001344#ifdef QCOM_VOIP_ENABLED
1345 (devices & AudioSystem::DEVICE_OUT_DIRECTOUTPUT) ||
1346#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001347 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) {
1348 /* Nothing to be done, use current active device */
1349 if (strncmp(curRxUCMDevice, "None", 4)) {
1350 return strdup(curRxUCMDevice);
1351 }
1352 } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
1353 return strdup(SND_USE_CASE_DEV_HDMI); /* HDMI RX */
Ajay Dudani9746c472012-06-18 16:01:16 -07001354#ifdef QCOM_PROXY_DEVICE_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001355 } else if (devices & AudioSystem::DEVICE_OUT_PROXY) {
1356 return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */
Ajay Dudani9746c472012-06-18 16:01:16 -07001357#endif
1358#ifdef QCOM_FM_TX_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001359 } else if (devices & AudioSystem::DEVICE_OUT_FM_TX) {
1360 return strdup(SND_USE_CASE_DEV_FM_TX); /* FM Tx */
1361#endif
1362 } else if (devices & AudioSystem::DEVICE_OUT_DEFAULT) {
ty.lee925596f2012-09-12 18:23:59 +09001363 if (callMode == AudioSystem::MODE_IN_CALL) {
1364 return strdup(SND_USE_CASE_DEV_VOC_SPEAKER); /* Voice SPEAKER RX */
1365 } else
1366 return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001367 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001368 ALOGD("No valid output device: %u", devices);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001369 }
1370 } else {
1371 if (!(mDevSettingsFlag & TTY_OFF) &&
1372 (callMode == AudioSystem::MODE_IN_CALL) &&
ty.lee924f7982012-08-01 23:15:30 +09001373 ((devices & AudioSystem::DEVICE_IN_WIRED_HEADSET))) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001374#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001375 ||(devices & AudioSystem::DEVICE_IN_ANC_HEADSET))) {
1376#endif
1377 if (mDevSettingsFlag & TTY_HCO) {
1378 return strdup(SND_USE_CASE_DEV_TTY_HEADSET_TX);
1379 } else if (mDevSettingsFlag & TTY_FULL) {
1380 return strdup(SND_USE_CASE_DEV_TTY_FULL_TX);
1381 } else if (mDevSettingsFlag & TTY_VCO) {
1382 if (!strncmp(mic_type, "analog", 6)) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001383 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_ANALOG_TX);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001384 } else {
1385 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_TX);
1386 }
1387 }
1388 } else if (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) {
1389 if (!strncmp(mic_type, "analog", 6)) {
1390 return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
1391 } else {
1392 if (mDevSettingsFlag & DMIC_FLAG) {
ty.lee924f7982012-08-01 23:15:30 +09001393#ifdef USES_FLUENCE_INCALL
1394 if(callMode == AudioSystem::MODE_IN_CALL) {
1395 if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
1396 return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
1397 } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
1398 return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
1399 } else {
1400 return strdup(SND_USE_CASE_DEV_HANDSET); /* BUILTIN-MIC TX */
1401 }
1402 }
1403#else
Iliyan Malchev4765c432012-06-11 14:36:16 -07001404 if (((rxDevice != NULL) &&
1405 !strncmp(rxDevice, SND_USE_CASE_DEV_SPEAKER,
1406 (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) ||
1407 !strncmp(curRxUCMDevice, SND_USE_CASE_DEV_SPEAKER,
1408 (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) {
1409 if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
1410 return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
1411 } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
1412 return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
1413 }
1414 } else {
1415 if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
1416 return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
1417 } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
1418 return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
1419 }
1420 }
ty.lee924f7982012-08-01 23:15:30 +09001421#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001422 } else if (mDevSettingsFlag & QMIC_FLAG){
1423 return strdup(SND_USE_CASE_DEV_QUAD_MIC);
ty.lee924f7982012-08-01 23:15:30 +09001424 }
Ajay Dudani9746c472012-06-18 16:01:16 -07001425#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001426 else if (mDevSettingsFlag & SSRQMIC_FLAG){
Iliyan Malchev4113f342012-06-11 14:39:47 -07001427 ALOGV("return SSRQMIC_FLAG: 0x%x devices:0x%x",mDevSettingsFlag,devices);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001428 // Mapping for quad mic input device.
1429 return strdup(SND_USE_CASE_DEV_SSR_QUAD_MIC); /* SSR Quad MIC */
ty.lee924f7982012-08-01 23:15:30 +09001430 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001431#endif
ty.lee74060de2012-08-02 00:47:00 +09001432#ifdef SEPERATED_AUDIO_INPUT
1433 if(input_source == AUDIO_SOURCE_VOICE_RECOGNITION) {
ty.lee74060de2012-08-02 00:47:00 +09001434 return strdup(SND_USE_CASE_DEV_VOICE_RECOGNITION ); /* VOICE RECOGNITION TX */
1435 } else if(input_source == AUDIO_SOURCE_CAMCORDER) {
ty.lee74060de2012-08-02 00:47:00 +09001436 return strdup(SND_USE_CASE_DEV_CAMCORDER_TX ); /* CAMCORDER TX */
1437 }
1438#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001439 else {
ty.lee74060de2012-08-02 00:47:00 +09001440 return strdup(SND_USE_CASE_DEV_HANDSET); /* BUILTIN-MIC TX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001441 }
1442 }
1443 } else if (devices & AudioSystem::DEVICE_IN_AUX_DIGITAL) {
1444 return strdup(SND_USE_CASE_DEV_HDMI_TX); /* HDMI TX */
Ajay Dudani9746c472012-06-18 16:01:16 -07001445#ifdef QCOM_ANC_HEADSET_ENABLED
ehgrace.kim249f87d2012-08-12 20:40:32 -07001446 } else if (devices & AudioSystem::DEVICE_IN_ANC_HEADSET) {
Iliyan Malchev4765c432012-06-11 14:36:16 -07001447 return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */
1448#endif
ehgrace.kim249f87d2012-08-12 20:40:32 -07001449 } else if (devices & AudioSystem::DEVICE_IN_WIRED_HEADSET) {
ty.lee925596f2012-09-12 18:23:59 +09001450 if (callMode == AudioSystem::MODE_IN_CALL) {
1451 return strdup(SND_USE_CASE_DEV_VOC_HEADSET); /* Voice HEADSET TX */
1452 } else
1453 return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001454 } else if (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
1455 if (btsco_samplerate == BTSCO_RATE_16KHZ)
1456 return strdup(SND_USE_CASE_DEV_BTSCO_WB_TX); /* BTSCO TX*/
1457 else
1458 return strdup(SND_USE_CASE_DEV_BTSCO_NB_TX); /* BTSCO TX*/
Ajay Dudani9746c472012-06-18 16:01:16 -07001459#ifdef QCOM_USBAUDIO_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001460 } else if ((devices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) ||
1461 (devices & AudioSystem::DEVICE_IN_PROXY)) {
1462 return strdup(SND_USE_CASE_DEV_PROXY_TX); /* PROXY TX */
1463#endif
1464 } else if ((devices & AudioSystem::DEVICE_IN_COMMUNICATION) ||
1465 (devices & AudioSystem::DEVICE_IN_VOICE_CALL)) {
1466 /* Nothing to be done, use current active device */
1467 if (strncmp(curTxUCMDevice, "None", 4)) {
1468 return strdup(curTxUCMDevice);
1469 }
Ajay Dudani9746c472012-06-18 16:01:16 -07001470#ifdef QCOM_FM_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001471 } else if ((devices & AudioSystem::DEVICE_IN_FM_RX) ||
1472 (devices & AudioSystem::DEVICE_IN_FM_RX_A2DP)) {
1473 /* Nothing to be done, use current tx device or set dummy device */
1474 if (strncmp(curTxUCMDevice, "None", 4)) {
1475 return strdup(curTxUCMDevice);
1476 } else {
1477 return strdup(SND_USE_CASE_DEV_DUMMY_TX);
1478 }
1479#endif
1480 } else if ((devices & AudioSystem::DEVICE_IN_AMBIENT) ||
1481 (devices & AudioSystem::DEVICE_IN_BACK_MIC)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001482 ALOGI("No proper mapping found with UCM device list, setting default");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001483 if (!strncmp(mic_type, "analog", 6)) {
1484 return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
1485 } else {
ty.lee925596f2012-09-12 18:23:59 +09001486 if (callMode == AudioSystem::MODE_IN_CALL) {
1487 return strdup(SND_USE_CASE_DEV_VOC_LINE); /* Voice BUILTIN-MIC TX */
1488 } else
1489 return strdup(SND_USE_CASE_DEV_LINE); /* BUILTIN-MIC TX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001490 }
1491 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001492 ALOGD("No valid input device: %u", devices);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001493 }
1494 }
1495 return NULL;
1496}
1497
1498void s_set_voice_volume(int vol)
1499{
1500 int err = 0;
SathishKumar Mani9efed762012-09-18 18:52:48 -07001501 ALOGV("s_set_voice_volume: volume %d", vol);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001502 ALSAControl control("/dev/snd/controlC0");
1503 control.set("Voice Rx Volume", vol, 0);
1504
1505 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001506#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001507 if (csd_volume == NULL) {
1508 ALOGE("dlsym:Error:%s Loading csd_client_volume", dlerror());
1509 } else {
1510 err = csd_volume(vol);
1511 if (err < 0) {
1512 ALOGE("s_set_voice_volume: csd_client error %d", err);
1513 }
SathishKumar Manie42406e2012-08-29 16:25:54 -07001514 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001515#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001516 }
1517}
1518
1519void s_set_volte_volume(int vol)
1520{
SathishKumar Mani9efed762012-09-18 18:52:48 -07001521 ALOGV("s_set_volte_volume: volume %d", vol);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001522 ALSAControl control("/dev/snd/controlC0");
1523 control.set("VoLTE Rx Volume", vol, 0);
1524}
1525
1526
1527void s_set_voip_volume(int vol)
1528{
SathishKumar Mani9efed762012-09-18 18:52:48 -07001529 ALOGV("s_set_voip_volume: volume %d", vol);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001530 ALSAControl control("/dev/snd/controlC0");
1531 control.set("Voip Rx Volume", vol, 0);
1532}
1533void s_set_mic_mute(int state)
1534{
1535 int err = 0;
SathishKumar Mani9efed762012-09-18 18:52:48 -07001536 ALOGV("s_set_mic_mute: state %d", state);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001537 ALSAControl control("/dev/snd/controlC0");
1538 control.set("Voice Tx Mute", state, 0);
1539
1540 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001541#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001542 if (csd_mic_mute == NULL) {
1543 ALOGE("dlsym:Error:%s Loading csd_mic_mute", dlerror());
1544 } else {
1545 err=csd_mic_mute(state);
1546 if (err < 0) {
1547 ALOGE("s_set_mic_mute: csd_client error %d", err);
1548 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001549 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001550#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001551 }
1552}
1553void s_set_volte_mic_mute(int state)
1554{
SathishKumar Mani9efed762012-09-18 18:52:48 -07001555 ALOGV("s_set_volte_mic_mute: state %d", state);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001556 ALSAControl control("/dev/snd/controlC0");
1557 control.set("VoLTE Tx Mute", state, 0);
1558}
1559
1560void s_set_voip_mic_mute(int state)
1561{
SathishKumar Mani9efed762012-09-18 18:52:48 -07001562 ALOGV("s_set_voip_mic_mute: state %d", state);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001563 ALSAControl control("/dev/snd/controlC0");
1564 control.set("Voip Tx Mute", state, 0);
1565}
1566
1567void s_set_voip_config(int mode, int rate)
1568{
SathishKumar Mani9efed762012-09-18 18:52:48 -07001569 ALOGV("s_set_voip_config: mode %d,rate %d", mode, rate);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001570 ALSAControl control("/dev/snd/controlC0");
1571 char** setValues;
1572 setValues = (char**)malloc(2*sizeof(char*));
1573 if (setValues == NULL) {
1574 return;
1575 }
1576 setValues[0] = (char*)malloc(4*sizeof(char));
1577 if (setValues[0] == NULL) {
1578 free(setValues);
1579 return;
1580 }
1581
1582 setValues[1] = (char*)malloc(8*sizeof(char));
1583 if (setValues[1] == NULL) {
1584 free(setValues);
1585 free(setValues[0]);
1586 return;
1587 }
1588
1589 sprintf(setValues[0], "%d",mode);
1590 sprintf(setValues[1], "%d",rate);
1591
1592 control.setext("Voip Mode Rate Config", 2, setValues);
1593 free(setValues[1]);
1594 free(setValues[0]);
1595 free(setValues);
1596 return;
1597}
1598
1599void s_set_btsco_rate(int rate)
1600{
1601 btsco_samplerate = rate;
1602}
1603
1604void s_enable_wide_voice(bool flag)
1605{
1606 int err = 0;
1607
SathishKumar Mani9efed762012-09-18 18:52:48 -07001608 ALOGV("s_enable_wide_voice: flag %d", flag);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001609 ALSAControl control("/dev/snd/controlC0");
1610 if(flag == true) {
1611 control.set("Widevoice Enable", 1, 0);
1612 } else {
1613 control.set("Widevoice Enable", 0, 0);
1614 }
1615
1616 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001617#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001618 if (csd_wide_voice == NULL) {
1619 ALOGE("dlsym:Error:%s Loading csd_wide_voice", dlerror());
1620 } else {
1621 err = csd_wide_voice(flag);
1622 if (err < 0) {
1623 ALOGE("enableWideVoice: csd_client_wide_voice error %d", err);
1624 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001625 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001626#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001627 }
1628}
1629
1630void s_set_voc_rec_mode(uint8_t mode)
1631{
SathishKumar Mani9efed762012-09-18 18:52:48 -07001632 ALOGV("s_set_voc_rec_mode: mode %d", mode);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001633 ALSAControl control("/dev/snd/controlC0");
1634 control.set("Incall Rec Mode", mode, 0);
1635}
1636
1637void s_enable_fens(bool flag)
1638{
1639 int err = 0;
1640
SathishKumar Mani9efed762012-09-18 18:52:48 -07001641 ALOGV("s_enable_fens: flag %d", flag);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001642 ALSAControl control("/dev/snd/controlC0");
1643 if(flag == true) {
1644 control.set("FENS Enable", 1, 0);
1645 } else {
1646 control.set("FENS Enable", 0, 0);
1647 }
1648
1649 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001650#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001651 if (csd_fens == NULL) {
1652 ALOGE("dlsym:Error:%s Loading csd_fens", dlerror());
1653 } else {
1654 err = csd_fens(flag);
1655 if (err < 0) {
1656 ALOGE("s_enable_fens: csd_client error %d", err);
1657 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001658 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001659#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001660 }
1661}
1662
1663void s_enable_slow_talk(bool flag)
1664{
1665 int err = 0;
1666
SathishKumar Mani9efed762012-09-18 18:52:48 -07001667 ALOGV("s_enable_slow_talk: flag %d", flag);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001668 ALSAControl control("/dev/snd/controlC0");
1669 if(flag == true) {
1670 control.set("Slowtalk Enable", 1, 0);
1671 } else {
1672 control.set("Slowtalk Enable", 0, 0);
1673 }
1674
1675 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001676#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001677 if (csd_slow_talk == NULL) {
1678 ALOGE("dlsym:Error:%s Loading csd_slow_talk", dlerror());
1679 } else {
1680 err = csd_slow_talk(flag);
1681 if (err < 0) {
1682 ALOGE("s_enable_slow_talk: csd_client error %d", err);
1683 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001684 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001685#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001686 }
1687}
1688
1689void s_set_flags(uint32_t flags)
1690{
Iliyan Malchev4113f342012-06-11 14:39:47 -07001691 ALOGV("s_set_flags: flags %d", flags);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001692 mDevSettingsFlag = flags;
1693}
1694
1695static status_t s_set_compressed_vol(int value)
1696{
1697 status_t err = NO_ERROR;
1698
1699 ALSAControl control("/dev/snd/controlC0");
1700 control.set("COMPRESSED RX Volume",value,0);
1701
1702 return err;
1703}
1704
ty.lee74060de2012-08-02 00:47:00 +09001705#ifdef SEPERATED_AUDIO_INPUT
1706void s_setInput(int input)
1707{
1708 input_source = input;
1709 ALOGD("s_setInput() : input_source = %d",input_source);
1710}
1711#endif
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001712
1713#ifdef QCOM_CSDCLIENT_ENABLED
1714static void s_set_csd_handle(void* handle)
1715{
1716 csd_handle = static_cast<void*>(handle);
1717 ALOGI("%s csd_handle: %p", __func__, csd_handle);
1718
1719 csd_disable_device = (int (*)())::dlsym(csd_handle,"csd_client_disable_device");
1720 csd_enable_device = (int (*)(int,int,uint32_t))::dlsym(csd_handle,"csd_client_enable_device");
1721 csd_start_voice = (int (*)())::dlsym(csd_handle,"csd_client_start_voice");
1722 csd_stop_voice = (int (*)())::dlsym(csd_handle,"csd_client_stop_voice");
1723 csd_volume = (int (*)(int))::dlsym(csd_handle,"csd_client_volume");
1724 csd_mic_mute = (int (*)(int))::dlsym(csd_handle,"csd_client_mic_mute");
1725 csd_wide_voice = (int (*)(uint8_t))::dlsym(csd_handle,"csd_client_wide_voice");
1726 csd_fens = (int (*)(uint8_t))::dlsym(csd_handle,"csd_client_fens");
1727 csd_slow_talk = (int (*)(uint8_t))::dlsym(csd_handle,"csd_client_slow_talk");
1728}
1729#endif
1730
Iliyan Malchev4765c432012-06-11 14:36:16 -07001731}