summaryrefslogtreecommitdiff
path: root/hdmi_audio_hw.c (plain)
blob: c19a095156266c2079d1d1a6fcc266ed6962ac4a
1/*
2 * Copyright (C) 2011 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_hdmi"
18#define LOG_NDEBUG 0
19//#define LOG_NDEBUG_FUNCTION
20#ifdef LOG_NDEBUG_FUNCTION
21#define LOGFUNC(...) ((void)0)
22#else
23#define LOGFUNC(...) (ALOGD(__VA_ARGS__))
24#endif
25//#define DEBUG_HWSYNC_PASSTHROUGH
26#ifndef DEBUG_HWSYNC_PASSTHROUGH
27#define DEBUG(...) ((void)0)
28#else
29#define DEBUG(...) (ALOGD(__VA_ARGS__))
30#endif
31#include <errno.h>
32#include <pthread.h>
33#include <stdint.h>
34#include <sys/time.h>
35#include <stdlib.h>
36#include <sys/stat.h>
37#include <fcntl.h>
38#include <time.h>
39#include <utils/Timers.h>
40#include <cutils/log.h>
41#include <cutils/str_parms.h>
42#include <cutils/properties.h>
43#include <linux/ioctl.h>
44#include <hardware/hardware.h>
45#include <system/audio.h>
46#include <hardware/audio.h>
47#include <sound/asound.h>
48#include <tinyalsa/asoundlib.h>
49
50#include <audio_utils/resampler.h>
51#include <audio_utils/echo_reference.h>
52#include <hardware/audio_effect.h>
53#include <audio_effects/effect_aec.h>
54
55#include "audio_hw.h"
56#include "audio_hwsync.h"
57#include "hdmi_audio_hw.h"
58#include "audio_hw_profile.h"
59#include "audio_hw_utils.h"
60extern int aml_audio_hwsync_find_frame(struct aml_stream_out *out, const void *in_buffer, size_t in_bytes, uint64_t *cur_pts, int *outsize);
61extern int spdifenc_write(const void *buffer, size_t numBytes);
62extern uint64_t spdifenc_get_total();
63
64extern int spdifenc_init(struct pcm *mypcm);
65
66struct pcm_config pcm_config_out = {
67 .channels = 2,
68 .rate = MM_FULL_POWER_SAMPLING_RATE,
69 .period_size = DEFAULT_PERIOD_SIZE,
70 .period_count = PLAYBACK_PERIOD_COUNT,
71 .format = PCM_FORMAT_S16_LE,
72};
73
74struct pcm_config pcm_config_in = {
75 .channels = 2,
76 .rate = MM_FULL_POWER_SAMPLING_RATE,
77 .period_size = DEFAULT_PERIOD_SIZE,
78 .period_count = PLAYBACK_PERIOD_COUNT,
79 .format = PCM_FORMAT_S16_LE,
80};
81
82static void select_output_device(struct aml_audio_device *adev);
83static void select_input_device(struct aml_audio_device *adev);
84static int adev_set_voice_volume(struct audio_hw_device *dev, float volume);
85static int do_input_standby(struct aml_stream_in *in);
86static int do_output_standby(struct aml_stream_out *out);
87
88extern void aml_audio_hwsync_clear_status(struct aml_stream_out *out);
89
90static void select_output_device(struct aml_audio_device *adev)
91{
92 LOGFUNC("%s(mode=%d, out_device=%#x)", __FUNCTION__, adev->mode,
93 adev->out_device);
94}
95
96static void select_input_device(struct aml_audio_device *adev)
97{
98 int mic_in = adev->in_device & AUDIO_DEVICE_IN_BUILTIN_MIC;
99 int headset_mic = adev->in_device & AUDIO_DEVICE_IN_WIRED_HEADSET;
100 LOGFUNC("~~~~ %s : in_device(%#x), mic_in(%#x), headset_mic(%#x)",
101 __func__, adev->in_device, mic_in, headset_mic);
102 return;
103}
104
105static void
106force_all_standby(struct aml_audio_device *adev)
107{
108 struct aml_stream_in *in;
109 struct aml_stream_out *out;
110
111 LOGFUNC("%s(%p)", __FUNCTION__, adev);
112
113 if (adev->active_output) {
114 out = adev->active_output;
115 pthread_mutex_lock(&out->lock);
116 do_output_standby(out);
117 pthread_mutex_unlock(&out->lock);
118 }
119
120 if (adev->active_input) {
121 in = adev->active_input;
122 pthread_mutex_lock(&in->lock);
123 do_input_standby(in);
124 pthread_mutex_unlock(&in->lock);
125 }
126}
127
128static void
129select_mode(struct aml_audio_device *adev)
130{
131 LOGFUNC("%s(out_device=%#x)", __FUNCTION__, adev->out_device);
132 LOGFUNC("%s(in_device=%#x)", __FUNCTION__, adev->in_device);
133 return;
134 force_all_standby(adev);
135 /* force earpiece route for in call state if speaker is the
136 only currently selected route. This prevents having to tear
137 down the modem PCMs to change route from speaker to earpiece
138 after the ringtone is played, but doesn't cause a route
139 change if a headset or bt device is already connected. If
140 speaker is not the only thing active, just remove it from
141 the route. We'll assume it'll never be used initally during
142 a call. This works because we're sure that the audio policy
143 manager will update the output device after the audio mode
144 change, even if the device selection did not change. */
145 if ((adev->out_device & AUDIO_DEVICE_OUT_ALL) == AUDIO_DEVICE_OUT_SPEAKER) {
146 adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN;
147 } else {
148 adev->out_device &= ~AUDIO_DEVICE_OUT_SPEAKER;
149 }
150 select_output_device(adev);
151 select_input_device(adev);
152 return;
153}
154
155
156static int
157check_output_stream(struct aml_stream_out *out)
158{
159 int ret = 0;
160 unsigned int card = CARD_AMLOGIC_DEFAULT;
161 unsigned int port = PORT_MM;
162 int ext_card;
163 ext_card = get_external_card(0);
164 if (ext_card < 0) {
165 card = CARD_AMLOGIC_DEFAULT;
166 } else {
167 card = ext_card;
168 }
169 out->config.start_threshold = PERIOD_SIZE * 2;
170 out->config.avail_min = 0; //SHORT_PERIOD_SIZE;
171 return 0;
172}
173
174/* must be called with hw device and output stream mutexes locked */
175static int start_output_stream(struct aml_stream_out *out)
176{
177 struct aml_audio_device *adev = out->dev;
178 int card = CARD_AMLOGIC_DEFAULT;
179 int port = PORT_MM;
180 int ret = 0;
181 int codec_type = get_codec_type(out->format);
182 if (out->format == AUDIO_FORMAT_PCM && out->config.rate > 48000 && (out->flags & AUDIO_OUTPUT_FLAG_DIRECT)) {
183 ALOGI("start output stream for high sample rate pcm for direct mode\n");
184 codec_type = TYPE_PCM_HIGH_SR;
185 }
186 if (codec_type == AUDIO_FORMAT_PCM && out->config.channels >= 6 && (out->flags & AUDIO_OUTPUT_FLAG_DIRECT)) {
187 ALOGI("start output stream for multi-channel pcm for direct mode\n");
188 codec_type = TYPE_MULTI_PCM;
189 }
190 adev->active_output = out;
191 if (adev->mode != AUDIO_MODE_IN_CALL) {
192 /* FIXME: only works if only one output can be active at a time */
193 select_output_device(adev);
194 }
195 LOGFUNC("%s(adev->out_device=%#x, adev->mode=%d)", __FUNCTION__,
196 adev->out_device, adev->mode);
197 card = get_aml_card();
198 if (card < 0) {
199 ALOGE("hdmi get aml card id failed \n");
200 card = CARD_AMLOGIC_DEFAULT;
201 }
202 port = get_spdif_port();
203 if (port < 0) {
204 ALOGE("hdmi get aml card port failed \n");
205 card = PORT_MM;
206 }
207 ALOGI("hdmi sound card id %d,device id %d \n", card, port);
208 if (out->config.channels == 6) {
209 ALOGI("round 6ch to 8 ch output \n");
210 /* our hw only support 8 channel configure,so when 5.1,hw mask the last two channels*/
211 sysfs_set_sysfs_str("/sys/class/amhdmitx/amhdmitx0/aud_output_chs", "6:7");
212 out->config.channels = 8;
213 }
214 /*
215 8 channel audio only support 32 byte mode,so need convert them to
216 PCM_FORMAT_S32_LE
217 */
218 if (out->config.channels == 8) {
219 port = 0;
220 out->config.format = PCM_FORMAT_S32_LE;
221 adev->out_device = AUDIO_DEVICE_OUT_SPEAKER;
222 ALOGI("[%s %d]8CH format output: set port/0 adev->out_device/%d\n",
223 __FUNCTION__, __LINE__, AUDIO_DEVICE_OUT_SPEAKER);
224 }
225 LOGFUNC("------------open on board audio-------");
226 if (getprop_bool("media.libplayer.wfd")) {
227 out->config.period_size = PERIOD_SIZE;
228 }
229 switch (out->format) {
230 case AUDIO_FORMAT_E_AC3:
231 out->config.period_size = PERIOD_SIZE * 2;
232 out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE * 2;
233 out->config.start_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE * 2;
234 break;
235 case AUDIO_FORMAT_DTS_HD:
236 case AUDIO_FORMAT_TRUEHD:
237 out->config.period_size = PERIOD_SIZE * 4 * 2;
238 out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE * 4 * 2;
239 out->config.start_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE * 4 * 2;
240 break;
241 case AUDIO_FORMAT_PCM:
242 default:
243 out->config.period_size = PERIOD_SIZE;
244 out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE;
245 out->config.start_threshold = PERIOD_SIZE * PLAYBACK_PERIOD_COUNT;
246 }
247 out->config.avail_min = 0;
248 if (codec_type != TYPE_DTS_HD)
249 set_codec_type(codec_type);
250 ALOGI("channels=%d---format=%d---period_count%d---period_size%d---rate=%d---",
251 out->config.channels, out->config.format, out->config.period_count,
252 out->config.period_size, out->config.rate);
253 out->pcm = pcm_open(card, port, PCM_OUT /*| PCM_MMAP | PCM_NOIRQ */ ,
254 &(out->config));
255 if (!pcm_is_ready(out->pcm)) {
256 ALOGE("cannot open pcm_out driver: %s", pcm_get_error(out->pcm));
257 pcm_close(out->pcm);
258 adev->active_output = NULL;
259 return -ENOMEM;
260 }
261#if 1
262 if (codec_type_is_raw_data(codec_type) && !(out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)) {
263 spdifenc_init(out->pcm);
264 out->spdif_enc_init_frame_write_sum = out->frame_write_sum;
265 }
266#endif
267 //out->frame_write_sum=0;
268 out->codec_type = codec_type;
269 out->bytes_write_total = 0;
270 if (adev->hw_sync_mode == 1) {
271 LOGFUNC("start_output_stream with hw sync enable\n");
272 }
273 return 0;
274}
275
276static int
277check_input_parameters(uint32_t sample_rate, int format, int channel_count)
278{
279 LOGFUNC("%s(sample_rate=%d, format=%d, channel_count=%d)", __FUNCTION__,
280 sample_rate, format, channel_count);
281
282 if (format != AUDIO_FORMAT_PCM_16_BIT) {
283 return -EINVAL;
284 }
285
286 if ((channel_count < 1) || (channel_count > 2)) {
287 return -EINVAL;
288 }
289
290 switch (sample_rate) {
291 case 8000:
292 case 11025:
293 case 16000:
294 case 22050:
295 case 24000:
296 case 32000:
297 case 44100:
298 case 48000:
299 break;
300 default:
301 return -EINVAL;
302 }
303
304 return 0;
305}
306
307static size_t
308get_input_buffer_size(uint32_t sample_rate, int format, int channel_count)
309{
310 size_t size;
311 size_t device_rate;
312
313 LOGFUNC("%s(sample_rate=%d, format=%d, channel_count=%d)", __FUNCTION__,
314 sample_rate, format, channel_count);
315
316 if (check_input_parameters(sample_rate, format, channel_count) != 0) {
317 return 0;
318 }
319
320 /* take resampling into account and return the closest majoring
321 multiple of 16 frames, as audioflinger expects audio buffers to
322 be a multiple of 16 frames */
323 size = (pcm_config_in.period_size * sample_rate) / pcm_config_in.rate;
324 size = ((size + 15) / 16) * 16;
325
326 return size * channel_count * sizeof(short);
327}
328
329
330
331static uint32_t
332out_get_sample_rate(const struct audio_stream *stream)
333{
334 struct aml_stream_out *out = (struct aml_stream_out *) stream;
335 if (out->config.rate > 0) {
336 return out->config.rate;
337 } else {
338 return DEFAULT_OUT_SAMPLING_RATE;
339 }
340}
341
342static int
343out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
344{
345 LOGFUNC("%s(%p, %d)", __FUNCTION__, stream, rate);
346
347 return 0;
348}
349
350static size_t
351out_get_buffer_size(const struct audio_stream *stream)
352{
353 struct aml_stream_out *out = (struct aml_stream_out *) stream;
354
355 LOGFUNC("%s(out->config.rate=%d)", __FUNCTION__, out->config.rate);
356
357 /* take resampling into account and return the closest majoring
358 * multiple of 16 frames, as audioflinger expects audio buffers to
359 * be a multiple of 16 frames
360 */
361 size_t size;
362 switch (out->format) {
363 case AUDIO_FORMAT_AC3:
364 case AUDIO_FORMAT_DTS:
365 if (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO) {
366 size = 4 * PERIOD_SIZE * PLAYBACK_PERIOD_COUNT;
367 } else {
368 size = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE / 2;
369 }
370 break;
371 case AUDIO_FORMAT_E_AC3:
372 if (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO) {
373 size = 16 * PERIOD_SIZE * PLAYBACK_PERIOD_COUNT;
374 } else {
375 size = PERIOD_SIZE; //2*PLAYBACK_PERIOD_COUNT*PERIOD_SIZE;
376 }
377 break;
378 case AUDIO_FORMAT_DTS_HD:
379 case AUDIO_FORMAT_TRUEHD:
380 if (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO) {
381 size = 16 * PERIOD_SIZE * PLAYBACK_PERIOD_COUNT;
382 } else {
383 size = 4 * PLAYBACK_PERIOD_COUNT * PERIOD_SIZE;
384 }
385 break;
386 case AUDIO_FORMAT_PCM:
387 default:
388 size = PERIOD_SIZE;
389 }
390 size = ((size + 15) / 16) * 16;
391 size = size * audio_stream_out_frame_size(&out->stream);
392 DEBUG("format %x,buffer size %d\n", out->format, size);
393 return size;
394}
395
396static audio_channel_mask_t
397out_get_channels(const struct audio_stream *stream)
398{
399 struct aml_stream_out *out = (struct aml_stream_out *) stream;
400 if (out->multich > 2) {
401 if (out->multich == 6) {
402 return AUDIO_CHANNEL_OUT_5POINT1;
403 } else if (out->multich == 8) {
404 return AUDIO_CHANNEL_OUT_7POINT1;
405 }
406 }
407 if (out->config.channels == 1) {
408 return AUDIO_CHANNEL_OUT_MONO;
409 } else {
410 return AUDIO_CHANNEL_OUT_STEREO;
411 }
412}
413
414static audio_format_t
415out_get_format(const struct audio_stream *stream)
416{
417 struct aml_stream_out *out = (struct aml_stream_out *)stream;
418
419 return out->format;
420}
421
422static int
423out_set_format(struct audio_stream *stream, int format)
424{
425 LOGFUNC("%s(%p)", __FUNCTION__, stream);
426
427 return 0;
428}
429
430/* must be called with hw device and output stream mutexes locked */
431static int
432do_output_standby(struct aml_stream_out *out)
433{
434 struct aml_audio_device *adev = out->dev;
435 if (!out->standby) {
436 pcm_close(out->pcm);
437 out->pcm = NULL;
438
439 adev->active_output = 0;
440
441 /* if in call, don't turn off the output stage. This will
442 be done when the call is ended */
443 if (adev->mode != AUDIO_MODE_IN_CALL) {
444 /* FIXME: only works if only one output can be active at a time */
445
446 //reset_mixer_state(adev->ar);
447 }
448 out->standby = 1;
449 }
450 ALOGI("clear out pause status\n");
451 out->pause_status = false;
452 return 0;
453}
454
455static int
456out_standby(struct audio_stream *stream)
457{
458 struct aml_stream_out *out = (struct aml_stream_out *) stream;
459 int status;
460
461 LOGFUNC("%s(%p),out %p", __FUNCTION__, stream, out);
462
463 pthread_mutex_lock(&out->dev->lock);
464 pthread_mutex_lock(&out->lock);
465 status = do_output_standby(out);
466 set_codec_type(TYPE_PCM);
467/* clear the hdmitx channel config to default */
468 if (out->multich == 6) {
469 sysfs_set_sysfs_str("/sys/class/amhdmitx/amhdmitx0/aud_output_chs", "0:0");
470 }
471 if (out->format != AUDIO_FORMAT_DTS_HD)
472 set_codec_type(TYPE_PCM);
473 pthread_mutex_unlock(&out->lock);
474 pthread_mutex_unlock(&out->dev->lock);
475 return status;
476}
477
478static int
479out_dump(const struct audio_stream *stream, int fd)
480{
481 LOGFUNC("%s(%p, %d)", __FUNCTION__, stream, fd);
482 return 0;
483}
484static int
485out_flush(const struct audio_stream *stream)
486{
487 LOGFUNC("%s(%p)", __FUNCTION__, stream);
488 struct aml_stream_out *out = (struct aml_stream_out *) stream;
489 struct aml_audio_device *adev = out->dev;
490 pthread_mutex_lock(&adev->lock);
491 pthread_mutex_lock(&out->lock);
492 do_output_standby(out);
493 out->spdif_enc_init_frame_write_sum = 0;
494 out->frame_write_sum = 0;
495 out->frame_skip_sum = 0;
496 out->skip_frame = 3;
497 pthread_mutex_unlock(&adev->lock);
498 pthread_mutex_unlock(&out->lock);
499 return 0;
500}
501
502static int
503out_set_parameters(struct audio_stream *stream, const char *kvpairs)
504{
505 struct aml_stream_out *out = (struct aml_stream_out *) stream;
506 struct aml_audio_device *adev = out->dev;
507 struct aml_stream_in *in;
508 struct str_parms *parms;
509 char *str;
510 char value[64] = {0};
511 int ret, val = 0;
512 bool force_input_standby = false;
513
514 LOGFUNC("%s(kvpairs(%s), out_device=%#x)", __FUNCTION__, kvpairs,
515 adev->out_device);
516 parms = str_parms_create_str(kvpairs);
517
518 ret =
519 str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value,
520 sizeof(value));
521 if (ret >= 0) {
522 val = atoi(value);
523 pthread_mutex_lock(&adev->lock);
524 pthread_mutex_lock(&out->lock);
525 if (((adev->out_device & AUDIO_DEVICE_OUT_ALL) != val) && (val != 0)) {
526 if (out == adev->active_output) {
527 do_output_standby(out);
528 /* a change in output device may change the microphone selection */
529 if (adev->active_input &&
530 adev->active_input->source ==
531 AUDIO_SOURCE_VOICE_COMMUNICATION) {
532 force_input_standby = true;
533 }
534 /* force standby if moving to/from HDMI */
535 if (((val & AUDIO_DEVICE_OUT_AUX_DIGITAL) ^
536 (adev->out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) ||
537 ((val & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) ^
538 (adev->out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET))) {
539 do_output_standby(out);
540 }
541 }
542 adev->out_device &= ~AUDIO_DEVICE_OUT_ALL;
543 adev->out_device |= val;
544 select_output_device(adev);
545 }
546 pthread_mutex_unlock(&out->lock);
547 if (force_input_standby) {
548 in = adev->active_input;
549 pthread_mutex_lock(&in->lock);
550 do_input_standby(in);
551 pthread_mutex_unlock(&in->lock);
552 }
553 pthread_mutex_unlock(&adev->lock);
554 goto exit;
555 }
556 int sr = 0;
557 ret = str_parms_get_int(parms, AUDIO_PARAMETER_STREAM_SAMPLING_RATE, &sr);
558 if (ret >= 0) {
559 if (sr > 0) {
560 ALOGI("audio hw sampling_rate change from %d to %d \n",
561 DEFAULT_OUT_SAMPLING_RATE, sr);
562 DEFAULT_OUT_SAMPLING_RATE = sr;
563 pcm_config_out.rate = DEFAULT_OUT_SAMPLING_RATE;
564 out->config.rate = DEFAULT_OUT_SAMPLING_RATE;
565 pthread_mutex_lock(&adev->lock);
566 pthread_mutex_lock(&out->lock);
567 if (!out->standby && (out == adev->active_output)) {
568 //do_output_standby (out);
569 //start_output_stream (out);
570 //out->standby = 0;
571 }
572 pthread_mutex_unlock(&adev->lock);
573 pthread_mutex_unlock(&out->lock);
574
575 }
576 goto exit;
577 }
578 int frame_size = 0;
579 ret =
580 str_parms_get_int(parms, AUDIO_PARAMETER_STREAM_FRAME_COUNT,
581 &frame_size);
582 if (ret >= 0) {
583 if (frame_size > 0) {
584 ALOGI("audio hw frame size change from %d to %d \n", PERIOD_SIZE,
585 frame_size);
586 PERIOD_SIZE = frame_size;
587 pcm_config_out.period_size = PERIOD_SIZE;
588 out->config.period_size = PERIOD_SIZE;
589 pthread_mutex_lock(&adev->lock);
590 pthread_mutex_lock(&out->lock);
591 if (!out->standby && (out == adev->active_output)) {
592 //do_output_standby (out);
593 //start_output_stream (out);
594 //out->standby = 0;
595 }
596 pthread_mutex_unlock(&adev->lock);
597 pthread_mutex_unlock(&out->lock);
598
599 }
600 goto exit;
601 }
602
603 ret = str_parms_get_str(parms, "hw_av_sync", value, sizeof(value));
604 if (ret >= 0) {
605 int hw_sync_id = atoi(value);
606 unsigned char sync_enable = (hw_sync_id == 12345678) ? 1 : 0;
607 ALOGI("(%p %p)set hw_sync_id %d,%s hw sync mode\n",
608 out, adev->active_output, hw_sync_id, sync_enable ? "enable" : "disable");
609 pthread_mutex_lock(&adev->lock);
610 pthread_mutex_lock(&out->lock);
611 adev->hw_sync_mode = sync_enable;
612 out->frame_write_sum = 0;
613 out->frame_skip_sum = 0;
614 /* clear up previous playback output status */
615 if (!out->standby && (out == adev->active_output)) {
616 do_output_standby(out);
617 }
618 pthread_mutex_unlock(&adev->lock);
619 pthread_mutex_unlock(&out->lock);
620 goto exit;
621 }
622 ret = str_parms_get_str(parms, "hdmi_arc_ad", value, sizeof(value));
623 if (ret >= 0) {
624 int r;
625 ALOGI("(%p %p)set hdmi_arc_ad %s\n",
626 out, adev->active_output, value);
627 pthread_mutex_lock(&adev->lock);
628 pthread_mutex_lock(&out->lock);
629 int i;
630 char temp[7] = {0};
631 unsigned ad = 0;
632 ALOGI("size of ad %d\n", strlen(value));
633 for (i = 0; i < strlen(value); i = i + 6) {
634 temp[6] = '\0';
635 memcpy(temp, value + i, 6);
636 ad = 0;
637 r = sscanf(temp, "%x", &ad);
638 if (r != 1) {
639 ALOGE("sscanf failed\n");
640 }
641 adev->hdmi_arc_ad[i] = ad;
642 ALOGI("hdmi arc support audio ad code %x,index %d\n", ad, i / 6);
643 }
644 pthread_mutex_unlock(&adev->lock);
645 pthread_mutex_unlock(&out->lock);
646 goto exit;
647 }
648exit:
649 str_parms_destroy(parms);
650 return ret;
651}
652static char *
653out_get_parameters(const struct audio_stream *stream, const char *keys)
654{
655 char *cap = NULL;
656 char *para = NULL;
657 struct aml_stream_out *out = (struct aml_stream_out *) stream;
658 struct aml_audio_device *adev = out->dev;
659 ALOGI("out_get_parameters %s,out %p\n", keys, out);
660 if (strstr(keys, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)) {
661 if (out->out_device & AUDIO_DEVICE_OUT_HDMI_ARC) {
662 cap = (char *)get_hdmi_arc_cap(adev->hdmi_arc_ad, HDMI_ARC_MAX_FORMAT, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES);
663 } else {
664 cap = (char *)get_hdmi_sink_cap(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES);
665 }
666 if (cap) {
667 para = strdup(cap);
668 free(cap);
669 } else {
670 para = strdup("");
671 }
672 ALOGI("%s\n", para);
673 return para;
674 } else if (strstr(keys, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
675 if (out->out_device & AUDIO_DEVICE_OUT_HDMI_ARC) {
676 cap = (char *)get_hdmi_arc_cap(adev->hdmi_arc_ad, HDMI_ARC_MAX_FORMAT, AUDIO_PARAMETER_STREAM_SUP_CHANNELS);
677 } else {
678 cap = (char *)get_hdmi_sink_cap(AUDIO_PARAMETER_STREAM_SUP_CHANNELS);
679 }
680 if (cap) {
681 para = strdup(cap);
682 free(cap);
683 } else {
684 para = strdup("");
685 }
686 ALOGI("%s\n", para);
687 return para;
688 } else if (strstr(keys, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
689 if (out->out_device & AUDIO_DEVICE_OUT_HDMI_ARC) {
690 cap = (char *)get_hdmi_arc_cap(adev->hdmi_arc_ad, HDMI_ARC_MAX_FORMAT, AUDIO_PARAMETER_STREAM_SUP_FORMATS);
691 } else {
692 cap = (char *)get_hdmi_sink_cap(AUDIO_PARAMETER_STREAM_SUP_FORMATS);
693 }
694 if (cap) {
695 para = strdup(cap);
696 free(cap);
697 } else {
698 para = strdup("");
699 }
700 ALOGI("%s\n", para);
701 return para;
702 }
703 return strdup("");
704}
705static uint32_t out_get_latency(const struct audio_stream_out *stream)
706{
707 struct aml_stream_out *out = (struct aml_stream_out *)stream;
708 uint32_t whole_latency;
709 uint32_t ret;
710 snd_pcm_sframes_t frames = 0;
711 whole_latency = (out->config.period_size * out->config.period_count * 1000) / out->config.rate;
712 if (!out->pcm || !pcm_is_ready(out->pcm)) {
713 return whole_latency;
714 }
715 ret = pcm_ioctl(out->pcm, SNDRV_PCM_IOCTL_DELAY, &frames);
716 if (ret < 0) {
717 return whole_latency;
718 }
719 if (out->format == AUDIO_FORMAT_E_AC3) {
720 frames /= 4;
721 }
722 return (frames * 1000) / out->config.rate;
723
724}
725static int
726out_set_volume(struct audio_stream_out *stream, float left, float right)
727{
728 return -ENOSYS;
729}
730
731static int out_pause(struct audio_stream_out *stream)
732{
733 struct aml_stream_out *out = (struct aml_stream_out *) stream;
734 struct aml_audio_device *adev = out->dev;
735 int r = 0;
736 LOGFUNC("(%p)out_pause", out);
737 pthread_mutex_lock(&adev->lock);
738 pthread_mutex_lock(&out->lock);
739 if (out->standby || out->pause_status == true) {
740 goto exit;
741 }
742 if (pcm_is_ready(out->pcm)) {
743 r = pcm_ioctl(out->pcm, SNDRV_PCM_IOCTL_PAUSE, 1);
744 if (r < 0) {
745 ALOGE("cannot pause channel\n");
746 } else {
747 r = 0;
748 }
749 }
750 if (out->dev->hw_sync_mode) {
751 sysfs_set_sysfs_str(TSYNC_EVENT, "AUDIO_PAUSE");
752 }
753 ALOGI("set out pause status\n");
754 out->pause_status = true;
755exit:
756 pthread_mutex_unlock(&adev->lock);
757 pthread_mutex_unlock(&out->lock);
758 return r;
759}
760
761static int out_resume(struct audio_stream_out *stream)
762{
763 LOGFUNC("out_resume");
764 struct aml_stream_out *out = (struct aml_stream_out *) stream;
765 struct aml_audio_device *adev = out->dev;
766 pthread_mutex_lock(&adev->lock);
767 pthread_mutex_lock(&out->lock);
768 int r = 0;
769 if (out->standby || out->pause_status == false) {
770 goto exit;
771 }
772 if (pcm_is_ready(out->pcm)) {
773 r = pcm_ioctl(out->pcm, SNDRV_PCM_IOCTL_PAUSE, 0);
774 if (r < 0) {
775 ALOGE("cannot resume channel\n");
776 } else {
777 r = 0;
778 }
779 }
780 if (out->dev->hw_sync_mode) {
781 sysfs_set_sysfs_str(TSYNC_EVENT, "AUDIO_RESUME");
782 }
783 ALOGI("clear out pause status\n");
784 out->pause_status = false;
785exit:
786 pthread_mutex_unlock(&adev->lock);
787 pthread_mutex_unlock(&out->lock);
788 return r;
789}
790
791static ssize_t
792out_write(struct audio_stream_out *stream, const void *buffer, size_t bytes)
793{
794 int ret = 0;
795 struct aml_stream_out *out = (struct aml_stream_out *) stream;
796 struct aml_audio_device *adev = out->dev;
797 size_t frame_size = audio_stream_out_frame_size(stream);
798 size_t in_frames = bytes / frame_size;
799 bool force_input_standby = false;
800 size_t out_frames = 0;
801 void *buf;
802 uint i, total_len;
803 char prop[PROPERTY_VALUE_MAX];
804 int codec_type = out->codec_type;
805 int samesource_flag = 0;
806 uint32_t latency_frames;
807 uint64_t total_frame = 0;
808 audio_hwsync_t *p_hwsync = &adev->hwsync;
809 /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
810 * on the output stream mutex - e.g. executing select_mode() while holding the hw device
811 * mutex
812 */
813 out->bytes_write_total += bytes;
814 DEBUG("out %p,dev %p out_write total size %lld\n", out, adev, out->bytes_write_total);
815 pthread_mutex_lock(&adev->lock);
816 pthread_mutex_lock(&out->lock);
817 if (out->pause_status == true) {
818 pthread_mutex_unlock(&adev->lock);
819 pthread_mutex_unlock(&out->lock);
820 ALOGI("call out_write when pause status,size %d,(%p)\n", bytes, out);
821 return 0;
822 }
823 if ((out->standby) && adev->hw_sync_mode) {
824 /*
825 there are two types of raw data come to hdmi audio hal
826 1) compressed audio data without IEC61937 wrapped
827 2) compressed audio data with IEC61937 wrapped (typically from amlogic amadec source)
828 we use the AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO to distiguwish the two cases.
829 */
830 if ((codec_type == TYPE_AC3 || codec_type == TYPE_EAC3) && (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)) {
831 spdifenc_init(out->pcm);
832 out->spdif_enc_init_frame_write_sum = out->frame_write_sum;
833 }
834 // todo: check timestamp header PTS discontinue for new sync point after seek
835 aml_audio_hwsync_clear_status(out);
836 out->spdif_enc_init_frame_write_sum = out->frame_write_sum;
837 }
838 if (out->standby) {
839 ret = start_output_stream(out);
840 if (ret != 0) {
841 pthread_mutex_unlock(&adev->lock);
842 goto exit;
843 }
844 out->standby = 0;
845 /* a change in output device may change the microphone selection */
846 if (adev->active_input &&
847 adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
848 force_input_standby = true;
849 }
850 }
851 void *write_buf = NULL;
852 int hwsync_cost_bytes = 0;
853 if (adev->hw_sync_mode == 1) {
854 uint64_t cur_pts = 0xffffffff;
855 int outsize = 0;
856 char tempbuf[128];
857 DEBUG("before aml_audio_hwsync_find_frame bytes %d\n", bytes);
858 hwsync_cost_bytes = aml_audio_hwsync_find_frame(out, buffer, bytes, &cur_pts, &outsize);
859 DEBUG("after aml_audio_hwsync_find_frame bytes remain %d,cost %d,outsize %d,pts %llx\n",
860 bytes - hwsync_cost_bytes, hwsync_cost_bytes, outsize, cur_pts);
861 //TODO,skip 3 frames after flush, to tmp fix seek pts discontinue issue.need dig more
862 // to find out why seek ppint pts frame is remained after flush.WTF.
863 if (out->skip_frame > 0) {
864 out->skip_frame--;
865 ALOGI("skip pts@%llx,cur frame size %d,cost size %d\n", cur_pts, outsize, hwsync_cost_bytes);
866 pthread_mutex_unlock(&adev->lock);
867 pthread_mutex_unlock(&out->lock);
868 return hwsync_cost_bytes;
869 }
870 if (cur_pts != 0xffffffff && outsize > 0) {
871 // if we got the frame body,which means we get a complete frame.
872 //we take this frame pts as the first apts.
873 //this can fix the seek discontinue,we got a fake frame,which maybe cached before the seek
874 if (p_hwsync->first_apts_flag == false) {
875 p_hwsync->first_apts_flag = true;
876 p_hwsync->first_apts = cur_pts;
877 sprintf(tempbuf, "AUDIO_START:0x%lx", cur_pts & 0xffffffff);
878 ALOGI("tsync -> %s,frame size %d", tempbuf, outsize);
879 if (sysfs_set_sysfs_str(TSYNC_EVENT, tempbuf) == -1) {
880 ALOGE("set AUDIO_START failed \n");
881 }
882 } else {
883 unsigned long apts;
884 unsigned long latency = out_get_latency(out) * 90;
885 // check PTS discontinue, which may happen when audio track switching
886 // discontinue means PTS calculated based on first_apts and frame_write_sum
887 // does not match the timestamp of next audio samples
888 if (cur_pts > latency) {
889 apts = (unsigned long)cur_pts - latency;
890 } else {
891 apts = 0;
892 }
893 if (0) { //abs(cur_pts -apts) > APTS_DISCONTINUE_THRESHOLD) {
894 ALOGI("HW sync PTS discontinue, 0x%llx->0x%llx(from header) diff %llx,last apts %llx(from header)",
895 apts, cur_pts, abs(cur_pts - apts), p_hwsync->last_apts_from_header);
896 p_hwsync->first_apts = cur_pts;
897 sprintf(tempbuf, "AUDIO_TSTAMP_DISCONTINUITY:0x%lx", cur_pts);
898 if (sysfs_set_sysfs_str(TSYNC_EVENT, tempbuf) == -1) {
899 ALOGE("unable to open file %s,err: %s", TSYNC_EVENT, strerror(errno));
900 }
901 } else {
902 unsigned long pcr = 0;
903 if (get_sysfs_int16(TSYNC_PCRSCR, &pcr) == 0) {
904 uint32_t apts_cal = apts & 0xffffffff;
905 if (abs(pcr - apts) < SYSTIME_CORRECTION_THRESHOLD) {
906 // do nothing
907 }
908 // limit the gap handle to 0.5~5 s.
909 else if ((apts - pcr) > APTS_DISCONTINUE_THRESHOLD_MIN && (apts - pcr) < APTS_DISCONTINUE_THRESHOLD_MAX) {
910 int insert_size = 0;
911 int once_write_size = 0;
912 if (out->codec_type == TYPE_EAC3) {
913 insert_size = abs(apts - pcr) / 90 * 48 * 4 * 4;
914 } else {
915 insert_size = abs(apts - pcr) / 90 * 48 * 4;
916 }
917 insert_size = insert_size & (~63);
918 ALOGI("audio gap %d ms ,need insert data %d\n", abs(apts - pcr) / 90, insert_size);
919 char *insert_buf = (char*)malloc(8192);
920 if (insert_buf == NULL) {
921 ALOGE("malloc size failed \n");
922 pthread_mutex_unlock(&adev->lock);
923 goto exit;
924 }
925 memset(insert_buf, 0, 8192);
926 while (insert_size > 0) {
927 once_write_size = insert_size > 8192 ? 8192 : insert_size;
928 ret = pcm_write(out->pcm, (void *) insert_buf, once_write_size);
929 if (ret != 0) {
930 ALOGE("pcm write failed\n");
931 free(insert_buf);
932 pthread_mutex_unlock(&adev->lock);
933 goto exit;
934 }
935 insert_size -= once_write_size;
936 }
937 free(insert_buf);
938 }
939 //audio pts smaller than pcr,need skip frame.
940 else if ((pcr - apts) > APTS_DISCONTINUE_THRESHOLD_MIN && (pcr - apts) < APTS_DISCONTINUE_THRESHOLD_MAX) {
941 //we assume one frame duration is 32 ms for DD+(6 blocks X 1536 frames,48K sample rate)
942 if (out->codec_type == TYPE_EAC3 && outsize > 0) {
943 ALOGI("audio slow 0x%x,skip frame @pts 0x%llx,pcr 0x%x,cur apts 0x%x\n", (pcr - apts), cur_pts, pcr, apts);
944 out->frame_skip_sum += 1536;
945 bytes = outsize;
946 pthread_mutex_unlock(&adev->lock);
947 goto exit;
948 }
949 } else {
950 sprintf(tempbuf, "0x%lx", apts);
951 ALOGI("tsync -> reset pcrscr 0x%x -> 0x%x, %s big,diff %d ms", pcr, apts, apts > pcr ? "apts" : "pcr", abs(apts - pcr) / 90);
952#if 0
953 int ret_val = sysfs_set_sysfs_str(TSYNC_APTS, tempbuf);
954 if (ret_val == -1) {
955 ALOGE("unable to open file %s,err: %s", TSYNC_APTS, strerror(errno));
956 }
957#endif
958 }
959 }
960 }
961 }
962 }
963 if (outsize > 0) {
964 in_frames = outsize / frame_size;
965 write_buf = p_hwsync->hw_sync_body_buf;
966 } else {
967 bytes = hwsync_cost_bytes;
968 pthread_mutex_unlock(&adev->lock);
969 goto exit;
970 }
971 } else {
972 write_buf = (void *) buffer;
973 }
974 pthread_mutex_unlock(&adev->lock);
975 out_frames = in_frames;
976 buf = (void *) write_buf;
977 if (getprop_bool("media.hdmihal.outdump")) {
978 FILE *fp1 = fopen("/data/tmp/hdmi_audio_out.pcm", "a+");
979 if (fp1) {
980 int flen = fwrite((char *)buffer, 1, out_frames * frame_size, fp1);
981 LOGFUNC("flen = %d---outlen=%d ", flen, out_frames * frame_size);
982 fclose(fp1);
983 } else {
984 LOGFUNC("could not open file:/data/hdmi_audio_out.pcm");
985 }
986 }
987 if (codec_type_is_raw_data(out->codec_type) && !(out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)) {
988 //here to do IEC61937 pack
989 DEBUG("IEC61937 write size %d,hw_sync_mode %d,flag %x\n", out_frames * frame_size, adev->hw_sync_mode, out->flags);
990 if (out->codec_type > 0) {
991 // compressed audio DD/DD+
992 bytes = spdifenc_write((void *) buf, out_frames * frame_size);
993 //need return actual size of this burst write
994 if (adev->hw_sync_mode == 1) {
995 bytes = hwsync_cost_bytes;
996 }
997 DEBUG("spdifenc_write return %d\n", bytes);
998 if (out->codec_type == TYPE_EAC3) {
999 out->frame_write_sum = spdifenc_get_total() / 16 + out->spdif_enc_init_frame_write_sum;
1000 } else {
1001 out->frame_write_sum = spdifenc_get_total() / 4 + out->spdif_enc_init_frame_write_sum;
1002 }
1003 DEBUG("out %p,spdifenc_get_total() / 4 %lld\n", out, spdifenc_get_total() / 16);
1004 }
1005 goto exit;
1006 }
1007 if (!out->standby) {
1008 if (out->multich == 8) {
1009 int *p32 = NULL;
1010 short *p16 = (short *) buf;
1011 short *p16_temp;
1012 int i, NumSamps;
1013 NumSamps = out_frames * frame_size / sizeof(short);
1014 p32 = malloc(NumSamps * sizeof(int));
1015 if (p32 != NULL) {
1016 //here to swap the channnl data here
1017 //actual now:L,missing,R,RS,RRS,,LS,LRS,missing
1018 //expect L,C,R,RS,RRS,LRS,LS,LFE (LFE comes from to center)
1019 //actual audio data layout L,R,C,none/LFE,LRS,RRS,LS,RS
1020 p16_temp = (short *) p32;
1021 for (i = 0; i < NumSamps; i = i + 8) {
1022 p16_temp[0 + i]/*L*/ = p16[0 + i];
1023 p16_temp[1 + i]/*R*/ = p16[1 + i];
1024 p16_temp[2 + i] /*LFE*/ = p16[3 + i];
1025 p16_temp[3 + i] /*C*/ = p16[2 + i];
1026 p16_temp[4 + i] /*LS*/ = p16[6 + i];
1027 p16_temp[5 + i] /*RS*/ = p16[7 + i];
1028 p16_temp[6 + i] /*LRS*/ = p16[4 + i];
1029 p16_temp[7 + i]/*RRS*/ = p16[5 + i];
1030 }
1031 memcpy(p16, p16_temp, NumSamps * sizeof(short));
1032 for (i = 0; i < NumSamps; i++) { //suppose 16bit/8ch PCM
1033 p32[i] = p16[i] << 16;
1034 }
1035 ret = pcm_write(out->pcm, (void *) p32, NumSamps * 4);
1036 free(p32);
1037 }
1038 } else if (out->multich == 6) {
1039 int *p32 = NULL;
1040 short *p16 = (short *) buf;
1041 short *p16_temp;
1042 int i, j, NumSamps, real_samples;
1043 real_samples = out_frames * frame_size / sizeof(short);
1044 NumSamps = real_samples * 8 / 6;
1045 //ALOGI("6ch to 8 ch real %d, to %d,bytes %d,frame size %d\n",real_samples,NumSamps,bytes,frame_size);
1046 p32 = malloc(NumSamps * sizeof(int));
1047 if (p32 != NULL) {
1048 p16_temp = (short *) p32;
1049 for (i = 0; i < real_samples; i = i + 6) {
1050 p16_temp[0 + i]/*L*/ = p16[0 + i];
1051 p16_temp[1 + i]/*R*/ = p16[1 + i];
1052 p16_temp[2 + i] /*LFE*/ = p16[3 + i];
1053 p16_temp[3 + i] /*C*/ = p16[2 + i];
1054 p16_temp[4 + i] /*LS*/ = p16[4 + i];
1055 p16_temp[5 + i] /*RS*/ = p16[5 + i];
1056 }
1057 memcpy(p16, p16_temp, real_samples * sizeof(short));
1058 memset(p32, 0, NumSamps * sizeof(int));
1059 for (i = 0, j = 0; j < NumSamps; i = i + 6, j = j + 8) { //suppose 16bit/8ch PCM
1060 p32[j] = p16[i] << 16;
1061 p32[j + 1] = p16[i + 1] << 16;
1062 p32[j + 2] = p16[i + 2] << 16;
1063 p32[j + 3] = p16[i + 3] << 16;
1064 p32[j + 4] = p16[i + 4] << 16;
1065 p32[j + 5] = p16[i + 5] << 16;
1066 }
1067 ret = pcm_write(out->pcm, (void *) p32, NumSamps * 4);
1068 free(p32);
1069 }
1070 } else {
1071#if 0
1072 codec_type =
1073 get_sysfs_int("/sys/class/audiodsp/digital_codec");
1074 samesource_flag =
1075 get_sysfs_int("/sys/class/audiodsp/audio_samesource");
1076 if (out->last_codec_type > 0 && codec_type != out->last_codec_type) {
1077 samesource_flag = 1;
1078 }
1079 if (samesource_flag == 1 && codec_type) {
1080 ALOGI
1081 ("to disable same source,need reset alsa,last %d,type %d,same source flag %d ,\n",
1082 out->last_codec_type, codec_type, samesource_flag);
1083 out->last_codec_type = codec_type;
1084 pcm_stop(out->pcm);
1085 }
1086#endif
1087 DEBUG("write size %d\n", out_frames * frame_size);
1088 ret = pcm_write(out->pcm, (void *) buf, out_frames * frame_size);
1089 if (ret == 0) {
1090 out->frame_write_sum += out_frames;
1091 }
1092 }
1093 }
1094exit:
1095 total_frame = out->frame_write_sum + out->frame_skip_sum;
1096 latency_frames = out_get_latency(out) * out->config.rate / 1000;
1097 if (total_frame >= latency_frames) {
1098 out->last_frames_postion = total_frame - latency_frames;
1099 } else {
1100 out->last_frames_postion = total_frame;
1101 }
1102 pthread_mutex_unlock(&out->lock);
1103 if (ret != 0) {
1104 usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
1105 out_get_sample_rate(&stream->common));
1106 }
1107 return bytes;
1108}
1109
1110static int
1111out_get_render_position(const struct audio_stream_out *stream,
1112 uint32_t * dsp_frames)
1113{
1114 LOGFUNC("%s(%p, %p)", __FUNCTION__, stream, dsp_frames);
1115 return -EINVAL;
1116}
1117
1118static int
1119out_add_audio_effect(const struct audio_stream *stream,
1120 effect_handle_t effect)
1121{
1122 LOGFUNC("%s(%p, %p)", __FUNCTION__, stream, effect);
1123 return 0;
1124}
1125
1126static int
1127out_remove_audio_effect(const struct audio_stream *stream,
1128 effect_handle_t effect)
1129{
1130 return 0;
1131}
1132
1133static int
1134out_get_next_write_timestamp(const struct audio_stream_out *stream,
1135 int64_t * timestamp)
1136{
1137 return -EINVAL;
1138}
1139static int out_get_presentation_position(const struct audio_stream_out *stream, uint64_t *frames, struct timespec *timestamp)
1140{
1141 struct aml_stream_out *out = (struct aml_stream_out *)stream;
1142#if 1
1143 if (frames != NULL) {
1144 *frames = out->last_frames_postion;
1145 }
1146 DEBUG("%p,*frames %lld\n", out, *frames);
1147 if (timestamp != NULL) {
1148 clock_gettime(CLOCK_MONOTONIC, timestamp);
1149 }
1150#else
1151#define TIME_TO_MS(time) ((uint64_t)time->tv_sec * 1000 + time->tv_nsec/1000000ULL)
1152
1153 if (timestamp != NULL) {
1154 clock_gettime(CLOCK_MONOTONIC, timestamp);
1155 if (out->last_frames_pos == 0) {
1156
1157 ALOGI("first frame pos \n");
1158 if (frames != NULL) {
1159 *frames = out->last_frames_pos;
1160 }
1161 out->last_frames_pos = TIME_TO_MS(timestamp) * 48;
1162 } else {
1163 if (frames != NULL) {
1164 *frames = TIME_TO_MS(timestamp) * 48 - out->last_frames_pos;
1165 }
1166 ALOGI("pos %lld,first %lld\n", *frames, out->last_frames_pos);
1167 }
1168
1169 }
1170#undef TIME_TO_MS
1171#endif
1172 return 0;
1173}
1174/** audio_stream_in implementation **/
1175
1176/* must be called with hw device and input stream mutexes locked */
1177static int
1178start_input_stream(struct aml_stream_in *in)
1179{
1180 int ret = 0;
1181 unsigned int card = CARD_AMLOGIC_DEFAULT;
1182 unsigned int port = PORT_MM;
1183 struct aml_audio_device *adev = in->dev;
1184 LOGFUNC
1185 ("%s(need_echo_reference=%d, channels=%d, rate=%d, requested_rate=%d, mode= %d)",
1186 __FUNCTION__, in->need_echo_reference, in->config.channels,
1187 in->config.rate, in->requested_rate, adev->mode);
1188 adev->active_input = in;
1189 if (adev->mode != AUDIO_MODE_IN_CALL) {
1190 adev->in_device &= ~AUDIO_DEVICE_IN_ALL;
1191 adev->in_device |= in->device;
1192 select_input_device(adev);
1193 }
1194 PERIOD_SIZE = DEFAULT_PERIOD_SIZE;
1195 in->config.period_size = PERIOD_SIZE;
1196 /* this assumes routing is done previously */
1197 in->pcm = pcm_open(card, port, PCM_IN, &in->config);
1198 if (!pcm_is_ready(in->pcm)) {
1199 ALOGE("cannot open pcm_in driver: %s", pcm_get_error(in->pcm));
1200 pcm_close(in->pcm);
1201 adev->active_input = NULL;
1202 return -ENOMEM;
1203 }
1204 ALOGI("pcm_open in: card(%d), port(%d)", card, port);
1205 return 0;
1206}
1207
1208static int
1209check_input_stream(struct aml_stream_in *in)
1210{
1211 int ret = 0;
1212 unsigned int card = CARD_AMLOGIC_BOARD;
1213 unsigned int port = 0;
1214 int ext_card;
1215 ext_card = get_external_card(1);
1216 if (ext_card < 0) {
1217 card = CARD_AMLOGIC_BOARD;
1218 } else {
1219 card = ext_card;
1220 }
1221 /* this assumes routing is done previously */
1222 in->pcm = pcm_open(card, port, PCM_IN, &in->config);
1223 if (!pcm_is_ready(in->pcm)) {
1224 ALOGE("check_input_stream:cannot open pcm_in driver: %s",
1225 pcm_get_error(in->pcm));
1226 pcm_close(in->pcm);
1227 return -ENOMEM;
1228 }
1229 pcm_close(in->pcm);
1230 return 0;
1231}
1232
1233static uint32_t
1234in_get_sample_rate(const struct audio_stream *stream)
1235{
1236 struct aml_stream_in *in = (struct aml_stream_in *) stream;
1237
1238 LOGFUNC("%s(%p)", __FUNCTION__, stream);
1239 return in->requested_rate;
1240}
1241
1242static int
1243in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
1244{
1245 LOGFUNC("%s(%p, %d)", __FUNCTION__, stream, rate);
1246 return 0;
1247}
1248
1249static size_t
1250in_get_buffer_size(const struct audio_stream *stream)
1251{
1252 struct aml_stream_in *in = (struct aml_stream_in *) stream;
1253
1254 LOGFUNC("%s(%p)", __FUNCTION__, stream);
1255 return get_input_buffer_size(in->config.rate,
1256 AUDIO_FORMAT_PCM_16_BIT, in->config.channels);
1257}
1258
1259static audio_channel_mask_t
1260in_get_channels(const struct audio_stream *stream)
1261{
1262 struct aml_stream_in *in = (struct aml_stream_in *) stream;
1263 if (in->config.channels == 1) {
1264 return AUDIO_CHANNEL_IN_MONO;
1265 } else {
1266 return AUDIO_CHANNEL_IN_STEREO;
1267 }
1268}
1269
1270static audio_format_t
1271in_get_format(const struct audio_stream *stream)
1272{
1273 return AUDIO_FORMAT_PCM_16_BIT;
1274}
1275
1276static int
1277in_set_format(struct audio_stream *stream, audio_format_t format)
1278{
1279 LOGFUNC("%s(%p, %d)", __FUNCTION__, stream, format);
1280 return 0;
1281}
1282
1283/* must be called with hw device and input stream mutexes locked */
1284static int
1285do_input_standby(struct aml_stream_in *in)
1286{
1287 struct aml_audio_device *adev = in->dev;
1288 LOGFUNC("%s(%p)", __FUNCTION__, in);
1289 if (!in->standby) {
1290 pcm_close(in->pcm);
1291 in->pcm = NULL;
1292 adev->active_input = 0;
1293 if (adev->mode != AUDIO_MODE_IN_CALL) {
1294 adev->in_device &= ~AUDIO_DEVICE_IN_ALL;
1295 select_input_device(adev);
1296 }
1297 in->standby = 1;
1298 }
1299 return 0;
1300}
1301
1302static int
1303in_standby(struct audio_stream *stream)
1304{
1305 struct aml_stream_in *in = (struct aml_stream_in *) stream;
1306 int status;
1307 LOGFUNC("%s(%p)", __FUNCTION__, stream);
1308 pthread_mutex_lock(&in->dev->lock);
1309 pthread_mutex_lock(&in->lock);
1310 status = do_input_standby(in);
1311 pthread_mutex_unlock(&in->lock);
1312 pthread_mutex_unlock(&in->dev->lock);
1313 return status;
1314}
1315
1316static int
1317in_dump(const struct audio_stream *stream, int fd)
1318{
1319 LOGFUNC("%s(%p, %d)", __FUNCTION__, stream, fd);
1320 return 0;
1321}
1322
1323static int
1324in_set_parameters(struct audio_stream *stream, const char *kvpairs)
1325{
1326 struct aml_stream_in *in = (struct aml_stream_in *) stream;
1327 struct aml_audio_device *adev = in->dev;
1328 struct str_parms *parms;
1329 char *str;
1330 char value[32];
1331 int ret, val = 0;
1332 bool do_standby = false;
1333 LOGFUNC("%s(%p, %s)", __FUNCTION__, stream, kvpairs);
1334 parms = str_parms_create_str(kvpairs);
1335 ret =
1336 str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value,
1337 sizeof(value));
1338 pthread_mutex_lock(&adev->lock);
1339 pthread_mutex_lock(&in->lock);
1340 if (ret >= 0) {
1341 val = atoi(value);
1342 /* no audio source uses val == 0 */
1343 if ((in->source != val) && (val != 0)) {
1344 in->source = val;
1345 do_standby = true;
1346 }
1347 }
1348 ret =
1349 str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value,
1350 sizeof(value));
1351 if (ret >= 0) {
1352 val = atoi(value) & ~AUDIO_DEVICE_BIT_IN;
1353 if ((in->device != val) && (val != 0)) {
1354 in->device = val;
1355 do_standby = true;
1356 }
1357 }
1358 if (do_standby) {
1359 do_input_standby(in);
1360 }
1361 pthread_mutex_unlock(&in->lock);
1362 pthread_mutex_unlock(&adev->lock);
1363 str_parms_destroy(parms);
1364 return ret;
1365}
1366
1367static char *
1368in_get_parameters(const struct audio_stream *stream, const char *keys)
1369{
1370 return strdup("");
1371}
1372
1373static int
1374in_set_gain(struct audio_stream_in *stream, float gain)
1375{
1376 LOGFUNC("%s(%p, %f)", __FUNCTION__, stream, gain);
1377 return 0;
1378}
1379static ssize_t
1380in_read(struct audio_stream_in *stream, void *buffer, size_t bytes)
1381{
1382 int ret = 0;
1383 int i = 0;
1384 struct aml_stream_in *in = (struct aml_stream_in *) stream;
1385 struct aml_audio_device *adev = in->dev;
1386 size_t frames_rq = bytes / audio_stream_in_frame_size(stream);
1387 /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
1388 * on the input stream mutex - e.g. executing select_mode() while holding the hw device
1389 * mutex
1390 */
1391 pthread_mutex_lock(&adev->lock);
1392 pthread_mutex_lock(&in->lock);
1393 if (in->standby) {
1394 ret = start_input_stream(in);
1395 if (ret == 0) {
1396 in->standby = 0;
1397 }
1398 }
1399 pthread_mutex_unlock(&adev->lock);
1400 ret = pcm_read(in->pcm, buffer, bytes);
1401 if (ret > 0) {
1402 ret = 0;
1403 }
1404 if (ret == 0 && adev->mic_mute) {
1405 LOGFUNC("%s(adev->mic_mute = %d)", __FUNCTION__, adev->mic_mute);
1406 memset(buffer, 0, bytes);
1407 }
1408exit:
1409 if (ret < 0)
1410 usleep(bytes * 1000000 / audio_stream_in_frame_size(stream) /
1411 in_get_sample_rate(&stream->common));
1412 pthread_mutex_unlock(&in->lock);
1413 return bytes;
1414}
1415
1416static uint32_t
1417in_get_input_frames_lost(struct audio_stream_in *stream)
1418{
1419 return 0;
1420}
1421
1422static int
1423adev_open_output_stream(struct audio_hw_device *dev,
1424 audio_io_handle_t handle,
1425 audio_devices_t devices,
1426 audio_output_flags_t flags,
1427 struct audio_config *config,
1428 struct audio_stream_out **stream_out)
1429{
1430 int ret;
1431 int digital_codec; //digital_codec
1432 struct aml_audio_device *ladev = (struct aml_audio_device *) dev;
1433 struct aml_stream_out *out;
1434 int channel_count = popcount(config->channel_mask);
1435 LOGFUNC("%s(devices=0x%04x,format=%d, chnum=0x%04x, SR=%d,io handle %d, flags = 0x%x )",
1436 __FUNCTION__, devices, config->format, channel_count,
1437 config->sample_rate, handle, flags);
1438 out = (struct aml_stream_out *) calloc(1, sizeof(struct aml_stream_out));
1439 if (!out) {
1440 return -ENOMEM;
1441 }
1442 out->stream.common.get_sample_rate = out_get_sample_rate;
1443 out->stream.common.set_sample_rate = out_set_sample_rate;
1444 out->stream.common.get_buffer_size = out_get_buffer_size;
1445 out->stream.common.get_channels = out_get_channels;
1446 out->stream.common.get_format = out_get_format;
1447 out->stream.common.set_format = out_set_format;
1448 out->stream.common.standby = out_standby;
1449 out->stream.common.dump = out_dump;
1450 out->stream.common.set_parameters = out_set_parameters;
1451 out->stream.common.get_parameters = out_get_parameters;
1452 out->stream.common.add_audio_effect = NULL;//out_add_audio_effect;
1453 out->stream.common.remove_audio_effect = NULL;//out_remove_audio_effect;
1454 out->stream.get_latency = out_get_latency;
1455 out->stream.set_volume = out_set_volume;
1456 out->stream.write = out_write;
1457 out->stream.get_render_position = out_get_render_position;
1458 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
1459 out->stream.pause = out_pause;
1460 out->stream.resume = out_resume;
1461 out->stream.get_presentation_position = out_get_presentation_position;
1462 out->stream.flush = out_flush;
1463 out->config = pcm_config_out;
1464 digital_codec = get_codec_type(config->format);
1465 if (digital_codec == TYPE_EAC3) {
1466 out->config.period_size = pcm_config_out.period_size * 2;
1467 } else if (digital_codec == TYPE_TRUE_HD || digital_codec == TYPE_DTS_HD) {
1468 out->config.period_size = pcm_config_out.period_size * 4 * 2;
1469 }
1470 if (channel_count > 2) {
1471 ALOGI("[adev_open_output_stream]: out/%p channel/%d\n", out,
1472 channel_count);
1473 out->multich = channel_count;
1474 out->config.channels = channel_count;
1475 }
1476 if (codec_type_is_raw_data(digital_codec)) {
1477 ALOGI("for raw audio output,force alsa stereo output\n");
1478 out->config.channels = 2;
1479 out->multich = 2;
1480 }
1481 /* if 2ch high sample rate PCM audio goes to direct output, set the required sample rate which needed by AF */
1482 if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) && config->sample_rate > 0) {
1483 out->config.rate = config->sample_rate;
1484 }
1485 out->format = config->format;
1486 out->dev = ladev;
1487 out->standby = 1;
1488 ladev->hw_sync_mode = false;
1489 ladev->hwsync.first_apts_flag = false;
1490 out->frame_write_sum = 0;
1491 if (flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) {
1492 ALOGI("Output stream open with AUDIO_OUTPUT_FLAG_HW_AV_SYNC");
1493 }
1494 if (audio_is_raw_data(config->format) || (flags & AUDIO_OUTPUT_FLAG_DIRECT)) {
1495 if (config->format == 0) {
1496 config->format = AUDIO_FORMAT_AC3;
1497 out->format = AUDIO_FORMAT_AC3;
1498 }
1499 }
1500 if (config->sample_rate == 0) {
1501 out->config.rate = config->sample_rate = 48000;
1502 }
1503 if (audio_is_raw_data(config->format)) {
1504 out->config.rate = config->sample_rate;
1505 }
1506 LOGFUNC("%s(devices=0x%04x,format=0x%x, chmask=0x%04x, SR=%d)",
1507 __FUNCTION__, devices, config->format, config->channel_mask,
1508 config->sample_rate);
1509 out->flags = flags;
1510 out->out_device = devices;
1511 *stream_out = &out->stream;
1512 if (devices & AUDIO_DEVICE_OUT_HDMI_ARC) {
1513 ALOGI("ARC stream %p\n", out);
1514 memset(ladev->hdmi_arc_ad, 0, sizeof(ladev->hdmi_arc_ad));
1515 }
1516 return 0;
1517err_open:
1518 free(out);
1519 *stream_out = NULL;
1520 return ret;
1521}
1522
1523static void
1524adev_close_output_stream(struct audio_hw_device *dev,
1525 struct audio_stream_out *stream)
1526{
1527 struct aml_stream_out *out = (struct aml_stream_out *) stream;
1528 LOGFUNC("%s(%p, %p)", __FUNCTION__, dev, stream);
1529 out_standby(&stream->common);
1530 if (out->buffer) {
1531 free(out->buffer);
1532 }
1533 free(stream);
1534}
1535
1536static int
1537adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
1538{
1539 LOGFUNC("%s(%p, %s)", __FUNCTION__, dev, kvpairs);
1540 struct aml_audio_device *adev = (struct aml_audio_device *) dev;
1541 return 0;
1542}
1543
1544static char *
1545adev_get_parameters(const struct audio_hw_device *dev, const char *keys)
1546{
1547 LOGFUNC("%s(%p, %s)", __FUNCTION__, dev, keys);
1548 struct aml_audio_device *adev = (struct aml_audio_device *)dev;
1549 if (!strcmp(keys, AUDIO_PARAMETER_HW_AV_EAC3_SYNC)) {
1550 return strdup("true");
1551 }
1552 return strdup("");
1553}
1554
1555static int
1556adev_init_check(const struct audio_hw_device *dev)
1557{
1558 LOGFUNC("%s(%p)", __FUNCTION__, dev);
1559 return 0;
1560}
1561
1562static int
1563adev_set_voice_volume(struct audio_hw_device *dev, float volume)
1564{
1565 struct aml_audio_device *adev = (struct aml_audio_device *) dev;
1566 LOGFUNC("%s(%p, %f)", __FUNCTION__, dev, volume);
1567 return 0;
1568}
1569
1570static int
1571adev_set_master_volume(struct audio_hw_device *dev, float volume)
1572{
1573 LOGFUNC("%s(%p, %f)", __FUNCTION__, dev, volume);
1574 return -ENOSYS;
1575}
1576
1577static int
1578adev_get_master_volume(struct audio_hw_device *dev, float *volume)
1579{
1580 return -ENOSYS;
1581}
1582
1583static int
1584adev_set_master_mute(struct audio_hw_device *dev, bool muted)
1585{
1586 return -ENOSYS;
1587}
1588
1589static int
1590adev_get_master_mute(struct audio_hw_device *dev, bool * muted)
1591{
1592 return -ENOSYS;
1593}
1594
1595static int
1596adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
1597{
1598 struct aml_audio_device *adev = (struct aml_audio_device *) dev;
1599 LOGFUNC("%s(%p, %d)", __FUNCTION__, dev, mode);
1600 pthread_mutex_lock(&adev->lock);
1601 if (adev->mode != mode) {
1602 adev->mode = mode;
1603 select_mode(adev);
1604 }
1605 pthread_mutex_unlock(&adev->lock);
1606 return 0;
1607}
1608
1609static int
1610adev_set_mic_mute(struct audio_hw_device *dev, bool state)
1611{
1612 struct aml_audio_device *adev = (struct aml_audio_device *) dev;
1613 LOGFUNC("%s(%p, %d)", __FUNCTION__, dev, state);
1614 adev->mic_mute = state;
1615 return 0;
1616}
1617
1618static int
1619adev_get_mic_mute(const struct audio_hw_device *dev, bool * state)
1620{
1621 struct aml_audio_device *adev = (struct aml_audio_device *) dev;
1622
1623 LOGFUNC("%s(%p, %p)", __FUNCTION__, dev, state);
1624 *state = adev->mic_mute;
1625 return 0;
1626
1627}
1628
1629static size_t
1630adev_get_input_buffer_size(const struct audio_hw_device *dev,
1631 const struct audio_config *config)
1632{
1633 size_t size;
1634 int channel_count = popcount(config->channel_mask);
1635 LOGFUNC("%s(%p, %d, %d, %d)", __FUNCTION__, dev, config->sample_rate,
1636 config->format, channel_count);
1637 if (check_input_parameters
1638 (config->sample_rate, config->format, channel_count) != 0) {
1639 return 0;
1640 }
1641 return get_input_buffer_size(config->sample_rate,
1642 config->format, channel_count);
1643
1644}
1645
1646static int
1647adev_open_input_stream(struct audio_hw_device *dev,
1648 audio_io_handle_t handle,
1649 audio_devices_t devices,
1650 struct audio_config *config,
1651 struct audio_stream_in **stream_in)
1652{
1653 struct aml_audio_device *ladev = (struct aml_audio_device *) dev;
1654 struct aml_stream_in *in;
1655 int ret;
1656 int channel_count = popcount(config->channel_mask);
1657 LOGFUNC("**********%s(%#x, %d, 0x%04x, %d)", __FUNCTION__,
1658 devices, config->format, config->channel_mask,
1659 config->sample_rate);
1660 if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) {
1661 return -EINVAL;
1662 }
1663 in = (struct aml_stream_in *) calloc(1, sizeof(struct aml_stream_in));
1664 if (!in) {
1665 return -ENOMEM;
1666 }
1667 in->stream.common.get_sample_rate = in_get_sample_rate;
1668 in->stream.common.set_sample_rate = in_set_sample_rate;
1669 in->stream.common.get_buffer_size = in_get_buffer_size;
1670 in->stream.common.get_channels = in_get_channels;
1671 in->stream.common.get_format = in_get_format;
1672 in->stream.common.set_format = in_set_format;
1673 in->stream.common.standby = in_standby;
1674 in->stream.common.dump = in_dump;
1675 in->stream.common.set_parameters = in_set_parameters;
1676 in->stream.common.get_parameters = in_get_parameters;
1677 in->stream.common.add_audio_effect = NULL;//in_add_audio_effect;
1678 in->stream.common.remove_audio_effect = NULL;//in_remove_audio_effect;
1679 in->stream.set_gain = in_set_gain;
1680 in->stream.read = in_read;
1681 in->stream.get_input_frames_lost = in_get_input_frames_lost;
1682 in->requested_rate = config->sample_rate;
1683 memcpy(&in->config, &pcm_config_in, sizeof(pcm_config_in));
1684 ret = check_input_stream(in);
1685 if (ret < 0) {
1686 ALOGE("fail to open input stream, change channel count from %d to %d",
1687 in->config.channels, channel_count);
1688 in->config.channels = channel_count;
1689 }
1690 if (in->config.channels == 1) {
1691 config->channel_mask = AUDIO_CHANNEL_IN_MONO;
1692 } else if (in->config.channels == 2) {
1693 config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
1694 } else {
1695 ALOGE("Bad value of channel count : %d", in->config.channels);
1696 }
1697 in->buffer = malloc(in->config.period_size *
1698 audio_stream_in_frame_size(&in->stream));
1699 if (!in->buffer) {
1700 ret = -ENOMEM;
1701 goto err_open;
1702 }
1703 in->dev = ladev;
1704 in->standby = 1;
1705 in->device = devices & ~AUDIO_DEVICE_BIT_IN;
1706 *stream_in = &in->stream;
1707 return 0;
1708err_open:
1709 free(in);
1710 *stream_in = NULL;
1711 return ret;
1712}
1713
1714static void
1715adev_close_input_stream(struct audio_hw_device *dev,
1716 struct audio_stream_in *stream)
1717{
1718 struct aml_stream_in *in = (struct aml_stream_in *) stream;
1719
1720 LOGFUNC("%s(%p, %p)", __FUNCTION__, dev, stream);
1721 in_standby(&stream->common);
1722 free(stream);
1723 return;
1724}
1725
1726static int
1727adev_dump(const audio_hw_device_t * device, int fd)
1728{
1729 LOGFUNC("%s(%p, %d)", __FUNCTION__, device, fd);
1730#if 0
1731 struct aml_audio_device *adev = (struct aml_audio_device *) device;
1732 struct aml_stream_out *out = (struct aml_stream_out *) stream;
1733 struct aml_audio_device *adev = out->dev;
1734 audio_hwsync_t *p_hwsync = &adev->hwsync;
1735 dprintf(fd, "Out %p dump:\n", out);
1736 dprintf(fd, "frame write sum %lld,spdif_enc_init_frame_write_sum %lld\n",
1737 out->frame_write_sum, out->spdif_enc_init_frame_write_sum);
1738 dprintf(fd, "HWSYNC status:\n");
1739 dprintf(fd, "hwsync enable:%d\n", adev->hw_sync_mode);
1740 dprintf(fd, "hw_sync_state:%d\n", p_hwsync->hw_sync_state);
1741 dprintf(fd, "first_apts_flag:%d\n", p_hwsync->first_apts_flag);
1742 dprintf(fd, "first_apts:%llx\n", p_hwsync->first_apts);
1743 dprintf(fd, "last_apts_from_header:%llx\n", p_hwsync->last_apts_from_header);
1744 dprintf(fd, "first_apts_flag:%d\n", p_hwsync->first_apts_flag);
1745 dprintf(fd, "hw_sync_frame_size:%d\n", p_hwsync->hw_sync_frame_size);
1746#endif
1747 return 0;
1748}
1749
1750static int
1751adev_close(hw_device_t * device)
1752{
1753 struct aml_audio_device *adev = (struct aml_audio_device *) device;
1754
1755 LOGFUNC("%s(%p)", __FUNCTION__, device);
1756 free(device);
1757 return 0;
1758}
1759
1760
1761static int
1762adev_open(const hw_module_t * module, const char *name,
1763 hw_device_t ** device)
1764{
1765 struct aml_audio_device *adev;
1766 int ret;
1767 LOGFUNC("%s(%p, %s, %p)", __FUNCTION__, module, name, device);
1768 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) {
1769 return -EINVAL;
1770 }
1771
1772 adev = calloc(1, sizeof(struct aml_audio_device));
1773 if (!adev) {
1774 return -ENOMEM;
1775 }
1776 adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
1777 adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
1778 adev->hw_device.common.module = (struct hw_module_t *) module;
1779 adev->hw_device.common.close = adev_close;
1780 //adev->hw_device.get_supported_devices = adev_get_supported_devices;
1781 adev->hw_device.init_check = adev_init_check;
1782 adev->hw_device.set_voice_volume = adev_set_voice_volume;
1783 adev->hw_device.set_master_volume = adev_set_master_volume;
1784 adev->hw_device.get_master_volume = adev_get_master_volume;
1785 adev->hw_device.set_master_mute = adev_set_master_mute;
1786 adev->hw_device.get_master_mute = adev_get_master_mute;
1787 adev->hw_device.set_mode = adev_set_mode;
1788 adev->hw_device.set_mic_mute = adev_set_mic_mute;
1789 adev->hw_device.get_mic_mute = adev_get_mic_mute;
1790 adev->hw_device.set_parameters = adev_set_parameters;
1791 adev->hw_device.get_parameters = adev_get_parameters;
1792 adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size;
1793 adev->hw_device.open_output_stream = adev_open_output_stream;
1794 adev->hw_device.close_output_stream = adev_close_output_stream;
1795 adev->hw_device.open_input_stream = adev_open_input_stream;
1796 adev->hw_device.close_input_stream = adev_close_input_stream;
1797 adev->hw_device.dump = adev_dump;
1798 /* Set the default route before the PCM stream is opened */
1799 adev->mode = AUDIO_MODE_NORMAL;
1800 adev->out_device = AUDIO_DEVICE_OUT_AUX_DIGITAL;
1801 adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN;
1802 select_output_device(adev);
1803 *device = &adev->hw_device.common;
1804 return 0;
1805}
1806
1807static struct hw_module_methods_t hal_module_methods = {
1808 .open = adev_open,
1809};
1810
1811struct audio_module HAL_MODULE_INFO_SYM = {
1812 .common = {
1813 .tag = HARDWARE_MODULE_TAG,
1814 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
1815 .hal_api_version = HARDWARE_HAL_API_VERSION,
1816 .id = AUDIO_HARDWARE_MODULE_ID,
1817 .name = "aml HDMI audio HW HAL",
1818 .author = "amlogic, Corp.",
1819 .methods = &hal_module_methods,
1820 },
1821};
1822