blob: f4c0e20129f33af2ec670b6ba5de8a42afca8e4e [file] [log] [blame]
Ravi Kumar Alamanda2dfba2b2013-01-17 16:50:22 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "audio_hw_primary"
18/*#define LOG_NDEBUG 0*/
19
20#include <errno.h>
21#include <pthread.h>
22#include <stdint.h>
23#include <sys/time.h>
24#include <stdlib.h>
25#include <dlfcn.h>
26#include <math.h>
27
28#include <cutils/log.h>
29#include <cutils/str_parms.h>
30#include <cutils/properties.h>
31
32#include "audio_hw.h"
33
34#define LIB_ACDB_LOADER "/system/lib/libacdbloader.so"
35#define LIB_CSD_CLIENT "/system/lib/libcsd-client.so"
36#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
37#define MIXER_CARD 0
38
39#define STRING_TO_ENUM(string) { #string, string }
40
41/* Flags used to initialize acdb_settings variable that goes to ACDB library */
42#define DMIC_FLAG 0x00000002
43#define TTY_OFF 0x00000010
44#define TTY_FULL 0x00000020
45#define TTY_VCO 0x00000040
46#define TTY_HCO 0x00000080
47#define TTY_CLEAR 0xFFFFFF0F
48
49struct string_to_enum {
50 const char *name;
51 uint32_t value;
52};
53
54static const struct string_to_enum out_channels_name_to_enum_table[] = {
55 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO),
56 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
57 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
58};
59
60static const char * const use_case_table[AUDIO_USECASE_MAX] = {
61 [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = "deep-buffer-playback",
62 [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = "low-latency-playback",
63 [USECASE_AUDIO_PLAYBACK_MULTI_CH] = "multi-channel-playback",
64 [USECASE_AUDIO_RECORD] = "audio-record",
65 [USECASE_AUDIO_RECORD_LOW_LATENCY] = "low-latency-record",
66 [USECASE_VOICE_CALL] = "voice-call",
67};
68
69static const int pcm_device_table[AUDIO_USECASE_MAX][2] = {
70 [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {0, 0},
71 [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {14, 14},
72 [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {1, 1},
73 [USECASE_AUDIO_RECORD] = {0, 0},
74 [USECASE_AUDIO_RECORD_LOW_LATENCY] = {14, 14},
75 [USECASE_VOICE_CALL] = {12, 12},
76};
77
78/* Array to store sound devices */
79static const char * const device_table[SND_DEVICE_ALL] = {
80 /* Playback sound devices */
81 [SND_DEVICE_OUT_HANDSET] = "handset",
82 [SND_DEVICE_OUT_SPEAKER] = "speaker",
83 [SND_DEVICE_OUT_HEADPHONES] = "headphones",
84 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
85 [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
86 [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
87 [SND_DEVICE_OUT_HDMI ] = "hdmi",
88 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
89 [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
90
91 /* Capture sound devices */
92 [SND_DEVICE_IN_HANDSET_MIC ] = "handset-mic",
93 [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
94 [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
95 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
96 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
97 [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
98 [SND_DEVICE_IN_BT_SCO_MIC ] = "bt-sco-mic",
99 [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
100 [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
101};
102
103static const int acdb_device_table[SND_DEVICE_ALL] = {
104 [SND_DEVICE_OUT_HANDSET] = 7,
105 [SND_DEVICE_OUT_SPEAKER] = 14,
106 [SND_DEVICE_OUT_HEADPHONES] = 10,
107 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
108 [SND_DEVICE_OUT_VOICE_SPEAKER] = 14,
109 [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
110 [SND_DEVICE_OUT_HDMI ] = 18,
111 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14,
112 [SND_DEVICE_OUT_BT_SCO] = 22,
113
114 [SND_DEVICE_IN_HANDSET_MIC ] = 4,
115 [SND_DEVICE_IN_SPEAKER_MIC] = 4,
116 [SND_DEVICE_IN_HEADSET_MIC] = 8,
117 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
118 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
119 [SND_DEVICE_IN_HDMI_MIC] = 4,
120 [SND_DEVICE_IN_BT_SCO_MIC ] = 21,
121 [SND_DEVICE_IN_CAMCORDER_MIC] = 61,
122 [SND_DEVICE_IN_VOICE_REC_MIC] = 62,
123};
124
125/* Array to store back-end paths */
126static const char * const backend_table[SND_DEVICE_ALL] = {
127 [SND_DEVICE_OUT_HANDSET] = "",
128 [SND_DEVICE_OUT_SPEAKER] = "",
129 [SND_DEVICE_OUT_HEADPHONES] = "",
130 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "",
131 [SND_DEVICE_OUT_VOICE_SPEAKER] = "",
132 [SND_DEVICE_OUT_VOICE_HEADPHONES] = "",
133
134 /* Note: Backend name should start with white space */
135 [SND_DEVICE_OUT_HDMI ] = " hdmi",
136 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = " speaker-and-hdmi",
137 [SND_DEVICE_OUT_BT_SCO] = " bt-sco",
138
139 [SND_DEVICE_IN_HANDSET_MIC ] = "",
140 [SND_DEVICE_IN_SPEAKER_MIC] = "",
141 [SND_DEVICE_IN_HEADSET_MIC] = "",
142 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "",
143 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "",
144 [SND_DEVICE_IN_HDMI_MIC] = " hdmi",
145 [SND_DEVICE_IN_BT_SCO_MIC ] = " bt-sco",
146 [SND_DEVICE_IN_CAMCORDER_MIC] = "",
147 [SND_DEVICE_IN_VOICE_REC_MIC] = "",
148};
149
150int edid_get_max_channels(void);
151
152static int get_pcm_device_id(struct audio_route *ar,
153 audio_usecase_t usecase,
154 int device_type)
155{
156 ALOGV("%s: enter: usecase(%d)", __func__, usecase);
157 int device_id;
158 if (device_type == PCM_PLAYBACK)
159 device_id = pcm_device_table[usecase][0];
160 else
161 device_id = pcm_device_table[usecase][1];
162 ALOGV("%s: exit: device_id(%d)", __func__, device_id);
163 return device_id;
164}
165
166static int get_acdb_device_id(snd_device_t snd_device)
167{
168 ALOGV("%s: enter: snd_devie(%d)", __func__, snd_device);
169 int acdb_dev_id = acdb_device_table[snd_device];
170 ALOGV("%s: exit: acdb_dev_id(%d)", __func__, acdb_dev_id);
171 return acdb_dev_id;
172}
173
174static int enable_audio_route(struct audio_route *ar,
175 audio_usecase_t usecase,
176 snd_device_t snd_device)
177{
178 ALOGV("%s: enter: usecase(%d) snd_device(%d)",
179 __func__, usecase, snd_device);
180 char mixer_path[50];
181 strcpy(mixer_path, use_case_table[usecase]);
182 strcat(mixer_path, backend_table[snd_device]);
183 audio_route_apply_path(ar, mixer_path);
184 ALOGV("%s: exit", __func__);
185 return 0;
186}
187
188static int disable_audio_route(struct audio_route *ar,
189 audio_usecase_t usecase,
190 snd_device_t snd_device)
191{
192 ALOGV("%s: enter: usecase(%d) snd_device(%d)",
193 __func__, usecase, snd_device);
194 char mixer_path[50];
195 strcpy(mixer_path, use_case_table[usecase]);
196 strcat(mixer_path, backend_table[snd_device]);
197 audio_route_reset_path(ar, mixer_path);
198 ALOGV("%s: exit", __func__);
199 return 0;
200}
201
202static int enable_snd_device(struct audio_device *adev,
203 snd_device_t snd_device)
204{
205 int acdb_dev_id, acdb_dev_type;
206
207 ALOGV("%s: enter: snd_device(%d)", __func__, snd_device);
208 acdb_dev_id = get_acdb_device_id(snd_device);
209 if (acdb_dev_id < 0) {
210 ALOGE("%s: Could not find acdb id for device(%d)",
211 __func__, snd_device);
212 return -EINVAL;
213 }
214 if (snd_device >= SND_DEVICE_OUT_BEGIN &&
215 snd_device < SND_DEVICE_OUT_END) {
216 acdb_dev_type = ACDB_DEV_TYPE_OUT;
217 } else {
218 acdb_dev_type = ACDB_DEV_TYPE_IN;
219 }
220 if (adev->acdb_send_audio_cal) {
221 ALOGV("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
222 __func__, snd_device, acdb_dev_id);
223 adev->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type);
224 } else {
225 ALOGW("%s: Could find the symbol acdb_send_audio_cal from %s",
226 __func__, LIB_ACDB_LOADER);
227 }
228
229 audio_route_apply_path(adev->audio_route, device_table[snd_device]);
230 ALOGV("%s: exit", __func__);
231 return 0;
232}
233
234static int disable_snd_device(struct audio_route *ar,
235 snd_device_t snd_device)
236{
237 ALOGV("%s: enter: snd_device(%d)", __func__, snd_device);
238 audio_route_reset_path(ar, device_table[snd_device]);
239 ALOGV("%s: exit", __func__);
240 return 0;
241}
242
243static int set_hdmi_channels(struct mixer *mixer,
244 int channel_count)
245{
246 struct mixer_ctl *ctl;
247 const char *channel_cnt_str = NULL;
248 const char *mixer_ctl_name = "HDMI_RX Channels";
249 switch (channel_count) {
250 case 8:
251 channel_cnt_str = "Eight"; break;
252 case 7:
253 channel_cnt_str = "Seven"; break;
254 case 6:
255 channel_cnt_str = "Six"; break;
256 case 5:
257 channel_cnt_str = "Five"; break;
258 case 4:
259 channel_cnt_str = "Four"; break;
260 case 3:
261 channel_cnt_str = "Three"; break;
262 default:
263 channel_cnt_str = "Two"; break;
264 }
265 ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
266 if (!ctl) {
267 ALOGE("%s: Could not get ctl for mixer cmd - %s",
268 __func__, mixer_ctl_name);
269 return -EINVAL;
270 }
271 ALOGV("HDMI channel count: %s", channel_cnt_str);
272 mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
273 return 0;
274}
275
276/* must be called with hw device mutex locked */
277static void read_hdmi_channel_masks(struct stream_out *out)
278{
279 int channels = edid_get_max_channels();
280 ALOGE("%s: enter", __func__);
281
282 switch (channels) {
283 /*
284 * Do not handle stereo output in Multi-channel cases
285 * Stereo case is handled in normal playback path
286 */
287 case 6:
288 ALOGV("%s: HDMI supports 5.1", __func__);
289 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1;
290 break;
291 case 8:
292 ALOGV("%s: HDMI supports 5.1 and 7.1 channels", __func__);
293 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1;
294 out->supported_channel_masks[1] = AUDIO_CHANNEL_OUT_7POINT1;
295 break;
296 default:
297 ALOGE("Unsupported number of channels (%d)", channels);
298 break;
299 }
300
301 ALOGE("%s: exit", __func__);
302}
303
304static snd_device_t get_output_snd_device(struct audio_device *adev)
305{
306 audio_source_t source = adev->input_source;
307 audio_mode_t mode = adev->mode;
308 audio_devices_t devices = adev->out_device;
309 snd_device_t snd_device = SND_DEVICE_INVALID;
310
311 ALOGV("%s: enter: output devices(0x%x)", __func__, devices);
312 if (devices == AUDIO_DEVICE_NONE ||
313 devices & AUDIO_DEVICE_BIT_IN) {
314 ALOGV("%s: Invalid output devices (0x%x)", __func__, devices);
315 goto exit;
316 }
317
318 if (mode == AUDIO_MODE_IN_CALL) {
319 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
320 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
321 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
322 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
323 snd_device = SND_DEVICE_OUT_BT_SCO;
324 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
325 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
326 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
327 snd_device = SND_DEVICE_OUT_HANDSET;
328 }
329 if (snd_device != SND_DEVICE_INVALID) {
330 goto exit;
331 }
332 }
333
334 if (popcount(devices) == 2) {
335 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
336 AUDIO_DEVICE_OUT_SPEAKER)) {
337 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
338 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
339 AUDIO_DEVICE_OUT_SPEAKER)) {
340 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
341 } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
342 AUDIO_DEVICE_OUT_SPEAKER)) {
343 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
344 } else {
345 ALOGE("%s: Invalid combo device(0x%x)", __func__, devices);
346 goto exit;
347 }
348 }
349 if (popcount(devices) != 1) {
350 ALOGE("%s: Invalid output devices(0x%x)", __func__, devices);
351 goto exit;
352 }
353
354 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
355 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
356 snd_device = SND_DEVICE_OUT_HEADPHONES;
357 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
358 snd_device = SND_DEVICE_OUT_SPEAKER;
359 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
360 snd_device = SND_DEVICE_OUT_BT_SCO;
361 } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
362 snd_device = SND_DEVICE_OUT_HDMI ;
363 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
364 snd_device = SND_DEVICE_OUT_HANDSET;
365 } else {
366 ALOGE("%s: Unknown device(s) 0x%x", __func__, devices);
367 }
368exit:
369 ALOGV("%s: exit: snd_device(%d)", __func__, snd_device);
370 return snd_device;
371}
372
373static snd_device_t get_input_snd_device(struct audio_device *adev)
374{
375 audio_source_t source = adev->input_source;
376 audio_mode_t mode = adev->mode;
377 audio_devices_t out_device = adev->out_device;
378 audio_devices_t in_device = adev->in_device;
379 snd_device_t snd_device = SND_DEVICE_INVALID;
380
381 ALOGV("%s: enter: out_device(0x%x) in_device(0x%x)",
382 __func__, out_device, in_device);
383 if (mode == AUDIO_MODE_IN_CALL) {
384 if (out_device == AUDIO_DEVICE_NONE) {
385 ALOGE("%s: No output device set for voice call", __func__);
386 goto exit;
387 }
388 /* ToDo: Consider TTY mode and fluence mode as well */
389 if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
390 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
391 snd_device = SND_DEVICE_IN_HANDSET_MIC ;
392 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
393 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
394 } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
395 snd_device = SND_DEVICE_IN_BT_SCO_MIC ;
396 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
397 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
398 }
399 } else if (source == AUDIO_SOURCE_CAMCORDER) {
400 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
401 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
402 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
403 }
404 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
405 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
406 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
407 }
408 } else if (source == AUDIO_SOURCE_DEFAULT) {
409 goto exit;
410 }
411
412 if (snd_device != SND_DEVICE_INVALID) {
413 goto exit;
414 }
415
416 if (in_device != AUDIO_DEVICE_NONE) {
417 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
418 snd_device = SND_DEVICE_IN_HANDSET_MIC ;
419 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
420 /* ToDo: Not a valid device, should set default ?
421 If not valid it should be removed from audio_policy.conf file ?
422 default: if mic_type = analog, use handset-mic otherwise speaker-mic*/
423 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
424 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
425 snd_device = SND_DEVICE_IN_HEADSET_MIC;
426 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
427 snd_device = SND_DEVICE_IN_BT_SCO_MIC ;
428 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
429 snd_device = SND_DEVICE_IN_HDMI_MIC;
430 } else {
431 ALOGE("%s: Unknown input device(s) 0x%x", __func__, in_device);
432 }
433 } else {
434 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
435 snd_device = SND_DEVICE_IN_HANDSET_MIC ;
436 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
437 snd_device = SND_DEVICE_IN_HEADSET_MIC;
438 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
439 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
440 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
441 snd_device = SND_DEVICE_IN_HANDSET_MIC ;
442 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
443 snd_device = SND_DEVICE_IN_BT_SCO_MIC ;
444 } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
445 snd_device = SND_DEVICE_IN_HDMI_MIC;
446 } else {
447 ALOGE("%s: Unknown output device(s) 0x%x", __func__, out_device);
448 }
449 }
450exit:
451 ALOGV("%s: exit: in_snd_device(%d)", __func__, snd_device);
452 return snd_device;
453}
454
455static int select_devices(struct audio_device *adev)
456{
457 snd_device_t out_snd_device = SND_DEVICE_INVALID;
458 snd_device_t in_snd_device = SND_DEVICE_INVALID;
459 struct audio_usecase *usecase;
460 int status = 0;
461 int acdb_rx_id, acdb_tx_id;
462 bool in_call_device_switch = false;
463
464 ALOGV("%s: enter", __func__);
465 out_snd_device = get_output_snd_device(adev);
466 in_snd_device = get_input_snd_device(adev);
467
468 if (out_snd_device == adev->cur_out_snd_device && adev->out_snd_device_active &&
469 in_snd_device == adev->cur_in_snd_device && adev->in_snd_device_active) {
470 ALOGV("%s: exit: snd_devices (%d and %d) is already active",
471 __func__, out_snd_device, in_snd_device);
472 return 0;
473 }
474
475 /*
476 * Limitation: While in call, to do a device switch we need to disable
477 * and enable both RX and TX devices though one of them is same as current
478 * device.
479 */
480 if (adev->mode == AUDIO_MODE_IN_CALL &&
481 adev->csd_client != NULL &&
482 out_snd_device != SND_DEVICE_INVALID &&
483 in_snd_device != SND_DEVICE_INVALID &&
484 adev->cur_out_snd_device != SND_DEVICE_INVALID &&
485 adev->cur_in_snd_device != SND_DEVICE_INVALID) {
486 in_call_device_switch = true;
487 }
488
489 if ((out_snd_device != adev->cur_out_snd_device || in_call_device_switch)
490 && adev->out_snd_device_active) {
491 usecase = &adev->usecase_list;
492 while (usecase->next != NULL) {
493 usecase = usecase->next;
494 if (usecase->type == PCM_PLAYBACK || usecase->type == VOICE_CALL) {
495 disable_audio_route(adev->audio_route, usecase->id,
496 adev->cur_out_snd_device);
497 }
498 }
499 audio_route_update_mixer(adev->audio_route);
500 /* Disable current rx device */
501 disable_snd_device(adev->audio_route, adev->cur_out_snd_device);
502 adev->out_snd_device_active = false;
503 }
504
505 if ((in_snd_device != adev->cur_in_snd_device || in_call_device_switch)
506 && adev->in_snd_device_active) {
507 usecase = &adev->usecase_list;
508 while (usecase->next != NULL) {
509 usecase = usecase->next;
510 if (usecase->type == PCM_CAPTURE) {
511 disable_audio_route(adev->audio_route, usecase->id,
512 adev->cur_in_snd_device);
513 }
514 }
515 audio_route_update_mixer(adev->audio_route);
516 /* Disable current tx device */
517 disable_snd_device(adev->audio_route, adev->cur_in_snd_device);
518 adev->in_snd_device_active = false;
519 }
520
521 if (in_call_device_switch) {
522 if (adev->csd_disable_device == NULL) {
523 ALOGE("%s: dlsym error:%s for csd_client_disable_device",
524 __func__, dlerror());
525 } else {
526 status = adev->csd_disable_device();
527 if (status < 0) {
528 ALOGE("%s: csd_client_disable_device, failed, error %d",
529 __func__, status);
530 }
531 }
532 }
533
534 if (out_snd_device != SND_DEVICE_INVALID && !adev->out_snd_device_active) {
535 /* Enable new rx device */
536 status = enable_snd_device(adev, out_snd_device);
537 if (status != 0) {
538 ALOGE("%s: Failed to set mixer ctls for snd_device(%d)",
539 __func__, out_snd_device);
540 return status;
541 }
542 adev->out_snd_device_active = true;
543 adev->cur_out_snd_device = out_snd_device;
544 }
545
546 if (in_snd_device != SND_DEVICE_INVALID && !adev->in_snd_device_active) {
547 /* Enable new tx device */
548 status = enable_snd_device(adev, in_snd_device);
549 if (status != 0) {
550 ALOGE("%s: Failed to set mixer ctls for snd_device(%d)",
551 __func__, out_snd_device);
552 return status;
553 }
554 adev->in_snd_device_active = true;
555 adev->cur_in_snd_device = in_snd_device;
556 }
557 audio_route_update_mixer(adev->audio_route);
558
559 if (in_call_device_switch) {
560 if (adev->csd_enable_device == NULL) {
561 ALOGE("%s: dlsym error: %s for csd_client_enable_device",
562 __func__, dlerror());
563 } else {
564 acdb_rx_id = get_acdb_device_id(out_snd_device);
565 acdb_tx_id = get_acdb_device_id(in_snd_device);
566
567 /* ToDo: To make sure acdb_settings is updated properly based on TTY mode */
568 status = adev->csd_enable_device(acdb_rx_id, acdb_tx_id, adev->acdb_settings);
569 if (status < 0) {
570 ALOGE("%s: csd_client_enable_device, failed, error %d",
571 __func__, status);
572 }
573 }
574 }
575
576 usecase = &adev->usecase_list;
577 while (usecase->next != NULL) {
578 usecase = usecase->next;
579 if (usecase->type == PCM_PLAYBACK || usecase->type == VOICE_CALL) {
580 usecase->devices = adev->out_device; /* TODO: fix device logic */
581 status = enable_audio_route(adev->audio_route, usecase->id,
582 adev->cur_out_snd_device);
583 } else {
584 status = enable_audio_route(adev->audio_route, usecase->id,
585 adev->cur_in_snd_device);
586 }
587 }
588 audio_route_update_mixer(adev->audio_route);
589
590 ALOGV("%s: exit: status(%d)", __func__, status);
591 return status;
592}
593
594static void add_usecase_to_list(struct audio_device *adev,
595 struct audio_usecase *uc_info)
596{
597 struct audio_usecase *first_entry = adev->usecase_list.next;
598 ALOGV("%s: enter: usecase(%d)", __func__, uc_info->id);
599 /* Insert the new entry on the top of the list */
600 adev->usecase_list.next = uc_info;
601 uc_info->next = first_entry;
602 ALOGV("%s: exit", __func__);
603}
604
605static void remove_usecase_from_list(struct audio_device *adev,
606 audio_usecase_t uc_id)
607{
608 struct audio_usecase *uc_to_remove = NULL;
609 struct audio_usecase *list_head = &adev->usecase_list;
610 ALOGV("%s: enter: usecase(%d)", __func__, uc_id);
611 while (list_head->next != NULL) {
612 if (list_head->next->id == uc_id) {
613 uc_to_remove = list_head->next;
614 list_head->next = list_head->next->next;
615 free(uc_to_remove);
616 break;
617 }
618 list_head = list_head->next;
619 }
620 ALOGV("%s: exit", __func__);
621}
622
623static struct audio_usecase *get_usecase_from_list(struct audio_device *adev,
624 audio_usecase_t uc_id)
625{
626 struct audio_usecase *uc_info = NULL;
627 struct audio_usecase *list_head = &adev->usecase_list;
628 ALOGV("%s: enter: uc_id(%d)", __func__, uc_id);
629 while (list_head->next != NULL) {
630 list_head = list_head->next;
631 if (list_head->id == uc_id) {
632 uc_info = list_head;
633 break;
634 }
635 }
636 ALOGV("%s: exit: uc_info(%p)", __func__, uc_info);
637 return uc_info;
638}
639
640static int get_num_active_usecases(struct audio_device *adev)
641{
642 int num_uc = 0;
643 struct audio_usecase *list_head = &adev->usecase_list;
644 while (list_head->next != NULL) {
645 num_uc++;
646 list_head = list_head->next;
647 }
648 return num_uc;
649}
650
651static audio_devices_t get_active_out_devices(struct audio_device *adev,
652 audio_usecase_t usecase)
653{
654 audio_devices_t devices = 0;
655 struct audio_usecase *list_head = &adev->usecase_list;
656 /* Return the output devices of usecases other than given usecase */
657 while (list_head->next != NULL) {
658 list_head = list_head->next;
659 if (list_head->type == PCM_PLAYBACK && list_head->id != usecase) {
660 devices |= list_head->devices;
661 }
662 }
663 return devices;
664}
665
666static audio_devices_t get_voice_call_out_device(struct audio_device *adev)
667{
668 audio_devices_t devices = 0;
669 struct audio_usecase *list_head = &adev->usecase_list;
670 /* Return the output devices of usecases other than given usecase */
671 while (list_head->next != NULL) {
672 list_head = list_head->next;
673 if (list_head->id == USECASE_VOICE_CALL) {
674 devices = list_head->devices;
675 break;
676 }
677 }
678 return devices;
679}
680
681static int stop_input_stream(struct stream_in *in)
682{
683 int i, ret = 0;
684 snd_device_t in_snd_device;
685 struct audio_usecase *uc_info;
686 struct audio_device *adev = in->dev;
687
688 ALOGV("%s: enter: usecase(%d)", __func__, in->usecase);
689 adev->input_source = AUDIO_SOURCE_DEFAULT;
690 adev->in_device = AUDIO_DEVICE_NONE;
691
692 uc_info = get_usecase_from_list(adev, in->usecase);
693 if (uc_info == NULL) {
694 ALOGE("%s: Could not find the usecase (%d) in the list",
695 __func__, in->usecase);
696 return -EINVAL;
697 }
698
699 /* 1. Close the PCM device first */
700 if (in->pcm) {
701 pcm_close(in->pcm);
702 in->pcm = NULL;
703 }
704
705 /* 2. Disable stream specific mixer controls */
706 in_snd_device = adev->cur_in_snd_device;
707 disable_audio_route(adev->audio_route, in->usecase, in_snd_device);
708 audio_route_update_mixer(adev->audio_route);
709
710 remove_usecase_from_list(adev, in->usecase);
711
712 /* 3. Disable the tx device */
713 select_devices(adev);
714
715 ALOGV("%s: exit: status(%d)", __func__, ret);
716 return ret;
717}
718
719int start_input_stream(struct stream_in *in)
720{
721 /* 1. Enable output device and stream routing controls */
722 int status, ret = 0;
723 snd_device_t in_snd_device;
724 struct audio_usecase *uc_info;
725 struct audio_device *adev = in->dev;
726
727 ALOGV("%s: enter: usecase(%d)", __func__, in->usecase);
728 adev->input_source = in->source;
729 adev->in_device = in->device;
730 in_snd_device = get_input_snd_device(adev);
731 if (in_snd_device == SND_DEVICE_INVALID) {
732 ALOGE("%s: Could not get valid input sound device", __func__);
733 /*
734 * TODO: use a single exit point to avoid duplicating code to
735 * reset input source and device
736 */
737 adev->input_source = AUDIO_SOURCE_DEFAULT;
738 adev->in_device = AUDIO_DEVICE_NONE;
739 return -EINVAL;
740 }
741
742 in->pcm_device_id = get_pcm_device_id(adev->audio_route,
743 in->usecase,
744 PCM_CAPTURE);
745 if (in->pcm_device_id < 0) {
746 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
747 __func__, in->usecase);
748 adev->input_source = AUDIO_SOURCE_DEFAULT;
749 adev->in_device = AUDIO_DEVICE_NONE;
750 return -EINVAL;
751 }
752 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
753 uc_info->id = in->usecase;
754 uc_info->type = PCM_CAPTURE;
755 uc_info->devices = in->device;
756
757 /* 1. Enable the TX device */
758 ret = select_devices(adev);
759 if (ret) {
760 ALOGE("%s: Failed to enable device(0x%x)",
761 __func__, adev->in_device);
762 adev->input_source = AUDIO_SOURCE_DEFAULT;
763 adev->in_device = AUDIO_DEVICE_NONE;
764 free(uc_info);
765 return ret;
766 }
767 in_snd_device = adev->cur_in_snd_device;
768
769 /* 2. Enable the mixer controls for the audio route */
770 enable_audio_route(adev->audio_route, in->usecase, in_snd_device);
771 audio_route_update_mixer(adev->audio_route);
772
773 /* 3. Add the usecase info to usecase list */
774 add_usecase_to_list(adev, uc_info);
775
776 /* 2. Open the pcm device */
777 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
778 __func__, SOUND_CARD, in->pcm_device_id);
779 in->pcm = pcm_open(SOUND_CARD, in->pcm_device_id,
780 PCM_IN, &in->config);
781 if (in->pcm && !pcm_is_ready(in->pcm)) {
782 ALOGE("%s: %s", __func__, pcm_get_error(in->pcm));
783 pcm_close(in->pcm);
784 in->pcm = NULL;
785 status = -EIO;
786 goto error;
787 }
788 ALOGV("%s: exit", __func__);
789 return 0;
790error:
791 ALOGV("%s: exit: status(%d)", __func__, status);
792 stop_input_stream(in);
793 return status;
794}
795
796static int stop_output_stream(struct stream_out *out)
797{
798 int i, ret = 0;
799 snd_device_t out_snd_device;
800 struct audio_usecase *uc_info;
801 struct audio_device *adev = out->dev;
802
803 ALOGV("%s: enter: usecase(%d)", __func__, out->usecase);
804 uc_info = get_usecase_from_list(adev, out->usecase);
805 if (uc_info == NULL) {
806 ALOGE("%s: Could not find the usecase (%d) in the list",
807 __func__, out->usecase);
808 return -EINVAL;
809 }
810
811 /* 1. Close the PCM device first */
812 if (out->pcm) {
813 pcm_close(out->pcm);
814 out->pcm = NULL;
815 }
816
817 /* 2. Get and set stream specific mixer controls */
818 out_snd_device = adev->cur_out_snd_device;
819 disable_audio_route(adev->audio_route, out->usecase, out_snd_device);
820 audio_route_update_mixer(adev->audio_route);
821
822 remove_usecase_from_list(adev, uc_info->id);
823
824 /* 3. Disable the rx device */
825 adev->out_device = get_active_out_devices(adev, out->usecase);
826 adev->out_device |= get_voice_call_out_device(adev);
827 ret = select_devices(adev);
828
829 ALOGV("%s: exit: status(%d)", __func__, ret);
830 return ret;
831}
832
833int start_output_stream(struct stream_out *out)
834{
835 int status;
836 int ret = 0;
837 snd_device_t out_snd_device;
838 struct audio_usecase *uc_info;
839 struct audio_device *adev = out->dev;
840
841 /* 1. Enable output device and stream routing controls */
842 ALOGV("%s: enter: usecase(%d)", __func__, out->usecase);
843 adev->out_device |= out->devices;
844 out_snd_device = get_output_snd_device(adev);
845 if (out_snd_device == SND_DEVICE_INVALID) {
846 ALOGE("%s: Could not get valid output sound device", __func__);
847 /*
848 * TODO: use a single exit point to avoid duplicating code to
849 * reset output device
850 */
851 adev->out_device = get_active_out_devices(adev, out->usecase);
852 adev->out_device |= get_voice_call_out_device(adev);
853 return -EINVAL;
854 }
855
856 out->pcm_device_id = get_pcm_device_id(adev->audio_route,
857 out->usecase,
858 PCM_PLAYBACK);
859 if (out->pcm_device_id < 0) {
860 ALOGE("%s: Invalid PCM device id(%d) for the usecase(%d)",
861 __func__, out->pcm_device_id, out->usecase);
862 adev->out_device = get_active_out_devices(adev, out->usecase);
863 adev->out_device |= get_voice_call_out_device(adev);
864 return -EINVAL;
865 }
866
867 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
868 uc_info->id = out->usecase;
869 uc_info->type = PCM_PLAYBACK;
870 uc_info->devices = out->devices;
871
872 ret = select_devices(adev);
873 if (ret) {
874 ALOGE("%s: Failed to enable device(0x%x)",
875 __func__, adev->out_device);
876 adev->out_device = get_active_out_devices(adev, out->usecase);
877 adev->out_device |= get_voice_call_out_device(adev);
878 free(uc_info);
879 return ret;
880 }
881
882 out_snd_device = adev->cur_out_snd_device;
883 enable_audio_route(adev->audio_route, out->usecase, out_snd_device);
884 audio_route_update_mixer(adev->audio_route);
885
886 add_usecase_to_list(adev, uc_info);
887
888 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
889 __func__, 0, out->pcm_device_id);
890 out->pcm = pcm_open(SOUND_CARD, out->pcm_device_id,
891 PCM_OUT, &out->config);
892 if (out->pcm && !pcm_is_ready(out->pcm)) {
893 ALOGE("%s: %s", __func__, pcm_get_error(out->pcm));
894 pcm_close(out->pcm);
895 out->pcm = NULL;
896 status = -EIO;
897 goto error;
898 }
899 ALOGV("%s: exit", __func__);
900 return 0;
901error:
902 stop_output_stream(out);
903 ALOGE("%s: exit: status(%d)", __func__, status);
904 return status;
905}
906
907static int stop_voice_call(struct audio_device *adev)
908{
909 int i, ret = 0;
910 snd_device_t out_snd_device;
911 struct audio_usecase *uc_info;
912
913 ALOGV("%s: enter: usecase(%d)", __func__, USECASE_VOICE_CALL);
914 if (adev->csd_client) {
915 if (adev->csd_stop_voice == NULL) {
916 ALOGE("dlsym:Error:%s Loading csd_client_disable_device", dlerror());
917 } else {
918 ret = adev->csd_stop_voice();
919 if (ret < 0) {
920 ALOGE("%s: csd_client error %d\n", __func__, ret);
921 }
922 }
923 }
924
925 /* 1. Close the PCM devices */
926 if (adev->voice_call_rx) {
927 pcm_close(adev->voice_call_rx);
928 adev->voice_call_rx = NULL;
929 }
930 if (adev->voice_call_tx) {
931 pcm_close(adev->voice_call_tx);
932 adev->voice_call_tx = NULL;
933 }
934
935 uc_info = get_usecase_from_list(adev, USECASE_VOICE_CALL);
936 if (uc_info == NULL) {
937 ALOGE("%s: Could not find the usecase (%d) in the list",
938 __func__, USECASE_VOICE_CALL);
939 return -EINVAL;
940 }
941 out_snd_device = adev->cur_out_snd_device;
942
943 /* 2. Get and set stream specific mixer controls */
944 /* ToDo: Status check ?*/
945 disable_audio_route(adev->audio_route, USECASE_VOICE_CALL, out_snd_device);
946 audio_route_update_mixer(adev->audio_route);
947
948 remove_usecase_from_list(adev, uc_info->id);
949
950 /* 3. Disable the rx and tx devices */
951 ret = select_devices(adev);
952 adev->in_call = false;
953
954 ALOGV("%s: exit: status(%d)", __func__, ret);
955 return ret;
956}
957
958static int start_voice_call(struct audio_device *adev)
959{
960 int i, ret = 0;
961 snd_device_t out_snd_device;
962 struct audio_usecase *uc_info;
963 int pcm_dev_rx_id, pcm_dev_tx_id;
964
965 ALOGV("%s: enter", __func__);
966
967 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
968 uc_info->id = USECASE_VOICE_CALL;
969 uc_info->type = VOICE_CALL;
970 uc_info->devices = adev->out_device;
971
972 ret = select_devices(adev);
973 if (ret) {
974 free(uc_info);
975 return ret;
976 }
977
978 /* 2. Get and set stream specific mixer controls */
979 out_snd_device = adev->cur_out_snd_device;
980 /* ToDo: Status check ?*/
981 enable_audio_route(adev->audio_route, uc_info->id, out_snd_device);
982 audio_route_update_mixer(adev->audio_route);
983
984 add_usecase_to_list(adev, uc_info);
985
986 pcm_dev_rx_id = get_pcm_device_id(adev->audio_route, uc_info->id,
987 PCM_PLAYBACK);
988 pcm_dev_tx_id = get_pcm_device_id(adev->audio_route, uc_info->id,
989 PCM_CAPTURE);
990
991 /* 2. Open the pcm device */
992 if (pcm_dev_rx_id < 0 || pcm_dev_tx_id < 0) {
993 ALOGE("%s: Invalid PCM devices (rx: %d tx: %d) for the usecase(%d)",
994 __func__, pcm_dev_rx_id, pcm_dev_tx_id, uc_info->id);
995 stop_voice_call(adev);
996 goto error;
997 }
998
999 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
1000 __func__, SOUND_CARD, pcm_dev_rx_id);
1001 adev->voice_call_rx = pcm_open(SOUND_CARD,
1002 pcm_dev_rx_id,
1003 PCM_OUT, &pcm_config_voice_call);
1004 if (adev->voice_call_rx && !pcm_is_ready(adev->voice_call_rx)) {
1005 ALOGE("%s: %s", __func__, pcm_get_error(adev->voice_call_rx));
1006 /* ToDo: Check return status ??*/
1007 stop_voice_call(adev);
1008 return -EIO;
1009 }
1010
1011 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
1012 __func__, SOUND_CARD, pcm_dev_tx_id);
1013 adev->voice_call_tx = pcm_open(SOUND_CARD,
1014 pcm_dev_tx_id,
1015 PCM_IN, &pcm_config_voice_call);
1016 if (adev->voice_call_tx && !pcm_is_ready(adev->voice_call_tx)) {
1017 ALOGE("%s: %s", __func__, pcm_get_error(adev->voice_call_tx));
1018 /* ToDo: Check return status ??*/
1019 stop_voice_call(adev);
1020 return -EIO;
1021 }
1022 pcm_start(adev->voice_call_rx);
1023 pcm_start(adev->voice_call_tx);
1024
1025 if (adev->csd_client) {
1026 if (adev->csd_start_voice == NULL) {
1027 ALOGE("dlsym:Error:%s Loading csd_client_start_voice", dlerror());
1028 } else {
1029 ret = adev->csd_start_voice();
1030 if (ret < 0) {
1031 ALOGE("%s: csd_client error %d\n", __func__, ret);
1032 }
1033 }
1034 }
1035
1036 adev->in_call = true;
1037error:
1038 ALOGV("%s: exit: status(%d)", __func__, ret);
1039 return ret;
1040}
1041
1042static int check_input_parameters(uint32_t sample_rate,
1043 audio_format_t format,
1044 int channel_count)
1045{
1046 if (format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
1047
1048 if ((channel_count < 1) || (channel_count > 2)) return -EINVAL;
1049
1050 switch (sample_rate) {
1051 case 8000:
1052 case 11025:
1053 case 12000:
1054 case 16000:
1055 case 22050:
1056 case 24000:
1057 case 32000:
1058 case 44100:
1059 case 48000:
1060 break;
1061 default:
1062 return -EINVAL;
1063 }
1064
1065 return 0;
1066}
1067
1068static size_t get_input_buffer_size(uint32_t sample_rate,
1069 audio_format_t format,
1070 int channel_count)
1071{
1072 size_t size = 0;
1073
1074 if (check_input_parameters(sample_rate, format, channel_count) != 0) return 0;
1075
1076 if (sample_rate == 8000 || sample_rate == 16000 || sample_rate == 32000) {
1077 size = (sample_rate * 20) / 1000;
1078 } else if (sample_rate == 11025 || sample_rate == 12000) {
1079 size = 256;
1080 } else if (sample_rate == 22050 || sample_rate == 24000) {
1081 size = 512;
1082 } else if (sample_rate == 44100 || sample_rate == 48000) {
1083 size = 1024;
1084 }
1085
1086 return size * sizeof(short) * channel_count;
1087}
1088
1089static uint32_t out_get_sample_rate(const struct audio_stream *stream)
1090{
1091 struct stream_out *out = (struct stream_out *)stream;
1092
1093 return out->config.rate;
1094}
1095
1096static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
1097{
1098 return -ENOSYS;
1099}
1100
1101static size_t out_get_buffer_size(const struct audio_stream *stream)
1102{
1103 struct stream_out *out = (struct stream_out *)stream;
1104
1105 return out->config.period_size * audio_stream_frame_size(stream);
1106}
1107
1108static uint32_t out_get_channels(const struct audio_stream *stream)
1109{
1110 struct stream_out *out = (struct stream_out *)stream;
1111
1112 return out->channel_mask;
1113}
1114
1115static audio_format_t out_get_format(const struct audio_stream *stream)
1116{
1117 return AUDIO_FORMAT_PCM_16_BIT;
1118}
1119
1120static int out_set_format(struct audio_stream *stream, audio_format_t format)
1121{
1122 return -ENOSYS;
1123}
1124
1125static int out_standby(struct audio_stream *stream)
1126{
1127 struct stream_out *out = (struct stream_out *)stream;
1128 struct audio_device *adev = out->dev;
1129 ALOGV("%s: enter: usecase(%d)", __func__, out->usecase);
1130 pthread_mutex_lock(&out->dev->lock);
1131 pthread_mutex_lock(&out->lock);
1132
1133 if (!out->standby) {
1134 out->standby = true;
1135 stop_output_stream(out);
1136 }
1137 pthread_mutex_unlock(&out->lock);
1138 pthread_mutex_unlock(&out->dev->lock);
1139 ALOGV("%s: exit", __func__);
1140 return 0;
1141}
1142
1143static int out_dump(const struct audio_stream *stream, int fd)
1144{
1145 return 0;
1146}
1147
1148static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
1149{
1150 struct stream_out *out = (struct stream_out *)stream;
1151 struct audio_device *adev = out->dev;
1152 struct str_parms *parms;
1153 char value[32];
1154 int ret, val = 0;
1155
1156 ALOGV("%s: enter: usecase(%d) kvpairs: %s",
1157 __func__, out->usecase, kvpairs);
1158 parms = str_parms_create_str(kvpairs);
1159 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
1160 if (ret >= 0) {
1161 val = atoi(value);
1162 pthread_mutex_lock(&adev->lock);
1163 pthread_mutex_lock(&out->lock);
1164
1165 if (adev->mode == AUDIO_MODE_IN_CALL && !adev->in_call) {
1166 adev->out_device = get_active_out_devices(adev, out->usecase) | val;
1167 start_voice_call(adev);
1168 } else if (adev->mode != AUDIO_MODE_IN_CALL && adev->in_call) {
1169 adev->out_device = get_active_out_devices(adev, out->usecase) | val;
1170 stop_voice_call(adev);
1171 } else if ((adev->out_device != (audio_devices_t)val) && (val != 0)) {
1172 if (!out->standby || adev->in_call) {
1173 adev->out_device = get_active_out_devices(adev, out->usecase) | val;
1174 ret = select_devices(adev);
1175 }
1176 }
1177 out->devices = val;
1178
1179 pthread_mutex_unlock(&out->lock);
1180 pthread_mutex_unlock(&adev->lock);
1181 }
1182 str_parms_destroy(parms);
1183 ALOGV("%s: exit: code(%d)", __func__, ret);
1184 return ret;
1185}
1186
1187static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
1188{
1189 struct stream_out *out = (struct stream_out *)stream;
1190 struct str_parms *query = str_parms_create_str(keys);
1191 char *str;
1192 char value[256];
1193 struct str_parms *reply = str_parms_create();
1194 size_t i, j;
1195 int ret;
1196 bool first = true;
1197 ALOGV("%s: enter: keys - %s", __func__, keys);
1198 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
1199 if (ret >= 0) {
1200 value[0] = '\0';
1201 i = 0;
1202 while (out->supported_channel_masks[i] != 0) {
1203 for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
1204 if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
1205 if (!first) {
1206 strcat(value, "|");
1207 }
1208 strcat(value, out_channels_name_to_enum_table[j].name);
1209 first = false;
1210 break;
1211 }
1212 }
1213 i++;
1214 }
1215 str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
1216 str = str_parms_to_str(reply);
1217 } else {
1218 str = strdup(keys);
1219 }
1220 str_parms_destroy(query);
1221 str_parms_destroy(reply);
1222 ALOGV("%s: exit: returns - %s", __func__, str);
1223 return str;
1224}
1225
1226static uint32_t out_get_latency(const struct audio_stream_out *stream)
1227{
1228 struct stream_out *out = (struct stream_out *)stream;
1229
1230 return (out->config.period_count * out->config.period_size * 1000) / (out->config.rate);
1231}
1232
1233static int out_set_volume(struct audio_stream_out *stream, float left,
1234 float right)
1235{
1236 return -ENOSYS;
1237}
1238
1239static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
1240 size_t bytes)
1241{
1242 struct stream_out *out = (struct stream_out *)stream;
1243 struct audio_device *adev = out->dev;
1244 int i, ret = -1;
1245
1246 /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
1247 * on the output stream mutex - e.g. executing select_mode() while holding the hw device
1248 * mutex
1249 */
1250 pthread_mutex_lock(&adev->lock);
1251 pthread_mutex_lock(&out->lock);
1252 if (out->standby) {
1253 ret = start_output_stream(out);
1254 if (ret != 0) {
1255 pthread_mutex_unlock(&adev->lock);
1256 goto exit;
1257 }
1258 out->standby = false;
1259 }
1260 pthread_mutex_unlock(&adev->lock);
1261
1262 if (out->pcm) {
1263 //ALOGV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
1264 ret = pcm_write(out->pcm, (void *)buffer, bytes);
1265 }
1266
1267exit:
1268 pthread_mutex_unlock(&out->lock);
1269
1270 if (ret != 0) {
1271 out_standby(&out->stream.common);
1272 usleep(bytes * 1000000 / audio_stream_frame_size(&out->stream.common) /
1273 out_get_sample_rate(&out->stream.common));
1274 }
1275 return bytes;
1276}
1277
1278static int out_get_render_position(const struct audio_stream_out *stream,
1279 uint32_t *dsp_frames)
1280{
1281 return -EINVAL;
1282}
1283
1284static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1285{
1286 return 0;
1287}
1288
1289static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1290{
1291 return 0;
1292}
1293
1294static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
1295 int64_t *timestamp)
1296{
1297 return -EINVAL;
1298}
1299
1300/** audio_stream_in implementation **/
1301static uint32_t in_get_sample_rate(const struct audio_stream *stream)
1302{
1303 struct stream_in *in = (struct stream_in *)stream;
1304
1305 return in->config.rate;
1306}
1307
1308static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
1309{
1310 return -ENOSYS;
1311}
1312
1313static size_t in_get_buffer_size(const struct audio_stream *stream)
1314{
1315 struct stream_in *in = (struct stream_in *)stream;
1316
1317 return in->config.period_size * audio_stream_frame_size(stream);
1318}
1319
1320static uint32_t in_get_channels(const struct audio_stream *stream)
1321{
1322 struct stream_in *in = (struct stream_in *)stream;
1323
1324 return in->channel_mask;
1325}
1326
1327static audio_format_t in_get_format(const struct audio_stream *stream)
1328{
1329 return AUDIO_FORMAT_PCM_16_BIT;
1330}
1331
1332static int in_set_format(struct audio_stream *stream, audio_format_t format)
1333{
1334 return -ENOSYS;
1335}
1336
1337static int in_standby(struct audio_stream *stream)
1338{
1339 struct stream_in *in = (struct stream_in *)stream;
1340 struct audio_device *adev = in->dev;
1341 int status = 0;
1342 ALOGV("%s: enter", __func__);
1343 pthread_mutex_lock(&adev->lock);
1344 pthread_mutex_lock(&in->lock);
1345 if (!in->standby) {
1346 adev->input_source = AUDIO_SOURCE_DEFAULT;
1347 adev->in_device = AUDIO_DEVICE_NONE;
1348 in->standby = true;
1349 status = stop_input_stream(in);
1350 }
1351 pthread_mutex_unlock(&in->lock);
1352 pthread_mutex_unlock(&adev->lock);
1353 ALOGV("%s: exit: status(%d)", __func__, status);
1354 return status;
1355}
1356
1357static int in_dump(const struct audio_stream *stream, int fd)
1358{
1359 return 0;
1360}
1361
1362static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
1363{
1364 struct stream_in *in = (struct stream_in *)stream;
1365 struct audio_device *adev = in->dev;
1366 struct str_parms *parms;
1367 char *str;
1368 char value[32];
1369 int ret, val = 0;
1370
1371 ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
1372 parms = str_parms_create_str(kvpairs);
1373
1374 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
1375
1376 pthread_mutex_lock(&adev->lock);
1377 pthread_mutex_lock(&in->lock);
1378 if (ret >= 0) {
1379 val = atoi(value);
1380 /* no audio source uses val == 0 */
1381 if ((in->source != val) && (val != 0)) {
1382 in->source = val;
1383 }
1384 }
1385
1386 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
1387 if (ret >= 0) {
1388 val = atoi(value);
1389 if ((in->device != val) && (val != 0)) {
1390 in->device = val;
1391 /* If recording is in progress, change the tx device to new device */
1392 if (!in->standby) {
1393 adev->input_source = in->source;
1394 adev->in_device = in->device;
1395 ret = select_devices(adev);
1396 }
1397 }
1398 }
1399
1400 pthread_mutex_unlock(&in->lock);
1401 pthread_mutex_unlock(&adev->lock);
1402
1403 str_parms_destroy(parms);
1404 ALOGV("%s: exit: status(%d)", __func__, ret);
1405 return ret;
1406}
1407
1408static char* in_get_parameters(const struct audio_stream *stream,
1409 const char *keys)
1410{
1411 return strdup("");
1412}
1413
1414static int in_set_gain(struct audio_stream_in *stream, float gain)
1415{
1416 return 0;
1417}
1418
1419static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
1420 size_t bytes)
1421{
1422 struct stream_in *in = (struct stream_in *)stream;
1423 struct audio_device *adev = in->dev;
1424 int i, ret = -1;
1425
1426 /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
1427 * on the output stream mutex - e.g. executing select_mode() while holding the hw device
1428 * mutex
1429 */
1430 //ALOGV("%s: buffer(%p) bytes(%d)", __func__, buffer, bytes);
1431 pthread_mutex_lock(&adev->lock);
1432 pthread_mutex_lock(&in->lock);
1433 if (in->standby) {
1434 ret = start_input_stream(in);
1435 if (ret != 0) {
1436 pthread_mutex_unlock(&adev->lock);
1437 goto exit;
1438 }
1439 in->standby = 0;
1440 }
1441 pthread_mutex_unlock(&adev->lock);
1442
1443 if (in->pcm) {
1444 ret = pcm_read(in->pcm, buffer, bytes);
1445 }
1446
1447 /*
1448 * Instead of writing zeroes here, we could trust the hardware
1449 * to always provide zeroes when muted.
1450 */
1451 if (ret == 0 && adev->mic_mute)
1452 memset(buffer, 0, bytes);
1453
1454exit:
1455 pthread_mutex_unlock(&in->lock);
1456
1457 if (ret != 0) {
1458 in_standby(&in->stream.common);
1459 ALOGV("%s: read failed - sleeping for buffer duration", __func__);
1460 usleep(bytes * 1000000 / audio_stream_frame_size(&in->stream.common) /
1461 in_get_sample_rate(&in->stream.common));
1462 }
1463 return bytes;
1464}
1465
1466static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
1467{
1468 return 0;
1469}
1470
1471static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1472{
1473 return 0;
1474}
1475
1476static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1477{
1478 return 0;
1479}
1480
1481static int adev_open_output_stream(struct audio_hw_device *dev,
1482 audio_io_handle_t handle,
1483 audio_devices_t devices,
1484 audio_output_flags_t flags,
1485 struct audio_config *config,
1486 struct audio_stream_out **stream_out)
1487{
1488 struct audio_device *adev = (struct audio_device *)dev;
1489 struct stream_out *out;
1490 int i, ret;
1491
1492 ALOGV("%s: enter: sample_rate(%d) channel_mask(0x%x) devices(0x%x) flags(0x%x)",
1493 __func__, config->sample_rate, config->channel_mask, devices, flags);
1494 *stream_out = NULL;
1495 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
1496
1497 if (devices == AUDIO_DEVICE_NONE)
1498 devices = AUDIO_DEVICE_OUT_SPEAKER;
1499
1500 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
1501 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1502 out->flags = flags;
1503 out->devices = devices;
1504
1505 /* Init use case and pcm_config */
1506 if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT &&
1507 out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1508 out->usecase = USECASE_AUDIO_PLAYBACK_MULTI_CH;
1509 out->config = pcm_config_hdmi_multi;
1510
1511 pthread_mutex_lock(&adev->lock);
1512 read_hdmi_channel_masks(out);
1513 pthread_mutex_unlock(&adev->lock);
1514
1515 if (config->sample_rate == 0) config->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
1516 if (config->channel_mask == 0) config->channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
1517 out->channel_mask = config->channel_mask;
1518 out->config.rate = config->sample_rate;
1519 out->config.channels = popcount(out->channel_mask);
1520 out->config.period_size = HDMI_MULTI_PERIOD_BYTES / (out->config.channels * 2);
1521 set_hdmi_channels(adev->mixer, out->config.channels);
1522 } else if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) {
1523 out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
1524 out->config = pcm_config_deep_buffer;
1525 } else {
1526 out->usecase = USECASE_AUDIO_PLAYBACK_LOW_LATENCY;
1527 out->config = pcm_config_low_latency;
1528 }
1529
1530 /* Check if this usecase is already existing */
1531 pthread_mutex_lock(&adev->lock);
1532 if (get_usecase_from_list(adev, out->usecase) != NULL) {
1533 ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
1534 free(out);
1535 *stream_out = NULL;
1536 pthread_mutex_unlock(&adev->lock);
1537 return -EEXIST;
1538 }
1539 pthread_mutex_unlock(&adev->lock);
1540
1541 out->stream.common.get_sample_rate = out_get_sample_rate;
1542 out->stream.common.set_sample_rate = out_set_sample_rate;
1543 out->stream.common.get_buffer_size = out_get_buffer_size;
1544 out->stream.common.get_channels = out_get_channels;
1545 out->stream.common.get_format = out_get_format;
1546 out->stream.common.set_format = out_set_format;
1547 out->stream.common.standby = out_standby;
1548 out->stream.common.dump = out_dump;
1549 out->stream.common.set_parameters = out_set_parameters;
1550 out->stream.common.get_parameters = out_get_parameters;
1551 out->stream.common.add_audio_effect = out_add_audio_effect;
1552 out->stream.common.remove_audio_effect = out_remove_audio_effect;
1553 out->stream.get_latency = out_get_latency;
1554 out->stream.set_volume = out_set_volume;
1555 out->stream.write = out_write;
1556 out->stream.get_render_position = out_get_render_position;
1557 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
1558
1559 out->dev = adev;
1560 out->standby = 1;
1561
1562 config->format = out->stream.common.get_format(&out->stream.common);
1563 config->channel_mask = out->stream.common.get_channels(&out->stream.common);
1564 config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
1565
1566 *stream_out = &out->stream;
1567 ALOGV("%s: exit", __func__);
1568 return 0;
1569}
1570
1571static void adev_close_output_stream(struct audio_hw_device *dev,
1572 struct audio_stream_out *stream)
1573{
1574 ALOGV("%s: enter", __func__);
1575 out_standby(&stream->common);
1576 free(stream);
1577 ALOGV("%s: exit", __func__);
1578}
1579
1580static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
1581{
1582 struct audio_device *adev = (struct audio_device *)dev;
1583 struct str_parms *parms;
1584 char *str;
1585 char value[32];
1586 int ret;
1587
1588 ALOGV("%s: enter", __func__);
1589
1590 parms = str_parms_create_str(kvpairs);
1591 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_TTY_MODE, value, sizeof(value));
1592 if (ret >= 0) {
1593 int tty_mode;
1594
1595 if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_OFF) == 0)
1596 tty_mode = TTY_MODE_OFF;
1597 else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_VCO) == 0)
1598 tty_mode = TTY_MODE_VCO;
1599 else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_HCO) == 0)
1600 tty_mode = TTY_MODE_HCO;
1601 else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_FULL) == 0)
1602 tty_mode = TTY_MODE_FULL;
1603 else
1604 return -EINVAL;
1605
1606 pthread_mutex_lock(&adev->lock);
1607 if (tty_mode != adev->tty_mode) {
1608 adev->tty_mode = tty_mode;
1609 /* ToDo: Device switch */
1610 }
1611 pthread_mutex_unlock(&adev->lock);
1612 }
1613
1614 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
1615 if (ret >= 0) {
1616 /* When set to false, HAL should disable EC and NS
1617 * But it is currently not supported.
1618 */
1619 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
1620 adev->bluetooth_nrec = true;
1621 else
1622 adev->bluetooth_nrec = false;
1623 }
1624
1625 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
1626 if (ret >= 0) {
1627 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
1628 adev->screen_off = false;
1629 else
1630 adev->screen_off = true;
1631 }
1632
1633 str_parms_destroy(parms);
1634 ALOGV("%s: exit with code(%d)", __func__, ret);
1635 return ret;
1636}
1637
1638static char* adev_get_parameters(const struct audio_hw_device *dev,
1639 const char *keys)
1640{
1641 /* ToDo: Return requested params */
1642 return strdup("");
1643}
1644
1645static int adev_init_check(const struct audio_hw_device *dev)
1646{
1647 return 0;
1648}
1649
1650static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
1651{
1652 struct audio_device *adev = (struct audio_device *)dev;
1653 int vol, err = 0;
1654
1655 pthread_mutex_lock(&adev->lock);
1656 adev->voice_volume = volume;
1657 if (adev->mode == AUDIO_MODE_IN_CALL) {
1658 if (volume < 0.0) {
1659 volume = 0.0;
1660 } else if (volume > 1.0) {
1661 volume = 1.0;
1662 }
1663
1664 vol = lrint(volume * 100.0);
1665
1666 // Voice volume levels from android are mapped to driver volume levels as follows.
1667 // 0 -> 5, 20 -> 4, 40 ->3, 60 -> 2, 80 -> 1, 100 -> 0
1668 // So adjust the volume to get the correct volume index in driver
1669 vol = 100 - vol;
1670
1671 if (adev->csd_client) {
1672 if (adev->csd_volume == NULL) {
1673 ALOGE("%s:Error:%s Loading csd_client_volume", __func__, dlerror());
1674 } else {
1675 err = adev->csd_volume(vol);
1676 if (err < 0) {
1677 ALOGE("%s: csd_client error %d", __func__, err);
1678 }
1679 }
1680 } else {
1681 ALOGE("%s: No CSD Client present", __func__);
1682 }
1683 }
1684 pthread_mutex_unlock(&adev->lock);
1685 return err;
1686}
1687
1688static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
1689{
1690 return -ENOSYS;
1691}
1692
1693static int adev_get_master_volume(struct audio_hw_device *dev,
1694 float *volume)
1695{
1696 return -ENOSYS;
1697}
1698
1699static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
1700{
1701 return -ENOSYS;
1702}
1703
1704static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
1705{
1706 return -ENOSYS;
1707}
1708
1709static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
1710{
1711 struct audio_device *adev = (struct audio_device *)dev;
1712
1713 pthread_mutex_lock(&adev->lock);
1714 if (adev->mode != mode) {
1715 adev->mode = mode;
1716 }
1717 pthread_mutex_unlock(&adev->lock);
1718 return 0;
1719}
1720
1721static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
1722{
1723 struct audio_device *adev = (struct audio_device *)dev;
1724 int err = 0;
1725
1726 adev->mic_mute = state;
1727 if (adev->mode == AUDIO_MODE_IN_CALL) {
1728 if (adev->csd_client) {
1729 if (adev->csd_mic_mute == NULL) {
1730 ALOGE("%s: Error:%s Loading csd_mic_mute", __func__, dlerror());
1731 } else {
1732 err = adev->csd_mic_mute(state);
1733 if (err < 0) {
1734 ALOGE("%s: csd_client error %d", __func__, err);
1735 }
1736 }
1737 } else {
1738 ALOGE("%s: No CSD Client present", __func__);
1739 }
1740 }
1741 return err;
1742}
1743
1744static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
1745{
1746 struct audio_device *adev = (struct audio_device *)dev;
1747
1748 *state = adev->mic_mute;
1749
1750 return 0;
1751}
1752
1753static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
1754 const struct audio_config *config)
1755{
1756 size_t size;
1757 int channel_count = popcount(config->channel_mask);
1758
1759 return get_input_buffer_size(config->sample_rate, config->format, channel_count);
1760}
1761
1762static int adev_open_input_stream(struct audio_hw_device *dev,
1763 audio_io_handle_t handle,
1764 audio_devices_t devices,
1765 struct audio_config *config,
1766 struct audio_stream_in **stream_in)
1767{
1768 struct audio_device *adev = (struct audio_device *)dev;
1769 struct stream_in *in;
1770 int ret, buffer_size, frame_size;
1771 int channel_count = popcount(config->channel_mask);
1772
1773 ALOGV("%s: enter", __func__);
1774 *stream_in = NULL;
1775 if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0)
1776 return -EINVAL;
1777
1778 in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
1779
1780 in->stream.common.get_sample_rate = in_get_sample_rate;
1781 in->stream.common.set_sample_rate = in_set_sample_rate;
1782 in->stream.common.get_buffer_size = in_get_buffer_size;
1783 in->stream.common.get_channels = in_get_channels;
1784 in->stream.common.get_format = in_get_format;
1785 in->stream.common.set_format = in_set_format;
1786 in->stream.common.standby = in_standby;
1787 in->stream.common.dump = in_dump;
1788 in->stream.common.set_parameters = in_set_parameters;
1789 in->stream.common.get_parameters = in_get_parameters;
1790 in->stream.common.add_audio_effect = in_add_audio_effect;
1791 in->stream.common.remove_audio_effect = in_remove_audio_effect;
1792 in->stream.set_gain = in_set_gain;
1793 in->stream.read = in_read;
1794 in->stream.get_input_frames_lost = in_get_input_frames_lost;
1795
1796 in->device = devices;
1797 in->source = AUDIO_SOURCE_DEFAULT;
1798 in->dev = adev;
1799 adev->in_device = devices;
1800 in->standby = 1;
1801 in->channel_mask = config->channel_mask;
1802
1803 /* Update config params with the requested sample rate and channels */
1804 in->usecase = USECASE_AUDIO_RECORD;
1805 in->config = pcm_config_audio_capture;
1806 in->config.channels = channel_count;
1807 in->config.rate = config->sample_rate;
1808
1809 frame_size = audio_stream_frame_size((struct audio_stream *)in);
1810 buffer_size = get_input_buffer_size(config->sample_rate,
1811 config->format,
1812 channel_count);
1813 in->config.period_size = buffer_size / frame_size;
1814
1815 *stream_in = &in->stream;
1816 ALOGV("%s: exit", __func__);
1817 return 0;
1818
1819err_open:
1820 free(in);
1821 *stream_in = NULL;
1822 return ret;
1823}
1824
1825static void adev_close_input_stream(struct audio_hw_device *dev,
1826 struct audio_stream_in *stream)
1827{
1828 in_standby(&stream->common);
1829 free(stream);
1830
1831 return;
1832}
1833
1834static int adev_dump(const audio_hw_device_t *device, int fd)
1835{
1836 return 0;
1837}
1838
1839static int adev_close(hw_device_t *device)
1840{
1841 struct audio_device *adev = (struct audio_device *)device;
1842 audio_route_free(adev->audio_route);
1843 free(device);
1844 return 0;
1845}
1846
1847static void init_platform_data(struct audio_device *adev)
1848{
1849 char platform[128], baseband[128];
1850
1851 adev->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
1852 if (adev->acdb_handle == NULL) {
1853 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
1854 } else {
1855 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
1856 adev->acdb_init = (acdb_init_t)dlsym(adev->acdb_handle,
1857 "acdb_loader_init_ACDB");
1858 adev->acdb_deallocate = (acdb_deallocate_t)dlsym(adev->acdb_handle,
1859 "acdb_loader_deallocate_ACDB");
1860 adev->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(adev->acdb_handle,
1861 "acdb_loader_send_audio_cal");
1862 adev->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(adev->acdb_handle,
1863 "acdb_loader_send_voice_cal");
1864 if (adev->acdb_init == NULL)
1865 ALOGE("%s: Error:%s Loading acdb_loader_init_ACDB", __func__, dlerror());
1866 else
1867 adev->acdb_init();
1868 }
1869
1870 /* If platform is Fusion3, load CSD Client specific symbols
1871 * Voice call is handled by MDM and apps processor talks to
1872 * MDM through CSD Client
1873 */
1874 property_get("ro.board.platform", platform, "");
1875 property_get("ro.baseband", baseband, "");
1876 if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband)) {
1877 adev->csd_client = dlopen(LIB_CSD_CLIENT, RTLD_NOW);
1878 if (adev->csd_client == NULL)
1879 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_CSD_CLIENT);
1880 }
1881
1882 if (adev->csd_client) {
1883 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_CSD_CLIENT);
1884 adev->csd_client_init = (csd_client_init_t)dlsym(adev->csd_client,
1885 "csd_client_init");
1886 adev->csd_client_deinit = (csd_client_deinit_t)dlsym(adev->csd_client,
1887 "csd_client_deinit");
1888 adev->csd_disable_device = (csd_disable_device_t)dlsym(adev->csd_client,
1889 "csd_client_disable_device");
1890 adev->csd_enable_device = (csd_enable_device_t)dlsym(adev->csd_client,
1891 "csd_client_enable_device");
1892 adev->csd_start_voice = (csd_start_voice_t)dlsym(adev->csd_client,
1893 "csd_client_start_voice");
1894 adev->csd_stop_voice = (csd_stop_voice_t)dlsym(adev->csd_client,
1895 "csd_client_stop_voice");
1896 adev->csd_volume = (csd_volume_t)dlsym(adev->csd_client,
1897 "csd_client_volume");
1898 adev->csd_mic_mute = (csd_mic_mute_t)dlsym(adev->csd_client,
1899 "csd_client_mic_mute");
1900
1901 if (adev->csd_client_init == NULL) {
1902 ALOGE("dlsym: Error:%s Loading csd_client_init", dlerror());
1903 } else {
1904 adev->csd_client_init();
1905 }
1906 }
1907}
1908
1909static int adev_open(const hw_module_t *module, const char *name,
1910 hw_device_t **device)
1911{
1912 struct audio_device *adev;
1913 int ret;
1914
1915 ALOGV("%s: enter", __func__);
1916 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
1917
1918 adev = calloc(1, sizeof(struct audio_device));
1919
1920 adev->mixer = mixer_open(MIXER_CARD);
1921 if (!adev->mixer) {
1922 ALOGE("Unable to open the mixer, aborting.");
1923 return -ENOSYS;
1924 }
1925
1926 adev->audio_route = audio_route_init(MIXER_CARD, MIXER_XML_PATH);
1927 if (!adev->audio_route) {
1928 free(adev);
1929 ALOGE("%s: Failed to init audio route controls, aborting.", __func__);
1930 *device = NULL;
1931 return -EINVAL;
1932 }
1933
1934 adev->device.common.tag = HARDWARE_DEVICE_TAG;
1935 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
1936 adev->device.common.module = (struct hw_module_t *)module;
1937 adev->device.common.close = adev_close;
1938
1939 adev->device.init_check = adev_init_check;
1940 adev->device.set_voice_volume = adev_set_voice_volume;
1941 adev->device.set_master_volume = adev_set_master_volume;
1942 adev->device.get_master_volume = adev_get_master_volume;
1943 adev->device.set_master_mute = adev_set_master_mute;
1944 adev->device.get_master_mute = adev_get_master_mute;
1945 adev->device.set_mode = adev_set_mode;
1946 adev->device.set_mic_mute = adev_set_mic_mute;
1947 adev->device.get_mic_mute = adev_get_mic_mute;
1948 adev->device.set_parameters = adev_set_parameters;
1949 adev->device.get_parameters = adev_get_parameters;
1950 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
1951 adev->device.open_output_stream = adev_open_output_stream;
1952 adev->device.close_output_stream = adev_close_output_stream;
1953 adev->device.open_input_stream = adev_open_input_stream;
1954 adev->device.close_input_stream = adev_close_input_stream;
1955 adev->device.dump = adev_dump;
1956
1957 /* Set the default route before the PCM stream is opened */
1958 pthread_mutex_lock(&adev->lock);
1959 adev->mode = AUDIO_MODE_NORMAL;
1960 adev->input_source = AUDIO_SOURCE_DEFAULT;
1961 adev->out_device = AUDIO_DEVICE_NONE;
1962 adev->in_device = AUDIO_DEVICE_NONE;
1963 adev->voice_call_rx = NULL;
1964 adev->voice_call_tx = NULL;
1965 adev->voice_volume = 1.0f;
1966 adev->tty_mode = TTY_MODE_OFF;
1967 adev->bluetooth_nrec = true;
1968 adev->cur_out_snd_device = 0;
1969 adev->cur_in_snd_device = 0;
1970 adev->out_snd_device_active = false;
1971 adev->in_snd_device_active = false;
1972 adev->usecase_list.next = NULL;
1973 adev->usecase_list.id = USECASE_INVALID;
1974 adev->in_call = false;
1975 adev->acdb_settings = TTY_OFF;
1976 pthread_mutex_unlock(&adev->lock);
1977
1978 /* Loads platform specific libraries dynamically */
1979 init_platform_data(adev);
1980
1981 *device = &adev->device.common;
1982
1983 ALOGV("%s: exit", __func__);
1984 return 0;
1985}
1986
1987static struct hw_module_methods_t hal_module_methods = {
1988 .open = adev_open,
1989};
1990
1991struct audio_module HAL_MODULE_INFO_SYM = {
1992 .common = {
1993 .tag = HARDWARE_MODULE_TAG,
1994 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
1995 .hal_api_version = HARDWARE_HAL_API_VERSION,
1996 .id = AUDIO_HARDWARE_MODULE_ID,
1997 .name = "QCOM Audio HAL",
1998 .author = "Code Aurora Forum",
1999 .methods = &hal_module_methods,
2000 },
2001};