blob: d589f5c111839993acea0f9bb5005b058cb69bbc [file] [log] [blame]
Iliyan Malchev4765c432012-06-11 14:36:16 -07001/* alsa_default.cpp
2 **
3 ** Copyright 2009 Wind River Systems
4 ** Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
5 **
6 ** Licensed under the Apache License, Version 2.0 (the "License");
7 ** you may not use this file except in compliance with the License.
8 ** You may obtain a copy of the License at
9 **
10 ** http://www.apache.org/licenses/LICENSE-2.0
11 **
12 ** Unless required by applicable law or agreed to in writing, software
13 ** distributed under the License is distributed on an "AS IS" BASIS,
14 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 ** See the License for the specific language governing permissions and
16 ** limitations under the License.
17 */
18
Ajay Dudani9746c472012-06-18 16:01:16 -070019#define LOG_TAG "ALSAModule"
Iliyan Malchev4765c432012-06-11 14:36:16 -070020//#define LOG_NDEBUG 0
Ajay Dudani9746c472012-06-18 16:01:16 -070021#define LOG_NDDEBUG 0
Iliyan Malchev4765c432012-06-11 14:36:16 -070022#include <utils/Log.h>
23#include <cutils/properties.h>
24#include <linux/ioctl.h>
25#include "AudioHardwareALSA.h"
26#include <media/AudioRecord.h>
Ajay Dudani9746c472012-06-18 16:01:16 -070027#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -070028extern "C" {
29#include "csd_client.h"
30}
Iliyan Malchev4113f342012-06-11 14:39:47 -070031#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -070032
33#ifndef ALSA_DEFAULT_SAMPLE_RATE
34#define ALSA_DEFAULT_SAMPLE_RATE 44100 // in Hz
35#endif
36
37#define BTSCO_RATE_16KHZ 16000
38#define USECASE_TYPE_RX 1
39#define USECASE_TYPE_TX 2
40
41namespace android_audio_legacy
42{
43
44static int s_device_open(const hw_module_t*, const char*, hw_device_t**);
45static int s_device_close(hw_device_t*);
46static status_t s_init(alsa_device_t *, ALSAHandleList &);
47static status_t s_open(alsa_handle_t *);
48static status_t s_close(alsa_handle_t *);
49static status_t s_standby(alsa_handle_t *);
50static status_t s_route(alsa_handle_t *, uint32_t, int);
51static status_t s_start_voice_call(alsa_handle_t *);
52static status_t s_start_voip_call(alsa_handle_t *);
53static status_t s_start_fm(alsa_handle_t *);
54static void s_set_voice_volume(int);
55static void s_set_voip_volume(int);
56static void s_set_mic_mute(int);
57static void s_set_voip_mic_mute(int);
58static void s_set_voip_config(int, int);
59static status_t s_set_fm_vol(int);
60static void s_set_btsco_rate(int);
61static status_t s_set_lpa_vol(int);
62static void s_enable_wide_voice(bool flag);
63static void s_enable_fens(bool flag);
64static void s_set_flags(uint32_t flags);
65static status_t s_set_compressed_vol(int);
66static void s_enable_slow_talk(bool flag);
67static void s_set_voc_rec_mode(uint8_t mode);
68static void s_set_volte_mic_mute(int state);
69static void s_set_volte_volume(int vol);
ty.lee74060de2012-08-02 00:47:00 +090070#ifdef SEPERATED_AUDIO_INPUT
71static void s_setInput(int);
72
73static int input_source;
74#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -070075
76static char mic_type[25];
77static char curRxUCMDevice[50];
78static char curTxUCMDevice[50];
79static int fluence_mode;
80static int fmVolume;
ty.lee924f7982012-08-01 23:15:30 +090081#ifdef USES_FLUENCE_INCALL
82static uint32_t mDevSettingsFlag = TTY_OFF | DMIC_FLAG;
83#else
Iliyan Malchev4765c432012-06-11 14:36:16 -070084static uint32_t mDevSettingsFlag = TTY_OFF;
ty.lee924f7982012-08-01 23:15:30 +090085#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -070086static int btsco_samplerate = 8000;
87static bool pflag = false;
88static ALSAUseCaseList mUseCaseList;
89
90static hw_module_methods_t s_module_methods = {
91 open : s_device_open
92};
93
Iliyan Malchev4113f342012-06-11 14:39:47 -070094extern "C" hw_module_t HAL_MODULE_INFO_SYM = {
Iliyan Malchev4765c432012-06-11 14:36:16 -070095 tag : HARDWARE_MODULE_TAG,
96 version_major : 1,
97 version_minor : 0,
98 id : ALSA_HARDWARE_MODULE_ID,
99 name : "QCOM ALSA module",
100 author : "QuIC Inc",
101 methods : &s_module_methods,
102 dso : 0,
103 reserved : {0,},
104};
105
106static int s_device_open(const hw_module_t* module, const char* name,
107 hw_device_t** device)
108{
109 char value[128];
110 alsa_device_t *dev;
111 dev = (alsa_device_t *) malloc(sizeof(*dev));
112 if (!dev) return -ENOMEM;
113
114 memset(dev, 0, sizeof(*dev));
115
116 /* initialize the procs */
117 dev->common.tag = HARDWARE_DEVICE_TAG;
118 dev->common.version = 0;
119 dev->common.module = (hw_module_t *) module;
120 dev->common.close = s_device_close;
121 dev->init = s_init;
122 dev->open = s_open;
123 dev->close = s_close;
124 dev->route = s_route;
125 dev->standby = s_standby;
126 dev->startVoiceCall = s_start_voice_call;
127 dev->startVoipCall = s_start_voip_call;
128 dev->startFm = s_start_fm;
129 dev->setVoiceVolume = s_set_voice_volume;
130 dev->setVoipVolume = s_set_voip_volume;
131 dev->setMicMute = s_set_mic_mute;
132 dev->setVoipMicMute = s_set_voip_mic_mute;
133 dev->setVoipConfig = s_set_voip_config;
134 dev->setFmVolume = s_set_fm_vol;
135 dev->setBtscoRate = s_set_btsco_rate;
136 dev->setLpaVolume = s_set_lpa_vol;
137 dev->enableWideVoice = s_enable_wide_voice;
138 dev->enableFENS = s_enable_fens;
139 dev->setFlags = s_set_flags;
140 dev->setCompressedVolume = s_set_compressed_vol;
141 dev->enableSlowTalk = s_enable_slow_talk;
142 dev->setVocRecMode = s_set_voc_rec_mode;
143 dev->setVoLTEMicMute = s_set_volte_mic_mute;
144 dev->setVoLTEVolume = s_set_volte_volume;
ty.lee74060de2012-08-02 00:47:00 +0900145#ifdef SEPERATED_AUDIO_INPUT
146 dev->setInput = s_setInput;
147#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700148
149 *device = &dev->common;
150
151 property_get("persist.audio.handset.mic",value,"0");
152 strlcpy(mic_type, value, sizeof(mic_type));
153 property_get("persist.audio.fluence.mode",value,"0");
154 if (!strcmp("broadside", value)) {
155 fluence_mode = FLUENCE_MODE_BROADSIDE;
156 } else {
157 fluence_mode = FLUENCE_MODE_ENDFIRE;
158 }
159 strlcpy(curRxUCMDevice, "None", sizeof(curRxUCMDevice));
160 strlcpy(curTxUCMDevice, "None", sizeof(curTxUCMDevice));
Ajay Dudani86c852b2012-07-19 15:28:45 -0700161#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -0700162 ALOGD("ALSA module opened");
Ajay Dudani86c852b2012-07-19 15:28:45 -0700163#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700164
165 return 0;
166}
167
168static int s_device_close(hw_device_t* device)
169{
170 free(device);
171 device = NULL;
172 return 0;
173}
174
175// ----------------------------------------------------------------------------
176
177static const int DEFAULT_SAMPLE_RATE = ALSA_DEFAULT_SAMPLE_RATE;
178
179static void switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode);
180static char *getUCMDevice(uint32_t devices, int input, char *rxDevice);
181static void disableDevice(alsa_handle_t *handle);
182int getUseCaseType(const char *useCase);
183
184static int callMode = AudioSystem::MODE_NORMAL;
185// ----------------------------------------------------------------------------
186
187bool platform_is_Fusion3()
188{
189 char platform[128], baseband[128];
190 property_get("ro.board.platform", platform, "");
191 property_get("ro.baseband", baseband, "");
192 if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband))
193 return true;
194 else
195 return false;
196}
197
198int deviceName(alsa_handle_t *handle, unsigned flags, char **value)
199{
200 int ret = 0;
201 char ident[70];
202
203 if (flags & PCM_IN) {
204 strlcpy(ident, "CapturePCM/", sizeof(ident));
205 } else {
206 strlcpy(ident, "PlaybackPCM/", sizeof(ident));
207 }
208 strlcat(ident, handle->useCase, sizeof(ident));
209 ret = snd_use_case_get(handle->ucMgr, ident, (const char **)value);
Iliyan Malchev4113f342012-06-11 14:39:47 -0700210 ALOGD("Device value returned is %s", (*value));
Iliyan Malchev4765c432012-06-11 14:36:16 -0700211 return ret;
212}
213
214status_t setHardwareParams(alsa_handle_t *handle)
215{
216 struct snd_pcm_hw_params *params;
217 unsigned long bufferSize, reqBuffSize;
218 unsigned int periodTime, bufferTime;
219 unsigned int requestedRate = handle->sampleRate;
220 int status = 0;
221 int channels = handle->channels;
222 snd_pcm_format_t format = SNDRV_PCM_FORMAT_S16_LE;
223
224 params = (snd_pcm_hw_params*) calloc(1, sizeof(struct snd_pcm_hw_params));
225 if (!params) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700226 ALOGE("Failed to allocate ALSA hardware parameters!");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700227 return NO_INIT;
228 }
229
230 reqBuffSize = handle->bufferSize;
Ajay Dudani86c852b2012-07-19 15:28:45 -0700231#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -0700232 ALOGD("setHardwareParams: reqBuffSize %d channels %d sampleRate %d",
Iliyan Malchev4765c432012-06-11 14:36:16 -0700233 (int) reqBuffSize, handle->channels, handle->sampleRate);
Ajay Dudani86c852b2012-07-19 15:28:45 -0700234#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700235
Ajay Dudani9746c472012-06-18 16:01:16 -0700236#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700237 if (channels == 6) {
238 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
239 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700240 ALOGV("HWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700241 channels = 4;
242 reqBuffSize = DEFAULT_IN_BUFFER_SIZE;
243 }
244 }
245#endif
246
247 param_init(params);
248 param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS,
249 SNDRV_PCM_ACCESS_RW_INTERLEAVED);
250 if (handle->format != SNDRV_PCM_FORMAT_S16_LE) {
Ajay Dudani9746c472012-06-18 16:01:16 -0700251 if (handle->format == AudioSystem::AMR_NB
252 || handle->format == AudioSystem::AMR_WB
253#ifdef QCOM_QCHAT_ENABLED
254 || handle->format == AudioSystem::EVRC
255 || handle->format == AudioSystem::EVRCB
256 || handle->format == AudioSystem::EVRCWB
257#endif
258 )
Iliyan Malchev4765c432012-06-11 14:36:16 -0700259 format = SNDRV_PCM_FORMAT_SPECIAL;
260 }
261 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
262 format);
263 param_set_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT,
264 SNDRV_PCM_SUBFORMAT_STD);
265 param_set_min(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, reqBuffSize);
266 param_set_int(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 16);
267 param_set_int(params, SNDRV_PCM_HW_PARAM_FRAME_BITS,
268 channels * 16);
269 param_set_int(params, SNDRV_PCM_HW_PARAM_CHANNELS,
270 channels);
271 param_set_int(params, SNDRV_PCM_HW_PARAM_RATE, handle->sampleRate);
272 param_set_hw_refine(handle->handle, params);
273
274 if (param_set_hw_params(handle->handle, params)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700275 ALOGE("cannot set hw params");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700276 return NO_INIT;
277 }
278 param_dump(params);
279
280 handle->handle->buffer_size = pcm_buffer_size(params);
281 handle->handle->period_size = pcm_period_size(params);
282 handle->handle->period_cnt = handle->handle->buffer_size/handle->handle->period_size;
Ajay Dudani86c852b2012-07-19 15:28:45 -0700283#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -0700284 ALOGD("setHardwareParams: buffer_size %d, period_size %d, period_cnt %d",
Iliyan Malchev4765c432012-06-11 14:36:16 -0700285 handle->handle->buffer_size, handle->handle->period_size,
286 handle->handle->period_cnt);
Ajay Dudani86c852b2012-07-19 15:28:45 -0700287#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700288 handle->handle->rate = handle->sampleRate;
289 handle->handle->channels = handle->channels;
290 handle->periodSize = handle->handle->period_size;
291 if (strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC) &&
292 strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC) &&
293 (6 != handle->channels)) {
294 //Do not update buffersize for 5.1 recording
295 handle->bufferSize = handle->handle->period_size;
296 }
297
298 return NO_ERROR;
299}
300
301status_t setSoftwareParams(alsa_handle_t *handle)
302{
303 struct snd_pcm_sw_params* params;
304 struct pcm* pcm = handle->handle;
305
306 unsigned long periodSize = pcm->period_size;
307 int channels = handle->channels;
308
309 params = (snd_pcm_sw_params*) calloc(1, sizeof(struct snd_pcm_sw_params));
310 if (!params) {
311 LOG_ALWAYS_FATAL("Failed to allocate ALSA software parameters!");
312 return NO_INIT;
313 }
314
Ajay Dudani9746c472012-06-18 16:01:16 -0700315#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700316 if (channels == 6) {
317 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
318 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700319 ALOGV("SWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700320 channels = 4;
321 }
322 }
323#endif
324
325 // Get the current software parameters
326 params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
327 params->period_step = 1;
328 if(((!strcmp(handle->useCase,SND_USE_CASE_MOD_PLAY_VOIP)) ||
329 (!strcmp(handle->useCase,SND_USE_CASE_VERB_IP_VOICECALL)))){
Iliyan Malchev4113f342012-06-11 14:39:47 -0700330 ALOGV("setparam: start & stop threshold for Voip ");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700331 params->avail_min = handle->channels - 1 ? periodSize/4 : periodSize/2;
332 params->start_threshold = periodSize/2;
333 params->stop_threshold = INT_MAX;
334 } else {
335 params->avail_min = periodSize/2;
336 params->start_threshold = channels * (periodSize/4);
337 params->stop_threshold = INT_MAX;
338 }
339 params->silence_threshold = 0;
340 params->silence_size = 0;
341
342 if (param_set_sw_params(handle->handle, params)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700343 ALOGE("cannot set sw params");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700344 return NO_INIT;
345 }
346 return NO_ERROR;
347}
348
349void switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode)
350{
351 const char **mods_list;
352 use_case_t useCaseNode;
353 unsigned usecase_type = 0;
354 bool inCallDevSwitch = false;
355 char *rxDevice, *txDevice, ident[70], *use_case = NULL;
356 int err = 0, index, mods_size;
357 int rx_dev_id, tx_dev_id;
Iliyan Malchev4113f342012-06-11 14:39:47 -0700358 ALOGV("%s: device %d", __FUNCTION__, devices);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700359
360 if ((mode == AudioSystem::MODE_IN_CALL) || (mode == AudioSystem::MODE_IN_COMMUNICATION)) {
361 if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
362 (devices & AudioSystem::DEVICE_IN_WIRED_HEADSET)) {
363 devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADSET |
364 AudioSystem::DEVICE_IN_WIRED_HEADSET);
365 } else if (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
366 devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADPHONE |
367 AudioSystem::DEVICE_IN_BUILTIN_MIC);
368 } else if ((devices & AudioSystem::DEVICE_OUT_EARPIECE) ||
369 (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC)) {
370 devices = devices | (AudioSystem::DEVICE_IN_BUILTIN_MIC |
371 AudioSystem::DEVICE_OUT_EARPIECE);
372 } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) {
ty.lee10dfa852012-08-01 21:09:45 +0900373 devices = devices | (AudioSystem::DEVICE_IN_BACK_MIC |
Iliyan Malchev4765c432012-06-11 14:36:16 -0700374 AudioSystem::DEVICE_OUT_SPEAKER);
375 } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) ||
376 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
377 (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
378 devices = devices | (AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET |
379 AudioSystem::DEVICE_OUT_BLUETOOTH_SCO);
Ajay Dudani9746c472012-06-18 16:01:16 -0700380#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700381 } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
382 (devices & AudioSystem::DEVICE_IN_ANC_HEADSET)) {
383 devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADSET |
384 AudioSystem::DEVICE_IN_ANC_HEADSET);
385 } else if (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE) {
386 devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADPHONE |
387 AudioSystem::DEVICE_IN_BUILTIN_MIC);
388#endif
389 } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
390 devices = devices | (AudioSystem::DEVICE_OUT_AUX_DIGITAL |
391 AudioSystem::DEVICE_IN_AUX_DIGITAL);
Ajay Dudani9746c472012-06-18 16:01:16 -0700392#ifdef QCOM_PROXY_DEVICE_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700393 } else if ((devices & AudioSystem::DEVICE_OUT_PROXY) ||
394 (devices & AudioSystem::DEVICE_IN_PROXY)) {
395 devices = devices | (AudioSystem::DEVICE_OUT_PROXY |
396 AudioSystem::DEVICE_IN_PROXY);
397#endif
398 }
399 }
Ajay Dudani9746c472012-06-18 16:01:16 -0700400#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700401 if ((devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) && ( 6 == handle->channels)) {
402 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
403 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700404 ALOGV(" switchDevice , use ssr devices for channels:%d usecase:%s",handle->channels,handle->useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700405 s_set_flags(SSRQMIC_FLAG);
406 }
407 }
408#endif
409
410 rxDevice = getUCMDevice(devices & AudioSystem::DEVICE_OUT_ALL, 0, NULL);
411 txDevice = getUCMDevice(devices & AudioSystem::DEVICE_IN_ALL, 1, rxDevice);
412
413 if (rxDevice != NULL) {
414 if ((handle->handle) && (((!strncmp(rxDevice, DEVICE_SPEAKER_HEADSET, strlen(DEVICE_SPEAKER_HEADSET))) &&
415 ((!strncmp(curRxUCMDevice, DEVICE_HEADPHONES, strlen(DEVICE_HEADPHONES))) ||
416 (!strncmp(curRxUCMDevice, DEVICE_HEADSET, strlen(DEVICE_HEADSET))))) ||
417 (((!strncmp(curRxUCMDevice, DEVICE_SPEAKER_HEADSET, strlen(DEVICE_SPEAKER_HEADSET))) &&
418 ((!strncmp(rxDevice, DEVICE_HEADPHONES, strlen(DEVICE_HEADPHONES))) ||
419 (!strncmp(rxDevice, DEVICE_HEADSET, strlen(DEVICE_HEADSET))))))) &&
420 ((!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI, strlen(SND_USE_CASE_VERB_HIFI))) ||
421 (!strncmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC, strlen(SND_USE_CASE_MOD_PLAY_MUSIC))))) {
422 pcm_close(handle->handle);
423 handle->handle=NULL;
424 handle->rxHandle=NULL;
425 pflag = true;
426 }
427 }
428
429 if ((rxDevice != NULL) && (txDevice != NULL)) {
430 if (((strncmp(rxDevice, curRxUCMDevice, MAX_STR_LEN)) ||
431 (strncmp(txDevice, curTxUCMDevice, MAX_STR_LEN))) && (mode == AudioSystem::MODE_IN_CALL))
432 inCallDevSwitch = true;
433 }
434 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&use_case);
435 mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
436 if (rxDevice != NULL) {
437 if ((strncmp(curRxUCMDevice, "None", 4)) &&
438 ((strncmp(rxDevice, curRxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
439 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
440 strlen(SND_USE_CASE_VERB_INACTIVE)))) {
441 usecase_type = getUseCaseType(use_case);
442 if (usecase_type & USECASE_TYPE_RX) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700443 ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700444 strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
445 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
446 mUseCaseList.push_front(useCaseNode);
447 }
448 }
449 if (mods_size) {
450 for(index = 0; index < mods_size; index++) {
451 usecase_type = getUseCaseType(mods_list[index]);
452 if (usecase_type & USECASE_TYPE_RX) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700453 ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700454 strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
455 snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
456 mUseCaseList.push_back(useCaseNode);
457 }
458 }
459 }
460 snd_use_case_set(handle->ucMgr, "_disdev", curRxUCMDevice);
461 }
462 }
463 if (txDevice != NULL) {
464 if ((strncmp(curTxUCMDevice, "None", 4)) &&
465 ((strncmp(txDevice, curTxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
466 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
467 strlen(SND_USE_CASE_VERB_INACTIVE)))) {
468 usecase_type = getUseCaseType(use_case);
469 if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700470 ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700471 strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
472 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
473 mUseCaseList.push_front(useCaseNode);
474 }
475 }
476 if (mods_size) {
477 for(index = 0; index < mods_size; index++) {
478 usecase_type = getUseCaseType(mods_list[index]);
479 if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700480 ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700481 strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
482 snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
483 mUseCaseList.push_back(useCaseNode);
484 }
485 }
486 }
487 snd_use_case_set(handle->ucMgr, "_disdev", curTxUCMDevice);
488 }
489 }
Iliyan Malchev4113f342012-06-11 14:39:47 -0700490 ALOGV("%s,rxDev:%s, txDev:%s, curRxDev:%s, curTxDev:%s\n", __FUNCTION__, rxDevice, txDevice, curRxUCMDevice, curTxUCMDevice);
Ajay Dudani9746c472012-06-18 16:01:16 -0700491#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700492 if (mode == AudioSystem::MODE_IN_CALL && platform_is_Fusion3() && (inCallDevSwitch == true)) {
493 err = csd_client_disable_device();
494 if (err < 0)
495 {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700496 ALOGE("csd_client_disable_device, failed, error %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700497 }
498 }
499#endif
500
501 if (rxDevice != NULL) {
502 snd_use_case_set(handle->ucMgr, "_enadev", rxDevice);
503 strlcpy(curRxUCMDevice, rxDevice, sizeof(curRxUCMDevice));
Ajay Dudani9746c472012-06-18 16:01:16 -0700504#ifdef QCOM_FM_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700505 if (devices & AudioSystem::DEVICE_OUT_FM)
506 s_set_fm_vol(fmVolume);
507#endif
508 }
509 if (txDevice != NULL) {
510 snd_use_case_set(handle->ucMgr, "_enadev", txDevice);
511 strlcpy(curTxUCMDevice, txDevice, sizeof(curTxUCMDevice));
512 }
513 for(ALSAUseCaseList::iterator it = mUseCaseList.begin(); it != mUseCaseList.end(); ++it) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700514 ALOGD("Route use case %s\n", it->useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700515 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
516 strlen(SND_USE_CASE_VERB_INACTIVE))) && (!strncmp(use_case, it->useCase, MAX_UC_LEN))) {
517 snd_use_case_set(handle->ucMgr, "_verb", it->useCase);
518 } else {
519 snd_use_case_set(handle->ucMgr, "_enamod", it->useCase);
520 }
521 }
522 if (!mUseCaseList.empty())
523 mUseCaseList.clear();
524 if (use_case != NULL) {
525 free(use_case);
526 use_case = NULL;
527 }
Iliyan Malchev4113f342012-06-11 14:39:47 -0700528 ALOGD("switchDevice: curTxUCMDevivce %s curRxDevDevice %s", curTxUCMDevice, curRxUCMDevice);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700529
530 if (mode == AudioSystem::MODE_IN_CALL && platform_is_Fusion3() && (inCallDevSwitch == true)) {
531 /* get tx acdb id */
532 memset(&ident,0,sizeof(ident));
533 strlcpy(ident, "ACDBID/", sizeof(ident));
534 strlcat(ident, curTxUCMDevice, sizeof(ident));
535 tx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
536
537 /* get rx acdb id */
538 memset(&ident,0,sizeof(ident));
539 strlcpy(ident, "ACDBID/", sizeof(ident));
540 strlcat(ident, curRxUCMDevice, sizeof(ident));
541 rx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
542
ehgrace.kim91e9fad2012-07-02 18:27:28 -0700543 if (((rx_dev_id == DEVICE_SPEAKER_MONO_RX_ACDB_ID ) || (rx_dev_id == DEVICE_SPEAKER_STEREO_RX_ACDB_ID ))
544 && tx_dev_id == DEVICE_HANDSET_TX_ACDB_ID) {
Iliyan Malchev4765c432012-06-11 14:36:16 -0700545 tx_dev_id = DEVICE_SPEAKER_TX_ACDB_ID;
546 }
547
Ajay Dudani9746c472012-06-18 16:01:16 -0700548#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4113f342012-06-11 14:39:47 -0700549 ALOGV("rx_dev_id=%d, tx_dev_id=%d\n", rx_dev_id, tx_dev_id);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700550 err = csd_client_enable_device(rx_dev_id, tx_dev_id, mDevSettingsFlag);
551 if (err < 0)
552 {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700553 ALOGE("csd_client_disable_device failed, error %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700554 }
Iliyan Malchev4113f342012-06-11 14:39:47 -0700555#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700556 }
557
558 if (rxDevice != NULL) {
559 if (pflag && (((!strncmp(rxDevice, DEVICE_SPEAKER_HEADSET, strlen(DEVICE_SPEAKER_HEADSET))) &&
560 ((!strncmp(curRxUCMDevice, DEVICE_HEADPHONES, strlen(DEVICE_HEADPHONES))) ||
561 (!strncmp(curRxUCMDevice, DEVICE_HEADSET, strlen(DEVICE_HEADSET))))) ||
562 (((!strncmp(curRxUCMDevice, DEVICE_SPEAKER_HEADSET, strlen(DEVICE_SPEAKER_HEADSET))) &&
563 ((!strncmp(rxDevice, DEVICE_HEADPHONES, strlen(DEVICE_HEADPHONES))) ||
564 (!strncmp(rxDevice, DEVICE_HEADSET, strlen(DEVICE_HEADSET))))))) &&
565 ((!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI, strlen(SND_USE_CASE_VERB_HIFI))) ||
566 (!strncmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC, strlen(SND_USE_CASE_MOD_PLAY_MUSIC))))) {
567 s_open(handle);
568 pflag = false;
569 }
570 }
571
572 if (rxDevice != NULL) {
573 free(rxDevice);
574 rxDevice = NULL;
575 }
576 if (txDevice != NULL) {
577 free(txDevice);
578 txDevice = NULL;
579 }
580}
581
582// ----------------------------------------------------------------------------
583
584static status_t s_init(alsa_device_t *module, ALSAHandleList &list)
585{
Ajay Dudani86c852b2012-07-19 15:28:45 -0700586#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -0700587 ALOGD("s_init: Initializing devices for ALSA module");
Ajay Dudani86c852b2012-07-19 15:28:45 -0700588#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700589
590 list.clear();
591
592 return NO_ERROR;
593}
594
595static status_t s_open(alsa_handle_t *handle)
596{
597 char *devName;
598 unsigned flags = 0;
599 int err = NO_ERROR;
600
601 /* No need to call s_close for LPA as pcm device open and close is handled by LPAPlayer in stagefright */
602 if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) || (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA))
603 ||(!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) || (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700604 ALOGD("s_open: Opening LPA /Tunnel playback");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700605 return NO_ERROR;
606 }
607
608 s_close(handle);
609
Ajay Dudani86c852b2012-07-19 15:28:45 -0700610#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -0700611 ALOGD("s_open: handle %p", handle);
Ajay Dudani86c852b2012-07-19 15:28:45 -0700612#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700613
614 // ASoC multicomponent requires a valid path (frontend/backend) for
615 // the device to be opened
616
617 // The PCM stream is opened in blocking mode, per ALSA defaults. The
618 // AudioFlinger seems to assume blocking mode too, so asynchronous mode
619 // should not be used.
620 if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI)) ||
621 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC))) {
622 flags = PCM_OUT;
623 } else {
624 flags = PCM_IN;
625 }
626 if (handle->channels == 1) {
627 flags |= PCM_MONO;
628 }
Ajay Dudani9746c472012-06-18 16:01:16 -0700629#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700630 else if (handle->channels == 4 ) {
631 flags |= PCM_QUAD;
632 } else if (handle->channels == 6 ) {
633 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
634 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
635 flags |= PCM_QUAD;
636 } else {
637 flags |= PCM_5POINT1;
638 }
639 }
640#endif
641 else {
642 flags |= PCM_STEREO;
643 }
644 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700645 ALOGE("Failed to get pcm device node: %s", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700646 return NO_INIT;
647 }
648 if (devName != NULL) {
649 handle->handle = pcm_open(flags, (char*)devName);
650 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700651 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700652 return NO_INIT;
653 }
654
655 if (!handle->handle) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700656 ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700657 free(devName);
658 return NO_INIT;
659 }
660
661 handle->handle->flags = flags;
662 err = setHardwareParams(handle);
663
664 if (err == NO_ERROR) {
665 err = setSoftwareParams(handle);
666 }
667
668 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700669 ALOGE("Set HW/SW params failed: Closing the pcm stream");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700670 s_standby(handle);
671 }
672
673 free(devName);
674 return NO_ERROR;
675}
676
677static status_t s_start_voip_call(alsa_handle_t *handle)
678{
679
680 char* devName;
681 char* devName1;
682 unsigned flags = 0;
683 int err = NO_ERROR;
684 uint8_t voc_pkt[VOIP_BUFFER_MAX_SIZE];
685
686 s_close(handle);
687 flags = PCM_OUT;
688 flags |= PCM_MONO;
Iliyan Malchev4113f342012-06-11 14:39:47 -0700689 ALOGV("s_open:s_start_voip_call handle %p", handle);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700690
691 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700692 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700693 return NO_INIT;
694 }
695
696 if (devName != NULL) {
697 handle->handle = pcm_open(flags, (char*)devName);
698 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700699 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700700 return NO_INIT;
701 }
702
703 if (!handle->handle) {
704 free(devName);
Iliyan Malchev4113f342012-06-11 14:39:47 -0700705 ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700706 return NO_INIT;
707 }
708
709 if (!pcm_ready(handle->handle)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700710 ALOGE(" pcm ready failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700711 }
712
713 handle->handle->flags = flags;
714 err = setHardwareParams(handle);
715
716 if (err == NO_ERROR) {
717 err = setSoftwareParams(handle);
718 }
719
720 err = pcm_prepare(handle->handle);
721 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700722 ALOGE("DEVICE_OUT_DIRECTOUTPUT: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700723 }
724
725 /* first write required start dsp */
726 memset(&voc_pkt,0,sizeof(voc_pkt));
727 pcm_write(handle->handle,&voc_pkt,handle->handle->period_size);
728 handle->rxHandle = handle->handle;
729 free(devName);
Iliyan Malchev4113f342012-06-11 14:39:47 -0700730 ALOGV("s_open: DEVICE_IN_COMMUNICATION ");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700731 flags = PCM_IN;
732 flags |= PCM_MONO;
733 handle->handle = 0;
734
735 if (deviceName(handle, flags, &devName1) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700736 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700737 return NO_INIT;
738 }
739 if (devName != NULL) {
740 handle->handle = pcm_open(flags, (char*)devName1);
741 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700742 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700743 return NO_INIT;
744 }
745
746 if (!handle->handle) {
747 free(devName);
Iliyan Malchev4113f342012-06-11 14:39:47 -0700748 ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700749 return NO_INIT;
750 }
751
752 if (!pcm_ready(handle->handle)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700753 ALOGE(" pcm ready in failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700754 }
755
756 handle->handle->flags = flags;
757
758 err = setHardwareParams(handle);
759
760 if (err == NO_ERROR) {
761 err = setSoftwareParams(handle);
762 }
763
764
765 err = pcm_prepare(handle->handle);
766 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700767 ALOGE("DEVICE_IN_COMMUNICATION: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700768 }
769
770 /* first read required start dsp */
771 memset(&voc_pkt,0,sizeof(voc_pkt));
772 pcm_read(handle->handle,&voc_pkt,handle->handle->period_size);
773 return NO_ERROR;
774}
775
776static status_t s_start_voice_call(alsa_handle_t *handle)
777{
778 char* devName;
779 unsigned flags = 0;
780 int err = NO_ERROR;
781
Ajay Dudani86c852b2012-07-19 15:28:45 -0700782#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -0700783 ALOGD("s_start_voice_call: handle %p", handle);
Ajay Dudani86c852b2012-07-19 15:28:45 -0700784#endif
785
Iliyan Malchev4765c432012-06-11 14:36:16 -0700786 // ASoC multicomponent requires a valid path (frontend/backend) for
787 // the device to be opened
788
789 flags = PCM_OUT | PCM_MONO;
790 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700791 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700792 return NO_INIT;
793 }
794 if (devName != NULL) {
795 handle->handle = pcm_open(flags, (char*)devName);
796 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700797 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700798 return NO_INIT;
799 }
800 if (!handle->handle) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700801 ALOGE("s_start_voicecall: could not open PCM device");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700802 goto Error;
803 }
804
805 handle->handle->flags = flags;
806 err = setHardwareParams(handle);
807 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700808 ALOGE("s_start_voice_call: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700809 goto Error;
810 }
811
812 err = setSoftwareParams(handle);
813 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700814 ALOGE("s_start_voice_call: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700815 goto Error;
816 }
817
818 err = pcm_prepare(handle->handle);
819 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700820 ALOGE("s_start_voice_call: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700821 goto Error;
822 }
823
824 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700825 ALOGE("s_start_voice_call:SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700826 goto Error;
827 }
828
829 // Store the PCM playback device pointer in rxHandle
830 handle->rxHandle = handle->handle;
831 free(devName);
832
833 // Open PCM capture device
834 flags = PCM_IN | PCM_MONO;
835 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700836 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700837 goto Error;
838 }
839 if (devName != NULL) {
840 handle->handle = pcm_open(flags, (char*)devName);
841 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700842 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700843 return NO_INIT;
844 }
845 if (!handle->handle) {
846 free(devName);
847 goto Error;
848 }
849
850 handle->handle->flags = flags;
851 err = setHardwareParams(handle);
852 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700853 ALOGE("s_start_voice_call: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700854 goto Error;
855 }
856
857 err = setSoftwareParams(handle);
858 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700859 ALOGE("s_start_voice_call: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700860 goto Error;
861 }
862
863 err = pcm_prepare(handle->handle);
864 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700865 ALOGE("s_start_voice_call: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700866 goto Error;
867 }
868
869 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700870 ALOGE("s_start_voice_call:SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700871 goto Error;
872 }
873
874 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -0700875#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700876 err = csd_client_start_voice();
877 if (err < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700878 ALOGE("s_start_voice_call: csd_client error %d\n", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700879 goto Error;
880 }
Iliyan Malchev4113f342012-06-11 14:39:47 -0700881#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700882 }
883
884 free(devName);
885 return NO_ERROR;
886
887Error:
Iliyan Malchev4113f342012-06-11 14:39:47 -0700888 ALOGE("s_start_voice_call: Failed to initialize ALSA device '%s'", devName);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700889 free(devName);
890 s_close(handle);
891 return NO_INIT;
892}
893
894static status_t s_start_fm(alsa_handle_t *handle)
895{
896 char *devName;
897 unsigned flags = 0;
898 int err = NO_ERROR;
899
Iliyan Malchev4113f342012-06-11 14:39:47 -0700900 ALOGE("s_start_fm: handle %p", handle);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700901
902 // ASoC multicomponent requires a valid path (frontend/backend) for
903 // the device to be opened
904
905 flags = PCM_OUT | PCM_STEREO;
906 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700907 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700908 goto Error;
909 }
910 if (devName != NULL) {
911 handle->handle = pcm_open(flags, (char*)devName);
912 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700913 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700914 return NO_INIT;
915 }
916 if (!handle->handle) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700917 ALOGE("s_start_fm: could not open PCM device");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700918 goto Error;
919 }
920
921 handle->handle->flags = flags;
922 err = setHardwareParams(handle);
923 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700924 ALOGE("s_start_fm: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700925 goto Error;
926 }
927
928 err = setSoftwareParams(handle);
929 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700930 ALOGE("s_start_fm: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700931 goto Error;
932 }
933
934 err = pcm_prepare(handle->handle);
935 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700936 ALOGE("s_start_fm: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700937 goto Error;
938 }
939
940 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700941 ALOGE("s_start_fm: SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700942 goto Error;
943 }
944
945 // Store the PCM playback device pointer in rxHandle
946 handle->rxHandle = handle->handle;
947 free(devName);
948
949 // Open PCM capture device
950 flags = PCM_IN | PCM_STEREO;
951 if (deviceName(handle, flags, &devName) < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700952 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700953 goto Error;
954 }
955 if (devName != NULL) {
956 handle->handle = pcm_open(flags, (char*)devName);
957 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700958 ALOGE("Failed to get pcm device node");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700959 return NO_INIT;
960 }
961 if (!handle->handle) {
962 goto Error;
963 }
964
965 handle->handle->flags = flags;
966 err = setHardwareParams(handle);
967 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700968 ALOGE("s_start_fm: setHardwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700969 goto Error;
970 }
971
972 err = setSoftwareParams(handle);
973 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700974 ALOGE("s_start_fm: setSoftwareParams failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700975 goto Error;
976 }
977
978 err = pcm_prepare(handle->handle);
979 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700980 ALOGE("s_start_fm: pcm_prepare failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700981 goto Error;
982 }
983
984 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700985 ALOGE("s_start_fm: SNDRV_PCM_IOCTL_START failed\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700986 goto Error;
987 }
988
989 s_set_fm_vol(fmVolume);
990 free(devName);
991 return NO_ERROR;
992
993Error:
994 free(devName);
995 s_close(handle);
996 return NO_INIT;
997}
998
999static status_t s_set_fm_vol(int value)
1000{
1001 status_t err = NO_ERROR;
1002
1003 ALSAControl control("/dev/snd/controlC0");
1004 control.set("Internal FM RX Volume",value,0);
1005 fmVolume = value;
1006
1007 return err;
1008}
1009
1010static status_t s_set_lpa_vol(int value)
1011{
1012 status_t err = NO_ERROR;
1013
1014 ALSAControl control("/dev/snd/controlC0");
1015 control.set("LPA RX Volume",value,0);
1016
1017 return err;
1018}
1019
1020static status_t s_start(alsa_handle_t *handle)
1021{
1022 status_t err = NO_ERROR;
1023
1024 if(!handle->handle) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001025 ALOGE("No active PCM driver to start");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001026 return err;
1027 }
1028
1029 err = pcm_prepare(handle->handle);
1030
1031 return err;
1032}
1033
1034static status_t s_close(alsa_handle_t *handle)
1035{
1036 int ret;
1037 status_t err = NO_ERROR;
1038 struct pcm *h = handle->rxHandle;
1039
1040 handle->rxHandle = 0;
Ajay Dudani86c852b2012-07-19 15:28:45 -07001041#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001042 ALOGD("s_close: handle %p h %p", handle, h);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001043#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001044 if (h) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001045 ALOGV("s_close rxHandle\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001046 err = pcm_close(h);
1047 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001048 ALOGE("s_close: pcm_close failed for rxHandle with err %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001049 }
1050 }
1051
1052 h = handle->handle;
1053 handle->handle = 0;
1054
1055 if (h) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001056 ALOGV("s_close handle h %p\n", h);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001057 err = pcm_close(h);
1058 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001059 ALOGE("s_close: pcm_close failed for handle with err %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001060 }
1061
1062 if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_VOICECALL) ||
1063 !strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_VOICE)) &&
1064 platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001065#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001066 err = csd_client_stop_voice();
1067 if (err < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001068 ALOGE("s_close: csd_client error %d\n", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001069 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001070#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001071 }
1072
1073 disableDevice(handle);
1074 } else if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
1075 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
1076 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
1077 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))){
1078 disableDevice(handle);
1079 }
1080
1081 return err;
1082}
1083
1084/*
1085 this is same as s_close, but don't discard
1086 the device/mode info. This way we can still
1087 close the device, hit idle and power-save, reopen the pcm
1088 for the same device/mode after resuming
1089*/
1090static status_t s_standby(alsa_handle_t *handle)
1091{
1092 int ret;
1093 status_t err = NO_ERROR;
1094 struct pcm *h = handle->rxHandle;
1095 handle->rxHandle = 0;
Ajay Dudani86c852b2012-07-19 15:28:45 -07001096#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001097 ALOGD("s_standby: handle %p h %p", handle, h);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001098#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001099 if (h) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001100 ALOGE("s_standby rxHandle\n");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001101 err = pcm_close(h);
1102 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001103 ALOGE("s_standby: pcm_close failed for rxHandle with err %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001104 }
1105 }
1106
1107 h = handle->handle;
1108 handle->handle = 0;
1109
1110 if (h) {
Ajay Dudani86c852b2012-07-19 15:28:45 -07001111#if LOCAL_LOGD
1112 ALOGD("s_standby handle h %p\n", h);
1113#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001114 err = pcm_close(h);
1115 if(err != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001116 ALOGE("s_standby: pcm_close failed for handle with err %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001117 }
1118 disableDevice(handle);
1119 } else if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
1120 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
1121 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
1122 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
1123 disableDevice(handle);
1124 }
1125
1126 return err;
1127}
1128
1129static status_t s_route(alsa_handle_t *handle, uint32_t devices, int mode)
1130{
1131 status_t status = NO_ERROR;
1132
Ajay Dudani86c852b2012-07-19 15:28:45 -07001133#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001134 ALOGD("s_route: devices 0x%x in mode %d", devices, mode);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001135#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001136 callMode = mode;
1137 switchDevice(handle, devices, mode);
1138 return status;
1139}
1140
1141int getUseCaseType(const char *useCase)
1142{
Iliyan Malchev4113f342012-06-11 14:39:47 -07001143 ALOGE("use case is %s\n", useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001144 if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI,
1145 strlen(SND_USE_CASE_VERB_HIFI)) ||
1146 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER,
1147 strlen(SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
1148 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_TUNNEL,
1149 strlen(SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
1150 !strncmp(useCase, SND_USE_CASE_VERB_DIGITAL_RADIO,
1151 strlen(SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
1152 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC,
1153 strlen(SND_USE_CASE_MOD_PLAY_MUSIC)) ||
1154 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LPA,
1155 strlen(SND_USE_CASE_MOD_PLAY_LPA)) ||
1156 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_TUNNEL,
1157 strlen(SND_USE_CASE_MOD_PLAY_TUNNEL)) ||
1158 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_FM,
1159 strlen(SND_USE_CASE_MOD_PLAY_FM))) {
1160 return USECASE_TYPE_RX;
1161 } else if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI_REC,
1162 strlen(SND_USE_CASE_VERB_HIFI_REC)) ||
1163 !strncmp(useCase, SND_USE_CASE_VERB_FM_REC,
1164 strlen(SND_USE_CASE_VERB_FM_REC)) ||
1165 !strncmp(useCase, SND_USE_CASE_VERB_FM_A2DP_REC,
1166 strlen(SND_USE_CASE_VERB_FM_A2DP_REC)) ||
1167 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC,
1168 strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC)) ||
1169 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_FM,
1170 strlen(SND_USE_CASE_MOD_CAPTURE_FM)) ||
1171 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM,
1172 strlen(SND_USE_CASE_MOD_CAPTURE_A2DP_FM))) {
1173 return USECASE_TYPE_TX;
1174 } else if (!strncmp(useCase, SND_USE_CASE_VERB_VOICECALL,
1175 strlen(SND_USE_CASE_VERB_VOICECALL)) ||
1176 !strncmp(useCase, SND_USE_CASE_VERB_IP_VOICECALL,
1177 strlen(SND_USE_CASE_VERB_IP_VOICECALL)) ||
1178 !strncmp(useCase, SND_USE_CASE_VERB_DL_REC,
1179 strlen(SND_USE_CASE_VERB_DL_REC)) ||
1180 !strncmp(useCase, SND_USE_CASE_VERB_UL_DL_REC,
1181 strlen(SND_USE_CASE_VERB_UL_DL_REC)) ||
1182 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOICE,
1183 strlen(SND_USE_CASE_MOD_PLAY_VOICE)) ||
1184 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOIP,
1185 strlen(SND_USE_CASE_MOD_PLAY_VOIP)) ||
1186 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
1187 strlen(SND_USE_CASE_MOD_CAPTURE_VOICE_DL)) ||
1188 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
1189 strlen(SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL)) ||
1190 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
1191 strlen(SND_USE_CASE_MOD_CAPTURE_VOICE)) ||
1192 !strncmp(useCase, SND_USE_CASE_VERB_VOLTE,
1193 strlen(SND_USE_CASE_VERB_VOLTE)) ||
1194 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOLTE,
1195 strlen(SND_USE_CASE_MOD_PLAY_VOLTE))) {
1196 return (USECASE_TYPE_RX | USECASE_TYPE_TX);
1197 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001198 ALOGE("unknown use case %s\n", useCase);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001199 return 0;
1200 }
1201}
1202
1203static void disableDevice(alsa_handle_t *handle)
1204{
1205 unsigned usecase_type = 0;
1206 int i, mods_size;
1207 char *useCase;
1208 const char **mods_list;
1209
1210 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
1211 if (useCase != NULL) {
1212 if (!strncmp(useCase, handle->useCase, MAX_UC_LEN)) {
1213 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
1214 } else {
1215 snd_use_case_set(handle->ucMgr, "_dismod", handle->useCase);
1216 }
1217 free(useCase);
1218 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
1219 if (strncmp(useCase, SND_USE_CASE_VERB_INACTIVE,
1220 strlen(SND_USE_CASE_VERB_INACTIVE)))
1221 usecase_type |= getUseCaseType(useCase);
1222 mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001223#if LOCAL_LOGD
1224 ALOGD("Number of modifiers %d\n", mods_size);
1225#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001226 if (mods_size) {
1227 for(i = 0; i < mods_size; i++) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001228 ALOGE("index %d modifier %s\n", i, mods_list[i]);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001229 usecase_type |= getUseCaseType(mods_list[i]);
1230 }
1231 }
Ajay Dudani86c852b2012-07-19 15:28:45 -07001232#if LOCAL_LOGD
1233 ALOGD("usecase_type is %d\n", usecase_type);
1234#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001235 if (!(usecase_type & USECASE_TYPE_TX) && (strncmp(curTxUCMDevice, "None", 4)))
1236 snd_use_case_set(handle->ucMgr, "_disdev", curTxUCMDevice);
1237 if (!(usecase_type & USECASE_TYPE_RX) && (strncmp(curRxUCMDevice, "None", 4)))
1238 snd_use_case_set(handle->ucMgr, "_disdev", curRxUCMDevice);
1239 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001240 ALOGE("Invalid state, no valid use case found to disable");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001241 }
1242 free(useCase);
1243}
1244
1245char *getUCMDevice(uint32_t devices, int input, char *rxDevice)
1246{
1247 if (!input) {
1248 if (!(mDevSettingsFlag & TTY_OFF) &&
1249 (callMode == AudioSystem::MODE_IN_CALL) &&
1250 ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
ty.lee924f7982012-08-01 23:15:30 +09001251 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001252#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001253 ||
1254 (devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
1255 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) {
1256#endif
1257 if (mDevSettingsFlag & TTY_VCO) {
1258 return strdup(SND_USE_CASE_DEV_TTY_HEADSET_RX);
1259 } else if (mDevSettingsFlag & TTY_FULL) {
1260 return strdup(SND_USE_CASE_DEV_TTY_FULL_RX);
1261 } else if (mDevSettingsFlag & TTY_HCO) {
1262 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_RX); /* HANDSET RX */
1263 }
1264 }else if ((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET) ||
1265 (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)) {
1266 return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */
1267 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1268 ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
1269 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
1270 if (mDevSettingsFlag & ANC_FLAG) {
1271 return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
1272 } else {
1273 return strdup(SND_USE_CASE_DEV_SPEAKER_HEADSET); /* COMBO SPEAKER+HEADSET RX */
1274 }
Ajay Dudani9746c472012-06-18 16:01:16 -07001275#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001276 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1277 ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
1278 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) {
1279 return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
1280 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1281 (devices & AudioSystem::DEVICE_OUT_FM_TX)) {
1282 return strdup(SND_USE_CASE_DEV_SPEAKER_FM_TX); /* COMBO SPEAKER+FM_TX RX */
1283#endif
1284 } else if (devices & AudioSystem::DEVICE_OUT_EARPIECE) {
1285 return strdup(SND_USE_CASE_DEV_EARPIECE); /* HANDSET RX */
1286 } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) {
1287 return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
1288 } else if ((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_ANC_HEADSET); /* ANC HEADSET RX */
1292 } else {
1293 return strdup(SND_USE_CASE_DEV_HEADPHONES); /* 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_ANC_HEADSET) ||
1297 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE)) {
1298 return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */
1299#endif
1300 } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) ||
1301 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
1302 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT)) {
1303 if (btsco_samplerate == BTSCO_RATE_16KHZ)
1304 return strdup(SND_USE_CASE_DEV_BTSCO_WB_RX); /* BTSCO RX*/
1305 else
1306 return strdup(SND_USE_CASE_DEV_BTSCO_NB_RX); /* BTSCO RX*/
1307 } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP) ||
1308 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES) ||
Ajay Dudani9746c472012-06-18 16:01:16 -07001309#ifdef QCOM_VOIP_ENABLED
1310 (devices & AudioSystem::DEVICE_OUT_DIRECTOUTPUT) ||
1311#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001312 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) {
1313 /* Nothing to be done, use current active device */
1314 if (strncmp(curRxUCMDevice, "None", 4)) {
1315 return strdup(curRxUCMDevice);
1316 }
1317 } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
1318 return strdup(SND_USE_CASE_DEV_HDMI); /* HDMI RX */
Ajay Dudani9746c472012-06-18 16:01:16 -07001319#ifdef QCOM_PROXY_DEVICE_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001320 } else if (devices & AudioSystem::DEVICE_OUT_PROXY) {
1321 return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */
Ajay Dudani9746c472012-06-18 16:01:16 -07001322#endif
1323#ifdef QCOM_FM_TX_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001324 } else if (devices & AudioSystem::DEVICE_OUT_FM_TX) {
1325 return strdup(SND_USE_CASE_DEV_FM_TX); /* FM Tx */
1326#endif
1327 } else if (devices & AudioSystem::DEVICE_OUT_DEFAULT) {
1328 return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
1329 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001330 ALOGD("No valid output device: %u", devices);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001331 }
1332 } else {
1333 if (!(mDevSettingsFlag & TTY_OFF) &&
1334 (callMode == AudioSystem::MODE_IN_CALL) &&
ty.lee924f7982012-08-01 23:15:30 +09001335 ((devices & AudioSystem::DEVICE_IN_WIRED_HEADSET))) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001336#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001337 ||(devices & AudioSystem::DEVICE_IN_ANC_HEADSET))) {
1338#endif
1339 if (mDevSettingsFlag & TTY_HCO) {
1340 return strdup(SND_USE_CASE_DEV_TTY_HEADSET_TX);
1341 } else if (mDevSettingsFlag & TTY_FULL) {
1342 return strdup(SND_USE_CASE_DEV_TTY_FULL_TX);
1343 } else if (mDevSettingsFlag & TTY_VCO) {
1344 if (!strncmp(mic_type, "analog", 6)) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001345 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_ANALOG_TX);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001346 } else {
1347 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_TX);
1348 }
1349 }
1350 } else if (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) {
1351 if (!strncmp(mic_type, "analog", 6)) {
1352 return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
1353 } else {
1354 if (mDevSettingsFlag & DMIC_FLAG) {
ty.lee924f7982012-08-01 23:15:30 +09001355#ifdef USES_FLUENCE_INCALL
1356 if(callMode == AudioSystem::MODE_IN_CALL) {
1357 if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
1358 return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
1359 } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
1360 return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
1361 } else {
1362 return strdup(SND_USE_CASE_DEV_HANDSET); /* BUILTIN-MIC TX */
1363 }
1364 }
1365#else
Iliyan Malchev4765c432012-06-11 14:36:16 -07001366 if (((rxDevice != NULL) &&
1367 !strncmp(rxDevice, SND_USE_CASE_DEV_SPEAKER,
1368 (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) ||
1369 !strncmp(curRxUCMDevice, SND_USE_CASE_DEV_SPEAKER,
1370 (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) {
1371 if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
1372 return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
1373 } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
1374 return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
1375 }
1376 } else {
1377 if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
1378 return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
1379 } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
1380 return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
1381 }
1382 }
ty.lee924f7982012-08-01 23:15:30 +09001383#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001384 } else if (mDevSettingsFlag & QMIC_FLAG){
1385 return strdup(SND_USE_CASE_DEV_QUAD_MIC);
ty.lee924f7982012-08-01 23:15:30 +09001386 }
Ajay Dudani9746c472012-06-18 16:01:16 -07001387#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001388 else if (mDevSettingsFlag & SSRQMIC_FLAG){
Iliyan Malchev4113f342012-06-11 14:39:47 -07001389 ALOGV("return SSRQMIC_FLAG: 0x%x devices:0x%x",mDevSettingsFlag,devices);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001390 // Mapping for quad mic input device.
1391 return strdup(SND_USE_CASE_DEV_SSR_QUAD_MIC); /* SSR Quad MIC */
ty.lee924f7982012-08-01 23:15:30 +09001392 }
Iliyan Malchev4765c432012-06-11 14:36:16 -07001393#endif
ty.lee74060de2012-08-02 00:47:00 +09001394#ifdef SEPERATED_AUDIO_INPUT
1395 if(input_source == AUDIO_SOURCE_VOICE_RECOGNITION) {
1396 ALOGV("getUCMdevice returned the VOICE_RECOGNITION UCM by input source = %d", input_source);
1397 return strdup(SND_USE_CASE_DEV_VOICE_RECOGNITION ); /* VOICE RECOGNITION TX */
1398 } else if(input_source == AUDIO_SOURCE_CAMCORDER) {
1399 ALOGV("getUCMdevice returned the Camcorder Tx UCM by input source = %d", input_source);
1400 return strdup(SND_USE_CASE_DEV_CAMCORDER_TX ); /* CAMCORDER TX */
1401 }
1402#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001403 else {
ty.lee74060de2012-08-02 00:47:00 +09001404 return strdup(SND_USE_CASE_DEV_HANDSET); /* BUILTIN-MIC TX */
Iliyan Malchev4765c432012-06-11 14:36:16 -07001405 }
1406 }
1407 } else if (devices & AudioSystem::DEVICE_IN_AUX_DIGITAL) {
1408 return strdup(SND_USE_CASE_DEV_HDMI_TX); /* HDMI TX */
Ajay Dudani9746c472012-06-18 16:01:16 -07001409#ifdef QCOM_ANC_HEADSET_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001410 } else if ((devices & AudioSystem::DEVICE_IN_WIRED_HEADSET) ||
1411 (devices & AudioSystem::DEVICE_IN_ANC_HEADSET)) {
1412 return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */
1413#endif
1414 } else if (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
1415 if (btsco_samplerate == BTSCO_RATE_16KHZ)
1416 return strdup(SND_USE_CASE_DEV_BTSCO_WB_TX); /* BTSCO TX*/
1417 else
1418 return strdup(SND_USE_CASE_DEV_BTSCO_NB_TX); /* BTSCO TX*/
Ajay Dudani9746c472012-06-18 16:01:16 -07001419#ifdef QCOM_USBAUDIO_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001420 } else if ((devices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) ||
1421 (devices & AudioSystem::DEVICE_IN_PROXY)) {
1422 return strdup(SND_USE_CASE_DEV_PROXY_TX); /* PROXY TX */
1423#endif
1424 } else if ((devices & AudioSystem::DEVICE_IN_COMMUNICATION) ||
1425 (devices & AudioSystem::DEVICE_IN_VOICE_CALL)) {
1426 /* Nothing to be done, use current active device */
1427 if (strncmp(curTxUCMDevice, "None", 4)) {
1428 return strdup(curTxUCMDevice);
1429 }
Ajay Dudani9746c472012-06-18 16:01:16 -07001430#ifdef QCOM_FM_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001431 } else if ((devices & AudioSystem::DEVICE_IN_FM_RX) ||
1432 (devices & AudioSystem::DEVICE_IN_FM_RX_A2DP)) {
1433 /* Nothing to be done, use current tx device or set dummy device */
1434 if (strncmp(curTxUCMDevice, "None", 4)) {
1435 return strdup(curTxUCMDevice);
1436 } else {
1437 return strdup(SND_USE_CASE_DEV_DUMMY_TX);
1438 }
1439#endif
1440 } else if ((devices & AudioSystem::DEVICE_IN_AMBIENT) ||
1441 (devices & AudioSystem::DEVICE_IN_BACK_MIC)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001442 ALOGI("No proper mapping found with UCM device list, setting default");
Iliyan Malchev4765c432012-06-11 14:36:16 -07001443 if (!strncmp(mic_type, "analog", 6)) {
1444 return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
1445 } else {
1446 return strdup(SND_USE_CASE_DEV_LINE); /* BUILTIN-MIC TX */
1447 }
1448 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001449 ALOGD("No valid input device: %u", devices);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001450 }
1451 }
1452 return NULL;
1453}
1454
1455void s_set_voice_volume(int vol)
1456{
1457 int err = 0;
Ajay Dudani86c852b2012-07-19 15:28:45 -07001458#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001459 ALOGD("s_set_voice_volume: volume %d", vol);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001460#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001461 ALSAControl control("/dev/snd/controlC0");
1462 control.set("Voice Rx Volume", vol, 0);
1463
1464 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001465#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001466 err = csd_client_volume(vol);
1467 if (err < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001468 ALOGE("s_set_voice_volume: csd_client error %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001469 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001470#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001471 }
1472}
1473
1474void s_set_volte_volume(int vol)
1475{
Ajay Dudani86c852b2012-07-19 15:28:45 -07001476#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001477 ALOGD("s_set_volte_volume: volume %d", vol);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001478#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001479 ALSAControl control("/dev/snd/controlC0");
1480 control.set("VoLTE Rx Volume", vol, 0);
1481}
1482
1483
1484void s_set_voip_volume(int vol)
1485{
Ajay Dudani86c852b2012-07-19 15:28:45 -07001486#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001487 ALOGD("s_set_voip_volume: volume %d", vol);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001488#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001489 ALSAControl control("/dev/snd/controlC0");
1490 control.set("Voip Rx Volume", vol, 0);
1491}
1492void s_set_mic_mute(int state)
1493{
1494 int err = 0;
Ajay Dudani86c852b2012-07-19 15:28:45 -07001495#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001496 ALOGD("s_set_mic_mute: state %d", state);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001497#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001498 ALSAControl control("/dev/snd/controlC0");
1499 control.set("Voice Tx Mute", state, 0);
1500
1501 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001502#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001503 err = csd_client_mic_mute(state);
1504 if (err < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001505 ALOGE("s_set_mic_mute: csd_client error %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001506 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001507#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001508 }
1509}
1510void s_set_volte_mic_mute(int state)
1511{
Ajay Dudani86c852b2012-07-19 15:28:45 -07001512#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001513 ALOGD("s_set_volte_mic_mute: state %d", state);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001514#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001515 ALSAControl control("/dev/snd/controlC0");
1516 control.set("VoLTE Tx Mute", state, 0);
1517}
1518
1519void s_set_voip_mic_mute(int state)
1520{
Ajay Dudani86c852b2012-07-19 15:28:45 -07001521#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001522 ALOGD("s_set_voip_mic_mute: state %d", state);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001523#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001524 ALSAControl control("/dev/snd/controlC0");
1525 control.set("Voip Tx Mute", state, 0);
1526}
1527
1528void s_set_voip_config(int mode, int rate)
1529{
Ajay Dudani86c852b2012-07-19 15:28:45 -07001530#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001531 ALOGD("s_set_voip_config: mode %d,rate %d", mode, rate);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001532#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001533 ALSAControl control("/dev/snd/controlC0");
1534 char** setValues;
1535 setValues = (char**)malloc(2*sizeof(char*));
1536 if (setValues == NULL) {
1537 return;
1538 }
1539 setValues[0] = (char*)malloc(4*sizeof(char));
1540 if (setValues[0] == NULL) {
1541 free(setValues);
1542 return;
1543 }
1544
1545 setValues[1] = (char*)malloc(8*sizeof(char));
1546 if (setValues[1] == NULL) {
1547 free(setValues);
1548 free(setValues[0]);
1549 return;
1550 }
1551
1552 sprintf(setValues[0], "%d",mode);
1553 sprintf(setValues[1], "%d",rate);
1554
1555 control.setext("Voip Mode Rate Config", 2, setValues);
1556 free(setValues[1]);
1557 free(setValues[0]);
1558 free(setValues);
1559 return;
1560}
1561
1562void s_set_btsco_rate(int rate)
1563{
1564 btsco_samplerate = rate;
1565}
1566
1567void s_enable_wide_voice(bool flag)
1568{
1569 int err = 0;
1570
Ajay Dudani86c852b2012-07-19 15:28:45 -07001571#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001572 ALOGD("s_enable_wide_voice: flag %d", flag);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001573#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001574 ALSAControl control("/dev/snd/controlC0");
1575 if(flag == true) {
1576 control.set("Widevoice Enable", 1, 0);
1577 } else {
1578 control.set("Widevoice Enable", 0, 0);
1579 }
1580
1581 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001582#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001583 err == csd_client_wide_voice(flag);
1584 if (err < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001585 ALOGE("s_enable_wide_voice: csd_client error %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001586 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001587#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001588 }
1589}
1590
1591void s_set_voc_rec_mode(uint8_t mode)
1592{
Ajay Dudani86c852b2012-07-19 15:28:45 -07001593#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001594 ALOGD("s_set_voc_rec_mode: mode %d", mode);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001595#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001596 ALSAControl control("/dev/snd/controlC0");
1597 control.set("Incall Rec Mode", mode, 0);
1598}
1599
1600void s_enable_fens(bool flag)
1601{
1602 int err = 0;
1603
Ajay Dudani86c852b2012-07-19 15:28:45 -07001604#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001605 ALOGD("s_enable_fens: flag %d", flag);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001606#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001607 ALSAControl control("/dev/snd/controlC0");
1608 if(flag == true) {
1609 control.set("FENS Enable", 1, 0);
1610 } else {
1611 control.set("FENS Enable", 0, 0);
1612 }
1613
1614 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001615#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001616 err = csd_client_fens(flag);
1617 if (err < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001618 ALOGE("s_enable_fens: csd_client error %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001619 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001620#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001621 }
1622}
1623
1624void s_enable_slow_talk(bool flag)
1625{
1626 int err = 0;
1627
Ajay Dudani86c852b2012-07-19 15:28:45 -07001628#if LOCAL_LOGD
Iliyan Malchev4113f342012-06-11 14:39:47 -07001629 ALOGD("s_enable_slow_talk: flag %d", flag);
Ajay Dudani86c852b2012-07-19 15:28:45 -07001630#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001631 ALSAControl control("/dev/snd/controlC0");
1632 if(flag == true) {
1633 control.set("Slowtalk Enable", 1, 0);
1634 } else {
1635 control.set("Slowtalk Enable", 0, 0);
1636 }
1637
1638 if (platform_is_Fusion3()) {
Ajay Dudani9746c472012-06-18 16:01:16 -07001639#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -07001640 err = csd_client_slow_talk(flag);
1641 if (err < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -07001642 ALOGE("s_enable_slow_talk: csd_client error %d", err);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001643 }
Iliyan Malchev4113f342012-06-11 14:39:47 -07001644#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001645 }
1646}
1647
1648void s_set_flags(uint32_t flags)
1649{
Iliyan Malchev4113f342012-06-11 14:39:47 -07001650 ALOGV("s_set_flags: flags %d", flags);
Iliyan Malchev4765c432012-06-11 14:36:16 -07001651 mDevSettingsFlag = flags;
1652}
1653
1654static status_t s_set_compressed_vol(int value)
1655{
1656 status_t err = NO_ERROR;
1657
1658 ALSAControl control("/dev/snd/controlC0");
1659 control.set("COMPRESSED RX Volume",value,0);
1660
1661 return err;
1662}
1663
ty.lee74060de2012-08-02 00:47:00 +09001664#ifdef SEPERATED_AUDIO_INPUT
1665void s_setInput(int input)
1666{
1667 input_source = input;
1668 ALOGD("s_setInput() : input_source = %d",input_source);
1669}
1670#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -07001671}