blob: fb83245efff1cc0526a0ada275065ae354a31fd3 [file] [log] [blame]
Dhananjay Kumardaf6ebb2013-10-07 11:38:46 -07001/*
2 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
3 * Not a Contribution.
4 *
5 * Copyright (C) 2013 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20#define LOG_TAG "audio_hw_primary"
21/*#define LOG_NDEBUG 0*/
22/*#define VERY_VERY_VERBOSE_LOGGING*/
23#ifdef VERY_VERY_VERBOSE_LOGGING
24#define ALOGVV ALOGV
25#else
26#define ALOGVV(a...) do { } while(0)
27#endif
28
29#include <errno.h>
30#include <pthread.h>
31#include <stdint.h>
32#include <sys/time.h>
33#include <stdlib.h>
34#include <math.h>
35#include <dlfcn.h>
36#include <sys/resource.h>
37#include <sys/prctl.h>
38
39#include <cutils/log.h>
40#include <cutils/str_parms.h>
41#include <cutils/properties.h>
42#include <cutils/atomic.h>
Dhananjay Kumardaf6ebb2013-10-07 11:38:46 -070043
44#include <hardware/audio_effect.h>
Dhananjay Kumardaf6ebb2013-10-07 11:38:46 -070045#include <audio_effects/effect_aec.h>
46#include <audio_effects/effect_ns.h>
47#include "audio_hw.h"
48#include "platform_api.h"
49#include <platform.h>
50
Dhananjay Kumardaf6ebb2013-10-07 11:38:46 -070051struct pcm_config pcm_config_audio_capture = {
52 .channels = 2,
53 .period_count = AUDIO_CAPTURE_PERIOD_COUNT,
54 .format = PCM_FORMAT_S16_LE,
55};
56
Dhananjay Kumardaf6ebb2013-10-07 11:38:46 -070057static struct audio_device *adev = NULL;
58static pthread_mutex_t adev_init_lock;
59static unsigned int audio_device_ref_count;
60
61static int set_voice_volume_l(struct audio_device *adev, float volume);
62
Dhananjay Kumardaf6ebb2013-10-07 11:38:46 -070063int enable_audio_route(struct audio_device *adev,
64 struct audio_usecase *usecase,
65 bool update_mixer)
66{
67 snd_device_t snd_device;
68 char mixer_path[MIXER_PATH_MAX_LENGTH];
69
70 if (usecase == NULL)
71 return -EINVAL;
72
73 ALOGV("%s: enter: usecase(%d)", __func__, usecase->id);
74
75 if (usecase->type == PCM_CAPTURE)
76 snd_device = usecase->in_snd_device;
77 else
78 snd_device = usecase->out_snd_device;
79
80 strlcpy(mixer_path, use_case_table[usecase->id], sizeof(mixer_path));
81 platform_add_backend_name(mixer_path, snd_device);
82 ALOGV("%s: apply mixer path: %s", __func__, mixer_path);
83 audio_route_apply_path(adev->audio_route, mixer_path);
84 if (update_mixer)
85 audio_route_update_mixer(adev->audio_route);
86
87 ALOGV("%s: exit", __func__);
88 return 0;
89}
90
91int disable_audio_route(struct audio_device *adev,
92 struct audio_usecase *usecase,
93 bool update_mixer)
94{
95 snd_device_t snd_device;
96 char mixer_path[MIXER_PATH_MAX_LENGTH];
97
98 if (usecase == NULL)
99 return -EINVAL;
100
101 ALOGV("%s: enter: usecase(%d)", __func__, usecase->id);
102 if (usecase->type == PCM_CAPTURE)
103 snd_device = usecase->in_snd_device;
104 else
105 snd_device = usecase->out_snd_device;
106 strlcpy(mixer_path, use_case_table[usecase->id], sizeof(mixer_path));
107 platform_add_backend_name(mixer_path, snd_device);
108 ALOGV("%s: reset mixer path: %s", __func__, mixer_path);
109 audio_route_reset_path(adev->audio_route, mixer_path);
110 if (update_mixer)
111 audio_route_update_mixer(adev->audio_route);
112
113 ALOGV("%s: exit", __func__);
114 return 0;
115}
116
117int enable_snd_device(struct audio_device *adev,
118 snd_device_t snd_device,
119 bool update_mixer)
120{
121 char device_name[DEVICE_NAME_MAX_SIZE] = {0};
122
123 if (snd_device < SND_DEVICE_MIN ||
124 snd_device >= SND_DEVICE_MAX) {
125 ALOGE("%s: Invalid sound device %d", __func__, snd_device);
126 return -EINVAL;
127 }
128
129 adev->snd_dev_ref_cnt[snd_device]++;
130
131 if(platform_get_snd_device_name_extn(adev->platform, snd_device, device_name) < 0 ) {
132 ALOGE("%s: Invalid sound device returned", __func__);
133 return -EINVAL;
134 }
135 if (adev->snd_dev_ref_cnt[snd_device] > 1) {
136 ALOGV("%s: snd_device(%d: %s) is already active",
137 __func__, snd_device, device_name);
138 return 0;
139 }
140
141 {
142 ALOGV("%s: snd_device(%d: %s)", __func__,
143 snd_device, device_name);
144 if (platform_send_audio_calibration(adev->platform, snd_device) < 0) {
145 adev->snd_dev_ref_cnt[snd_device]--;
146 return -EINVAL;
147 }
148 audio_route_apply_path(adev->audio_route, device_name);
149 }
150 if (update_mixer)
151 audio_route_update_mixer(adev->audio_route);
152
153 return 0;
154}
155
156int disable_snd_device(struct audio_device *adev,
157 snd_device_t snd_device,
158 bool update_mixer)
159{
160 char device_name[DEVICE_NAME_MAX_SIZE] = {0};
161
162 if (snd_device < SND_DEVICE_MIN ||
163 snd_device >= SND_DEVICE_MAX) {
164 ALOGE("%s: Invalid sound device %d", __func__, snd_device);
165 return -EINVAL;
166 }
167 if (adev->snd_dev_ref_cnt[snd_device] <= 0) {
168 ALOGE("%s: device ref cnt is already 0", __func__);
169 return -EINVAL;
170 }
171
172 adev->snd_dev_ref_cnt[snd_device]--;
173
174 if(platform_get_snd_device_name_extn(adev->platform, snd_device, device_name) < 0) {
175 ALOGE("%s: Invalid sound device returned", __func__);
176 return -EINVAL;
177 }
178
179 if (adev->snd_dev_ref_cnt[snd_device] == 0) {
180 ALOGV("%s: snd_device(%d: %s)", __func__,
181 snd_device, device_name);
182 audio_route_reset_path(adev->audio_route, device_name);
183
184 if (update_mixer)
185 audio_route_update_mixer(adev->audio_route);
186 }
187
188 return 0;
189}
190
191static void check_usecases_codec_backend(struct audio_device *adev,
192 struct audio_usecase *uc_info,
193 snd_device_t snd_device)
194{
195 struct listnode *node;
196 struct audio_usecase *usecase;
197 bool switch_device[AUDIO_USECASE_MAX];
198 int i, num_uc_to_switch = 0;
199
200 /*
201 * This function is to make sure that all the usecases that are active on
202 * the hardware codec backend are always routed to any one device that is
203 * handled by the hardware codec.
204 * For example, if low-latency and deep-buffer usecases are currently active
205 * on speaker and out_set_parameters(headset) is received on low-latency
206 * output, then we have to make sure deep-buffer is also switched to headset,
207 * because of the limitation that both the devices cannot be enabled
208 * at the same time as they share the same backend.
209 */
210 /* Disable all the usecases on the shared backend other than the
211 specified usecase */
212 for (i = 0; i < AUDIO_USECASE_MAX; i++)
213 switch_device[i] = false;
214
215 list_for_each(node, &adev->usecase_list) {
216 usecase = node_to_item(node, struct audio_usecase, list);
217 if (usecase->type == PCM_PLAYBACK &&
218 usecase != uc_info &&
219 usecase->out_snd_device != snd_device &&
220 usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) {
221 ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
222 __func__, use_case_table[usecase->id],
223 platform_get_snd_device_name(usecase->out_snd_device));
224 disable_audio_route(adev, usecase, false);
225 switch_device[usecase->id] = true;
226 num_uc_to_switch++;
227 }
228 }
229
230 if (num_uc_to_switch) {
231 /* Make sure all the streams are de-routed before disabling the device */
232 audio_route_update_mixer(adev->audio_route);
233
234 list_for_each(node, &adev->usecase_list) {
235 usecase = node_to_item(node, struct audio_usecase, list);
236 if (switch_device[usecase->id]) {
237 disable_snd_device(adev, usecase->out_snd_device, false);
238 }
239 }
240
241 list_for_each(node, &adev->usecase_list) {
242 usecase = node_to_item(node, struct audio_usecase, list);
243 if (switch_device[usecase->id]) {
244 enable_snd_device(adev, snd_device, false);
245 }
246 }
247 /* Make sure new snd device is enabled before re-routing the streams */
248 audio_route_update_mixer(adev->audio_route);
249
250 /* Re-route all the usecases on the shared backend other than the
251 specified usecase to new snd devices */
252 list_for_each(node, &adev->usecase_list) {
253 usecase = node_to_item(node, struct audio_usecase, list);
254 /* Update the out_snd_device only before enabling the audio route */
255 if (switch_device[usecase->id] ) {
256 usecase->out_snd_device = snd_device;
257 enable_audio_route(adev, usecase, false);
258 }
259 }
260
261 audio_route_update_mixer(adev->audio_route);
262 }
263}
264
265static void check_and_route_capture_usecases(struct audio_device *adev,
266 struct audio_usecase *uc_info,
267 snd_device_t snd_device)
268{
269 struct listnode *node;
270 struct audio_usecase *usecase;
271 bool switch_device[AUDIO_USECASE_MAX];
272 int i, num_uc_to_switch = 0;
273
274 /*
275 * This function is to make sure that all the active capture usecases
276 * are always routed to the same input sound device.
277 * For example, if audio-record and voice-call usecases are currently
278 * active on speaker(rx) and speaker-mic (tx) and out_set_parameters(earpiece)
279 * is received for voice call then we have to make sure that audio-record
280 * usecase is also switched to earpiece i.e. voice-dmic-ef,
281 * because of the limitation that two devices cannot be enabled
282 * at the same time if they share the same backend.
283 */
284 for (i = 0; i < AUDIO_USECASE_MAX; i++)
285 switch_device[i] = false;
286
287 list_for_each(node, &adev->usecase_list) {
288 usecase = node_to_item(node, struct audio_usecase, list);
289 if (usecase->type == PCM_CAPTURE &&
290 usecase != uc_info &&
291 usecase->in_snd_device != snd_device) {
292 ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
293 __func__, use_case_table[usecase->id],
294 platform_get_snd_device_name(usecase->in_snd_device));
295 disable_audio_route(adev, usecase, false);
296 switch_device[usecase->id] = true;
297 num_uc_to_switch++;
298 }
299 }
300
301 if (num_uc_to_switch) {
302 /* Make sure all the streams are de-routed before disabling the device */
303 audio_route_update_mixer(adev->audio_route);
304
305 list_for_each(node, &adev->usecase_list) {
306 usecase = node_to_item(node, struct audio_usecase, list);
307 if (switch_device[usecase->id]) {
308 disable_snd_device(adev, usecase->in_snd_device, false);
309 enable_snd_device(adev, snd_device, false);
310 }
311 }
312
313 /* Make sure new snd device is enabled before re-routing the streams */
314 audio_route_update_mixer(adev->audio_route);
315
316 /* Re-route all the usecases on the shared backend other than the
317 specified usecase to new snd devices */
318 list_for_each(node, &adev->usecase_list) {
319 usecase = node_to_item(node, struct audio_usecase, list);
320 /* Update the in_snd_device only before enabling the audio route */
321 if (switch_device[usecase->id] ) {
322 usecase->in_snd_device = snd_device;
323 enable_audio_route(adev, usecase, false);
324 }
325 }
326
327 audio_route_update_mixer(adev->audio_route);
328 }
329}
330
331static int disable_all_usecases_of_type(struct audio_device *adev,
332 usecase_type_t usecase_type,
333 bool update_mixer)
334{
335 struct audio_usecase *usecase;
336 struct listnode *node;
337 int ret = 0;
338
339 list_for_each(node, &adev->usecase_list) {
340 usecase = node_to_item(node, struct audio_usecase, list);
341 if (usecase->type == usecase_type) {
342 ALOGV("%s: usecase id %d", __func__, usecase->id);
343 ret = disable_audio_route(adev, usecase, update_mixer);
344 if (ret) {
345 ALOGE("%s: Failed to disable usecase id %d",
346 __func__, usecase->id);
347 }
348 }
349 }
350
351 return ret;
352}
353
354static int enable_all_usecases_of_type(struct audio_device *adev,
355 usecase_type_t usecase_type,
356 bool update_mixer)
357{
358 struct audio_usecase *usecase;
359 struct listnode *node;
360 int ret = 0;
361
362 list_for_each(node, &adev->usecase_list) {
363 usecase = node_to_item(node, struct audio_usecase, list);
364 if (usecase->type == usecase_type) {
365 ALOGV("%s: usecase id %d", __func__, usecase->id);
366 ret = enable_audio_route(adev, usecase, update_mixer);
367 if (ret) {
368 ALOGE("%s: Failed to enable usecase id %d",
369 __func__, usecase->id);
370 }
371 }
372 }
373
374 return ret;
375}
376
Dhananjay Kumardaf6ebb2013-10-07 11:38:46 -0700377static audio_usecase_t get_voice_usecase_id_from_list(struct audio_device *adev)
378{
379 struct audio_usecase *usecase;
380 struct listnode *node;
381
382 list_for_each(node, &adev->usecase_list) {
383 usecase = node_to_item(node, struct audio_usecase, list);
384 if (usecase->type == VOICE_CALL) {
385 ALOGV("%s: usecase id %d", __func__, usecase->id);
386 return usecase->id;
387 }
388 }
389 return USECASE_INVALID;
390}
391
392struct audio_usecase *get_usecase_from_list(struct audio_device *adev,
393 audio_usecase_t uc_id)
394{
395 struct audio_usecase *usecase;
396 struct listnode *node;
397
398 list_for_each(node, &adev->usecase_list) {
399 usecase = node_to_item(node, struct audio_usecase, list);
400 if (usecase->id == uc_id)
401 return usecase;
402 }
403 return NULL;
404}
405
406int select_devices(struct audio_device *adev, audio_usecase_t uc_id)
407{
408 snd_device_t out_snd_device = SND_DEVICE_NONE;
409 snd_device_t in_snd_device = SND_DEVICE_NONE;
410 struct audio_usecase *usecase = NULL;
411 struct audio_usecase *vc_usecase = NULL;
412 struct audio_usecase *voip_usecase = NULL;
413 struct listnode *node;
414 int status = 0;
415
416 usecase = get_usecase_from_list(adev, uc_id);
417 if (usecase == NULL) {
418 ALOGE("%s: Could not find the usecase(%d)", __func__, uc_id);
419 return -EINVAL;
420 }
421
422 if ((usecase->type == VOICE_CALL) ||
423 (usecase->type == VOIP_CALL)) {
424 out_snd_device = platform_get_output_snd_device(adev->platform,
425 usecase->stream.out->devices);
426 in_snd_device = platform_get_input_snd_device(adev->platform, usecase->stream.out->devices);
427 usecase->devices = usecase->stream.out->devices;
428 } else {
429 /*
430 * If the voice call is active, use the sound devices of voice call usecase
431 * so that it would not result any device switch. All the usecases will
432 * be switched to new device when select_devices() is called for voice call
433 * usecase. This is to avoid switching devices for voice call when
434 * check_usecases_codec_backend() is called below.
435 */
436 if (usecase->type == PCM_PLAYBACK) {
437 usecase->devices = usecase->stream.out->devices;
438 in_snd_device = SND_DEVICE_NONE;
439 if (out_snd_device == SND_DEVICE_NONE) {
440 out_snd_device = platform_get_output_snd_device(adev->platform,
441 usecase->stream.out->devices);
442 if (usecase->stream.out == adev->primary_output &&
443 adev->active_input &&
444 adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
445 select_devices(adev, adev->active_input->usecase);
446 }
447 }
448 } else if (usecase->type == PCM_CAPTURE) {
449 usecase->devices = usecase->stream.in->device;
450 out_snd_device = SND_DEVICE_NONE;
451 if (in_snd_device == SND_DEVICE_NONE) {
452 if (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
453 adev->primary_output && !adev->primary_output->standby) {
454 in_snd_device = platform_get_input_snd_device(adev->platform,
455 adev->primary_output->devices);
456 } else {
457 in_snd_device = platform_get_input_snd_device(adev->platform,
458 AUDIO_DEVICE_NONE);
459 }
460 }
461 }
462 }
463
464 if (out_snd_device == usecase->out_snd_device &&
465 in_snd_device == usecase->in_snd_device) {
466 return 0;
467 }
468
469 ALOGD("%s: out_snd_device(%d: %s) in_snd_device(%d: %s)", __func__,
470 out_snd_device, platform_get_snd_device_name(out_snd_device),
471 in_snd_device, platform_get_snd_device_name(in_snd_device));
472
473 /*
474 * Limitation: While in call, to do a device switch we need to disable
475 * and enable both RX and TX devices though one of them is same as current
476 * device.
477 */
478 if (usecase->type == VOICE_CALL || usecase->type == VOIP_CALL) {
479 status = platform_switch_voice_call_device_pre(adev->platform);
480 disable_all_usecases_of_type(adev, VOICE_CALL, true);
481 }
482
483 /* Disable current sound devices */
484 if (usecase->out_snd_device != SND_DEVICE_NONE) {
485 disable_audio_route(adev, usecase, true);
486 disable_snd_device(adev, usecase->out_snd_device, false);
487 }
488
489 if (usecase->in_snd_device != SND_DEVICE_NONE) {
490 disable_audio_route(adev, usecase, true);
491 disable_snd_device(adev, usecase->in_snd_device, false);
492 }
493
494 /* Enable new sound devices */
495 if (out_snd_device != SND_DEVICE_NONE) {
496 if (usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND)
497 check_usecases_codec_backend(adev, usecase, out_snd_device);
498 enable_snd_device(adev, out_snd_device, false);
499 }
500
501 if (in_snd_device != SND_DEVICE_NONE) {
502 check_and_route_capture_usecases(adev, usecase, in_snd_device);
503 enable_snd_device(adev, in_snd_device, false);
504 }
505
506 if (usecase->type == VOICE_CALL || usecase->type == VOIP_CALL)
507 status = platform_switch_voice_call_device_post(adev->platform,
508 out_snd_device,
509 in_snd_device);
510
511 audio_route_update_mixer(adev->audio_route);
512
513 usecase->in_snd_device = in_snd_device;
514 usecase->out_snd_device = out_snd_device;
515
516 if (usecase->type == VOICE_CALL || usecase->type == VOIP_CALL)
517 enable_all_usecases_of_type(adev, usecase->type, true);
518 else
519 enable_audio_route(adev, usecase, true);
520
521 /* Applicable only on the targets that has external modem.
522 * Enable device command should be sent to modem only after
523 * enabling voice call mixer controls
524 */
525 if (usecase->type == VOICE_CALL)
526 status = platform_switch_voice_call_usecase_route_post(adev->platform,
527 out_snd_device,
528 in_snd_device);
529
530 return status;
531}
532
533static int stop_input_stream(struct stream_in *in)
534{
535 int i, ret = 0;
536 struct audio_usecase *uc_info;
537 struct audio_device *adev = in->dev;
538
539 adev->active_input = NULL;
540
541 ALOGV("%s: enter: usecase(%d: %s)", __func__,
542 in->usecase, use_case_table[in->usecase]);
543 uc_info = get_usecase_from_list(adev, in->usecase);
544 if (uc_info == NULL) {
545 ALOGE("%s: Could not find the usecase (%d) in the list",
546 __func__, in->usecase);
547 return -EINVAL;
548 }
549
550 /* 1. Disable stream specific mixer controls */
551 disable_audio_route(adev, uc_info, true);
552
553 /* 2. Disable the tx device */
554 disable_snd_device(adev, uc_info->in_snd_device, true);
555
556 list_remove(&uc_info->list);
557 free(uc_info);
558
559 ALOGV("%s: exit: status(%d)", __func__, ret);
560 return ret;
561}
562
563int start_input_stream(struct stream_in *in)
564{
565 /* 1. Enable output device and stream routing controls */
566 int ret = 0;
567 struct audio_usecase *uc_info;
568 struct audio_device *adev = in->dev;
569
570 in->usecase = platform_update_usecase_from_source(in->source,in->usecase);
571 ALOGV("%s: enter: usecase(%d)", __func__, in->usecase);
572
573 in->pcm_device_id = platform_get_pcm_device_id(in->usecase, PCM_CAPTURE);
574 if (in->pcm_device_id < 0) {
575 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
576 __func__, in->usecase);
577 ret = -EINVAL;
578 goto error_config;
579 }
580
581 adev->active_input = in;
582 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
583 uc_info->id = in->usecase;
584 uc_info->type = PCM_CAPTURE;
585 uc_info->stream.in = in;
586 uc_info->devices = in->device;
587 uc_info->in_snd_device = SND_DEVICE_NONE;
588 uc_info->out_snd_device = SND_DEVICE_NONE;
589
590 list_add_tail(&adev->usecase_list, &uc_info->list);
591 select_devices(adev, in->usecase);
592
593 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d",
594 __func__, SOUND_CARD, in->pcm_device_id, in->config.channels);
595 in->pcm = pcm_open(SOUND_CARD, in->pcm_device_id,
596 PCM_IN, &in->config);
597 if (in->pcm && !pcm_is_ready(in->pcm)) {
598 ALOGE("%s: %s", __func__, pcm_get_error(in->pcm));
599 pcm_close(in->pcm);
600 in->pcm = NULL;
601 ret = -EIO;
602 goto error_open;
603 }
604 ALOGV("%s: exit", __func__);
605 return ret;
606
607error_open:
608 stop_input_stream(in);
609
610error_config:
611 adev->active_input = NULL;
612 ALOGD("%s: exit: status(%d)", __func__, ret);
613
614 return ret;
615}
616
Dhananjay Kumardaf6ebb2013-10-07 11:38:46 -0700617static int check_input_parameters(uint32_t sample_rate,
618 audio_format_t format,
619 int channel_count)
620{
621 int ret = 0;
622
623 if ((format != AUDIO_FORMAT_PCM_16_BIT)) ret = -EINVAL;
624
625 switch (channel_count) {
626 case 1:
627 case 2:
628 case 6:
629 break;
630 default:
631 ret = -EINVAL;
632 }
633
634 switch (sample_rate) {
635 case 8000:
636 case 11025:
637 case 12000:
638 case 16000:
639 case 22050:
640 case 24000:
641 case 32000:
642 case 44100:
643 case 48000:
644 break;
645 default:
646 ret = -EINVAL;
647 }
648
649 return ret;
650}
651
652static size_t get_input_buffer_size(uint32_t sample_rate,
653 audio_format_t format,
654 int channel_count)
655{
656 size_t size = 0;
657
658 if (check_input_parameters(sample_rate, format, channel_count) != 0)
659 return 0;
660
661 size = (sample_rate * AUDIO_CAPTURE_PERIOD_DURATION_MSEC) / 1000;
662 /* ToDo: should use frame_size computed based on the format and
663 channel_count here. */
664 size *= sizeof(short) * channel_count;
665
666 /* make sure the size is multiple of 64 */
667 size += 0x3f;
668 size &= ~0x3f;
669
670 return size;
671}
672
Dhananjay Kumardaf6ebb2013-10-07 11:38:46 -0700673/** audio_stream_in implementation **/
674static uint32_t in_get_sample_rate(const struct audio_stream *stream)
675{
676 struct stream_in *in = (struct stream_in *)stream;
677
678 return in->config.rate;
679}
680
681static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
682{
683 return -ENOSYS;
684}
685
686static size_t in_get_buffer_size(const struct audio_stream *stream)
687{
688 struct stream_in *in = (struct stream_in *)stream;
689
690 return in->config.period_size * audio_stream_frame_size(stream);
691}
692
693static uint32_t in_get_channels(const struct audio_stream *stream)
694{
695 struct stream_in *in = (struct stream_in *)stream;
696
697 return in->channel_mask;
698}
699
700static audio_format_t in_get_format(const struct audio_stream *stream)
701{
702 struct stream_in *in = (struct stream_in *)stream;
703
704 return in->format;
705}
706
707static int in_set_format(struct audio_stream *stream, audio_format_t format)
708{
709 return -ENOSYS;
710}
711
712static int in_standby(struct audio_stream *stream)
713{
714 struct stream_in *in = (struct stream_in *)stream;
715 struct audio_device *adev = in->dev;
716 int status = 0;
717 ALOGV("%s: enter", __func__);
718
719 if (in->usecase == USECASE_COMPRESS_VOIP_CALL) {
720 /* Ignore standby in case of voip call because the voip input
721 * stream is closed in adev_close_input_stream()
722 */
723 ALOGV("%s: Ignore Standby in VOIP call", __func__);
724 return status;
725 }
726
727 pthread_mutex_lock(&in->lock);
728 if (!in->standby) {
729 in->standby = true;
730 if (in->pcm) {
731 pcm_close(in->pcm);
732 in->pcm = NULL;
733 }
734 pthread_mutex_lock(&adev->lock);
735 status = stop_input_stream(in);
736 pthread_mutex_unlock(&adev->lock);
737 }
738 pthread_mutex_unlock(&in->lock);
739 ALOGV("%s: exit: status(%d)", __func__, status);
740 return status;
741}
742
743static int in_dump(const struct audio_stream *stream, int fd)
744{
745 return 0;
746}
747
748static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
749{
750 struct stream_in *in = (struct stream_in *)stream;
751 struct audio_device *adev = in->dev;
752 struct str_parms *parms;
753 char *str;
754 char value[32];
755 int ret, val = 0;
756
757 ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
758 parms = str_parms_create_str(kvpairs);
759
760 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
761
762 pthread_mutex_lock(&in->lock);
763 pthread_mutex_lock(&adev->lock);
764 if (ret >= 0) {
765 val = atoi(value);
766 /* no audio source uses val == 0 */
767 if ((in->source != val) && (val != 0)) {
768 in->source = val;
769 }
770 }
771
772 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
773 if (ret >= 0) {
774 val = atoi(value);
775 if ((in->device != val) && (val != 0)) {
776 in->device = val;
777 /* If recording is in progress, change the tx device to new device */
778 if (!in->standby)
779 ret = select_devices(adev, in->usecase);
780 }
781 }
782
783 pthread_mutex_unlock(&adev->lock);
784 pthread_mutex_unlock(&in->lock);
785
786 str_parms_destroy(parms);
787 ALOGV("%s: exit: status(%d)", __func__, ret);
788 return ret;
789}
790
791static char* in_get_parameters(const struct audio_stream *stream,
792 const char *keys)
793{
794 struct stream_in *in = (struct stream_in *)stream;
795 struct str_parms *query = str_parms_create_str(keys);
796 char *str;
797 char value[256];
798 struct str_parms *reply = str_parms_create();
799 ALOGV("%s: enter: keys - %s", __func__, keys);
800
801 str = str_parms_to_str(reply);
802 str_parms_destroy(query);
803 str_parms_destroy(reply);
804
805 ALOGV("%s: exit: returns - %s", __func__, str);
806 return str;
807}
808
809static int in_set_gain(struct audio_stream_in *stream, float gain)
810{
811 return 0;
812}
813
814static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
815 size_t bytes)
816{
817 struct stream_in *in = (struct stream_in *)stream;
818 struct audio_device *adev = in->dev;
819 int i, ret = -1;
820
821 pthread_mutex_lock(&in->lock);
822 if (in->standby) {
823 pthread_mutex_lock(&adev->lock);
824 ret = start_input_stream(in);
825 pthread_mutex_unlock(&adev->lock);
826 if (ret != 0) {
827 goto exit;
828 }
829 in->standby = 0;
830 }
831
832 if (in->pcm) {
833 ret = pcm_read(in->pcm, buffer, bytes);
834 }
835
836exit:
837 pthread_mutex_unlock(&in->lock);
838
839 if (ret != 0) {
840 in_standby(&in->stream.common);
841 ALOGV("%s: read failed - sleeping for buffer duration", __func__);
842 usleep(bytes * 1000000 / audio_stream_frame_size(&in->stream.common) /
843 in_get_sample_rate(&in->stream.common));
844 }
845 return bytes;
846}
847
848static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
849{
850 return 0;
851}
852
853static int add_remove_audio_effect(const struct audio_stream *stream,
854 effect_handle_t effect,
855 bool enable)
856{
857 struct stream_in *in = (struct stream_in *)stream;
858 int status = 0;
Dhananjay Kumardaf6ebb2013-10-07 11:38:46 -0700859
860 return 0;
861}
862
863static int in_add_audio_effect(const struct audio_stream *stream,
864 effect_handle_t effect)
865{
866 ALOGV("%s: effect %p", __func__, effect);
867 return add_remove_audio_effect(stream, effect, true);
868}
869
870static int in_remove_audio_effect(const struct audio_stream *stream,
871 effect_handle_t effect)
872{
873 ALOGV("%s: effect %p", __func__, effect);
874 return add_remove_audio_effect(stream, effect, false);
875}
876
Dhananjay Kumardaf6ebb2013-10-07 11:38:46 -0700877static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
878{
879 struct audio_device *adev = (struct audio_device *)dev;
880 struct str_parms *parms;
881 char *str;
882 char value[32];
883 int val;
884 int ret;
885
886 ALOGD("%s: enter: %s", __func__, kvpairs);
887
888 pthread_mutex_lock(&adev->lock);
889 parms = str_parms_create_str(kvpairs);
890
891 platform_set_parameters(adev->platform, parms);
892
893 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
894 if (ret >= 0) {
895 /* When set to false, HAL should disable EC and NS
896 * But it is currently not supported.
897 */
898 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
899 adev->bluetooth_nrec = true;
900 else
901 adev->bluetooth_nrec = false;
902 }
903
904 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
905 if (ret >= 0) {
906 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
907 adev->screen_off = false;
908 else
909 adev->screen_off = true;
910 }
911
912 ret = str_parms_get_int(parms, "rotation", &val);
913 if (ret >= 0) {
914 bool reverse_speakers = false;
915 switch(val) {
916 // FIXME: note that the code below assumes that the speakers are in the correct placement
917 // relative to the user when the device is rotated 90deg from its default rotation. This
918 // assumption is device-specific, not platform-specific like this code.
919 case 270:
920 reverse_speakers = true;
921 break;
922 case 0:
923 case 90:
924 case 180:
925 break;
926 default:
927 ALOGE("%s: unexpected rotation of %d", __func__, val);
928 }
929 if (adev->speaker_lr_swap != reverse_speakers) {
930 adev->speaker_lr_swap = reverse_speakers;
931 // only update the selected device if there is active pcm playback
932 struct audio_usecase *usecase;
933 struct listnode *node;
934 list_for_each(node, &adev->usecase_list) {
935 usecase = node_to_item(node, struct audio_usecase, list);
936 if (usecase->type == PCM_PLAYBACK) {
937 select_devices(adev, usecase->id);
938 break;
939 }
940 }
941 }
942 }
943
944 str_parms_destroy(parms);
945
946 pthread_mutex_unlock(&adev->lock);
947 ALOGV("%s: exit with code(%d)", __func__, ret);
948 return ret;
949}
950
951static char* adev_get_parameters(const struct audio_hw_device *dev,
952 const char *keys)
953{
954 struct audio_device *adev = (struct audio_device *)dev;
955 struct str_parms *reply = str_parms_create();
956 struct str_parms *query = str_parms_create_str(keys);
957 char *str;
958
959 pthread_mutex_lock(&adev->lock);
960
961 platform_get_parameters(adev->platform, query, reply);
962 str = str_parms_to_str(reply);
963 str_parms_destroy(query);
964 str_parms_destroy(reply);
965
966 pthread_mutex_unlock(&adev->lock);
967 ALOGV("%s: exit: returns - %s", __func__, str);
968 return str;
969}
970
971static int adev_init_check(const struct audio_hw_device *dev)
972{
973 return 0;
974}
975
976static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
977{
978 int ret = 0;
979 return ret;
980}
981
982static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
983{
984 return -ENOSYS;
985}
986
987static int adev_get_master_volume(struct audio_hw_device *dev,
988 float *volume)
989{
990 return -ENOSYS;
991}
992
993static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
994{
995 return -ENOSYS;
996}
997
998static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
999{
1000 return -ENOSYS;
1001}
1002
1003static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
1004{
1005 struct audio_device *adev = (struct audio_device *)dev;
1006 pthread_mutex_lock(&adev->lock);
1007 if (adev->mode != mode) {
1008 ALOGD("%s mode %d\n", __func__, mode);
1009 adev->mode = mode;
1010 }
1011 pthread_mutex_unlock(&adev->lock);
1012 return 0;
1013}
1014
1015static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
1016{
1017 int ret = 0;
1018
1019 return ret;
1020}
1021
1022static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
1023{
1024 return 0;
1025}
1026
1027static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
1028 const struct audio_config *config)
1029{
1030 int channel_count = popcount(config->channel_mask);
1031
1032 return get_input_buffer_size(config->sample_rate, config->format, channel_count);
1033}
1034
1035static int adev_open_input_stream(struct audio_hw_device *dev,
1036 audio_io_handle_t handle,
1037 audio_devices_t devices,
1038 struct audio_config *config,
1039 struct audio_stream_in **stream_in)
1040{
1041 struct audio_device *adev = (struct audio_device *)dev;
1042 struct stream_in *in;
1043 int ret = 0, buffer_size, frame_size;
1044 int channel_count = popcount(config->channel_mask);
1045
1046 ALOGV("%s: enter", __func__);
1047 *stream_in = NULL;
1048 if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0)
1049 return -EINVAL;
1050
1051 in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
1052
1053 in->stream.common.get_sample_rate = in_get_sample_rate;
1054 in->stream.common.set_sample_rate = in_set_sample_rate;
1055 in->stream.common.get_buffer_size = in_get_buffer_size;
1056 in->stream.common.get_channels = in_get_channels;
1057 in->stream.common.get_format = in_get_format;
1058 in->stream.common.set_format = in_set_format;
1059 in->stream.common.standby = in_standby;
1060 in->stream.common.dump = in_dump;
1061 in->stream.common.set_parameters = in_set_parameters;
1062 in->stream.common.get_parameters = in_get_parameters;
1063 in->stream.common.add_audio_effect = in_add_audio_effect;
1064 in->stream.common.remove_audio_effect = in_remove_audio_effect;
1065 in->stream.set_gain = in_set_gain;
1066 in->stream.read = in_read;
1067 in->stream.get_input_frames_lost = in_get_input_frames_lost;
1068
1069 in->device = devices;
1070 in->source = AUDIO_SOURCE_DEFAULT;
1071 in->dev = adev;
1072 in->standby = 1;
1073 in->channel_mask = config->channel_mask;
1074
1075 /* Update config params with the requested sample rate and channels */
1076 in->usecase = USECASE_AUDIO_RECORD;
1077 in->config = pcm_config_audio_capture;
1078 in->config.rate = config->sample_rate;
1079 in->format = config->format;
1080
1081 {
1082 in->config.channels = channel_count;
1083 frame_size = audio_stream_frame_size((struct audio_stream *)in);
1084 buffer_size = get_input_buffer_size(config->sample_rate,
1085 config->format,
1086 channel_count);
1087 in->config.period_size = buffer_size / frame_size;
1088 }
1089
1090 *stream_in = &in->stream;
1091 ALOGV("%s: exit", __func__);
1092 return ret;
1093
1094err_open:
1095 free(in);
1096 *stream_in = NULL;
1097 return ret;
1098}
1099
1100static void adev_close_input_stream(struct audio_hw_device *dev,
1101 struct audio_stream_in *stream)
1102{
1103 int ret;
1104 struct stream_in *in = (struct stream_in *)stream;
1105 ALOGV("%s", __func__);
1106
1107 in_standby(&stream->common);
1108
1109 free(stream);
1110
1111 return;
1112}
1113
1114static int adev_dump(const audio_hw_device_t *device, int fd)
1115{
1116 return 0;
1117}
1118
1119static int adev_close(hw_device_t *device)
1120{
1121 struct audio_device *adev = (struct audio_device *)device;
1122
1123 if (!adev)
1124 return 0;
1125
1126 pthread_mutex_lock(&adev_init_lock);
1127
1128 if ((--audio_device_ref_count) == 0) {
1129 audio_route_free(adev->audio_route);
1130 free(adev->snd_dev_ref_cnt);
1131 platform_deinit(adev->platform);
1132 free(device);
1133 adev = NULL;
1134 }
1135 pthread_mutex_unlock(&adev_init_lock);
1136 return 0;
1137}
1138
1139static int adev_open(const hw_module_t *module, const char *name,
1140 hw_device_t **device)
1141{
1142 int i, ret;
1143
1144 ALOGD("%s: enter", __func__);
1145 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
1146
1147 pthread_mutex_lock(&adev_init_lock);
1148 if (audio_device_ref_count != 0){
1149 *device = &adev->device.common;
1150 audio_device_ref_count++;
1151 ALOGD("%s: returning existing instance of adev", __func__);
1152 ALOGD("%s: exit", __func__);
1153 pthread_mutex_unlock(&adev_init_lock);
1154 return 0;
1155 }
1156
1157 adev = calloc(1, sizeof(struct audio_device));
1158
1159 adev->device.common.tag = HARDWARE_DEVICE_TAG;
1160 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
1161 adev->device.common.module = (struct hw_module_t *)module;
1162 adev->device.common.close = adev_close;
1163
1164 adev->device.init_check = adev_init_check;
1165 adev->device.set_voice_volume = adev_set_voice_volume;
1166 adev->device.set_master_volume = adev_set_master_volume;
1167 adev->device.get_master_volume = adev_get_master_volume;
1168 adev->device.set_master_mute = adev_set_master_mute;
1169 adev->device.get_master_mute = adev_get_master_mute;
1170 adev->device.set_mode = adev_set_mode;
1171 adev->device.set_mic_mute = adev_set_mic_mute;
1172 adev->device.get_mic_mute = adev_get_mic_mute;
1173 adev->device.set_parameters = adev_set_parameters;
1174 adev->device.get_parameters = adev_get_parameters;
1175 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
1176 adev->device.open_output_stream = adev_open_output_stream;
1177 adev->device.close_output_stream = adev_close_output_stream;
1178 adev->device.open_input_stream = adev_open_input_stream;
1179 adev->device.close_input_stream = adev_close_input_stream;
1180 adev->device.dump = adev_dump;
1181
1182 /* Set the default route before the PCM stream is opened */
1183 adev->mode = AUDIO_MODE_NORMAL;
1184 adev->active_input = NULL;
1185 adev->primary_output = NULL;
1186 adev->out_device = AUDIO_DEVICE_NONE;
1187 adev->bluetooth_nrec = true;
1188 adev->acdb_settings = TTY_MODE_OFF;
1189 /* adev->cur_hdmi_channels = 0; by calloc() */
1190 adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
1191 list_init(&adev->usecase_list);
1192
1193 /* Loads platform specific libraries dynamically */
1194 adev->platform = platform_init(adev);
1195 if (!adev->platform) {
1196 free(adev->snd_dev_ref_cnt);
1197 free(adev);
1198 ALOGE("%s: Failed to init platform data, aborting.", __func__);
1199 *device = NULL;
1200 return -EINVAL;
1201 }
1202
1203 if (access(VISUALIZER_LIBRARY_PATH, R_OK) == 0) {
1204 adev->visualizer_lib = dlopen(VISUALIZER_LIBRARY_PATH, RTLD_NOW);
1205 if (adev->visualizer_lib == NULL) {
1206 ALOGE("%s: DLOPEN failed for %s", __func__, VISUALIZER_LIBRARY_PATH);
1207 } else {
1208 ALOGV("%s: DLOPEN successful for %s", __func__, VISUALIZER_LIBRARY_PATH);
1209 adev->visualizer_start_output =
1210 (int (*)(audio_io_handle_t))dlsym(adev->visualizer_lib,
1211 "visualizer_hal_start_output");
1212 adev->visualizer_stop_output =
1213 (int (*)(audio_io_handle_t))dlsym(adev->visualizer_lib,
1214 "visualizer_hal_stop_output");
1215 }
1216 }
1217 *device = &adev->device.common;
1218
1219 audio_device_ref_count++;
1220 pthread_mutex_unlock(&adev_init_lock);
1221
1222 ALOGV("%s: exit", __func__);
1223 return 0;
1224}
1225
1226static struct hw_module_methods_t hal_module_methods = {
1227 .open = adev_open,
1228};
1229
1230struct audio_module HAL_MODULE_INFO_SYM = {
1231 .common = {
1232 .tag = HARDWARE_MODULE_TAG,
1233 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
1234 .hal_api_version = HARDWARE_HAL_API_VERSION,
1235 .id = AUDIO_HARDWARE_MODULE_ID,
1236 .name = "MPQ Audio HAL",
1237 .author = "The Linux Foundation",
1238 .methods = &hal_module_methods,
1239 },
1240};