blob: 240a4927ebc2d48731ebef5f9d92b87718c7ef80 [file] [log] [blame]
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001/* ALSADevice.cpp
2 **
3 ** Copyright 2009 Wind River Systems
Mingming Yinfddaa942012-12-27 17:42:46 -08004 ** Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
Mingming Yinbbd94ad2012-11-29 20:04:36 -08005 **
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
19#define LOG_TAG "ALSADevice"
Steve Kondik341c8502013-05-04 01:55:32 -070020//#define LOG_NDEBUG 0
Mingming Yinbbd94ad2012-11-29 20:04:36 -080021#include <utils/Log.h>
22#include <cutils/properties.h>
23#include <linux/ioctl.h>
24#include "AudioUtil.h"
25#include "AudioHardwareALSA.h"
26#include <media/AudioRecord.h>
27#include <dlfcn.h>
Steve Kondike5066ed2013-04-06 19:23:58 +000028#ifdef USE_A2220
29#include <sound/a2220.h>
30#endif
31
Daniel Hillenbrandc757e342013-05-23 06:40:42 +020032#ifdef USES_AUDIO_AMPLIFIER
33#include <audio_amplifier.h>
34#endif
35
Mingming Yinbbd94ad2012-11-29 20:04:36 -080036extern "C" {
Mingming Yinf158b282013-01-08 15:09:00 -080037#ifdef QCOM_CSDCLIENT_ENABLED
Mingming Yinbbd94ad2012-11-29 20:04:36 -080038static int (*csd_disable_device)();
39static int (*csd_enable_device)(int, int, uint32_t);
Giulio Cervera9a6c7802013-05-02 01:51:16 +020040#ifdef NEW_CSDCLIENT
Vidyakumar Athotadf9175f2013-03-25 13:58:05 -070041static int (*csd_enable_device_config)(int, int);
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -080042static int (*csd_volume)(uint32_t, int);
43static int (*csd_mic_mute)(uint32_t, int);
44static int (*csd_wide_voice)(uint32_t, uint8_t);
45static int (*csd_slow_talk)(uint32_t, uint8_t);
46static int (*csd_fens)(uint32_t, uint8_t);
47static int (*csd_start_voice)(uint32_t);
48static int (*csd_stop_voice)(uint32_t);
Giulio Cervera9a6c7802013-05-02 01:51:16 +020049#else
50static int (*csd_volume)(int);
51static int (*csd_mic_mute)(int);
52static int (*csd_wide_voice)(uint8_t);
53static int (*csd_slow_talk)(uint8_t);
54static int (*csd_fens)(uint8_t);
55static int (*csd_start_voice)();
56static int (*csd_stop_voice)();
57#endif
Mingming Yinbbd94ad2012-11-29 20:04:36 -080058#endif
Mingming Yinf158b282013-01-08 15:09:00 -080059#ifdef QCOM_ACDB_ENABLED
60static int (*acdb_loader_get_ecrx_device)(int acdb_id);
61#endif
62}
Mingming Yinbbd94ad2012-11-29 20:04:36 -080063
64#define SAMPLE_RATE_8KHZ 8000
65
Mingming Yinbbd94ad2012-11-29 20:04:36 -080066#define BTSCO_RATE_16KHZ 16000
67#define USECASE_TYPE_RX 1
68#define USECASE_TYPE_TX 2
Subhash Chandra Bose Naripeddy27c90302012-12-19 20:14:54 -080069#define MAX_HDMI_CHANNEL_CNT 8
Mingming Yinbbd94ad2012-11-29 20:04:36 -080070
71#define AFE_PROXY_PERIOD_SIZE 3072
72#define KILL_A2DP_THREAD 1
73#define SIGNAL_A2DP_THREAD 2
Krishnankutty Kolathappillya2787ae2013-03-28 17:49:22 -070074
75// Setting number of periods to 4. If the system is loaded
76// and record obtain buffer is seen increase
77// PCM_RECORD_PERIOD_COUNT to a value between 4-16.
78#define PCM_RECORD_PERIOD_COUNT 4
Mingming Yinbbd94ad2012-11-29 20:04:36 -080079#define PROXY_CAPTURE_DEVICE_NAME (const char *)("hw:0,8")
Ravishankar Sarawadibd30aeb2013-04-01 11:02:18 -070080#define ADSP_UP_CHK_TRIES 5
81#define ADSP_UP_CHK_SLEEP 1*1000*1000
82
Mingming Yinbbd94ad2012-11-29 20:04:36 -080083namespace sys_close {
84 ssize_t lib_close(int fd) {
85 return close(fd);
86 }
87};
88
89namespace android_audio_legacy
90{
91
92ALSADevice::ALSADevice() {
93#ifdef USES_FLUENCE_INCALL
94 mDevSettingsFlag = TTY_OFF | DMIC_FLAG;
95#else
96 mDevSettingsFlag = TTY_OFF;
97#endif
Ravishankar Sarawadibd30aeb2013-04-01 11:02:18 -070098 mADSPState = ADSP_UP;
Mingming Yinbbd94ad2012-11-29 20:04:36 -080099 mBtscoSamplerate = 8000;
100 mCallMode = AUDIO_MODE_NORMAL;
101 mInChannels = 0;
Krishnankutty Kolathappilly58c98932013-03-18 23:45:04 -0700102 mIsFmEnabled = false;
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800103 char value[128], platform[128], baseband[128];
104
105 property_get("persist.audio.handset.mic",value,"0");
106 strlcpy(mMicType, value, sizeof(mMicType));
107 property_get("persist.audio.fluence.mode",value,"0");
108 if (!strcmp("broadside", value)) {
109 mFluenceMode = FLUENCE_MODE_BROADSIDE;
110 } else {
111 mFluenceMode = FLUENCE_MODE_ENDFIRE;
112 }
113 property_get("ro.board.platform", platform, "");
114 property_get("ro.baseband", baseband, "");
115 if (!strcmp("msm8960", platform) && !strcmp("sglte", baseband)) {
116 mIsSglte = true;
117 }
118 else {
119 mIsSglte = false;
120 }
121 strlcpy(mCurRxUCMDevice, "None", sizeof(mCurRxUCMDevice));
122 strlcpy(mCurTxUCMDevice, "None", sizeof(mCurTxUCMDevice));
123
124 mMixer = mixer_open("/dev/snd/controlC0");
125
126 mProxyParams.mExitRead = false;
Subhash Chandra Bose Naripeddy9c37bad2012-12-10 19:45:07 -0800127 mProxyParams.mPfdProxy[1].fd = -1;
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800128 resetProxyVariables();
129 mProxyParams.mCaptureBufferSize = AFE_PROXY_PERIOD_SIZE;
130 mProxyParams.mCaptureBuffer = NULL;
131 mProxyParams.mProxyState = proxy_params::EProxyClosed;
132 mProxyParams.mProxyPcmHandle = NULL;
133
Steve Kondike5066ed2013-04-06 19:23:58 +0000134#ifdef USE_A2220
135 mA2220Fd = -1;
136 mA2220Mode = A2220_PATH_INCALL_RECEIVER_NSOFF;
137#endif
138
Sam Mortimer67685072013-08-26 22:13:43 -0700139#ifdef SEPERATED_AUDIO_INPUT
140 mInputSource = AUDIO_SOURCE_DEFAULT;
141#endif
142
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800143 ALOGD("ALSA module opened");
144}
145
146//static int s_device_close(hw_device_t* device)
147ALSADevice::~ALSADevice()
148{
149 if (mMixer) mixer_close(mMixer);
150 if(mProxyParams.mCaptureBuffer != NULL) {
151 free(mProxyParams.mCaptureBuffer);
152 mProxyParams.mCaptureBuffer = NULL;
153 }
154 mProxyParams.mProxyState = proxy_params::EProxyClosed;
155
156}
157
Damir Didjusto10b6ce42013-02-04 12:43:26 -0800158static bool isPlatformFusion3() {
Daniel Hillenbrand2cb27912013-04-26 22:47:49 +0200159 char platform[128], baseband[128], baseband_arch[128];
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800160 property_get("ro.board.platform", platform, "");
161 property_get("ro.baseband", baseband, "");
Daniel Hillenbrand2cb27912013-04-26 22:47:49 +0200162 property_get("ro.baseband.arch", baseband_arch, "");
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -0800163 if (!strcmp("msm8960", platform) &&
Daniel Hillenbrand2cb27912013-04-26 22:47:49 +0200164 (!strcmp("mdm", baseband) || !strcmp("sglte2", baseband) ||
165 !strcmp("mdm", baseband_arch)))
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800166 return true;
167 else
168 return false;
169}
170
Steve Kondike5066ed2013-04-06 19:23:58 +0000171#ifdef USE_A2220
172int ALSADevice::setA2220Mode(int mode)
173{
174 Mutex::Autolock autoLock(mA2220Lock);
175 int rc = -1;
176
177 if (mA2220Mode != mode) {
178 if (mA2220Fd < 0) {
179 mA2220Fd = ::open("/dev/audience_a2220", O_RDWR);
180 if (!mA2220Fd) {
181 ALOGE("%s: unable to open a2220 device!", __func__);
182 return rc;
183 } else {
184 ALOGI("%s: device opened, fd=%d", __func__, mA2220Fd);
185 }
186 }
187
188 rc = ioctl(mA2220Fd, A2220_SET_CONFIG, mode);
189 if (rc < 0)
190 ALOGE("%s: ioctl failed, errno=%d", __func__, errno);
191 else {
192 mA2220Mode = mode;
193 ALOGD("%s: set mode=%d", __func__, mode);
194 }
195 }
196 return rc;
197}
198#endif
199
Damir Didjusto10b6ce42013-02-04 12:43:26 -0800200static bool shouldUseHandsetAnc(int flags, int inChannels)
201{
202 if (!isPlatformFusion3()) {
203 return false;
204 }
205 return (flags & ANC_FLAG) && (inChannels == 1);
206}
207
208static int adjustFlagsForCsd(int flags, const char *rxDevice)
209{
210 int adjustedFlags = flags;
211 if (0 != strcmp(rxDevice, SND_USE_CASE_DEV_ANC_HANDSET)) {
212 /* if not using Adaptive ANC, clear the ANC bit; this
213 is the only adaptive mode CSD Client cares about */
214 adjustedFlags &= ~(ANC_FLAG);
215 }
Steve Kondik32352f02013-05-31 16:27:31 -0700216
Damir Didjusto10b6ce42013-02-04 12:43:26 -0800217 ALOGD("%s: current Rx device: %s, flags: %x, adjustedFlags: %x",
218 __FUNCTION__, rxDevice, flags, adjustedFlags);
219 return adjustedFlags;
220}
221
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800222int ALSADevice::deviceName(alsa_handle_t *handle, unsigned flags, char **value)
223{
224 int ret = 0;
225 char ident[70];
226
227 if (flags & PCM_IN) {
228 strlcpy(ident, "CapturePCM/", sizeof(ident));
229 } else {
230 strlcpy(ident, "PlaybackPCM/", sizeof(ident));
231 }
232 strlcat(ident, handle->useCase, sizeof(ident));
233 ret = snd_use_case_get(handle->ucMgr, ident, (const char **)value);
234 ALOGD("Device value returned is %s", (*value));
235 return ret;
236}
237
238status_t ALSADevice::setHDMIChannelCount()
239{
240 status_t err = NO_ERROR;
241 int channel_count = 0;
242 const char *channel_cnt_str = NULL;
243 EDID_AUDIO_INFO info = { 0 };
244
Subhash Chandra Bose Naripeddy6000eb52013-01-05 18:02:44 -0800245#ifdef TARGET_8974
246 char hdmiEDIDData[MAX_SHORT_AUDIO_DESC_CNT+1];
247 if(!getEDIDData(hdmiEDIDData)) {
248 if (AudioUtil::getHDMIAudioSinkCaps(&info, hdmiEDIDData)) {
249 for (int i = 0; i < info.nAudioBlocks && i < MAX_EDID_BLOCKS; i++) {
250 if (info.AudioBlocksArray[i].nChannels > channel_count &&
251 info.AudioBlocksArray[i].nChannels <= MAX_HDMI_CHANNEL_CNT) {
252 channel_count = info.AudioBlocksArray[i].nChannels;
253 }
254 }
255 pcm_set_channel_map(NULL, mMixer, MAX_HDMI_CHANNEL_CNT, info.channelMap);
256 setChannelAlloc(info.channelAllocation);
257 }
258 }
259#else
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800260 if (AudioUtil::getHDMIAudioSinkCaps(&info)) {
261 for (int i = 0; i < info.nAudioBlocks && i < MAX_EDID_BLOCKS; i++) {
262 if (info.AudioBlocksArray[i].nChannels > channel_count &&
263 info.AudioBlocksArray[i].nChannels <= MAX_HDMI_CHANNEL_CNT) {
264 channel_count = info.AudioBlocksArray[i].nChannels;
265 }
266 }
267 }
Subhash Chandra Bose Naripeddy6000eb52013-01-05 18:02:44 -0800268#endif
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800269
270 switch (channel_count) {
Subhash Chandra Bose Naripeddy27c90302012-12-19 20:14:54 -0800271 case 8: channel_cnt_str = "Eight"; break;
272 case 7: channel_cnt_str = "Seven"; break;
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800273 case 6: channel_cnt_str = "Six"; break;
274 case 5: channel_cnt_str = "Five"; break;
275 case 4: channel_cnt_str = "Four"; break;
276 case 3: channel_cnt_str = "Three"; break;
277 default: channel_cnt_str = "Two"; break;
278 }
279 ALOGD("HDMI channel count: %s", channel_cnt_str);
280 setMixerControl("HDMI_RX Channels", channel_cnt_str);
281
282 return err;
283}
284
285status_t ALSADevice::setHardwareParams(alsa_handle_t *handle)
286{
287 struct snd_pcm_hw_params *params;
288 unsigned long bufferSize, reqBuffSize;
289 unsigned int periodTime, bufferTime;
290 unsigned int requestedRate = handle->sampleRate;
291 int status = 0;
292 int channels = handle->channels;
293 status_t err;
294 snd_pcm_format_t format = SNDRV_PCM_FORMAT_S16_LE;
295 struct snd_compr_caps compr_cap;
296 struct snd_compr_params compr_params;
297 uint32_t codec_id = 0;
298
299 ALOGD("handle->format: 0x%x", handle->format);
300 if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
301 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL)) ||
302 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED)) ||
303 (!strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED)) ||
304 (!strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_DL)) ||
305 (!strcmp(handle->useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_DL)) ||
306 (!strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_UL_DL)) ||
307 (!strcmp(handle->useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_UL_DL))) {
308 ALOGV("Tunnel mode detected...");
309 //get the list of codec supported by hardware
310 if (ioctl(handle->handle->fd, SNDRV_COMPRESS_GET_CAPS, &compr_cap)) {
311 ALOGE("SNDRV_COMPRESS_GET_CAPS, failed Error no %d \n", errno);
312 err = -errno;
313 return err;
314 }
315 if( handle->format == AUDIO_FORMAT_AAC ) {
316 codec_id = get_compressed_format("AAC");
317 ALOGV("### AAC CODEC codec_id %d",codec_id);
318 }
319 else if (handle->format == AUDIO_FORMAT_AMR_WB) {
320 codec_id = get_compressed_format("AMR_WB");
321 if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED)) ||
322 (!strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED)) ||
323 (!strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_UL_DL)) ||
324 (!strcmp(handle->useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_UL_DL)) ||
325 (!strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_DL)) ||
326 (!strcmp(handle->useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_DL))) {
327 compr_params.codec.options.generic.reserved[0] = 8; /*band mode - 23.85 kbps*/
328 compr_params.codec.options.generic.reserved[1] = 0; /*dtx mode - disable*/
329 }
330 ALOGV("### AMR WB CODEC codec_id %d",codec_id);
331 }
332#ifdef QCOM_AUDIO_FORMAT_ENABLED
333 else if (handle->format == AUDIO_FORMAT_AMR_WB_PLUS) {
334 codec_id = get_compressed_format("AMR_WB_PLUS");
335 ALOGV("### AMR WB+ CODEC codec_id %d",codec_id);
336 }
337#endif
338 else if (handle->format == AUDIO_FORMAT_MP3) {
339 codec_id = get_compressed_format("MP3");
340 ALOGV("### MP3 CODEC codec_id %d",codec_id);
341 }
342 else {
343 return UNKNOWN_ERROR;
344 }
345 //find if codec_id matches with any of h/w supported codecs.
346 for (int i = 0; i < compr_cap.num_codecs; i++) {
347 if (compr_cap.codecs[i] == codec_id) {
348 ALOGV("### MatchedFcodec_id %u", codec_id);
349 compr_params.codec.id = codec_id;
350 break;
351 }
352 }
353 if (!compr_params.codec.id) {
354 ALOGE("### Codec %u not supported",codec_id);
355 return UNKNOWN_ERROR;
356 }
357
358 if (ioctl(handle->handle->fd, SNDRV_COMPRESS_SET_PARAMS, &compr_params)) {
359 ALOGE("SNDRV_COMPRESS_SET_PARAMS,failed Error no %d \n", errno);
360 err = -errno;
361 return err;
362 }
363 }
364
365 params = (snd_pcm_hw_params*) calloc(1, sizeof(struct snd_pcm_hw_params));
366 if (!params) {
367 ALOGE("Failed to allocate ALSA hardware parameters!");
368 return NO_INIT;
369 }
370
371 reqBuffSize = handle->bufferSize;
372 ALOGD("setHardwareParams: reqBuffSize %d channels %d sampleRate %d",
373 (int) reqBuffSize, handle->channels, handle->sampleRate);
374
375#ifdef QCOM_SSR_ENABLED
376 if (channels == 6) {
377 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
378 || !strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED, strlen(SND_USE_CASE_VERB_HIFI_REC_COMPRESSED))
379 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))
380 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED))) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800381 channels = 4;
Mingming Yin783a7b92013-01-06 17:04:08 -0800382 reqBuffSize = DEFAULT_IN_BUFFER_SIZE*4;
383 ALOGV("HWParams: Use 4 channels in kernel for 5.1(%s) recording reqBuffSize:%d", handle->useCase,reqBuffSize);
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800384 }
385 }
386#endif
387
388 param_init(params);
389 if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
390 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
391 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
392 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
393 param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS,
394 SNDRV_PCM_ACCESS_MMAP_INTERLEAVED);
395 }
396 else {
397 param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS,
398 SNDRV_PCM_ACCESS_RW_INTERLEAVED);
399 }
400
401 if (handle->format != SNDRV_PCM_FORMAT_S16_LE) {
402 if (handle->format == AUDIO_FORMAT_AMR_NB
403 || handle->format == AUDIO_FORMAT_AMR_WB
404#ifdef QCOM_AUDIO_FORMAT_ENABLED
405 || handle->format == AUDIO_FORMAT_EVRC
406 || handle->format == AUDIO_FORMAT_EVRCB
407 || handle->format == AUDIO_FORMAT_EVRCWB
408#endif
409 ) {
410 if ((strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) &&
411 (strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL)) &&
412 (strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED)) &&
413 (strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_UL_DL)) &&
414 (strcmp(handle->useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_UL_DL)) &&
415 (strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_DL)) &&
416 (strcmp(handle->useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_DL)) &&
417 (strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED))) {
418 format = SNDRV_PCM_FORMAT_SPECIAL;
419 ALOGW("setting format to SNDRV_PCM_FORMAT_SPECIAL");
420 }
421 }
422 }
423 //TODO: Add format setting for tunnel mode using the usecase.
424 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
425 format);
426 param_set_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT,
427 SNDRV_PCM_SUBFORMAT_STD);
Daniel Hillenbrand671cd2c2013-03-30 18:42:36 +0100428#ifdef SET_MIN_PERIOD_BYTES
429 param_set_min(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, reqBuffSize);
430#else
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800431 param_set_int(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, reqBuffSize);
Daniel Hillenbrand671cd2c2013-03-30 18:42:36 +0100432#endif
Krishnankutty Kolathappillya2787ae2013-03-28 17:49:22 -0700433 //Setting number of periods to 4. If the system is loaded and record
434 // obtain buffer is seen increase PCM_RECORD_PERIOD_COUNT to a value between 4-16.
435 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC,
436 strlen(SND_USE_CASE_VERB_HIFI_REC)) ||
437 !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC,
438 strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
439 param_set_int(params, SNDRV_PCM_HW_PARAM_PERIODS, PCM_RECORD_PERIOD_COUNT);
440 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800441 param_set_int(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 16);
442 param_set_int(params, SNDRV_PCM_HW_PARAM_FRAME_BITS,
443 channels * 16);
444 param_set_int(params, SNDRV_PCM_HW_PARAM_CHANNELS,
445 channels);
446 param_set_int(params, SNDRV_PCM_HW_PARAM_RATE, handle->sampleRate);
447 param_set_hw_refine(handle->handle, params);
448
449 if (param_set_hw_params(handle->handle, params)) {
450 ALOGE("cannot set hw params");
Mingming Yin4d33ffd2012-12-10 00:11:29 -0800451 if(params) {
452 free(params);
453 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800454 return NO_INIT;
455 }
456 param_dump(params);
457
458 handle->handle->buffer_size = pcm_buffer_size(params);
459 handle->handle->period_size = pcm_period_size(params);
460 handle->handle->period_cnt = handle->handle->buffer_size/handle->handle->period_size;
461 ALOGD("setHardwareParams: buffer_size %d, period_size %d, period_cnt %d",
462 handle->handle->buffer_size, handle->handle->period_size,
463 handle->handle->period_cnt);
464 handle->handle->rate = handle->sampleRate;
465 handle->handle->channels = handle->channels;
466 handle->periodSize = handle->handle->period_size;
467 if (strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC) &&
468 strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED) &&
469 strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC) &&
470 strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED) &&
471 (6 != handle->channels)) {
472 //Do not update buffersize for 5.1 recording
473 if (handle->format == AUDIO_FORMAT_AMR_WB &&
474 format != SNDRV_PCM_FORMAT_SPECIAL) {
475 ALOGV("### format AMWB, set bufsize to 61");
476 handle->bufferSize = 61;
477 } else {
478 handle->bufferSize = handle->handle->period_size;
479 }
480 }
481
482 return NO_ERROR;
483}
484
485status_t ALSADevice::setSoftwareParams(alsa_handle_t *handle)
486{
487 struct snd_pcm_sw_params* params;
488 struct pcm* pcm = handle->handle;
489
490 unsigned long periodSize = pcm->period_size;
491 int channels = handle->channels;
492
493 params = (snd_pcm_sw_params*) calloc(1, sizeof(struct snd_pcm_sw_params));
494 if (!params) {
495 LOG_ALWAYS_FATAL("Failed to allocate ALSA software parameters!");
496 return NO_INIT;
497 }
498
499#ifdef QCOM_SSR_ENABLED
500 if (channels == 6) {
501 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
502 || !strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED, strlen(SND_USE_CASE_VERB_HIFI_REC_COMPRESSED))
503 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))
504 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED))) {
505 ALOGV("SWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase);
506 channels = 4;
507 }
508 }
509#endif
510
511 // Get the current software parameters
512 params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
513 params->period_step = 1;
514 if(((!strcmp(handle->useCase,SND_USE_CASE_MOD_PLAY_VOIP)) ||
515 (!strcmp(handle->useCase,SND_USE_CASE_VERB_IP_VOICECALL)))){
516 ALOGV("setparam: start & stop threshold for Voip ");
517 params->avail_min = handle->channels - 1 ? periodSize/4 : periodSize/2;
518 params->start_threshold = periodSize/2;
519 params->stop_threshold = INT_MAX;
520 } else {
521 params->avail_min = periodSize/(channels * 2);
522 params->start_threshold = periodSize/(channels * 2);
523 params->stop_threshold = INT_MAX;
524 }
525 params->silence_threshold = 0;
526 params->silence_size = 0;
527
528 if (param_set_sw_params(handle->handle, params)) {
529 ALOGE("cannot set sw params");
Mingming Yin4d33ffd2012-12-10 00:11:29 -0800530 if (params) {
531 free(params);
532 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800533 return NO_INIT;
534 }
535 return NO_ERROR;
536}
537
538void ALSADevice::switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode)
539{
540 const char **mods_list;
541 use_case_t useCaseNode;
542 unsigned usecase_type = 0;
543 bool inCallDevSwitch = false;
544 char *rxDevice, *txDevice, ident[70], *use_case = NULL;
545 int err = 0, index, mods_size;
546 int rx_dev_id, tx_dev_id;
547 ALOGV("%s: device %#x mode:%d", __FUNCTION__, devices, mode);
548
549 if ((mode == AUDIO_MODE_IN_CALL) || (mode == AUDIO_MODE_IN_COMMUNICATION)) {
550 if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
551 (devices & AudioSystem::DEVICE_IN_WIRED_HEADSET)) {
552 devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADSET |
553 AudioSystem::DEVICE_IN_WIRED_HEADSET);
554 } else if (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
555 devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADPHONE |
556 AudioSystem::DEVICE_IN_BUILTIN_MIC);
557 } else if ((devices & AudioSystem::DEVICE_OUT_EARPIECE) ||
Araemoac921402013-04-06 19:20:45 +0000558 (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) ||
559 (devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)) {
Sidipotu Ashok14b98b02013-05-22 20:08:51 +0530560 if ((mode == AudioSystem::MODE_IN_COMMUNICATION) &&
561 (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC)) {
562 if (!strncmp(mCurRxUCMDevice, SND_USE_CASE_DEV_SPEAKER,
563 strlen(SND_USE_CASE_DEV_SPEAKER))) {
564 devices = devices | (AudioSystem::DEVICE_IN_BUILTIN_MIC |
565 AudioSystem::DEVICE_OUT_SPEAKER);
566 }
567 else if (!strncmp(mCurRxUCMDevice, SND_USE_CASE_DEV_HDMI,
568 strlen(SND_USE_CASE_DEV_HDMI))) {
569 devices = devices | (AudioSystem::DEVICE_OUT_AUX_DIGITAL |
570 AudioSystem::DEVICE_IN_AUX_DIGITAL);
571 }
572 else {
573 devices = devices | (AudioSystem::DEVICE_IN_BUILTIN_MIC |
574 AudioSystem::DEVICE_OUT_EARPIECE);
575 }
Sidipotu Ashokf61e98d2013-02-22 21:07:26 +0530576 }
Sidipotu Ashok14b98b02013-05-22 20:08:51 +0530577 else {
Sidipotu Ashokf61e98d2013-02-22 21:07:26 +0530578 devices = devices | (AudioSystem::DEVICE_IN_BUILTIN_MIC |
Sidipotu Ashok14b98b02013-05-22 20:08:51 +0530579 AudioSystem::DEVICE_OUT_EARPIECE);
Sidipotu Ashokf61e98d2013-02-22 21:07:26 +0530580 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800581 } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) {
582 devices = devices | (AudioSystem::DEVICE_IN_BUILTIN_MIC |
583 AudioSystem::DEVICE_OUT_SPEAKER);
584 } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) ||
585 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
586 (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
587 devices = devices | (AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET |
588 AudioSystem::DEVICE_OUT_BLUETOOTH_SCO);
589#ifdef QCOM_ANC_HEADSET_ENABLED
590 } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
591 (devices & AudioSystem::DEVICE_IN_ANC_HEADSET)) {
592 devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADSET |
593 AudioSystem::DEVICE_IN_ANC_HEADSET);
594 } else if (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE) {
595 devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADPHONE |
596 AudioSystem::DEVICE_IN_BUILTIN_MIC);
597#endif
598#ifdef QCOM_USBAUDIO_ENABLED
599 } else if ((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET ) ||
600 (devices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET )) {
601 devices = devices | (AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET |
602 AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET);
603#endif
Srikanth Kattadd170562013-04-24 16:21:22 +0530604 } else if ((devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) ||
605 (devices & AudioSystem::DEVICE_IN_AUX_DIGITAL)) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800606 devices = devices | (AudioSystem::DEVICE_OUT_AUX_DIGITAL |
607 AudioSystem::DEVICE_IN_AUX_DIGITAL);
608#ifdef QCOM_PROXY_DEVICE_ENABLED
609 } else if ((devices & AudioSystem::DEVICE_OUT_PROXY) ||
610 (devices & AudioSystem::DEVICE_IN_PROXY)) {
611 devices = devices | (AudioSystem::DEVICE_OUT_PROXY |
612 AudioSystem::DEVICE_IN_PROXY);
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800613#endif
Mingming Yin4d33ffd2012-12-10 00:11:29 -0800614 } else if (devices & AUDIO_DEVICE_OUT_ALL_USB) {
615 devices = devices | AudioSystem::DEVICE_IN_BUILTIN_MIC;
616 } else if (devices & AudioSystem::DEVICE_OUT_ALL_A2DP) {
617 ALOGE("SwitchDevice:: Invalid A2DP Combination for mode %d", mode);
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800618 }
619 }
620#ifdef QCOM_SSR_ENABLED
621 if ((devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) && ( 6 == handle->channels)) {
622 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
623 || !strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED, strlen(SND_USE_CASE_VERB_HIFI_REC_COMPRESSED))
624 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))
625 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED))) {
626 ALOGV(" switchDevice , use ssr devices for channels:%d usecase:%s",handle->channels,handle->useCase);
627 setFlags(SSRQMIC_FLAG);
628 }
629 }
630#endif
631
632 rxDevice = getUCMDevice(devices & AudioSystem::DEVICE_OUT_ALL, 0, NULL);
633 ALOGV("%s: rxDevice %s devices:0x%x", __FUNCTION__, rxDevice,devices);
634 txDevice = getUCMDevice(devices & AudioSystem::DEVICE_IN_ALL, 1, rxDevice);
635 ALOGV("%s: txDevice:%s devices:0x%x", __FUNCTION__, txDevice,devices);
636
637 if ((rxDevice != NULL) && (txDevice != NULL)) {
638 if (((strncmp(rxDevice, mCurRxUCMDevice, MAX_STR_LEN)) ||
639 (strncmp(txDevice, mCurTxUCMDevice, MAX_STR_LEN))) &&
640 ((mode == AUDIO_MODE_IN_CALL) ||
641 (mode == AUDIO_MODE_IN_COMMUNICATION)))
642 inCallDevSwitch = true;
643 }
644
645#ifdef QCOM_CSDCLIENT_ENABLED
Damir Didjusto10b6ce42013-02-04 12:43:26 -0800646 if (isPlatformFusion3() && (inCallDevSwitch == true)) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800647 if (csd_disable_device == NULL) {
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -0800648 ALOGE("csd_client_disable_device is NULL");
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800649 } else {
Steve Kondik32352f02013-05-31 16:27:31 -0700650#ifdef USE_ES325_2MIC
651 setMixerControl("ES325 2Mic Enable", 0, 0);
652#endif
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800653 err = csd_disable_device();
654 if (err < 0)
655 {
656 ALOGE("csd_client_disable_device, failed, error %d", err);
657 }
658 }
659 }
660#endif
661
662 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&use_case);
663 mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
664 if (rxDevice != NULL) {
665 if ((strncmp(mCurRxUCMDevice, "None", 4)) &&
Ravishankar Sarawadibd30aeb2013-04-01 11:02:18 -0700666 ((mADSPState == ADSP_UP_AFTER_SSR) ||
667 (strncmp(rxDevice, mCurRxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800668 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
669 strlen(SND_USE_CASE_VERB_INACTIVE)))) {
670 usecase_type = getUseCaseType(use_case);
671 if (usecase_type & USECASE_TYPE_RX) {
672 ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
673 strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
674 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
675 mUseCaseList.push_front(useCaseNode);
676 }
677 }
678 if (mods_size) {
679 for(index = 0; index < mods_size; index++) {
680 usecase_type = getUseCaseType(mods_list[index]);
681 if (usecase_type & USECASE_TYPE_RX) {
682 ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
683 strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
684 snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
685 mUseCaseList.push_back(useCaseNode);
686 }
687 }
688 }
689 snd_use_case_set(handle->ucMgr, "_disdev", mCurRxUCMDevice);
690 }
691 }
692 if (txDevice != NULL) {
693 if ((strncmp(mCurTxUCMDevice, "None", 4)) &&
Ravishankar Sarawadibd30aeb2013-04-01 11:02:18 -0700694 ((mADSPState == ADSP_UP_AFTER_SSR) ||
695 (strncmp(txDevice, mCurTxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800696 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
697 strlen(SND_USE_CASE_VERB_INACTIVE)))) {
698 usecase_type = getUseCaseType(use_case);
699 if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
700 ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
701 strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
702 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
703 mUseCaseList.push_front(useCaseNode);
704 }
705 }
706 if (mods_size) {
707 for(index = 0; index < mods_size; index++) {
708 usecase_type = getUseCaseType(mods_list[index]);
709 if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
710 ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
711 strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
712 snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
713 mUseCaseList.push_back(useCaseNode);
714 }
715 }
716 }
717 snd_use_case_set(handle->ucMgr, "_disdev", mCurTxUCMDevice);
718 }
719 }
720
721 ALOGV("%s,rxDev:%s, txDev:%s, curRxDev:%s, curTxDev:%s\n", __FUNCTION__, rxDevice, txDevice, mCurRxUCMDevice, mCurTxUCMDevice);
722
723 if (rxDevice != NULL) {
724 snd_use_case_set(handle->ucMgr, "_enadev", rxDevice);
725 strlcpy(mCurRxUCMDevice, rxDevice, sizeof(mCurRxUCMDevice));
726 }
727 if (txDevice != NULL) {
728 snd_use_case_set(handle->ucMgr, "_enadev", txDevice);
729 strlcpy(mCurTxUCMDevice, txDevice, sizeof(mCurTxUCMDevice));
730 }
Steve Kondik775f9d72013-06-01 02:14:02 -0700731
732#if defined(QCOM_CSDCLIENT_ENABLED) && defined (NEW_CSDCLIENT)
Vidyakumar Athotadf9175f2013-03-25 13:58:05 -0700733 if (isPlatformFusion3() && (inCallDevSwitch == true)) {
734
735 /* Get tx acdb id */
736 memset(&ident,0,sizeof(ident));
737 strlcpy(ident, "ACDBID/", sizeof(ident));
738 strlcat(ident, mCurTxUCMDevice, sizeof(ident));
739 tx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
740
741 /* Get rx acdb id */
742 memset(&ident,0,sizeof(ident));
743 strlcpy(ident, "ACDBID/", sizeof(ident));
744 strlcat(ident, mCurRxUCMDevice, sizeof(ident));
745 rx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
746
747 if (rx_dev_id == DEVICE_SPEAKER_RX_ACDB_ID && tx_dev_id == DEVICE_HANDSET_TX_ACDB_ID) {
748 tx_dev_id = DEVICE_SPEAKER_TX_ACDB_ID;
749 }
750
751 /* Parallelize codec configuration on APQ with CSD voice call
752 * sequence on MDM. This will reduce in call device switch delay
753 */
754 if (csd_enable_device_config == NULL) {
755 ALOGE("csd_enable_device_config is NULL");
756 } else {
757 err = csd_enable_device_config(rx_dev_id, tx_dev_id);
758 if (err < 0) {
759 ALOGE("csd_enable_device_config failed, error %d", err);
760 }
761 }
762 }
763#endif
Nitesh Bhardwaje77335d2013-09-11 12:35:46 -0700764
765ALOGD("switchDevice: mCurTxUCMDevivce %s mCurRxDevDevice %s", mCurTxUCMDevice, mCurRxUCMDevice);
766 /* Enable the EC ref device before enabling the Rx/Tx devices */
767 /* Enabling the Rx/Tx devices is being happened while enabling _verb/_enamod usecases */
Mingming Yinf158b282013-01-08 15:09:00 -0800768#ifdef QCOM_ACDB_ENABLED
769 if (((devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) || (devices & AudioSystem::DEVICE_IN_BACK_MIC))
770 && (mInChannels == 1)) {
771 ALOGD("switchDevice:use device %x for channels:%d usecase:%s",devices,handle->channels,handle->useCase);
772 int ec_acdbid;
773 char *ec_dev;
774 char *ec_rx_dev;
775 memset(&ident,0,sizeof(ident));
776 strlcpy(ident, "ACDBID/", sizeof(ident));
777 strlcat(ident, mCurTxUCMDevice, sizeof(ident));
778 tx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
779 if (acdb_loader_get_ecrx_device) {
780 ec_acdbid = acdb_loader_get_ecrx_device(tx_dev_id);
781 ec_dev = getUCMDeviceFromAcdbId(ec_acdbid);
782 if (ec_dev) {
783 memset(&ident,0,sizeof(ident));
784 strlcpy(ident, "EC_REF_RXMixerCTL/", sizeof(ident));
785 strlcat(ident, ec_dev, sizeof(ident));
786 snd_use_case_get(handle->ucMgr, ident, (const char **)&ec_rx_dev);
787 ALOGD("SwitchDevice: ec_ref_rx_acdbid:%d ec_dev:%s ec_rx_dev:%s", ec_acdbid, ec_dev, ec_rx_dev);
788 if (ec_rx_dev) {
789 setEcrxDevice(ec_rx_dev);
790 free(ec_rx_dev);
791 }
792 }
793 } else {
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -0800794 ALOGE("acdb_loader_get_ecrx_device is NULL");
Mingming Yinf158b282013-01-08 15:09:00 -0800795 }
796 }
797#endif
Nitesh Bhardwaje77335d2013-09-11 12:35:46 -0700798 for(ALSAUseCaseList::iterator it = mUseCaseList.begin(); it != mUseCaseList.end(); ++it) {
799 ALOGD("Route use case %s\n", it->useCase);
800 if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
801 strlen(SND_USE_CASE_VERB_INACTIVE))) && (!strncmp(use_case, it->useCase, MAX_UC_LEN))) {
802 snd_use_case_set(handle->ucMgr, "_verb", it->useCase);
803 } else {
804 snd_use_case_set(handle->ucMgr, "_enamod", it->useCase);
805 }
806 }
807 if (!mUseCaseList.empty())
808 mUseCaseList.clear();
809 if (use_case != NULL) {
810 free(use_case);
811 use_case = NULL;
812 }
813#ifdef QCOM_FM_ENABLED
814 if (rxDevice != NULL) {
815 setFmVolume(mFmVolume, handle);
816 }
817#endif
818
Vidyakumar Athotadf9175f2013-03-25 13:58:05 -0700819#ifdef QCOM_CSDCLIENT_ENABLED
Damir Didjusto10b6ce42013-02-04 12:43:26 -0800820 if (isPlatformFusion3() && (inCallDevSwitch == true)) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800821
Steve Kondik775f9d72013-06-01 02:14:02 -0700822#ifndef NEW_CSDCLIENT
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800823 /* get tx acdb id */
824 memset(&ident,0,sizeof(ident));
825 strlcpy(ident, "ACDBID/", sizeof(ident));
826 strlcat(ident, mCurTxUCMDevice, sizeof(ident));
827 tx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
828
829 /* get rx acdb id */
830 memset(&ident,0,sizeof(ident));
831 strlcpy(ident, "ACDBID/", sizeof(ident));
832 strlcat(ident, mCurRxUCMDevice, sizeof(ident));
833 rx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
Steve Kondik775f9d72013-06-01 02:14:02 -0700834#endif
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800835
ehgrace.kimd347e372013-06-03 11:47:54 +0200836 if (((rx_dev_id == DEVICE_SPEAKER_MONO_RX_ACDB_ID ) || (rx_dev_id == DEVICE_SPEAKER_STEREO_RX_ACDB_ID ))
837 && tx_dev_id == DEVICE_HANDSET_TX_ACDB_ID) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800838 tx_dev_id = DEVICE_SPEAKER_TX_ACDB_ID;
839 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800840 ALOGV("rx_dev_id=%d, tx_dev_id=%d\n", rx_dev_id, tx_dev_id);
Vidyakumar Athotadf9175f2013-03-25 13:58:05 -0700841
Steve Kondik775f9d72013-06-01 02:14:02 -0700842#ifndef NEW_CSDCLIENT
Vidyakumar Athotadf9175f2013-03-25 13:58:05 -0700843 if (csd_enable_device == NULL) {
844 ALOGE("csd_client_enable_device is NULL");
845 } else {
Steve Kondik775f9d72013-06-01 02:14:02 -0700846 int tmp_tx_id = tx_dev_id;
Steve Kondik102705c2013-06-18 19:24:30 -0700847 int tmp_rx_id = rx_dev_id;
Steve Kondik32352f02013-05-31 16:27:31 -0700848
849#ifdef USE_ES325_2MIC
Steve Kondike912e3e2013-06-26 12:48:22 -0700850 if (!strcmp(rxDevice, SND_USE_CASE_DEV_VOC_EARPIECE) ||
851 !strcmp(rxDevice, SND_USE_CASE_DEV_VOC_EARPIECE_XGAIN) ||
852 !strcmp(rxDevice, SND_USE_CASE_DEV_VOC_SPEAKER)) {
853 if (tx_dev_id == 4) {
854 tmp_tx_id = 34;
855 setMixerControl("VEQ Enable", 1, 0);
856 setMixerControl("ES325 2Mic Enable", 1, 0);
857 } else {
858 setMixerControl("ES325 2Mic Enable", 0, 0);
859 }
Steve Kondik775f9d72013-06-01 02:14:02 -0700860 }
Steve Kondik32352f02013-05-31 16:27:31 -0700861#endif
tbalden75e2a912013-06-01 21:10:12 +0200862#ifdef HTC_CSDCLIENT
Steve Kondik102705c2013-06-18 19:24:30 -0700863 if (tx_dev_id == DEVICE_BT_SCO_TX_ACDB_ID)
864 {
865 tmp_tx_id = 1027;
866 }
867 if (rx_dev_id == DEVICE_BT_SCO_RX_ACDB_ID)
868 {
869 tmp_rx_id = 1127;
870 }
tbalden75e2a912013-06-01 21:10:12 +0200871#endif
Vidyakumar Athotadf9175f2013-03-25 13:58:05 -0700872 int adjustedFlags = adjustFlagsForCsd(mDevSettingsFlag,
873 mCurRxUCMDevice);
Steve Kondik102705c2013-06-18 19:24:30 -0700874 err = csd_enable_device(tmp_rx_id, tmp_tx_id, adjustedFlags);
Vidyakumar Athotadf9175f2013-03-25 13:58:05 -0700875 if (err < 0)
876 {
Steve Kondik102705c2013-06-18 19:24:30 -0700877 ALOGE("csd_client_disable_device failed, error %d", err);
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800878 }
879 }
Vidyakumar Athotadf9175f2013-03-25 13:58:05 -0700880#endif
Arne Coucheron41a3f3f2013-07-20 05:39:06 +0200881 }
Steve Kondik775f9d72013-06-01 02:14:02 -0700882#endif
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800883
Steve Kondike5066ed2013-04-06 19:23:58 +0000884#ifdef USE_A2220
885 ALOGI("a2220: txDevice=%s rxDevice=%s", txDevice, rxDevice);
886 if (rxDevice != NULL && txDevice != NULL &&
887 (!strcmp(txDevice, SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE) ||
888 !strcmp(txDevice, SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE)) &&
889 (!strcmp(rxDevice, SND_USE_CASE_DEV_VOC_EARPIECE) ||
890 !strcmp(rxDevice, SND_USE_CASE_DEV_VOC_EARPIECE_XGAIN))) {
891 setA2220Mode(A2220_PATH_INCALL_RECEIVER_NSON);
892 } else {
893 setA2220Mode(A2220_PATH_INCALL_RECEIVER_NSOFF);
894 }
895#endif
896
Daniel Hillenbrandc757e342013-05-23 06:40:42 +0200897#ifdef USES_AUDIO_AMPLIFIER
898 amplifier_set_devices(devices);
899#endif
900
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800901 if (rxDevice != NULL) {
902 free(rxDevice);
903 rxDevice = NULL;
904 }
905 if (txDevice != NULL) {
906 free(txDevice);
907 txDevice = NULL;
908 }
909}
910
911// ----------------------------------------------------------------------------
912/*
913status_t ALSADevice::init(alsa_device_t *module, ALSAHandleList &list)
914{
915 ALOGD("s_init: Initializing devices for ALSA module");
916
917 list.clear();
918
919 return NO_ERROR;
920}
921*/
922status_t ALSADevice::open(alsa_handle_t *handle)
923{
924 char *devName = NULL;
Ravishankar Sarawadibd30aeb2013-04-01 11:02:18 -0700925 unsigned flags = 0, maxTries = ADSP_UP_CHK_TRIES;
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800926 int err = NO_ERROR;
927
Subhash Chandra Bose Naripeddy8ad6c3a2013-03-20 15:35:54 -0700928 if(mCurDevice & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800929 err = setHDMIChannelCount();
930 if(err != OK) {
931 ALOGE("setHDMIChannelCount err = %d", err);
932 return err;
933 }
934 }
Ravishankar Sarawadibd30aeb2013-04-01 11:02:18 -0700935
936 // This fix is required to avoid calling device open when ADSP SSR
937 // is not complete.
938 // Fix me: USB/proxy/a2dp
939
940 ALOGV("mADSPState: %d", mADSPState);
941 while(mADSPState == ADSP_DOWN)
942 {
943 if(maxTries--)
944 {
945 ALOGD("ADSP is not UP! Sleep for 1 sec, tries: %d.", maxTries);
946 usleep(ADSP_UP_CHK_SLEEP);
947 }
948 else
949 {
950 ALOGE("Error opening device! ADSP is not UP!");
951 return NO_INIT;
952 }
953 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800954 close(handle);
955
956 ALOGD("open: handle %p, format 0x%x", handle, handle->format);
957
958 // ASoC multicomponent requires a valid path (frontend/backend) for
959 // the device to be opened
960
961 // The PCM stream is opened in blocking mode, per ALSA defaults. The
962 // AudioFlinger seems to assume blocking mode too, so asynchronous mode
963 // should not be used.
964 if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
965 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
966 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
967 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
968 ALOGV("LPA/tunnel use case");
969 flags |= PCM_MMAP;
970 flags |= DEBUG_ON;
971 } else if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI)) ||
972 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI2)) ||
973 (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) ||
974 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) ||
975 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC2)) ||
976 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC))) {
977 ALOGV("Music case");
978 flags = PCM_OUT;
979 } else {
980 flags = PCM_IN;
981 }
982
983 if (handle->channels == 1) {
984 flags |= PCM_MONO;
985 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800986 else if (handle->channels == 4 ) {
987 flags |= PCM_QUAD;
988 } else if (handle->channels == 6 ) {
Subhash Chandra Bose Naripeddy27c90302012-12-19 20:14:54 -0800989#ifdef QCOM_SSR_ENABLED
Mingming Yin783a7b92013-01-06 17:04:08 -0800990 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
991 || !strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED, strlen(SND_USE_CASE_VERB_HIFI_REC_COMPRESSED))
992 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))
993 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED))) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800994 flags |= PCM_QUAD;
Mingming Yin783a7b92013-01-06 17:04:08 -0800995 } else
996#endif
997 {
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800998 flags |= PCM_5POINT1;
999 }
1000 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001001 else {
1002 flags |= PCM_STEREO;
1003 }
1004
1005 if (deviceName(handle, flags, &devName) < 0) {
1006 ALOGE("Failed to get pcm device node: %s", devName);
1007 return NO_INIT;
1008 }
1009 if (devName != NULL) {
1010 ALOGV("flags %x, devName %s",flags,devName);
1011 handle->handle = pcm_open(flags, (char*)devName);
1012 } else {
1013 ALOGE("Failed to get pcm device node");
1014 return NO_INIT;
1015 }
1016 ALOGV("pcm_open returned fd %d", handle->handle->fd);
1017
1018 if (!handle->handle || (handle->handle->fd < 0)) {
1019 ALOGE("open: Failed to initialize ALSA device '%s'", devName);
1020 if (devName) {
1021 free(devName);
1022 devName = NULL;
1023 }
1024 return NO_INIT;
1025 }
1026
1027 handle->handle->flags = flags;
1028 err = setHardwareParams(handle);
1029
1030 if (err == NO_ERROR) {
1031 err = setSoftwareParams(handle);
1032 }
1033
1034 if(err != NO_ERROR) {
1035 ALOGE("Set HW/SW params failed: Closing the pcm stream");
1036 standby(handle);
1037 free(devName);
1038 devName = NULL;
1039 return err;
1040 }
1041
1042 if (devName) {
1043 free(devName);
1044 devName = NULL;
1045 }
Subhash Chandra Bose Naripeddy6000eb52013-01-05 18:02:44 -08001046
1047#ifdef TARGET_8974
1048 if(handle->channels > 2)
1049 setChannelMap(handle, MAX_HDMI_CHANNEL_CNT);
1050#endif
1051
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001052 return NO_ERROR;
1053}
1054
1055status_t ALSADevice::startVoipCall(alsa_handle_t *handle)
1056{
1057
1058 char* devName = NULL;
1059 unsigned flags = 0;
1060 int err = NO_ERROR;
1061 uint8_t voc_pkt[VOIP_BUFFER_MAX_SIZE];
1062
1063 close(handle);
1064 flags = PCM_OUT;
1065 flags |= PCM_MONO;
1066 ALOGV("startVoipCall handle %p", handle);
1067
1068 if (deviceName(handle, flags, &devName) < 0) {
1069 ALOGE("Failed to get pcm device node");
1070 return NO_INIT;
1071 }
1072
1073 if (devName != NULL) {
1074 handle->handle = pcm_open(flags, (char*)devName);
1075 } else {
1076 ALOGE("Failed to get pcm device node");
1077 return NO_INIT;
1078 }
1079
1080 if (!handle->handle || (handle->handle->fd < 0)) {
1081 if (devName) {
1082 free(devName);
1083 devName = NULL;
1084 }
1085 ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
1086 return NO_INIT;
1087 }
1088
1089 if (!pcm_ready(handle->handle)) {
1090 ALOGE(" pcm ready failed");
1091 }
1092
1093 handle->handle->flags = flags;
1094 err = setHardwareParams(handle);
1095
1096 if (err == NO_ERROR) {
1097 err = setSoftwareParams(handle);
1098 }
1099
1100 err = pcm_prepare(handle->handle);
1101 if(err != NO_ERROR) {
1102 ALOGE("startVoipCall: pcm_prepare failed");
1103 }
1104
1105 /* first write required start dsp */
1106 memset(&voc_pkt,0,sizeof(voc_pkt));
1107 pcm_write(handle->handle,&voc_pkt,handle->handle->period_size);
1108 handle->rxHandle = handle->handle;
1109 if (devName) {
1110 free(devName);
1111 devName = NULL;
1112 }
1113 ALOGV("s_open: DEVICE_IN_COMMUNICATION ");
1114 flags = PCM_IN;
1115 flags |= PCM_MONO;
1116 handle->handle = 0;
1117
1118 if (deviceName(handle, flags, &devName) < 0) {
1119 ALOGE("Failed to get pcm device node");
1120 return NO_INIT;
1121 }
1122 if (devName != NULL) {
1123 handle->handle = pcm_open(flags, (char*)devName);
1124 } else {
1125 ALOGE("Failed to get pcm device node");
1126 return NO_INIT;
1127 }
1128
1129 if (!handle->handle) {
1130 if (devName) {
1131 free(devName);
1132 devName = NULL;
1133 }
1134 ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
1135 return NO_INIT;
1136 }
1137
1138 if (!pcm_ready(handle->handle)) {
1139 ALOGE(" pcm ready in failed");
1140 }
1141
1142 handle->handle->flags = flags;
1143
1144 err = setHardwareParams(handle);
1145
1146 if (err == NO_ERROR) {
1147 err = setSoftwareParams(handle);
1148 }
1149
1150
1151 err = pcm_prepare(handle->handle);
1152 if(err != NO_ERROR) {
1153 ALOGE("DEVICE_IN_COMMUNICATION: pcm_prepare failed");
1154 }
1155
1156 /* first read required start dsp */
1157 memset(&voc_pkt,0,sizeof(voc_pkt));
1158 pcm_read(handle->handle,&voc_pkt,handle->handle->period_size);
1159 if (devName) {
1160 free(devName);
1161 devName = NULL;
1162 }
1163 return NO_ERROR;
1164}
1165
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -08001166status_t ALSADevice::startVoiceCall(alsa_handle_t *handle, uint32_t vsid)
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001167{
1168 char* devName = NULL;
1169 unsigned flags = 0;
1170 int err = NO_ERROR;
1171
1172 ALOGD("startVoiceCall: handle %p", handle);
1173 // ASoC multicomponent requires a valid path (frontend/backend) for
1174 // the device to be opened
1175
1176 flags = PCM_OUT | PCM_MONO;
1177 if (deviceName(handle, flags, &devName) < 0) {
1178 ALOGE("Failed to get pcm device node");
1179 return NO_INIT;
1180 }
1181 if (devName != NULL) {
1182 handle->handle = pcm_open(flags, (char*)devName);
1183 } else {
1184 ALOGE("Failed to get pcm device node");
1185 return NO_INIT;
1186 }
1187
1188 if (!handle->handle || (handle->handle->fd < 0)) {
1189 ALOGE("startVoiceCall: could not open PCM device");
1190 goto Error;
1191 }
1192
1193 handle->handle->flags = flags;
1194 err = setHardwareParams(handle);
1195 if(err != NO_ERROR) {
1196 ALOGE("startVoiceCall: setHardwareParams failed");
1197 goto Error;
1198 }
1199
1200 err = setSoftwareParams(handle);
1201 if(err != NO_ERROR) {
1202 ALOGE("startVoiceCall: setSoftwareParams failed");
1203 goto Error;
1204 }
1205
1206 err = pcm_prepare(handle->handle);
1207 if(err != NO_ERROR) {
1208 ALOGE("startVoiceCall: pcm_prepare failed");
1209 goto Error;
1210 }
1211
1212 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
1213 ALOGE("startVoiceCall:SNDRV_PCM_IOCTL_START failed\n");
1214 goto Error;
1215 }
1216
1217 // Store the PCM playback device pointer in rxHandle
1218 handle->rxHandle = handle->handle;
1219 if (devName) {
1220 free(devName);
1221 devName = NULL;
1222 }
1223
1224 // Open PCM capture device
1225 flags = PCM_IN | PCM_MONO;
1226 if (deviceName(handle, flags, &devName) < 0) {
1227 ALOGE("Failed to get pcm device node");
1228 goto Error;
1229 }
1230 if (devName != NULL) {
1231 handle->handle = pcm_open(flags, (char*)devName);
1232 } else {
1233 ALOGE("Failed to get pcm device node");
1234 return NO_INIT;
1235 }
1236 if (!handle->handle || (handle->handle->fd < 0)) {
1237 free(devName);
1238 goto Error;
1239 }
1240
1241 handle->handle->flags = flags;
1242 err = setHardwareParams(handle);
1243 if(err != NO_ERROR) {
1244 ALOGE("startVoiceCall: setHardwareParams failed");
1245 goto Error;
1246 }
1247
1248 err = setSoftwareParams(handle);
1249 if(err != NO_ERROR) {
1250 ALOGE("startVoiceCall: setSoftwareParams failed");
1251 goto Error;
1252 }
1253
1254 err = pcm_prepare(handle->handle);
1255 if(err != NO_ERROR) {
1256 ALOGE("startVoiceCall: pcm_prepare failed");
1257 goto Error;
1258 }
1259
1260 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
1261 ALOGE("startVoiceCall:SNDRV_PCM_IOCTL_START failed\n");
1262 goto Error;
1263 }
1264
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001265#ifdef QCOM_CSDCLIENT_ENABLED
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -08001266 if (isPlatformFusion3()) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001267 if (csd_start_voice == NULL) {
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -08001268 ALOGE("csd_client_start_voice is NULL");
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001269 } else {
Giulio Cervera9a6c7802013-05-02 01:51:16 +02001270#ifdef NEW_CSDCLIENT
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -08001271 err = csd_start_voice(vsid);
Giulio Cervera9a6c7802013-05-02 01:51:16 +02001272#else
1273 err = csd_start_voice();
1274#endif
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001275 if (err < 0){
1276 ALOGE("s_start_voice_call: csd_client error %d\n", err);
1277 goto Error;
1278 }
1279 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001280 }
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -08001281#endif
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001282
1283 if (devName) {
1284 free(devName);
1285 devName = NULL;
1286 }
1287 return NO_ERROR;
1288
1289Error:
1290 ALOGE("startVoiceCall: Failed to initialize ALSA device '%s'", devName);
1291 if (devName) {
1292 free(devName);
1293 devName = NULL;
1294 }
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -08001295 close(handle, vsid);
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001296 return NO_INIT;
1297}
1298
1299status_t ALSADevice::startFm(alsa_handle_t *handle)
1300{
1301 char *devName = NULL;
1302 unsigned flags = 0;
1303 int err = NO_ERROR;
1304
1305 ALOGV("startFm: handle %p", handle);
1306
1307 // ASoC multicomponent requires a valid path (frontend/backend) for
1308 // the device to be opened
1309
1310 flags = PCM_OUT | PCM_STEREO;
1311 if (deviceName(handle, flags, &devName) < 0) {
1312 ALOGE("Failed to get pcm device node");
1313 goto Error;
1314 }
1315 if (devName != NULL) {
1316 handle->handle = pcm_open(flags, (char*)devName);
1317 } else {
1318 ALOGE("Failed to get pcm device node");
1319 return NO_INIT;
1320 }
1321 if (!handle->handle || (handle->handle->fd < 0)) {
1322 ALOGE("startFm: could not open PCM device");
1323 goto Error;
1324 }
1325
1326 handle->handle->flags = flags;
1327 err = setHardwareParams(handle);
1328 if(err != NO_ERROR) {
1329 ALOGE("startFm: setHardwareParams failed");
1330 goto Error;
1331 }
1332
1333 err = setSoftwareParams(handle);
1334 if(err != NO_ERROR) {
1335 ALOGE("startFm: setSoftwareParams failed");
1336 goto Error;
1337 }
1338
1339 err = pcm_prepare(handle->handle);
1340 if(err != NO_ERROR) {
1341 ALOGE("startFm: setSoftwareParams failed");
1342 goto Error;
1343 }
1344
1345 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
1346 ALOGE("startFm: SNDRV_PCM_IOCTL_START failed\n");
1347 goto Error;
1348 }
1349
1350 // Store the PCM playback device pointer in rxHandle
1351 handle->rxHandle = handle->handle;
1352 if (devName) {
1353 free(devName);
1354 devName = NULL;
1355 }
1356
1357 // Open PCM capture device
1358 flags = PCM_IN | PCM_STEREO;
1359 if (deviceName(handle, flags, &devName) < 0) {
1360 ALOGE("Failed to get pcm device node");
1361 goto Error;
1362 }
1363 if (devName != NULL) {
1364 handle->handle = pcm_open(flags, (char*)devName);
1365 } else {
1366 ALOGE("Failed to get pcm device node");
1367 return NO_INIT;
1368 }
1369 if (!handle->handle) {
1370 goto Error;
1371 }
1372
1373 handle->handle->flags = flags;
1374 err = setHardwareParams(handle);
1375 if(err != NO_ERROR) {
1376 ALOGE("startFm: setHardwareParams failed");
1377 goto Error;
1378 }
1379
1380 err = setSoftwareParams(handle);
1381 if(err != NO_ERROR) {
1382 ALOGE("startFm: setSoftwareParams failed");
1383 goto Error;
1384 }
1385
1386 err = pcm_prepare(handle->handle);
1387 if(err != NO_ERROR) {
1388 ALOGE("startFm: pcm_prepare failed");
1389 goto Error;
1390 }
1391
1392 if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
1393 ALOGE("startFm: SNDRV_PCM_IOCTL_START failed\n");
1394 goto Error;
1395 }
1396
Krishnankutty Kolathappilly58c98932013-03-18 23:45:04 -07001397 mIsFmEnabled = true;
Damir Didjustofd5ea632013-05-03 09:53:32 -07001398 setFmVolume(mFmVolume, handle);
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001399 if (devName) {
1400 free(devName);
1401 devName = NULL;
1402 }
1403 return NO_ERROR;
1404
1405Error:
1406 if (devName) {
1407 free(devName);
1408 devName = NULL;
1409 }
1410 close(handle);
1411 return NO_INIT;
1412}
1413
Damir Didjustofd5ea632013-05-03 09:53:32 -07001414status_t ALSADevice::setFmVolume(int value, alsa_handle_t *handle)
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001415{
1416 status_t err = NO_ERROR;
Damir Didjustofd5ea632013-05-03 09:53:32 -07001417 int ret = 0;
1418 char val_str[100], *volMixerCTL;
1419
Krishnankutty Kolathappilly58c98932013-03-18 23:45:04 -07001420 if (!mIsFmEnabled) {
1421 return INVALID_OPERATION;
1422 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001423
Damir Didjustofd5ea632013-05-03 09:53:32 -07001424 strlcpy(val_str, "PlaybackVolume/",sizeof("PlaybackVolume/"));
1425 strlcat(val_str, "Play FM", sizeof(val_str));
1426
1427 ret = snd_use_case_get(handle->ucMgr, val_str, (const char **)&volMixerCTL);
1428 if (ret < 0) {
1429 ALOGE("Failed to get volume mixer control: %s", val_str);
1430 return NAME_NOT_FOUND;
1431 } else {
1432 ALOGV("volMixerCTL %s\n", volMixerCTL);
1433 }
1434
1435 setMixerControl(volMixerCTL,value,0);
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001436 mFmVolume = value;
1437
1438 return err;
1439}
1440
1441status_t ALSADevice::setLpaVolume(int value)
1442{
1443 status_t err = NO_ERROR;
1444
1445 setMixerControl("LPA RX Volume",value,0);
1446
1447 return err;
1448}
1449
1450status_t ALSADevice::start(alsa_handle_t *handle)
1451{
1452 status_t err = NO_ERROR;
1453
1454 if(!handle->handle) {
1455 ALOGE("No active PCM driver to start");
1456 return err;
1457 }
1458
1459 err = pcm_prepare(handle->handle);
1460
1461 return err;
1462}
1463
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -08001464status_t ALSADevice::close(alsa_handle_t *handle, uint32_t vsid)
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001465{
1466 int ret;
1467 status_t err = NO_ERROR;
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -08001468 struct pcm *h = handle->rxHandle;
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001469
1470 handle->rxHandle = 0;
1471 ALOGD("close: handle %p h %p", handle, h);
1472 if (h) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001473#ifdef QCOM_CSDCLIENT_ENABLED
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -08001474 if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_VOICECALL) ||
1475 !strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_VOICE)) ||
1476 (!strcmp(handle->useCase, SND_USE_CASE_VERB_VOLTE) ||
1477 !strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_VOLTE)) ||
1478 (!strcmp(handle->useCase, SND_USE_CASE_VERB_VOICE2) ||
1479 !strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_VOICE2)) &&
1480 isPlatformFusion3()) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001481 if (csd_stop_voice == NULL) {
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -08001482 ALOGE("csd_client_disable_device is NULL");
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001483 } else {
Giulio Cervera9a6c7802013-05-02 01:51:16 +02001484#ifdef NEW_CSDCLIENT
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -08001485 err = csd_stop_voice(vsid);
Giulio Cervera9a6c7802013-05-02 01:51:16 +02001486#else
1487 err = csd_stop_voice();
1488#endif
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001489 if (err < 0) {
1490 ALOGE("s_close: csd_client error %d\n", err);
1491 }
1492 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001493 }
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -08001494#endif
Krishnankutty Kolathappilly58c98932013-03-18 23:45:04 -07001495
1496 if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
1497 (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_FM))) {
1498 mIsFmEnabled = false;
1499 }
1500
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001501 ALOGV("close rxHandle\n");
1502 err = pcm_close(h);
1503 if(err != NO_ERROR) {
1504 ALOGE("close: pcm_close failed for rxHandle with err %d", err);
1505 }
1506 }
1507
1508 h = handle->handle;
1509 handle->handle = 0;
1510
1511 if (h) {
1512 ALOGV("close handle h %p\n", h);
1513 err = pcm_close(h);
1514 if(err != NO_ERROR) {
1515 ALOGE("close: pcm_close failed for handle with err %d", err);
1516 }
1517 disableDevice(handle);
1518 }
1519
1520 return err;
1521}
1522
1523/*
1524 this is same as s_close, but don't discard
1525 the device/mode info. This way we can still
1526 close the device, hit idle and power-save, reopen the pcm
1527 for the same device/mode after resuming
1528*/
1529status_t ALSADevice::standby(alsa_handle_t *handle)
1530{
1531 int ret;
1532 status_t err = NO_ERROR;
1533 struct pcm *h = handle->rxHandle;
1534 handle->rxHandle = 0;
1535 ALOGD("standby: handle %p h %p", handle, h);
1536 if (h) {
1537 ALOGV("standby rxHandle\n");
1538 err = pcm_close(h);
1539 if(err != NO_ERROR) {
1540 ALOGE("standby: pcm_close failed for rxHandle with err %d", err);
1541 }
1542 }
1543
1544 h = handle->handle;
1545 handle->handle = 0;
1546
1547 if (h) {
1548 ALOGV("standby handle h %p\n", h);
1549 err = pcm_close(h);
1550 if(err != NO_ERROR) {
1551 ALOGE("standby: pcm_close failed for handle with err %d", err);
1552 }
1553 disableDevice(handle);
1554 }
1555
1556 return err;
1557}
1558
1559status_t ALSADevice::route(alsa_handle_t *handle, uint32_t devices, int mode)
1560{
1561 status_t status = NO_ERROR;
1562
1563 ALOGD("route: devices 0x%x in mode %d", devices, mode);
1564 mCallMode = mode;
1565 switchDevice(handle, devices, mode);
1566 return status;
1567}
1568
1569int ALSADevice::getUseCaseType(const char *useCase)
1570{
1571 ALOGV("use case is %s\n", useCase);
1572 if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI,
1573 MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI)) ||
1574 !strncmp(useCase, SND_USE_CASE_VERB_HIFI2,
1575 MAX_LEN(useCase, SND_USE_CASE_VERB_HIFI2)) ||
1576 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC,
1577 MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) ||
1578 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER,
1579 MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
1580 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_TUNNEL,
1581 MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
1582 !strncmp(useCase, SND_USE_CASE_VERB_HIFI2,
1583 MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI2)) ||
1584 !strncmp(useCase, SND_USE_CASE_VERB_DIGITAL_RADIO,
1585 MAX_LEN(useCase,SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
1586 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC,
1587 MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_MUSIC)) ||
1588 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC2,
1589 MAX_LEN(useCase, SND_USE_CASE_MOD_PLAY_MUSIC2)) ||
1590 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC,
1591 MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) ||
1592 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC2,
1593 MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_MUSIC2)) ||
1594 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LPA,
1595 MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_LPA)) ||
1596 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_TUNNEL,
1597 MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_TUNNEL)) ||
1598 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_FM,
1599 MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_FM))) {
1600 return USECASE_TYPE_RX;
1601 } else if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI_REC,
1602 MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_REC)) ||
1603 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC,
1604 MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC)) ||
1605 !strncmp(useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED,
1606 MAX_LEN(useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED)) ||
1607 !strncmp(useCase, SND_USE_CASE_VERB_FM_REC,
1608 MAX_LEN(useCase,SND_USE_CASE_VERB_FM_REC)) ||
1609 !strncmp(useCase, SND_USE_CASE_VERB_FM_A2DP_REC,
1610 MAX_LEN(useCase,SND_USE_CASE_VERB_FM_A2DP_REC)) ||
1611 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC,
1612 MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_MUSIC)) ||
1613 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC,
1614 MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC)) ||
1615 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_FM,
1616 MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_FM)) ||
1617 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM,
1618 MAX_LEN(useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM)) ||
1619 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED,
1620 MAX_LEN(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED))) {
1621 return USECASE_TYPE_TX;
1622 } else if (!strncmp(useCase, SND_USE_CASE_VERB_VOICECALL,
1623 MAX_LEN(useCase,SND_USE_CASE_VERB_VOICECALL)) ||
1624 !strncmp(useCase, SND_USE_CASE_VERB_IP_VOICECALL,
1625 MAX_LEN(useCase,SND_USE_CASE_VERB_IP_VOICECALL)) ||
1626 !strncmp(useCase, SND_USE_CASE_VERB_DL_REC,
1627 MAX_LEN(useCase,SND_USE_CASE_VERB_DL_REC)) ||
1628 !strncmp(useCase, SND_USE_CASE_VERB_UL_DL_REC,
1629 MAX_LEN(useCase,SND_USE_CASE_VERB_UL_DL_REC)) ||
1630 !strncmp(useCase, SND_USE_CASE_VERB_INCALL_REC,
1631 MAX_LEN(useCase,SND_USE_CASE_VERB_INCALL_REC)) ||
1632 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOICE,
1633 MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_VOICE)) ||
1634 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOIP,
1635 MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_VOIP)) ||
1636 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
1637 MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_VOICE_DL)) ||
1638 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
1639 MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL)) ||
1640 !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
1641 MAX_LEN(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE)) ||
Neema Shetty83d616c2013-02-20 19:18:05 -08001642 !strncmp(useCase, SND_USE_CASE_VERB_VOICE2,
1643 MAX_LEN(useCase, SND_USE_CASE_VERB_VOICE2)) ||
1644 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOICE2,
1645 MAX_LEN(useCase, SND_USE_CASE_MOD_PLAY_VOICE2)) ||
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001646 !strncmp(useCase, SND_USE_CASE_VERB_VOLTE,
1647 MAX_LEN(useCase,SND_USE_CASE_VERB_VOLTE)) ||
1648 !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOLTE,
1649 MAX_LEN(useCase, SND_USE_CASE_MOD_PLAY_VOLTE))) {
1650 return (USECASE_TYPE_RX | USECASE_TYPE_TX);
1651 } else {
1652 ALOGV("unknown use case %s\n", useCase);
1653 return 0;
1654 }
1655}
1656
1657void ALSADevice::disableDevice(alsa_handle_t *handle)
1658{
1659 unsigned usecase_type = 0;
1660 int i, mods_size;
1661 char *useCase;
1662 const char **mods_list;
1663
1664 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
1665 if (useCase != NULL) {
1666 if (!strncmp(useCase, handle->useCase, MAX_UC_LEN)) {
1667 snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
1668 } else {
1669 snd_use_case_set(handle->ucMgr, "_dismod", handle->useCase);
1670 }
1671 free(useCase);
1672 snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
1673 if (strncmp(useCase, SND_USE_CASE_VERB_INACTIVE,
1674 strlen(SND_USE_CASE_VERB_INACTIVE)))
1675 usecase_type |= getUseCaseType(useCase);
1676 mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
1677 ALOGV("Number of modifiers %d\n", mods_size);
1678 if (mods_size) {
1679 for(i = 0; i < mods_size; i++) {
1680 ALOGV("index %d modifier %s\n", i, mods_list[i]);
1681 usecase_type |= getUseCaseType(mods_list[i]);
1682 }
1683 }
1684 ALOGV("usecase_type is %d\n", usecase_type);
1685 if (!(usecase_type & USECASE_TYPE_TX) && (strncmp(mCurTxUCMDevice, "None", 4)))
1686 snd_use_case_set(handle->ucMgr, "_disdev", mCurTxUCMDevice);
1687 if (!(usecase_type & USECASE_TYPE_RX) && (strncmp(mCurRxUCMDevice, "None", 4)))
1688 snd_use_case_set(handle->ucMgr, "_disdev", mCurRxUCMDevice);
1689 } else {
1690 ALOGE("Invalid state, no valid use case found to disable");
1691 }
1692 free(useCase);
1693}
1694
1695char *ALSADevice::getUCMDeviceFromAcdbId(int acdb_id)
1696{
1697 switch(acdb_id) {
1698 case DEVICE_HANDSET_RX_ACDB_ID:
1699 return strdup(SND_USE_CASE_DEV_HANDSET);
ehgrace.kimd347e372013-06-03 11:47:54 +02001700 case DEVICE_SPEAKER_MONO_RX_ACDB_ID:
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001701 case DEVICE_SPEAKER_RX_ACDB_ID:
1702 return strdup(SND_USE_CASE_DEV_SPEAKER);
1703 case DEVICE_HEADSET_RX_ACDB_ID:
1704 return strdup(SND_USE_CASE_DEV_HEADPHONES);
1705 case DEVICE_TTY_HEADSET_MONO_RX_ACDB_ID:
1706 return strdup(SND_USE_CASE_DEV_TTY_HEADSET_RX);
1707 case DEVICE_ANC_HEADSET_STEREO_RX_ACDB_ID:
1708 return strdup(SND_USE_CASE_DEV_ANC_HEADSET);
1709 default:
1710 return NULL;
1711 }
1712}
1713
1714char* ALSADevice::getUCMDevice(uint32_t devices, int input, char *rxDevice)
1715{
Mike Kasick5ec33142012-12-26 21:27:52 -08001716 char value[PROPERTY_VALUE_MAX];
1717
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001718 if (!input) {
1719 ALOGV("getUCMDevice for output device: devices:%x is input device:%d",devices,input);
1720 if (!(mDevSettingsFlag & TTY_OFF) &&
1721 (mCallMode == AUDIO_MODE_IN_CALL) &&
1722 ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET)
1723 || (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)
1724#ifdef QCOM_ANC_HEADSET_ENABLED
1725 || (devices & AudioSystem::DEVICE_OUT_ANC_HEADSET)
1726 || (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE)
1727#endif
1728 )) {
1729 if (mDevSettingsFlag & TTY_VCO) {
1730 return strdup(SND_USE_CASE_DEV_TTY_HEADSET_RX);
1731 } else if (mDevSettingsFlag & TTY_FULL) {
1732 return strdup(SND_USE_CASE_DEV_TTY_FULL_RX);
1733 } else if (mDevSettingsFlag & TTY_HCO) {
1734 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_RX); /* HANDSET RX */
1735 }
1736 } else if (devices & AudioSystem::DEVICE_OUT_ALL_A2DP &&
1737 devices & AudioSystem::DEVICE_OUT_SPEAKER) {
1738 return strdup(SND_USE_CASE_DEV_PROXY_RX_SPEAKER);
1739 } else if (devices & AudioSystem::DEVICE_OUT_ALL_A2DP) {
1740 return strdup(SND_USE_CASE_DEV_PROXY_RX);
Mingming Yin4d33ffd2012-12-10 00:11:29 -08001741 } else if (devices & AUDIO_DEVICE_OUT_ALL_USB &&
1742 devices & AudioSystem::DEVICE_OUT_SPEAKER) {
1743 return strdup(SND_USE_CASE_DEV_PROXY_RX_SPEAKER);
1744 } else if (devices & AUDIO_DEVICE_OUT_ALL_USB) {
1745 return strdup(SND_USE_CASE_DEV_PROXY_RX);
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001746 } else if ((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET ||
1747 devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET) &&
Steve Kondik4ff69022013-08-14 01:49:12 -07001748 mCallMode != AUDIO_MODE_IN_CALL &&
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001749 devices & AudioSystem::DEVICE_OUT_SPEAKER) {
Steve Kondik2c29b432013-08-13 22:09:55 -07001750#ifdef SAMSUNG_AUDIO
1751 if (AudioUtil::isSamsungDockConnected()) {
1752 return strdup(SND_USE_CASE_DEV_DOCK);
1753 }
Araemoac921402013-04-06 19:20:45 +00001754#endif
Steve Kondik2c29b432013-08-13 22:09:55 -07001755 return strdup(SND_USE_CASE_DEV_USB_PROXY_RX_SPEAKER); /* USB PROXY RX + SPEAKER */
Steve Kondik4ff69022013-08-14 01:49:12 -07001756 } else if (((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET) ||
1757 (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)) &&
1758 mCallMode != AUDIO_MODE_IN_CALL) {
Steve Kondik2c29b432013-08-13 22:09:55 -07001759#ifdef SAMSUNG_AUDIO
1760 if (AudioUtil::isSamsungDockConnected()) {
1761 return strdup(SND_USE_CASE_DEV_DOCK); /* Dock RX */
1762 }
Araemoac921402013-04-06 19:20:45 +00001763#endif
Steve Kondik2c29b432013-08-13 22:09:55 -07001764 return strdup(SND_USE_CASE_DEV_USB_PROXY_RX); /* PROXY RX */
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001765#ifdef QCOM_PROXY_DEVICE_ENABLED
1766 } else if( (devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1767 (devices & AudioSystem::DEVICE_OUT_PROXY) &&
1768 ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
1769 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) ) ) {
1770 if (mDevSettingsFlag & ANC_FLAG) {
1771 return strdup(SND_USE_CASE_DEV_PROXY_RX_SPEAKER_ANC_HEADSET);
1772 } else {
1773 return strdup(SND_USE_CASE_DEV_PROXY_RX_SPEAKER_HEADSET);
1774 }
1775#endif
1776 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1777 ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
1778 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
1779 if (mDevSettingsFlag & ANC_FLAG) {
1780 return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
1781 } else {
1782 return strdup(SND_USE_CASE_DEV_SPEAKER_HEADSET); /* COMBO SPEAKER+HEADSET RX */
1783 }
1784 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1785 ((devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL))) {
1786 return strdup(SND_USE_CASE_DEV_HDMI_SPEAKER);
1787#ifdef QCOM_ANC_HEADSET_ENABLED
1788 } else if ((devices & AudioSystem::DEVICE_OUT_PROXY) &&
1789 ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET)||
1790 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE)) ) {
1791 return strdup(SND_USE_CASE_DEV_PROXY_RX_ANC_HEADSET);
1792 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1793 ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
1794 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) {
1795 return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
1796#endif
Giulio Cervera99dfda52013-02-14 12:26:00 +01001797#if defined(QCOM_FM_ENABLED) || defined(STE_FM)
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001798 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1799 (devices & AudioSystem::DEVICE_OUT_FM_TX)) {
1800 return strdup(SND_USE_CASE_DEV_SPEAKER_FM_TX); /* COMBO SPEAKER+FM_TX RX */
1801#endif
1802#ifdef QCOM_PROXY_DEVICE_ENABLED
1803 } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
1804 (devices & AudioSystem::DEVICE_OUT_PROXY)) {
1805 return strdup(SND_USE_CASE_DEV_PROXY_RX_SPEAKER); /* COMBO SPEAKER + PROXY RX */
1806 } else if ((devices & AudioSystem::DEVICE_OUT_EARPIECE) &&
1807 (devices & AudioSystem::DEVICE_OUT_PROXY)) {
1808 return strdup(SND_USE_CASE_DEV_PROXY_RX_HANDSET); /* COMBO EARPIECE + PROXY RX */
1809#endif
1810 } else if (devices & AudioSystem::DEVICE_OUT_EARPIECE) {
Steve Kondikf7b50ca2013-06-26 00:07:01 -07001811#ifdef SEPERATED_VOIP
1812 if (mCallMode == AUDIO_MODE_IN_COMMUNICATION) {
1813 return strdup(SND_USE_CASE_DEV_VOIP_EARPIECE);
1814 } else if (mCallMode == AUDIO_MODE_IN_CALL) {
1815#else
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001816 if (mCallMode == AUDIO_MODE_IN_CALL ||
1817 mCallMode == AUDIO_MODE_IN_COMMUNICATION) {
Steve Kondikf7b50ca2013-06-26 00:07:01 -07001818#endif
Damir Didjusto10b6ce42013-02-04 12:43:26 -08001819 if (shouldUseHandsetAnc(mDevSettingsFlag, mInChannels)) {
1820 return strdup(SND_USE_CASE_DEV_ANC_HANDSET); /* ANC Handset RX */
1821 } else {
Mike Kasick5ec33142012-12-26 21:27:52 -08001822 property_get("persist.audio.voc_ep.xgain", value, "");
1823 return strdup(strcmp(value, "1") == 0 ?
1824 SND_USE_CASE_DEV_VOC_EARPIECE_XGAIN :
1825 SND_USE_CASE_DEV_VOC_EARPIECE); /* Voice HANDSET RX */
Damir Didjusto10b6ce42013-02-04 12:43:26 -08001826 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001827 } else {
1828 return strdup(SND_USE_CASE_DEV_EARPIECE); /* HANDSET RX */
1829 }
1830 } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) {
Steve Kondikf7b50ca2013-06-26 00:07:01 -07001831#ifdef SEPERATED_VOIP
1832 if (mCallMode == AUDIO_MODE_IN_COMMUNICATION) {
1833 return strdup(SND_USE_CASE_DEV_VOIP_SPEAKER);
Steve Kondik5f2d3182013-08-12 17:22:55 -07001834 }
Steve Kondikf7b50ca2013-06-26 00:07:01 -07001835#endif
Steve Kondik5f2d3182013-08-12 17:22:55 -07001836#ifdef SEPERATED_VOICE_SPEAKER
1837 if (mCallMode == AUDIO_MODE_IN_CALL) {
Steve Kondik07eb3c22013-05-03 18:15:25 -07001838 return strdup(SND_USE_CASE_DEV_VOC_SPEAKER); /* Voice SPEAKER RX */
1839 }
1840#endif
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001841 return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
1842 } else if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
1843 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) {
1844 if (mDevSettingsFlag & ANC_FLAG) {
1845 if (mCallMode == AUDIO_MODE_IN_CALL ||
1846 mCallMode == AUDIO_MODE_IN_COMMUNICATION) {
1847 return strdup(SND_USE_CASE_DEV_VOC_ANC_HEADSET); /* Voice ANC HEADSET RX */
1848 } else {
1849 return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */
1850 }
1851 } else {
Steve Kondikf7b50ca2013-06-26 00:07:01 -07001852#ifdef SEPERATED_VOIP
1853 if (mCallMode == AUDIO_MODE_IN_COMMUNICATION) {
1854 return strdup(SND_USE_CASE_DEV_VOIP_HEADPHONE);
1855 } else if (mCallMode == AUDIO_MODE_IN_CALL) {
1856#else
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001857 if (mCallMode == AUDIO_MODE_IN_CALL ||
1858 mCallMode == AUDIO_MODE_IN_COMMUNICATION) {
Steve Kondikf7b50ca2013-06-26 00:07:01 -07001859#endif
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001860 return strdup(SND_USE_CASE_DEV_VOC_HEADPHONE); /* Voice HEADSET RX */
1861 } else {
1862 return strdup(SND_USE_CASE_DEV_HEADPHONES); /* HEADSET RX */
1863 }
1864 }
1865#ifdef QCOM_ANC_HEADSET_ENABLED
1866 } else if ((devices & AudioSystem::DEVICE_OUT_PROXY) &&
1867 ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
1868 (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
1869 if (mDevSettingsFlag & ANC_FLAG) {
1870 return strdup(SND_USE_CASE_DEV_PROXY_RX_ANC_HEADSET);
1871 } else {
1872 return strdup(SND_USE_CASE_DEV_PROXY_RX_HEADSET);
1873 }
1874 } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
1875 (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE)) {
1876 if (mCallMode == AUDIO_MODE_IN_CALL ||
1877 mCallMode == AUDIO_MODE_IN_COMMUNICATION) {
1878 return strdup(SND_USE_CASE_DEV_VOC_ANC_HEADSET); /* Voice ANC HEADSET RX */
1879 } else {
1880 return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */
1881 }
1882#endif
1883 } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) ||
1884 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
1885 (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT)) {
1886 if (mBtscoSamplerate == BTSCO_RATE_16KHZ)
1887 return strdup(SND_USE_CASE_DEV_BTSCO_WB_RX); /* BTSCO RX*/
1888 else
1889 return strdup(SND_USE_CASE_DEV_BTSCO_NB_RX); /* BTSCO RX*/
1890 } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
1891 return strdup(SND_USE_CASE_DEV_HDMI); /* HDMI RX */
1892#ifdef QCOM_PROXY_DEVICE_ENABLED
1893 } else if (devices & AudioSystem::DEVICE_OUT_PROXY) {
1894 return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */
1895#endif
Giulio Cervera99dfda52013-02-14 12:26:00 +01001896#if defined(QCOM_FM_ENABLED) || defined(STE_FM)
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001897 } else if (devices & AudioSystem::DEVICE_OUT_FM_TX) {
1898 return strdup(SND_USE_CASE_DEV_FM_TX); /* FM Tx */
1899#endif
1900 } else if (devices & AudioSystem::DEVICE_OUT_DEFAULT) {
1901 return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
1902 } else {
1903 ALOGD("No valid output device: %u", devices);
1904 }
1905 } else {
1906 ALOGV("getUCMDevice for input device: devices:%x is input device:%d",devices,input);
1907 if (!(mDevSettingsFlag & TTY_OFF) &&
1908 (mCallMode == AUDIO_MODE_IN_CALL) &&
1909 ((devices & AudioSystem::DEVICE_IN_WIRED_HEADSET)
1910#ifdef QCOM_ANC_HEADSET_ENABLED
1911 || (devices & AudioSystem::DEVICE_IN_ANC_HEADSET)
1912#endif
1913 )) {
1914 if (mDevSettingsFlag & TTY_HCO) {
1915 return strdup(SND_USE_CASE_DEV_TTY_HEADSET_TX);
1916 } else if (mDevSettingsFlag & TTY_FULL) {
1917 return strdup(SND_USE_CASE_DEV_TTY_FULL_TX);
1918 } else if (mDevSettingsFlag & TTY_VCO) {
1919 if (!strncmp(mMicType, "analog", 6)) {
1920 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_ANALOG_TX);
1921 } else {
1922 return strdup(SND_USE_CASE_DEV_TTY_HANDSET_TX);
1923 }
1924 }
1925 } else if (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) {
1926 if (!strncmp(mMicType, "analog", 6)) {
1927 return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
1928 } else {
1929 if ((mDevSettingsFlag & DMIC_FLAG) && (mInChannels == 1)) {
1930#ifdef USES_FLUENCE_INCALL
Steve Kondik195e30b2013-08-12 17:56:19 -07001931 if (mCallMode == AUDIO_MODE_IN_CALL
1932#ifdef USES_FLUENCE_FOR_VOIP
1933 || mCallMode == AUDIO_MODE_IN_COMMUNICATION
1934#endif
1935 ) {
Mike Kasick67a0a0a2013-01-04 16:12:55 -05001936#endif
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001937 if (((rxDevice != NULL) &&
Steve Kondik07eb3c22013-05-03 18:15:25 -07001938 (!strncmp(rxDevice, SND_USE_CASE_DEV_SPEAKER,
1939 (strlen(SND_USE_CASE_DEV_SPEAKER)+1))
1940#ifdef SEPERATED_VOICE_SPEAKER
1941 || !strncmp(rxDevice, SND_USE_CASE_DEV_VOC_SPEAKER,
1942 (strlen(SND_USE_CASE_DEV_VOC_SPEAKER)+1))
1943#endif
1944 )) ||
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001945 ((rxDevice == NULL) &&
1946 !strncmp(mCurRxUCMDevice, SND_USE_CASE_DEV_SPEAKER,
1947 (strlen(SND_USE_CASE_DEV_SPEAKER)+1)))) {
1948 if (mFluenceMode == FLUENCE_MODE_ENDFIRE) {
1949 if (mIsSglte == false) {
1950 return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
1951 }
1952 else {
1953 return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_ENDFIRE_SGLTE); /* DUALMIC EF TX */
1954 }
1955 } else if (mFluenceMode == FLUENCE_MODE_BROADSIDE) {
1956 return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
1957 }
1958 } else {
1959 if (mFluenceMode == FLUENCE_MODE_ENDFIRE) {
1960 if (mIsSglte == false) {
Damir Didjusto10b6ce42013-02-04 12:43:26 -08001961 if ((rxDevice != NULL) &&
1962 !strncmp(rxDevice, SND_USE_CASE_DEV_ANC_HANDSET,
1963 strlen(SND_USE_CASE_DEV_ANC_HANDSET) + 1)) {
1964 /* if using ANC_HANDSET, already in-call */
1965 return strdup(SND_USE_CASE_DEV_AANC_DMIC_ENDFIRE); /* DUALMIC AANC TX */
1966 } else {
1967 return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
1968 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001969 }
1970 else {
1971 return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE_SGLTE); /* DUALMIC EF TX */
1972 }
1973 } else if (mFluenceMode == FLUENCE_MODE_BROADSIDE) {
1974 return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
1975 }
1976 }
Mike Kasick67a0a0a2013-01-04 16:12:55 -05001977#ifdef USES_FLUENCE_INCALL
1978 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001979#endif
1980 } else if ((mDevSettingsFlag & DMIC_FLAG) && (mInChannels > 1)) {
1981 if (((rxDevice != NULL) &&
1982 !strncmp(rxDevice, SND_USE_CASE_DEV_SPEAKER,
1983 (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) ||
1984 ((rxDevice == NULL) &&
1985 !strncmp(mCurRxUCMDevice, SND_USE_CASE_DEV_SPEAKER,
1986 (strlen(SND_USE_CASE_DEV_SPEAKER)+1)))) {
1987 if (mIsSglte == false) {
1988 return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_STEREO); /* DUALMIC EF TX */
1989 }
1990 else {
1991 return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_STEREO_SGLTE); /* DUALMIC EF TX */
1992 }
1993 } else {
1994 if (mIsSglte == false) {
1995 return strdup(SND_USE_CASE_DEV_DUAL_MIC_HANDSET_STEREO); /* DUALMIC EF TX */
1996 }
1997 else {
1998 return strdup(SND_USE_CASE_DEV_DUAL_MIC_HANDSET_STEREO_SGLTE); /* DUALMIC EF TX */
1999 }
2000 }
2001 } else if ((mDevSettingsFlag & QMIC_FLAG) && (mInChannels == 1)) {
2002 if (((rxDevice != NULL) &&
2003 !strncmp(rxDevice, SND_USE_CASE_DEV_SPEAKER,
2004 (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) ||
2005 ((rxDevice == NULL) &&
2006 !strncmp(mCurRxUCMDevice, SND_USE_CASE_DEV_SPEAKER,
2007 (strlen(SND_USE_CASE_DEV_SPEAKER)+1)))) {
2008 return strdup(SND_USE_CASE_DEV_QUAD_MIC); /* QUADMIC TX */
2009 } else {
Damir Didjusto10b6ce42013-02-04 12:43:26 -08002010 if ((rxDevice != NULL) &&
2011 !strncmp(rxDevice, SND_USE_CASE_DEV_ANC_HANDSET,
2012 strlen(SND_USE_CASE_DEV_ANC_HANDSET) + 1)) {
2013 /* if using ANC_HANDSET, already in-call */
2014 return strdup(SND_USE_CASE_DEV_AANC_LINE); /* AANC LINE TX */
2015 } else {
2016 return strdup(SND_USE_CASE_DEV_LINE);
2017 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -08002018 }
2019 }
2020#ifdef QCOM_SSR_ENABLED
2021 else if ((mDevSettingsFlag & QMIC_FLAG) && (mInChannels > 1)) {
2022 return strdup(SND_USE_CASE_DEV_SSR_QUAD_MIC);
2023 } else if ((mDevSettingsFlag & SSRQMIC_FLAG) && (mInChannels > 1)){
2024 ALOGV("return SSRQMIC_FLAG: 0x%x devices:0x%x",mDevSettingsFlag,devices);
2025 // Mapping for quad mic input device.
2026 return strdup(SND_USE_CASE_DEV_SSR_QUAD_MIC); /* SSR Quad MIC */
2027 }
2028#endif
2029#ifdef SEPERATED_AUDIO_INPUT
Steve Kondik152073a2013-04-06 19:44:23 +00002030 if(mInputSource == AUDIO_SOURCE_VOICE_RECOGNITION) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -08002031 return strdup(SND_USE_CASE_DEV_VOICE_RECOGNITION ); /* VOICE RECOGNITION TX */
2032 }
2033#endif
Ethan Chen58bd7712013-09-04 12:28:39 -07002034#ifdef SEPERATED_CAMCORDER
2035 if (mInputSource == AUDIO_SOURCE_CAMCORDER) {
2036 return strdup(SND_USE_CASE_DEV_CAMCORDER_TX); /* CAMCORDER TX */
2037 }
2038#endif
Steve Kondikf7b50ca2013-06-26 00:07:01 -07002039#ifdef SEPERATED_VOIP
2040 if (mCallMode == AUDIO_MODE_IN_COMMUNICATION) {
2041 if (!strncmp(rxDevice, SND_USE_CASE_DEV_VOIP_EARPIECE,
2042 (strlen(SND_USE_CASE_DEV_VOIP_EARPIECE)+1))) {
2043 return strdup(SND_USE_CASE_DEV_VOIP_HANDSET);
2044 } else {
2045 return strdup(SND_USE_CASE_DEV_VOIP_LINE);
2046 }
2047 }
2048#endif
Mingming Yinbbd94ad2012-11-29 20:04:36 -08002049 else {
Damir Didjusto10b6ce42013-02-04 12:43:26 -08002050 if ((rxDevice != NULL) &&
2051 !strncmp(rxDevice, SND_USE_CASE_DEV_ANC_HANDSET,
2052 strlen(SND_USE_CASE_DEV_ANC_HANDSET) + 1)) {
2053 return strdup(SND_USE_CASE_DEV_AANC_LINE); /* AANC LINE TX */
2054 } else {
2055 return strdup(SND_USE_CASE_DEV_LINE); /* BUILTIN-MIC TX */
2056 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -08002057 }
2058 }
2059 } else if (devices & AudioSystem::DEVICE_IN_AUX_DIGITAL) {
2060 return strdup(SND_USE_CASE_DEV_HDMI_TX); /* HDMI TX */
2061 } else if ((devices & AudioSystem::DEVICE_IN_WIRED_HEADSET)) {
Steve Kondike912e3e2013-06-26 12:48:22 -07002062#ifdef SEPERATED_HEADSET_MIC
2063#ifdef SEPERATED_VOIP
2064 if (mCallMode == AUDIO_MODE_IN_COMMUNICATION) {
2065 return strdup(SND_USE_CASE_DEV_VOIP_HEADSET);
2066 }
2067#endif
2068 if (mCallMode == AUDIO_MODE_IN_CALL) {
2069 return strdup(SND_USE_CASE_DEV_VOC_HEADSET);
2070 }
Steve Kondik4fed5f52013-06-26 13:57:34 -07002071 if (mInputSource == AUDIO_SOURCE_VOICE_RECOGNITION) {
2072 return strdup(SND_USE_CASE_DEV_VOICE_RECOGNITION_HEADSET);
2073 }
Steve Kondike912e3e2013-06-26 12:48:22 -07002074#endif
Mingming Yinbbd94ad2012-11-29 20:04:36 -08002075 return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */
2076#ifdef QCOM_ANC_HEADSET_ENABLED
2077 } else if (devices & AudioSystem::DEVICE_IN_ANC_HEADSET) {
2078 return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */
2079#endif
2080 } else if (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
2081 if (mBtscoSamplerate == BTSCO_RATE_16KHZ)
2082 return strdup(SND_USE_CASE_DEV_BTSCO_WB_TX); /* BTSCO TX*/
2083 else
2084 return strdup(SND_USE_CASE_DEV_BTSCO_NB_TX); /* BTSCO TX*/
2085#ifdef QCOM_USBAUDIO_ENABLED
2086 } else if (devices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) {
2087 if ((mCallMode == AUDIO_MODE_IN_CALL) ||
2088 (mCallMode == AUDIO_MODE_IN_COMMUNICATION)) {
2089 if ((rxDevice != NULL) &&
2090 (!strncmp(rxDevice, SND_USE_CASE_DEV_USB_PROXY_RX,
2091 (strlen(SND_USE_CASE_DEV_USB_PROXY_RX)+1)))) {
2092 return strdup(SND_USE_CASE_DEV_USB_PROXY_TX); /* USB PROXY TX */
2093 } else if ((rxDevice != NULL) &&
2094 (!strncmp(rxDevice, SND_USE_CASE_DEV_PROXY_RX,
2095 (strlen(SND_USE_CASE_DEV_PROXY_RX)+1)))) {
2096 return strdup(SND_USE_CASE_DEV_PROXY_TX); /* PROXY TX */
2097 } else {
2098 return strdup(SND_USE_CASE_DEV_USB_PROXY_TX); /* USB PROXY TX */
2099 }
2100 } else {
2101 return strdup(SND_USE_CASE_DEV_USB_PROXY_TX); /* USB PROXY TX */
2102 }
2103#endif
2104#ifdef QCOM_PROXY_DEVICE_ENABLED
2105 } else if (devices & AudioSystem::DEVICE_IN_PROXY) {
2106 return strdup(SND_USE_CASE_DEV_PROXY_TX); /* PROXY TX */
2107#endif
2108 } else if ((devices & AudioSystem::DEVICE_IN_COMMUNICATION) ||
2109 (devices & AudioSystem::DEVICE_IN_VOICE_CALL)) {
2110 /* Nothing to be done, use current active device */
2111 if (strncmp(mCurTxUCMDevice, "None", 4)) {
2112 return strdup(mCurTxUCMDevice);
2113 }
Giulio Cervera99dfda52013-02-14 12:26:00 +01002114#if defined(QCOM_FM_ENABLED) || defined(STE_FM)
Mingming Yinbbd94ad2012-11-29 20:04:36 -08002115 } else if ((devices & AudioSystem::DEVICE_IN_FM_RX) ||
2116 (devices & AudioSystem::DEVICE_IN_FM_RX_A2DP)) {
2117 /* Nothing to be done, use current tx device or set dummy device */
2118 if (strncmp(mCurTxUCMDevice, "None", 4)) {
2119 return strdup(mCurTxUCMDevice);
2120 } else {
2121 return strdup(SND_USE_CASE_DEV_DUMMY_TX);
2122 }
2123#endif
2124 } else if ((devices & AudioSystem::DEVICE_IN_AMBIENT) ||
2125 (devices & AudioSystem::DEVICE_IN_BACK_MIC)) {
2126 ALOGI("No proper mapping found with UCM device list, setting default");
2127 if (!strncmp(mMicType, "analog", 6)) {
2128 return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
2129 } else {
2130#ifdef SEPERATED_AUDIO_INPUT
Steve Kondik152073a2013-04-06 19:44:23 +00002131 if (mCallMode == AUDIO_MODE_IN_CALL) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -08002132 return strdup(SND_USE_CASE_DEV_VOC_LINE); /* Voice BUILTIN-MIC TX */
Mingming Yinbbd94ad2012-11-29 20:04:36 -08002133 } else
2134#endif
2135 return strdup(SND_USE_CASE_DEV_LINE); /* BUILTIN-MIC TX */
2136 }
2137 } else {
2138 ALOGD("No valid input device: %u", devices);
2139 }
2140 }
2141 return NULL;
2142}
2143
2144void ALSADevice::setVoiceVolume(int vol)
2145{
2146 int err = 0;
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -08002147
Mingming Yinbbd94ad2012-11-29 20:04:36 -08002148 ALOGD("setVoiceVolume: volume %d", vol);
2149 setMixerControl("Voice Rx Volume", vol, 0);
2150
Mingming Yinbbd94ad2012-11-29 20:04:36 -08002151#ifdef QCOM_CSDCLIENT_ENABLED
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -08002152 if (isPlatformFusion3()) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -08002153 if (csd_volume == NULL) {
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -08002154 ALOGE("csd_client_volume is NULL");
Mingming Yinbbd94ad2012-11-29 20:04:36 -08002155 } else {
Giulio Cervera9a6c7802013-05-02 01:51:16 +02002156#ifdef NEW_CSDCLIENT
Shiv Maliyappanahallic2e34a72013-03-03 18:37:28 -08002157 err = csd_volume(ALL_SESSION_VSID, vol);
Giulio Cervera9a6c7802013-05-02 01:51:16 +02002158#else
2159 err = csd_volume(vol);
2160#endif
Mingming Yinbbd94ad2012-11-29 20:04:36 -08002161 if (err < 0) {
2162 ALOGE("s_set_voice_volume: csd_client error %d", err);
2163 }
2164 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800