blob: d44be175e9ede8762a6f8bffa3c41269b4919c5d [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" {
30#include "csd_client.h"
SathishKumar Mani5ff7a022012-09-14 11:36:35 -070031static int (*csd_disable_device)();
32static int (*csd_enable_device)(int, int, uint32_t);
33static int (*csd_volume)(int);
34static int (*csd_mic_mute)(int);
35static int (*csd_wide_voice)(uint8_t);
36static int (*csd_slow_talk)(uint8_t);
37static int (*csd_fens)(uint8_t);
38static int (*csd_start_voice)();
39static int (*csd_stop_voice)();
Iliyan Malchev4765c432012-06-11 14:36:16 -070040}
Iliyan Malchev4113f342012-06-11 14:39:47 -070041#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -070042
43#ifndef ALSA_DEFAULT_SAMPLE_RATE
44#define ALSA_DEFAULT_SAMPLE_RATE 44100 // in Hz
45#endif
46
47#define BTSCO_RATE_16KHZ 16000
48#define USECASE_TYPE_RX 1
49#define USECASE_TYPE_TX 2
50
51namespace android_audio_legacy
52{
53
54static int s_device_open(const hw_module_t*, const char*, hw_device_t**);
55static int s_device_close(hw_device_t*);
56static status_t s_init(alsa_device_t *, ALSAHandleList &);
57static status_t s_open(alsa_handle_t *);
58static status_t s_close(alsa_handle_t *);
59static status_t s_standby(alsa_handle_t *);
60static status_t s_route(alsa_handle_t *, uint32_t, int);
61static status_t s_start_voice_call(alsa_handle_t *);
62static status_t s_start_voip_call(alsa_handle_t *);
63static status_t s_start_fm(alsa_handle_t *);
64static void s_set_voice_volume(int);
65static void s_set_voip_volume(int);
66static void s_set_mic_mute(int);
67static void s_set_voip_mic_mute(int);
68static void s_set_voip_config(int, int);
69static status_t s_set_fm_vol(int);
70static void s_set_btsco_rate(int);
71static status_t s_set_lpa_vol(int);
72static void s_enable_wide_voice(bool flag);
73static void s_enable_fens(bool flag);
74static void s_set_flags(uint32_t flags);
75static status_t s_set_compressed_vol(int);
76static void s_enable_slow_talk(bool flag);
77static void s_set_voc_rec_mode(uint8_t mode);
78static void s_set_volte_mic_mute(int state);
79static void s_set_volte_volume(int vol);
ty.lee74060de2012-08-02 00:47:00 +090080#ifdef SEPERATED_AUDIO_INPUT
81static void s_setInput(int);
82
83static int input_source;
84#endif
SathishKumar Mani5ff7a022012-09-14 11:36:35 -070085#ifdef QCOM_CSDCLIENT_ENABLED
86static void s_set_csd_handle(void*);
87#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -070088
89static char mic_type[25];
90static char curRxUCMDevice[50];
91static char curTxUCMDevice[50];
92static int fluence_mode;
93static int fmVolume;
ty.lee924f7982012-08-01 23:15:30 +090094#ifdef USES_FLUENCE_INCALL
95static uint32_t mDevSettingsFlag = TTY_OFF | DMIC_FLAG;
96#else
Iliyan Malchev4765c432012-06-11 14:36:16 -070097static uint32_t mDevSettingsFlag = TTY_OFF;
ty.lee924f7982012-08-01 23:15:30 +090098#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -070099static int btsco_samplerate = 8000;
100static bool pflag = false;
101static ALSAUseCaseList mUseCaseList;
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700102static void *csd_handle;
Iliyan Malchev4765c432012-06-11 14:36:16 -0700103
104static hw_module_methods_t s_module_methods = {
105 open : s_device_open
106};
107
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700108extern "C" {
109hw_module_t HAL_MODULE_INFO_SYM = {
Iliyan Malchev4765c432012-06-11 14:36:16 -0700110 tag : HARDWARE_MODULE_TAG,
111 version_major : 1,
112 version_minor : 0,
113 id : ALSA_HARDWARE_MODULE_ID,
114 name : "QCOM ALSA module",
115 author : "QuIC Inc",
116 methods : &s_module_methods,
117 dso : 0,
118 reserved : {0,},
119};
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700120}
Iliyan Malchev4765c432012-06-11 14:36:16 -0700121
122static int s_device_open(const hw_module_t* module, const char* name,
123 hw_device_t** device)
124{
125 char value[128];
126 alsa_device_t *dev;
127 dev = (alsa_device_t *) malloc(sizeof(*dev));
128 if (!dev) return -ENOMEM;
129
130 memset(dev, 0, sizeof(*dev));
131
132 /* initialize the procs */
133 dev->common.tag = HARDWARE_DEVICE_TAG;
134 dev->common.version = 0;
135 dev->common.module = (hw_module_t *) module;
136 dev->common.close = s_device_close;
137 dev->init = s_init;
138 dev->open = s_open;
139 dev->close = s_close;
140 dev->route = s_route;
141 dev->standby = s_standby;
142 dev->startVoiceCall = s_start_voice_call;
143 dev->startVoipCall = s_start_voip_call;
144 dev->startFm = s_start_fm;
145 dev->setVoiceVolume = s_set_voice_volume;
146 dev->setVoipVolume = s_set_voip_volume;
147 dev->setMicMute = s_set_mic_mute;
148 dev->setVoipMicMute = s_set_voip_mic_mute;
149 dev->setVoipConfig = s_set_voip_config;
150 dev->setFmVolume = s_set_fm_vol;
151 dev->setBtscoRate = s_set_btsco_rate;
152 dev->setLpaVolume = s_set_lpa_vol;
153 dev->enableWideVoice = s_enable_wide_voice;
154 dev->enableFENS = s_enable_fens;
155 dev->setFlags = s_set_flags;
156 dev->setCompressedVolume = s_set_compressed_vol;
157 dev->enableSlowTalk = s_enable_slow_talk;
158 dev->setVocRecMode = s_set_voc_rec_mode;
159 dev->setVoLTEMicMute = s_set_volte_mic_mute;
160 dev->setVoLTEVolume = s_set_volte_volume;
ty.lee74060de2012-08-02 00:47:00 +0900161#ifdef SEPERATED_AUDIO_INPUT
162 dev->setInput = s_setInput;
163#endif
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700164#ifdef QCOM_CSDCLIENT_ENABLED
165 dev->setCsdHandle = s_set_csd_handle;
166#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700167 *device = &dev->common;
168
169 property_get("persist.audio.handset.mic",value,"0");
170 strlcpy(mic_type, value, sizeof(mic_type));
171 property_get("persist.audio.fluence.mode",value,"0");
172 if (!strcmp("broadside", value)) {
173 fluence_mode = FLUENCE_MODE_BROADSIDE;
174 } else {
175 fluence_mode = FLUENCE_MODE_ENDFIRE;
176 }
177 strlcpy(curRxUCMDevice, "None", sizeof(curRxUCMDevice));
178 strlcpy(curTxUCMDevice, "None", sizeof(curTxUCMDevice));
SathishKumar Mani9efed762012-09-18 18:52:48 -0700179 ALOGV("ALSA module opened");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700180
181 return 0;
182}
183
184static int s_device_close(hw_device_t* device)
185{
186 free(device);
187 device = NULL;
188 return 0;
189}
190
191// ----------------------------------------------------------------------------
192
193static const int DEFAULT_SAMPLE_RATE = ALSA_DEFAULT_SAMPLE_RATE;
194
195static void switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode);
196static char *getUCMDevice(uint32_t devices, int input, char *rxDevice);
197static void disableDevice(alsa_handle_t *handle);
198int getUseCaseType(const char *useCase);
199
200static int callMode = AudioSystem::MODE_NORMAL;
201// ----------------------------------------------------------------------------
202
203bool platform_is_Fusion3()
204{
205 char platform[128], baseband[128];
206 property_get("ro.board.platform", platform, "");
207 property_get("ro.baseband", baseband, "");
208 if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband))
209 return true;
210 else
211 return false;
212}
213
214int deviceName(alsa_handle_t *handle, unsigned flags, char **value)
215{
216 int ret = 0;
217 char ident[70];
218
219 if (flags & PCM_IN) {
220 strlcpy(ident, "CapturePCM/", sizeof(ident));
221 } else {
222 strlcpy(ident, "PlaybackPCM/", sizeof(ident));
223 }
224 strlcat(ident, handle->useCase, sizeof(ident));
225 ret = snd_use_case_get(handle->ucMgr, ident, (const char **)value);
Iliyan Malchev4113f342012-06-11 14:39:47 -0700226 ALOGD("Device value returned is %s", (*value));
Iliyan Malchev4765c432012-06-11 14:36:16 -0700227 return ret;
228}
229
230status_t setHardwareParams(alsa_handle_t *handle)
231{
232 struct snd_pcm_hw_params *params;
233 unsigned long bufferSize, reqBuffSize;
234 unsigned int periodTime, bufferTime;
235 unsigned int requestedRate = handle->sampleRate;
236 int status = 0;
237 int channels = handle->channels;
238 snd_pcm_format_t format = SNDRV_PCM_FORMAT_S16_LE;
239
240 params = (snd_pcm_hw_params*) calloc(1, sizeof(struct snd_pcm_hw_params));
241 if (!params) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700242 ALOGE("Failed to allocate ALSA hardware parameters!");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700243 return NO_INIT;
244 }
245
246 reqBuffSize = handle->bufferSize;
Iliyan Malchev4113f342012-06-11 14:39:47 -0700247 ALOGD("setHardwareParams: reqBuffSize %d channels %d sampleRate %d",
Iliyan Malchev4765c432012-06-11 14:36:16 -0700248 (int) reqBuffSize, handle->channels, handle->sampleRate);
249
Ajay Dudani9746c472012-06-18 16:01:16 -0700250#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700251 if (channels == 6) {
252 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
253 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700254 ALOGV("HWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700255 channels = 4;
256 reqBuffSize = DEFAULT_IN_BUFFER_SIZE;
257 }
258 }
259#endif
260
261 param_init(params);
262 param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS,
263 SNDRV_PCM_ACCESS_RW_INTERLEAVED);
264 if (handle->format != SNDRV_PCM_FORMAT_S16_LE) {
Ajay Dudani9746c472012-06-18 16:01:16 -0700265 if (handle->format == AudioSystem::AMR_NB
266 || handle->format == AudioSystem::AMR_WB
267#ifdef QCOM_QCHAT_ENABLED
268 || handle->format == AudioSystem::EVRC
269 || handle->format == AudioSystem::EVRCB
270 || handle->format == AudioSystem::EVRCWB
271#endif
272 )
Iliyan Malchev4765c432012-06-11 14:36:16 -0700273 format = SNDRV_PCM_FORMAT_SPECIAL;
274 }
275 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
276 format);
277 param_set_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT,
278 SNDRV_PCM_SUBFORMAT_STD);
279 param_set_min(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, reqBuffSize);
280 param_set_int(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 16);
281 param_set_int(params, SNDRV_PCM_HW_PARAM_FRAME_BITS,
282 channels * 16);
283 param_set_int(params, SNDRV_PCM_HW_PARAM_CHANNELS,
284 channels);
285 param_set_int(params, SNDRV_PCM_HW_PARAM_RATE, handle->sampleRate);
286 param_set_hw_refine(handle->handle, params);
287
288 if (param_set_hw_params(handle->handle, params)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700289 ALOGE("cannot set hw params");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700290 return NO_INIT;
291 }
292 param_dump(params);
293
294 handle->handle->buffer_size = pcm_buffer_size(params);
295 handle->handle->period_size = pcm_period_size(params);
296 handle->handle->period_cnt = handle->handle->buffer_size/handle->handle->period_size;
Iliyan Malchev4113f342012-06-11 14:39:47 -0700297 ALOGD("setHardwareParams: buffer_size %d, period_size %d, period_cnt %d",
Iliyan Malchev4765c432012-06-11 14:36:16 -0700298 handle->handle->buffer_size, handle->handle->period_size,
299 handle->handle->period_cnt);
300 handle->handle->rate = handle->sampleRate;
301 handle->handle->channels = handle->channels;
302 handle->periodSize = handle->handle->period_size;
303 if (strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC) &&
304 strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC) &&
305 (6 != handle->channels)) {
306 //Do not update buffersize for 5.1 recording
307 handle->bufferSize = handle->handle->period_size;
308 }
309
310 return NO_ERROR;
311}
312
313status_t setSoftwareParams(alsa_handle_t *handle)
314{
315 struct snd_pcm_sw_params* params;
316 struct pcm* pcm = handle->handle;
317
318 unsigned long periodSize = pcm->period_size;
319 int channels = handle->channels;
320
321 params = (snd_pcm_sw_params*) calloc(1, sizeof(struct snd_pcm_sw_params));
322 if (!params) {
323 LOG_ALWAYS_FATAL("Failed to allocate ALSA software parameters!");
324 return NO_INIT;
325 }
326
Ajay Dudani9746c472012-06-18 16:01:16 -0700327#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700328 if (channels == 6) {
329 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
330 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700331 ALOGV("SWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700332 channels = 4;
333 }
334 }
335#endif
336
337 // Get the current software parameters
338 params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
339 params->period_step = 1;
340 if(((!strcmp(handle->useCase,SND_USE_CASE_MOD_PLAY_VOIP)) ||
341 (!strcmp(handle->useCase,SND_USE_CASE_VERB_IP_VOICECALL)))){
Iliyan Malchev4113f342012-06-11 14:39:47 -0700342 ALOGV("setparam: start & stop threshold for Voip ");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700343 params->avail_min = handle->channels - 1 ? periodSize/4 : periodSize/2;
344 params->start_threshold = periodSize/2;
345 params->stop_threshold = INT_MAX;
346 } else {
347 params->avail_min = periodSize/2;
348 params->start_threshold = channels * (periodSize/4);
349 params->stop_threshold = INT_MAX;
350 }
351 params->silence_threshold = 0;
352 params->silence_size = 0;
353
354 if (param_set_sw_params(handle->handle, params)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700355 ALOGE("cannot set sw params");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700356 return NO_INIT;
357 }
358 return NO_ERROR;
359}
360
361void switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode)
362{
363 const char **mods_list;
364 use_case_t useCaseNode;
365 unsigned usecase_type = 0;
366 bool inCallDevSwitch = false;
367 char *rxDevice, *txDevice, ident[70], *use_case = NULL;
368 int err = 0, index, mods_size;
369 int rx_dev_id, tx_dev_id;
SathishKumar Mani9efed762012-09-18 18:52:48 -0700370 ALOGD("%s: device %d mode:%d", __FUNCTION__, devices, mode);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700371
372 if ((mode == AudioSystem::MODE_IN_CALL) || (mode == AudioSystem::MODE_IN_COMMUNICATION)) {
373 if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
374 (devices & AudioSystem::DEVICE_IN_WIRED_HEADSET)) {
375 devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADSET |
376 AudioSystem::DEVICE_IN_WIRED_HEADSET);
377 } else if (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
378 devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADPHONE |
379 AudioSystem::DEVICE_IN_BUILTIN_MIC);
380 } else if ((devices & AudioSystem::DEVICE_OUT_EARPIECE) ||
381 (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC)) {
382 devices = devices | (AudioSystem::DEVICE_IN_BUILTIN_MIC |
383 AudioSystem::DEVICE_OUT_EARPIECE);
384 } 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) {
402 devices = devices | (AudioSystem::DEVICE_OUT_AUX_DIGITAL |
403 AudioSystem::DEVICE_IN_AUX_DIGITAL);
Ajay Dudani9746c472012-06-18 16:01:16 -0700404#ifdef QCOM_PROXY_DEVICE_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700405 } else if ((devices & AudioSystem::DEVICE_OUT_PROXY) ||
406 (devices & AudioSystem::DEVICE_IN_PROXY)) {
407 devices = devices | (AudioSystem::DEVICE_OUT_PROXY |
408 AudioSystem::DEVICE_IN_PROXY);
409#endif
410 }
411 }
Ajay Dudani9746c472012-06-18 16:01:16 -0700412#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700413 if ((devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) && ( 6 == handle->channels)) {
414 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
415 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700416 ALOGV(" switchDevice , use ssr devices for channels:%d usecase:%s",handle->channels,handle->useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700417 s_set_flags(SSRQMIC_FLAG);
418 }
419 }
420#endif
421
422 rxDevice = getUCMDevice(devices & AudioSystem::DEVICE_OUT_ALL, 0, NULL);
423 txDevice = getUCMDevice(devices & AudioSystem::DEVICE_IN_ALL, 1, rxDevice);
424
Iliyan Malchev4765c432012-06-11 14:36:16 -0700425 if ((rxDevice != NULL) && (txDevice != NULL)) {
426 if (((strncmp(rxDevice, curRxUCMDevice, MAX_STR_LEN)) ||
427 (strncmp(txDevice, curTxUCMDevice, MAX_STR_LEN))) && (mode == AudioSystem::MODE_IN_CALL))
428 inCallDevSwitch = true;
429 }
Ajay Dudani91bf8912012-08-20 18:48:13 -0700430
431#ifdef QCOM_CSDCLIENT_ENABLED
432 if (mode == AudioSystem::MODE_IN_CALL && platform_is_Fusion3() && (inCallDevSwitch == true)) {
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700433 if (csd_disable_device == NULL) {
434 ALOGE("dlsym:Error:%s Loading csd_client_disable_device", dlerror());
435 } else {
436 err = csd_disable_device();
437 if (err < 0)
438 {
439 ALOGE("csd_client_disable_device, failed, error %d", err);
440 }
Ajay Dudani91bf8912012-08-20 18:48:13 -0700441 }
442 }
443#endif
444
Iliyan Malchev4765c432012-06-11 14:36:16 -0700445 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&use_case);
446 mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
447 if (rxDevice != NULL) {
448 if ((strncmp(curRxUCMDevice, "None", 4)) &&
449 ((strncmp(rxDevice, curRxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
450 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
451 strlen(SND_USE_CASE_VERB_INACTIVE)))) {
452 usecase_type = getUseCaseType(use_case);
453 if (usecase_type & USECASE_TYPE_RX) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700454 ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700455 strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
456 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
457 mUseCaseList.push_front(useCaseNode);
458 }
459 }
460 if (mods_size) {
461 for(index = 0; index < mods_size; index++) {
462 usecase_type = getUseCaseType(mods_list[index]);
463 if (usecase_type & USECASE_TYPE_RX) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700464 ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700465 strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
466 snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
467 mUseCaseList.push_back(useCaseNode);
468 }
469 }
470 }
471 snd_use_case_set(handle->ucMgr, "_disdev", curRxUCMDevice);
472 }
473 }
474 if (txDevice != NULL) {
475 if ((strncmp(curTxUCMDevice, "None", 4)) &&
476 ((strncmp(txDevice, curTxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
477 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
478 strlen(SND_USE_CASE_VERB_INACTIVE)))) {
479 usecase_type = getUseCaseType(use_case);
480 if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700481 ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700482 strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
483 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
484 mUseCaseList.push_front(useCaseNode);
485 }
486 }
487 if (mods_size) {
488 for(index = 0; index < mods_size; index++) {
489 usecase_type = getUseCaseType(mods_list[index]);
490 if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700491 ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700492 strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
493 snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
494 mUseCaseList.push_back(useCaseNode);
495 }
496 }
497 }
498 snd_use_case_set(handle->ucMgr, "_disdev", curTxUCMDevice);
499 }
500 }
SathishKumar Mani9efed762012-09-18 18:52:48 -0700501 ALOGD("%s,rxDev:%s, txDev:%s, curRxDev:%s, curTxDev:%s\n", __FUNCTION__, rxDevice, txDevice, curRxUCMDevice, curTxUCMDevice);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700502
503 if (rxDevice != NULL) {
504 snd_use_case_set(handle->ucMgr, "_enadev", rxDevice);
505 strlcpy(curRxUCMDevice, rxDevice, sizeof(curRxUCMDevice));
Ajay Dudani9746c472012-06-18 16:01:16 -0700506#ifdef QCOM_FM_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700507 if (devices & AudioSystem::DEVICE_OUT_FM)
508 s_set_fm_vol(fmVolume);
509#endif
510 }
511 if (txDevice != NULL) {
512 snd_use_case_set(handle->ucMgr, "_enadev", txDevice);
513 strlcpy(curTxUCMDevice, txDevice, sizeof(curTxUCMDevice));
514 }
515 for(ALSAUseCaseList::iterator it = mUseCaseList.begin(); it != mUseCaseList.end(); ++it) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700516 ALOGD("Route use case %s\n", it->useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700517 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
518 strlen(SND_USE_CASE_VERB_INACTIVE))) && (!strncmp(use_case, it->useCase, MAX_UC_LEN))) {
519 snd_use_case_set(handle->ucMgr, "_verb", it->useCase);
520 } else {
521 snd_use_case_set(handle->ucMgr, "_enamod", it->useCase);
522 }
523 }
524 if (!mUseCaseList.empty())
525 mUseCaseList.clear();
526 if (use_case != NULL) {
527 free(use_case);
528 use_case = NULL;
529 }
Iliyan Malchev4113f342012-06-11 14:39:47 -0700530 ALOGD("switchDevice: curTxUCMDevivce %s curRxDevDevice %s", curTxUCMDevice, curRxUCMDevice);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700531
532 if (mode == AudioSystem::MODE_IN_CALL && platform_is_Fusion3() && (inCallDevSwitch == true)) {
533 /* get tx acdb id */
534 memset(&ident,0,sizeof(ident));
535 strlcpy(ident, "ACDBID/", sizeof(ident));
536 strlcat(ident, curTxUCMDevice, sizeof(ident));
537 tx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
538
539 /* get rx acdb id */
540 memset(&ident,0,sizeof(ident));
541 strlcpy(ident, "ACDBID/", sizeof(ident));
542 strlcat(ident, curRxUCMDevice, sizeof(ident));
543 rx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
544
ehgrace.kim91e9fad2012-07-02 18:27:28 -0700545 if (((rx_dev_id == DEVICE_SPEAKER_MONO_RX_ACDB_ID ) || (rx_dev_id == DEVICE_SPEAKER_STEREO_RX_ACDB_ID ))
546 && tx_dev_id == DEVICE_HANDSET_TX_ACDB_ID) {
Iliyan Malchev4765c432012-06-11 14:36:16 -0700547 tx_dev_id = DEVICE_SPEAKER_TX_ACDB_ID;
548 }
549
Ajay Dudani9746c472012-06-18 16:01:16 -0700550#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4113f342012-06-11 14:39:47 -0700551 ALOGV("rx_dev_id=%d, tx_dev_id=%d\n", rx_dev_id, tx_dev_id);
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700552 if (csd_enable_device == NULL) {
553 ALOGE("dlsym:Error:%s Loading csd_client_enable_device", dlerror());
554 } else {
555 err = csd_enable_device(rx_dev_id, tx_dev_id, mDevSettingsFlag);
556 if (err < 0)
557 {
558 ALOGE("csd_client_disable_device failed, error %d", err);
559 }
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{
SathishKumar Mani9efed762012-09-18 18:52:48 -0700592 ALOGV("s_init: Initializing devices for ALSA module");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700593
594 list.clear();
595
596 return NO_ERROR;
597}
598
599static status_t s_open(alsa_handle_t *handle)
600{
601 char *devName;
602 unsigned flags = 0;
603 int err = NO_ERROR;
604
605 /* No need to call s_close for LPA as pcm device open and close is handled by LPAPlayer in stagefright */
606 if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) || (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA))
607 ||(!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 -0700608 ALOGV("s_open: Opening LPA /Tunnel playback");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700609 return NO_ERROR;
610 }
611
612 s_close(handle);
613
SathishKumar Mani9efed762012-09-18 18:52:48 -0700614 ALOGV("s_open: handle %p", handle);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700615
616 // ASoC multicomponent requires a valid path (frontend/backend) for
617 // the device to be opened
618
619 // The PCM stream is opened in blocking mode, per ALSA defaults. The
620 // AudioFlinger seems to assume blocking mode too, so asynchronous mode
621 // should not be used.
SathishKumar Mani88613382012-08-13 18:40:18 -0700622 if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
623 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
624 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
625 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
626 ALOGV("LPA/tunnel use case");
627 flags |= PCM_MMAP;
628 flags |= DEBUG_ON;
629 } else if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI)) ||
630 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) ||
631 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -0700632 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC))) {
SathishKumar Mani88613382012-08-13 18:40:18 -0700633 ALOGV("Music case");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700634 flags = PCM_OUT;
635 } else {
636 flags = PCM_IN;
637 }
638 if (handle->channels == 1) {
639 flags |= PCM_MONO;
SathishKumar Manie42406e2012-08-29 16:25:54 -0700640 }
Ajay Dudani9746c472012-06-18 16:01:16 -0700641#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700642 else if (handle->channels == 4 ) {
643 flags |= PCM_QUAD;
644 } else if (handle->channels == 6 ) {
645 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
646 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
647 flags |= PCM_QUAD;
648 } else {
649 flags |= PCM_5POINT1;
650 }
SathishKumar Manie42406e2012-08-29 16:25:54 -0700651 }
Iliyan Malchev4765c432012-06-11 14:36:16 -0700652#endif
653 else {
654 flags |= PCM_STEREO;
655 }
656 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700657 ALOGE("Failed to get pcm device node: %s", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700658 return NO_INIT;
659 }
660 if (devName != NULL) {
661 handle->handle = pcm_open(flags, (char*)devName);
662 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700663 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700664 return NO_INIT;
665 }
666
667 if (!handle->handle) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700668 ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700669 free(devName);
670 return NO_INIT;
671 }
672
673 handle->handle->flags = flags;
674 err = setHardwareParams(handle);
675
676 if (err == NO_ERROR) {
677 err = setSoftwareParams(handle);
678 }
679
680 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700681 ALOGE("Set HW/SW params failed: Closing the pcm stream");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700682 s_standby(handle);
683 }
684
685 free(devName);
686 return NO_ERROR;
687}
688
689static status_t s_start_voip_call(alsa_handle_t *handle)
690{
691
692 char* devName;
693 char* devName1;
694 unsigned flags = 0;
695 int err = NO_ERROR;
696 uint8_t voc_pkt[VOIP_BUFFER_MAX_SIZE];
697
698 s_close(handle);
699 flags = PCM_OUT;
700 flags |= PCM_MONO;
Iliyan Malchev4113f342012-06-11 14:39:47 -0700701 ALOGV("s_open:s_start_voip_call handle %p", handle);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700702
703 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700704 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700705 return NO_INIT;
706 }
707
708 if (devName != NULL) {
709 handle->handle = pcm_open(flags, (char*)devName);
710 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700711 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700712 return NO_INIT;
713 }
714
715 if (!handle->handle) {
716 free(devName);
Iliyan Malchev4113f342012-06-11 14:39:47 -0700717 ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700718 return NO_INIT;
719 }
720
721 if (!pcm_ready(handle->handle)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700722 ALOGE(" pcm ready failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700723 }
724
725 handle->handle->flags = flags;
726 err = setHardwareParams(handle);
727
728 if (err == NO_ERROR) {
729 err = setSoftwareParams(handle);
730 }
731
732 err = pcm_prepare(handle->handle);
733 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700734 ALOGE("DEVICE_OUT_DIRECTOUTPUT: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700735 }
736
737 /* first write required start dsp */
738 memset(&voc_pkt,0,sizeof(voc_pkt));
739 pcm_write(handle->handle,&voc_pkt,handle->handle->period_size);
740 handle->rxHandle = handle->handle;
741 free(devName);
Iliyan Malchev4113f342012-06-11 14:39:47 -0700742 ALOGV("s_open: DEVICE_IN_COMMUNICATION ");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700743 flags = PCM_IN;
744 flags |= PCM_MONO;
745 handle->handle = 0;
746
747 if (deviceName(handle, flags, &devName1) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700748 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700749 return NO_INIT;
750 }
751 if (devName != NULL) {
752 handle->handle = pcm_open(flags, (char*)devName1);
753 } else {
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
758 if (!handle->handle) {
759 free(devName);
Iliyan Malchev4113f342012-06-11 14:39:47 -0700760 ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700761 return NO_INIT;
762 }
763
764 if (!pcm_ready(handle->handle)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700765 ALOGE(" pcm ready in failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700766 }
767
768 handle->handle->flags = flags;
769
770 err = setHardwareParams(handle);
771
772 if (err == NO_ERROR) {
773 err = setSoftwareParams(handle);
774 }
775
776
777 err = pcm_prepare(handle->handle);
778 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700779 ALOGE("DEVICE_IN_COMMUNICATION: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700780 }
781
782 /* first read required start dsp */
783 memset(&voc_pkt,0,sizeof(voc_pkt));
784 pcm_read(handle->handle,&voc_pkt,handle->handle->period_size);
785 return NO_ERROR;
786}
787
788static status_t s_start_voice_call(alsa_handle_t *handle)
789{
790 char* devName;
791 unsigned flags = 0;
792 int err = NO_ERROR;
793
SathishKumar Mani9efed762012-09-18 18:52:48 -0700794 ALOGV("s_start_voice_call: handle %p", handle);
Ajay Dudani86c852b2012-07-19 15:28:45 -0700795
Iliyan Malchev4765c432012-06-11 14:36:16 -0700796 // ASoC multicomponent requires a valid path (frontend/backend) for
797 // the device to be opened
798
799 flags = PCM_OUT | PCM_MONO;
800 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700801 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700802 return NO_INIT;
803 }
804 if (devName != NULL) {
805 handle->handle = pcm_open(flags, (char*)devName);
806 } else {
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 (!handle->handle) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700811 ALOGE("s_start_voicecall: could not open PCM device");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700812 goto Error;
813 }
814
815 handle->handle->flags = flags;
816 err = setHardwareParams(handle);
817 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700818 ALOGE("s_start_voice_call: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700819 goto Error;
820 }
821
822 err = setSoftwareParams(handle);
823 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700824 ALOGE("s_start_voice_call: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700825 goto Error;
826 }
827
828 err = pcm_prepare(handle->handle);
829 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700830 ALOGE("s_start_voice_call: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700831 goto Error;
832 }
833
834 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700835 ALOGE("s_start_voice_call:SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700836 goto Error;
837 }
838
839 // Store the PCM playback device pointer in rxHandle
840 handle->rxHandle = handle->handle;
841 free(devName);
842
843 // Open PCM capture device
844 flags = PCM_IN | PCM_MONO;
845 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700846 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700847 goto Error;
848 }
849 if (devName != NULL) {
850 handle->handle = pcm_open(flags, (char*)devName);
851 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700852 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700853 return NO_INIT;
854 }
855 if (!handle->handle) {
856 free(devName);
857 goto Error;
858 }
859
860 handle->handle->flags = flags;
861 err = setHardwareParams(handle);
862 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700863 ALOGE("s_start_voice_call: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700864 goto Error;
865 }
866
867 err = setSoftwareParams(handle);
868 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700869 ALOGE("s_start_voice_call: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700870 goto Error;
871 }
872
873 err = pcm_prepare(handle->handle);
874 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700875 ALOGE("s_start_voice_call: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700876 goto Error;
877 }
878
879 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700880 ALOGE("s_start_voice_call:SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700881 goto Error;
882 }
883
884 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -0700885#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700886 if (csd_start_voice == NULL) {
887 ALOGE("dlsym:Error:%s Loading csd_client_start_voice", dlerror());
888 } else {
889 err = csd_start_voice();
890 if (err < 0){
891 ALOGE("s_start_voice_call: csd_client error %d\n", err);
892 goto Error;
893 }
Iliyan Malchev4765c432012-06-11 14:36:16 -0700894 }
Iliyan Malchev4113f342012-06-11 14:39:47 -0700895#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700896 }
897
898 free(devName);
899 return NO_ERROR;
900
901Error:
Iliyan Malchev4113f342012-06-11 14:39:47 -0700902 ALOGE("s_start_voice_call: Failed to initialize ALSA device '%s'", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700903 free(devName);
904 s_close(handle);
905 return NO_INIT;
906}
907
908static status_t s_start_fm(alsa_handle_t *handle)
909{
910 char *devName;
911 unsigned flags = 0;
912 int err = NO_ERROR;
913
SathishKumar Mani9efed762012-09-18 18:52:48 -0700914 ALOGV("s_start_fm: handle %p", handle);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700915
916 // ASoC multicomponent requires a valid path (frontend/backend) for
917 // the device to be opened
918
919 flags = PCM_OUT | PCM_STEREO;
920 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700921 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700922 goto Error;
923 }
924 if (devName != NULL) {
925 handle->handle = pcm_open(flags, (char*)devName);
926 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700927 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700928 return NO_INIT;
929 }
930 if (!handle->handle) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700931 ALOGE("s_start_fm: could not open PCM device");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700932 goto Error;
933 }
934
935 handle->handle->flags = flags;
936 err = setHardwareParams(handle);
937 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700938 ALOGE("s_start_fm: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700939 goto Error;
940 }
941
942 err = setSoftwareParams(handle);
943 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700944 ALOGE("s_start_fm: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700945 goto Error;
946 }
947
948 err = pcm_prepare(handle->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 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700955 ALOGE("s_start_fm: SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700956 goto Error;
957 }
958
959 // Store the PCM playback device pointer in rxHandle
960 handle->rxHandle = handle->handle;
961 free(devName);
962
963 // Open PCM capture device
964 flags = PCM_IN | PCM_STEREO;
965 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700966 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700967 goto Error;
968 }
969 if (devName != NULL) {
970 handle->handle = pcm_open(flags, (char*)devName);
971 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700972 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700973 return NO_INIT;
974 }
975 if (!handle->handle) {
976 goto Error;
977 }
978
979 handle->handle->flags = flags;
980 err = setHardwareParams(handle);
981 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700982 ALOGE("s_start_fm: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700983 goto Error;
984 }
985
986 err = setSoftwareParams(handle);
987 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700988 ALOGE("s_start_fm: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700989 goto Error;
990 }
991
992 err = pcm_prepare(handle->handle);
993 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700994 ALOGE("s_start_fm: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700995 goto Error;
996 }
997
998 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700999 ALOGE("s_start_fm: SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001000 goto Error;
1001 }
1002
1003 s_set_fm_vol(fmVolume);
1004 free(devName);
1005 return NO_ERROR;
1006
1007Error:
1008 free(devName);
1009 s_close(handle);
1010 return NO_INIT;
1011}
1012
1013static status_t s_set_fm_vol(int value)
1014{
1015 status_t err = NO_ERROR;
1016
1017 ALSAControl control("/dev/snd/controlC0");
1018 control.set("Internal FM RX Volume",value,0);
1019 fmVolume = value;
1020
1021 return err;
1022}
1023
1024static status_t s_set_lpa_vol(int value)
1025{
1026 status_t err = NO_ERROR;
1027
1028 ALSAControl control("/dev/snd/controlC0");
1029 control.set("LPA RX Volume",value,0);
1030
1031 return err;
1032}
1033
1034static status_t s_start(alsa_handle_t *handle)
1035{
1036 status_t err = NO_ERROR;
1037
1038 if(!handle->handle) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001039 ALOGE("No active PCM driver to start");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001040 return err;
1041 }
1042
1043 err = pcm_prepare(handle->handle);
1044
1045 return err;
1046}
1047
1048static status_t s_close(alsa_handle_t *handle)
1049{
1050 int ret;
1051 status_t err = NO_ERROR;
1052 struct pcm *h = handle->rxHandle;
1053
1054 handle->rxHandle = 0;
SathishKumar Mani9efed762012-09-18 18:52:48 -07001055 ALOGV("s_close: handle %p h %p", handle, h);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001056 if (h) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001057 ALOGV("s_close rxHandle\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001058 err = pcm_close(h);
1059 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001060 ALOGE("s_close: pcm_close failed for rxHandle with err %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001061 }
1062 }
1063
1064 h = handle->handle;
1065 handle->handle = 0;
1066
1067 if (h) {
SathishKumar Mani9efed762012-09-18 18:52:48 -07001068 ALOGV("s_close handle h %p\n", h);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001069 err = pcm_close(h);
1070 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001071 ALOGE("s_close: pcm_close failed for handle with err %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001072 }
1073
1074 if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_VOICECALL) ||
1075 !strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_VOICE)) &&
1076 platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001077#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001078 if (csd_stop_voice == NULL) {
1079 ALOGE("dlsym:Error:%s Loading csd_client_disable_device", dlerror());
1080 } else {
1081 err = csd_stop_voice();
1082 if (err < 0) {
1083 ALOGE("s_close: csd_client error %d\n", err);
1084 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001085 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001086#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001087 }
1088
1089 disableDevice(handle);
1090 } else if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
1091 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
1092 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
1093 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))){
1094 disableDevice(handle);
1095 }
1096
1097 return err;
1098}
1099
1100/*
1101 this is same as s_close, but don't discard
1102 the device/mode info. This way we can still
1103 close the device, hit idle and power-save, reopen the pcm
1104 for the same device/mode after resuming
1105*/
1106static status_t s_standby(alsa_handle_t *handle)
1107{
1108 int ret;
SathishKumar Manie42406e2012-08-29 16:25:54 -07001109 status_t err = NO_ERROR;
Iliyan Malchev4765c432012-06-11 14:36:16 -07001110 struct pcm *h = handle->rxHandle;
1111 handle->rxHandle = 0;
SathishKumar Mani9efed762012-09-18 18:52:48 -07001112 ALOGV("s_standby: handle %p h %p", handle, h);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001113 if (h) {
SathishKumar Mani0a019912012-09-11 12:33:11 -07001114 ALOGD("s_standby rxHandle\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001115 err = pcm_close(h);
1116 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001117 ALOGE("s_standby: pcm_close failed for rxHandle with err %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001118 }
1119 }
1120
1121 h = handle->handle;
1122 handle->handle = 0;
1123
1124 if (h) {
SathishKumar Mani9efed762012-09-18 18:52:48 -07001125 ALOGV("s_standby handle h %p\n", h);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001126 err = pcm_close(h);
1127 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001128 ALOGE("s_standby: pcm_close failed for handle with err %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001129 }
1130 disableDevice(handle);
1131 } else if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
1132 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
1133 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
1134 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
1135 disableDevice(handle);
1136 }
1137
1138 return err;
1139}
1140
1141static status_t s_route(alsa_handle_t *handle, uint32_t devices, int mode)
1142{
1143 status_t status = NO_ERROR;
1144
Iliyan Malchev4113f342012-06-11 14:39:47 -07001145 ALOGD("s_route: devices 0x%x in mode %d", devices, mode);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001146 callMode = mode;
1147 switchDevice(handle, devices, mode);
1148 return status;
1149}
1150
1151int getUseCaseType(const char *useCase)
1152{
SathishKumar Mani0a019912012-09-11 12:33:11 -07001153 ALOGD("use case is %s\n", useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001154 if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI,
1155 strlen(SND_USE_CASE_VERB_HIFI)) ||
SathishKumar Mani88613382012-08-13 18:40:18 -07001156 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC,
1157 strlen(SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -07001158 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER,
1159 strlen(SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
1160 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_TUNNEL,
1161 strlen(SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
1162 !strncmp(useCase, SND_USE_CASE_VERB_DIGITAL_RADIO,
1163 strlen(SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
1164 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC,
1165 strlen(SND_USE_CASE_MOD_PLAY_MUSIC)) ||
SathishKumar Mani88613382012-08-13 18:40:18 -07001166 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC,
1167 strlen(SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -07001168 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LPA,
1169 strlen(SND_USE_CASE_MOD_PLAY_LPA)) ||
1170 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_TUNNEL,
1171 strlen(SND_USE_CASE_MOD_PLAY_TUNNEL)) ||
1172 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_FM,
1173 strlen(SND_USE_CASE_MOD_PLAY_FM))) {
1174 return USECASE_TYPE_RX;
1175 } else if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI_REC,
1176 strlen(SND_USE_CASE_VERB_HIFI_REC)) ||
SathishKumar Mani88613382012-08-13 18:40:18 -07001177 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC,
1178 strlen(SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC)) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -07001179 !strncmp(useCase, SND_USE_CASE_VERB_FM_REC,
1180 strlen(SND_USE_CASE_VERB_FM_REC)) ||
1181 !strncmp(useCase, SND_USE_CASE_VERB_FM_A2DP_REC,
1182 strlen(SND_USE_CASE_VERB_FM_A2DP_REC)) ||
1183 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC,
1184 strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC)) ||
SathishKumar Mani88613382012-08-13 18:40:18 -07001185 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC,
1186 strlen(SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC)) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -07001187 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_FM,
1188 strlen(SND_USE_CASE_MOD_CAPTURE_FM)) ||
1189 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM,
1190 strlen(SND_USE_CASE_MOD_CAPTURE_A2DP_FM))) {
1191 return USECASE_TYPE_TX;
1192 } else if (!strncmp(useCase, SND_USE_CASE_VERB_VOICECALL,
1193 strlen(SND_USE_CASE_VERB_VOICECALL)) ||
1194 !strncmp(useCase, SND_USE_CASE_VERB_IP_VOICECALL,
1195 strlen(SND_USE_CASE_VERB_IP_VOICECALL)) ||
1196 !strncmp(useCase, SND_USE_CASE_VERB_DL_REC,
1197 strlen(SND_USE_CASE_VERB_DL_REC)) ||
1198 !strncmp(useCase, SND_USE_CASE_VERB_UL_DL_REC,
1199 strlen(SND_USE_CASE_VERB_UL_DL_REC)) ||
1200 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOICE,
1201 strlen(SND_USE_CASE_MOD_PLAY_VOICE)) ||
1202 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOIP,
1203 strlen(SND_USE_CASE_MOD_PLAY_VOIP)) ||
1204 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
1205 strlen(SND_USE_CASE_MOD_CAPTURE_VOICE_DL)) ||
1206 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
1207 strlen(SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL)) ||
1208 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
1209 strlen(SND_USE_CASE_MOD_CAPTURE_VOICE)) ||
1210 !strncmp(useCase, SND_USE_CASE_VERB_VOLTE,
1211 strlen(SND_USE_CASE_VERB_VOLTE)) ||
1212 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOLTE,
1213 strlen(SND_USE_CASE_MOD_PLAY_VOLTE))) {
1214 return (USECASE_TYPE_RX | USECASE_TYPE_TX);
1215 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001216 ALOGE("unknown use case %s\n", useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001217 return 0;
1218 }
1219}
1220
1221static void disableDevice(alsa_handle_t *handle)
1222{
1223 unsigned usecase_type = 0;
1224 int i, mods_size;
1225 char *useCase;
1226 const char **mods_list;
1227
1228 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
1229 if (useCase != NULL) {
1230 if (!strncmp(useCase, handle->useCase, MAX_UC_LEN)) {
1231 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
1232 } else {
1233 snd_use_case_set(handle->ucMgr, "_dismod", handle->useCase);
1234 }
1235 free(useCase);
1236 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
1237 if (strncmp(useCase, SND_USE_CASE_VERB_INACTIVE,
1238 strlen(SND_USE_CASE_VERB_INACTIVE)))
1239 usecase_type |= getUseCaseType(useCase);
1240 mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
SathishKumar Mani9efed762012-09-18 18:52:48 -07001241 ALOGV("Number of modifiers %d\n", mods_size);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001242 if (mods_size) {
1243 for(i = 0; i < mods_size; i++) {
SathishKumar Mani9efed762012-09-18 18:52:48 -07001244 ALOGV("index %d modifier %s\n", i, mods_list[i]);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001245 usecase_type |= getUseCaseType(mods_list[i]);
1246 }
1247 }
SathishKumar Mani9efed762012-09-18 18:52:48 -07001248 ALOGV("usecase_type is %d\n", usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001249 if (!(usecase_type & USECASE_TYPE_TX) && (strncmp(curTxUCMDevice, "None", 4)))
1250 snd_use_case_set(handle->ucMgr, "_disdev", curTxUCMDevice);
1251 if (!(usecase_type & USECASE_TYPE_RX) && (strncmp(curRxUCMDevice, "None", 4)))
1252 snd_use_case_set(handle->ucMgr, "_disdev", curRxUCMDevice);
1253 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001254 ALOGE("Invalid state, no valid use case found to disable");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001255 }
1256 free(useCase);
1257}
1258
1259char *getUCMDevice(uint32_t devices, int input, char *rxDevice)
1260{
1261 if (!input) {
1262 if (!(mDevSettingsFlag & TTY_OFF) &&
1263 (callMode == AudioSystem::MODE_IN_CALL) &&
1264 ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
ty.lee924f7982012-08-01 23:15:30 +09001265 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001266#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001267 ||
1268 (devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
1269 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) {
1270#endif
1271 if (mDevSettingsFlag & TTY_VCO) {
1272 return strdup(SND_USE_CASE_DEV_TTY_HEADSET_RX);
1273 } else if (mDevSettingsFlag & TTY_FULL) {
1274 return strdup(SND_USE_CASE_DEV_TTY_FULL_RX);
1275 } else if (mDevSettingsFlag & TTY_HCO) {
1276 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_RX); /* HANDSET RX */
1277 }
1278 }else if ((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET) ||
1279 (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)) {
1280 return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */
1281 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1282 ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
1283 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
1284 if (mDevSettingsFlag & ANC_FLAG) {
1285 return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
1286 } else {
1287 return strdup(SND_USE_CASE_DEV_SPEAKER_HEADSET); /* COMBO SPEAKER+HEADSET RX */
1288 }
Ajay Dudani9746c472012-06-18 16:01:16 -07001289#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001290 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1291 ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
1292 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) {
1293 return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
1294 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1295 (devices & AudioSystem::DEVICE_OUT_FM_TX)) {
1296 return strdup(SND_USE_CASE_DEV_SPEAKER_FM_TX); /* COMBO SPEAKER+FM_TX RX */
1297#endif
1298 } else if (devices & AudioSystem::DEVICE_OUT_EARPIECE) {
1299 return strdup(SND_USE_CASE_DEV_EARPIECE); /* HANDSET RX */
1300 } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) {
1301 return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
1302 } else if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
1303 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) {
1304 if (mDevSettingsFlag & ANC_FLAG) {
1305 return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */
1306 } else {
1307 return strdup(SND_USE_CASE_DEV_HEADPHONES); /* HEADSET RX */
1308 }
Ajay Dudani9746c472012-06-18 16:01:16 -07001309#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001310 } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
1311 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE)) {
1312 return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */
1313#endif
1314 } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) ||
1315 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
1316 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT)) {
1317 if (btsco_samplerate == BTSCO_RATE_16KHZ)
1318 return strdup(SND_USE_CASE_DEV_BTSCO_WB_RX); /* BTSCO RX*/
1319 else
1320 return strdup(SND_USE_CASE_DEV_BTSCO_NB_RX); /* BTSCO RX*/
1321 } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP) ||
1322 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES) ||
Ajay Dudani9746c472012-06-18 16:01:16 -07001323#ifdef QCOM_VOIP_ENABLED
1324 (devices & AudioSystem::DEVICE_OUT_DIRECTOUTPUT) ||
1325#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001326 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) {
1327 /* Nothing to be done, use current active device */
1328 if (strncmp(curRxUCMDevice, "None", 4)) {
1329 return strdup(curRxUCMDevice);
1330 }
1331 } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
1332 return strdup(SND_USE_CASE_DEV_HDMI); /* HDMI RX */
Ajay Dudani9746c472012-06-18 16:01:16 -07001333#ifdef QCOM_PROXY_DEVICE_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001334 } else if (devices & AudioSystem::DEVICE_OUT_PROXY) {
1335 return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */
Ajay Dudani9746c472012-06-18 16:01:16 -07001336#endif
1337#ifdef QCOM_FM_TX_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001338 } else if (devices & AudioSystem::DEVICE_OUT_FM_TX) {
1339 return strdup(SND_USE_CASE_DEV_FM_TX); /* FM Tx */
1340#endif
1341 } else if (devices & AudioSystem::DEVICE_OUT_DEFAULT) {
1342 return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
1343 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001344 ALOGD("No valid output device: %u", devices);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001345 }
1346 } else {
1347 if (!(mDevSettingsFlag & TTY_OFF) &&
1348 (callMode == AudioSystem::MODE_IN_CALL) &&
ty.lee924f7982012-08-01 23:15:30 +09001349 ((devices & AudioSystem::DEVICE_IN_WIRED_HEADSET))) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001350#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001351 ||(devices & AudioSystem::DEVICE_IN_ANC_HEADSET))) {
1352#endif
1353 if (mDevSettingsFlag & TTY_HCO) {
1354 return strdup(SND_USE_CASE_DEV_TTY_HEADSET_TX);
1355 } else if (mDevSettingsFlag & TTY_FULL) {
1356 return strdup(SND_USE_CASE_DEV_TTY_FULL_TX);
1357 } else if (mDevSettingsFlag & TTY_VCO) {
1358 if (!strncmp(mic_type, "analog", 6)) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001359 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_ANALOG_TX);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001360 } else {
1361 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_TX);
1362 }
1363 }
1364 } else if (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) {
1365 if (!strncmp(mic_type, "analog", 6)) {
1366 return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
1367 } else {
1368 if (mDevSettingsFlag & DMIC_FLAG) {
ty.lee924f7982012-08-01 23:15:30 +09001369#ifdef USES_FLUENCE_INCALL
1370 if(callMode == AudioSystem::MODE_IN_CALL) {
1371 if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
1372 return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
1373 } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
1374 return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
1375 } else {
1376 return strdup(SND_USE_CASE_DEV_HANDSET); /* BUILTIN-MIC TX */
1377 }
1378 }
1379#else
Iliyan Malchev4765c432012-06-11 14:36:16 -07001380 if (((rxDevice != NULL) &&
1381 !strncmp(rxDevice, SND_USE_CASE_DEV_SPEAKER,
1382 (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) ||
1383 !strncmp(curRxUCMDevice, SND_USE_CASE_DEV_SPEAKER,
1384 (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) {
1385 if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
1386 return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
1387 } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
1388 return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
1389 }
1390 } else {
1391 if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
1392 return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
1393 } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
1394 return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
1395 }
1396 }
ty.lee924f7982012-08-01 23:15:30 +09001397#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001398 } else if (mDevSettingsFlag & QMIC_FLAG){
1399 return strdup(SND_USE_CASE_DEV_QUAD_MIC);
ty.lee924f7982012-08-01 23:15:30 +09001400 }
Ajay Dudani9746c472012-06-18 16:01:16 -07001401#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001402 else if (mDevSettingsFlag & SSRQMIC_FLAG){
Iliyan Malchev4113f342012-06-11 14:39:47 -07001403 ALOGV("return SSRQMIC_FLAG: 0x%x devices:0x%x",mDevSettingsFlag,devices);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001404 // Mapping for quad mic input device.
1405 return strdup(SND_USE_CASE_DEV_SSR_QUAD_MIC); /* SSR Quad MIC */
ty.lee924f7982012-08-01 23:15:30 +09001406 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001407#endif
ty.lee74060de2012-08-02 00:47:00 +09001408#ifdef SEPERATED_AUDIO_INPUT
1409 if(input_source == AUDIO_SOURCE_VOICE_RECOGNITION) {
1410 ALOGV("getUCMdevice returned the VOICE_RECOGNITION UCM by input source = %d", input_source);
1411 return strdup(SND_USE_CASE_DEV_VOICE_RECOGNITION ); /* VOICE RECOGNITION TX */
1412 } else if(input_source == AUDIO_SOURCE_CAMCORDER) {
1413 ALOGV("getUCMdevice returned the Camcorder Tx UCM by input source = %d", input_source);
1414 return strdup(SND_USE_CASE_DEV_CAMCORDER_TX ); /* CAMCORDER TX */
1415 }
1416#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001417 else {
ty.lee74060de2012-08-02 00:47:00 +09001418 return strdup(SND_USE_CASE_DEV_HANDSET); /* BUILTIN-MIC TX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001419 }
1420 }
1421 } else if (devices & AudioSystem::DEVICE_IN_AUX_DIGITAL) {
1422 return strdup(SND_USE_CASE_DEV_HDMI_TX); /* HDMI TX */
Ajay Dudani9746c472012-06-18 16:01:16 -07001423#ifdef QCOM_ANC_HEADSET_ENABLED
ehgrace.kim249f87d2012-08-12 20:40:32 -07001424 } else if (devices & AudioSystem::DEVICE_IN_ANC_HEADSET) {
Iliyan Malchev4765c432012-06-11 14:36:16 -07001425 return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */
1426#endif
ehgrace.kim249f87d2012-08-12 20:40:32 -07001427 } else if (devices & AudioSystem::DEVICE_IN_WIRED_HEADSET) {
1428 return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001429 } else if (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
1430 if (btsco_samplerate == BTSCO_RATE_16KHZ)
1431 return strdup(SND_USE_CASE_DEV_BTSCO_WB_TX); /* BTSCO TX*/
1432 else
1433 return strdup(SND_USE_CASE_DEV_BTSCO_NB_TX); /* BTSCO TX*/
Ajay Dudani9746c472012-06-18 16:01:16 -07001434#ifdef QCOM_USBAUDIO_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001435 } else if ((devices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) ||
1436 (devices & AudioSystem::DEVICE_IN_PROXY)) {
1437 return strdup(SND_USE_CASE_DEV_PROXY_TX); /* PROXY TX */
1438#endif
1439 } else if ((devices & AudioSystem::DEVICE_IN_COMMUNICATION) ||
1440 (devices & AudioSystem::DEVICE_IN_VOICE_CALL)) {
1441 /* Nothing to be done, use current active device */
1442 if (strncmp(curTxUCMDevice, "None", 4)) {
1443 return strdup(curTxUCMDevice);
1444 }
Ajay Dudani9746c472012-06-18 16:01:16 -07001445#ifdef QCOM_FM_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001446 } else if ((devices & AudioSystem::DEVICE_IN_FM_RX) ||
1447 (devices & AudioSystem::DEVICE_IN_FM_RX_A2DP)) {
1448 /* Nothing to be done, use current tx device or set dummy device */
1449 if (strncmp(curTxUCMDevice, "None", 4)) {
1450 return strdup(curTxUCMDevice);
1451 } else {
1452 return strdup(SND_USE_CASE_DEV_DUMMY_TX);
1453 }
1454#endif
1455 } else if ((devices & AudioSystem::DEVICE_IN_AMBIENT) ||
1456 (devices & AudioSystem::DEVICE_IN_BACK_MIC)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001457 ALOGI("No proper mapping found with UCM device list, setting default");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001458 if (!strncmp(mic_type, "analog", 6)) {
1459 return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
1460 } else {
1461 return strdup(SND_USE_CASE_DEV_LINE); /* BUILTIN-MIC TX */
1462 }
1463 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001464 ALOGD("No valid input device: %u", devices);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001465 }
1466 }
1467 return NULL;
1468}
1469
1470void s_set_voice_volume(int vol)
1471{
1472 int err = 0;
SathishKumar Mani9efed762012-09-18 18:52:48 -07001473 ALOGV("s_set_voice_volume: volume %d", vol);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001474 ALSAControl control("/dev/snd/controlC0");
1475 control.set("Voice Rx Volume", vol, 0);
1476
1477 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001478#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001479 if (csd_volume == NULL) {
1480 ALOGE("dlsym:Error:%s Loading csd_client_volume", dlerror());
1481 } else {
1482 err = csd_volume(vol);
1483 if (err < 0) {
1484 ALOGE("s_set_voice_volume: csd_client error %d", err);
1485 }
SathishKumar Manie42406e2012-08-29 16:25:54 -07001486 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001487#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001488 }
1489}
1490
1491void s_set_volte_volume(int vol)
1492{
SathishKumar Mani9efed762012-09-18 18:52:48 -07001493 ALOGV("s_set_volte_volume: volume %d", vol);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001494 ALSAControl control("/dev/snd/controlC0");
1495 control.set("VoLTE Rx Volume", vol, 0);
1496}
1497
1498
1499void s_set_voip_volume(int vol)
1500{
SathishKumar Mani9efed762012-09-18 18:52:48 -07001501 ALOGV("s_set_voip_volume: volume %d", vol);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001502 ALSAControl control("/dev/snd/controlC0");
1503 control.set("Voip Rx Volume", vol, 0);
1504}
1505void s_set_mic_mute(int state)
1506{
1507 int err = 0;
SathishKumar Mani9efed762012-09-18 18:52:48 -07001508 ALOGV("s_set_mic_mute: state %d", state);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001509 ALSAControl control("/dev/snd/controlC0");
1510 control.set("Voice Tx Mute", state, 0);
1511
1512 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001513#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001514 if (csd_mic_mute == NULL) {
1515 ALOGE("dlsym:Error:%s Loading csd_mic_mute", dlerror());
1516 } else {
1517 err=csd_mic_mute(state);
1518 if (err < 0) {
1519 ALOGE("s_set_mic_mute: csd_client error %d", err);
1520 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001521 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001522#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001523 }
1524}
1525void s_set_volte_mic_mute(int state)
1526{
SathishKumar Mani9efed762012-09-18 18:52:48 -07001527 ALOGV("s_set_volte_mic_mute: state %d", state);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001528 ALSAControl control("/dev/snd/controlC0");
1529 control.set("VoLTE Tx Mute", state, 0);
1530}
1531
1532void s_set_voip_mic_mute(int state)
1533{
SathishKumar Mani9efed762012-09-18 18:52:48 -07001534 ALOGV("s_set_voip_mic_mute: state %d", state);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001535 ALSAControl control("/dev/snd/controlC0");
1536 control.set("Voip Tx Mute", state, 0);
1537}
1538
1539void s_set_voip_config(int mode, int rate)
1540{
SathishKumar Mani9efed762012-09-18 18:52:48 -07001541 ALOGV("s_set_voip_config: mode %d,rate %d", mode, rate);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001542 ALSAControl control("/dev/snd/controlC0");
1543 char** setValues;
1544 setValues = (char**)malloc(2*sizeof(char*));
1545 if (setValues == NULL) {
1546 return;
1547 }
1548 setValues[0] = (char*)malloc(4*sizeof(char));
1549 if (setValues[0] == NULL) {
1550 free(setValues);
1551 return;
1552 }
1553
1554 setValues[1] = (char*)malloc(8*sizeof(char));
1555 if (setValues[1] == NULL) {
1556 free(setValues);
1557 free(setValues[0]);
1558 return;
1559 }
1560
1561 sprintf(setValues[0], "%d",mode);
1562 sprintf(setValues[1], "%d",rate);
1563
1564 control.setext("Voip Mode Rate Config", 2, setValues);
1565 free(setValues[1]);
1566 free(setValues[0]);
1567 free(setValues);
1568 return;
1569}
1570
1571void s_set_btsco_rate(int rate)
1572{
1573 btsco_samplerate = rate;
1574}
1575
1576void s_enable_wide_voice(bool flag)
1577{
1578 int err = 0;
1579
SathishKumar Mani9efed762012-09-18 18:52:48 -07001580 ALOGV("s_enable_wide_voice: flag %d", flag);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001581 ALSAControl control("/dev/snd/controlC0");
1582 if(flag == true) {
1583 control.set("Widevoice Enable", 1, 0);
1584 } else {
1585 control.set("Widevoice Enable", 0, 0);
1586 }
1587
1588 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001589#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001590 if (csd_wide_voice == NULL) {
1591 ALOGE("dlsym:Error:%s Loading csd_wide_voice", dlerror());
1592 } else {
1593 err = csd_wide_voice(flag);
1594 if (err < 0) {
1595 ALOGE("enableWideVoice: csd_client_wide_voice error %d", err);
1596 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001597 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001598#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001599 }
1600}
1601
1602void s_set_voc_rec_mode(uint8_t mode)
1603{
SathishKumar Mani9efed762012-09-18 18:52:48 -07001604 ALOGV("s_set_voc_rec_mode: mode %d", mode);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001605 ALSAControl control("/dev/snd/controlC0");
1606 control.set("Incall Rec Mode", mode, 0);
1607}
1608
1609void s_enable_fens(bool flag)
1610{
1611 int err = 0;
1612
SathishKumar Mani9efed762012-09-18 18:52:48 -07001613 ALOGV("s_enable_fens: flag %d", flag);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001614 ALSAControl control("/dev/snd/controlC0");
1615 if(flag == true) {
1616 control.set("FENS Enable", 1, 0);
1617 } else {
1618 control.set("FENS Enable", 0, 0);
1619 }
1620
1621 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001622#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001623 if (csd_fens == NULL) {
1624 ALOGE("dlsym:Error:%s Loading csd_fens", dlerror());
1625 } else {
1626 err = csd_fens(flag);
1627 if (err < 0) {
1628 ALOGE("s_enable_fens: csd_client error %d", err);
1629 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001630 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001631#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001632 }
1633}
1634
1635void s_enable_slow_talk(bool flag)
1636{
1637 int err = 0;
1638
SathishKumar Mani9efed762012-09-18 18:52:48 -07001639 ALOGV("s_enable_slow_talk: flag %d", flag);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001640 ALSAControl control("/dev/snd/controlC0");
1641 if(flag == true) {
1642 control.set("Slowtalk Enable", 1, 0);
1643 } else {
1644 control.set("Slowtalk Enable", 0, 0);
1645 }
1646
1647 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001648#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001649 if (csd_slow_talk == NULL) {
1650 ALOGE("dlsym:Error:%s Loading csd_slow_talk", dlerror());
1651 } else {
1652 err = csd_slow_talk(flag);
1653 if (err < 0) {
1654 ALOGE("s_enable_slow_talk: csd_client error %d", err);
1655 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001656 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001657#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001658 }
1659}
1660
1661void s_set_flags(uint32_t flags)
1662{
Iliyan Malchev4113f342012-06-11 14:39:47 -07001663 ALOGV("s_set_flags: flags %d", flags);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001664 mDevSettingsFlag = flags;
1665}
1666
1667static status_t s_set_compressed_vol(int value)
1668{
1669 status_t err = NO_ERROR;
1670
1671 ALSAControl control("/dev/snd/controlC0");
1672 control.set("COMPRESSED RX Volume",value,0);
1673
1674 return err;
1675}
1676
ty.lee74060de2012-08-02 00:47:00 +09001677#ifdef SEPERATED_AUDIO_INPUT
1678void s_setInput(int input)
1679{
1680 input_source = input;
1681 ALOGD("s_setInput() : input_source = %d",input_source);
1682}
1683#endif
SathishKumar Mani5ff7a022012-09-14 11:36:35 -07001684
1685#ifdef QCOM_CSDCLIENT_ENABLED
1686static void s_set_csd_handle(void* handle)
1687{
1688 csd_handle = static_cast<void*>(handle);
1689 ALOGI("%s csd_handle: %p", __func__, csd_handle);
1690
1691 csd_disable_device = (int (*)())::dlsym(csd_handle,"csd_client_disable_device");
1692 csd_enable_device = (int (*)(int,int,uint32_t))::dlsym(csd_handle,"csd_client_enable_device");
1693 csd_start_voice = (int (*)())::dlsym(csd_handle,"csd_client_start_voice");
1694 csd_stop_voice = (int (*)())::dlsym(csd_handle,"csd_client_stop_voice");
1695 csd_volume = (int (*)(int))::dlsym(csd_handle,"csd_client_volume");
1696 csd_mic_mute = (int (*)(int))::dlsym(csd_handle,"csd_client_mic_mute");
1697 csd_wide_voice = (int (*)(uint8_t))::dlsym(csd_handle,"csd_client_wide_voice");
1698 csd_fens = (int (*)(uint8_t))::dlsym(csd_handle,"csd_client_fens");
1699 csd_slow_talk = (int (*)(uint8_t))::dlsym(csd_handle,"csd_client_slow_talk");
1700}
1701#endif
1702
Iliyan Malchev4765c432012-06-11 14:36:16 -07001703}