summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'audio/hdmi/hdmi_audio_hw.c')
-rw-r--r--audio/hdmi/hdmi_audio_hw.c824
1 files changed, 824 insertions, 0 deletions
diff --git a/audio/hdmi/hdmi_audio_hw.c b/audio/hdmi/hdmi_audio_hw.c
new file mode 100644
index 0000000..1f5c520
--- /dev/null
+++ b/audio/hdmi/hdmi_audio_hw.c
@@ -0,0 +1,824 @@
1/* -*- mode: C; c-file-style: "stroustrup"; indent-tabs-mode: nil; -*- */
2/*
3 * Copyright (C) 2012 Texas Instruments
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#define LOG_TAG "hdmi_audio_hw"
19/* #define LOG_NDEBUG 0 */
20/* #define LOG_TRACE_FUNCTION */
21
22#ifndef LOG_TRACE_FUNCTION
23#define TRACE() ((void)0)
24#define TRACEM(fmt, ...) ((void)0)
25#else
26#define tfmt(x) x
27#define TRACE() (ALOGV("%s() %s:%d", __func__, __FILE__, __LINE__))
28#define TRACEM(fmt, ...) (ALOGV("%s() " tfmt(fmt) " %s:%d", __func__, ##__VA_ARGS__, __FILE__, __LINE__))
29#endif
30
31#include <errno.h>
32#include <pthread.h>
33#include <stdint.h>
34#include <sys/time.h>
35#include <stdlib.h>
36#include <stdio.h>
37
38#include <cutils/log.h>
39#include <cutils/str_parms.h>
40#include <cutils/properties.h>
41
42#include <hardware/hardware.h>
43#include <system/audio.h>
44#include <hardware/audio.h>
45
46#include <tinyalsa/asoundlib.h>
47
48#include <OMX_Audio.h>
49
50#include "hdmi_audio_hal.h"
51
52#define UNUSED(x) (void)(x)
53
54/* XXX TODO: Dynamically detect the HDMI card
55 * E.g. if a USB device is plugged in at boot time,
56 * it sometimes takes the card #1 slot and puts us
57 * on card #2.
58 */
59#define HDMI_PCM_CARD 1
60#define HDMI_PCM_DEV 0
61#define HDMI_SAMPLING_RATE 44100
62#define HDMI_PERIOD_SIZE 1920
63#define HDMI_PERIOD_COUNT 4
64#define HDMI_MAX_CHANNELS 8
65
66typedef struct _hdmi_device {
67 audio_hw_device_t device;
68 int map[HDMI_MAX_CHANNELS];
69 bool CEAMap;
70} hdmi_device_t;
71
72int cea_channel_map[HDMI_MAX_CHANNELS] = {OMX_AUDIO_ChannelLF,OMX_AUDIO_ChannelRF,OMX_AUDIO_ChannelLFE,
73 OMX_AUDIO_ChannelCF,OMX_AUDIO_ChannelLS,OMX_AUDIO_ChannelRS,
74 OMX_AUDIO_ChannelLR,OMX_AUDIO_ChannelRR}; /*Using OMX_AUDIO_CHANNELTYPE mapping*/
75
76typedef struct _hdmi_out {
77 audio_stream_out_t stream_out;
78 hdmi_device_t *dev;
79 struct pcm_config config;
80 struct pcm *pcm;
81 audio_config_t android_config;
82 int up;
83 void *buffcpy;
84} hdmi_out_t;
85
86#define S16_SIZE sizeof(int16_t)
87
88
89/*****************************************************************
90 * UTILITY FUNCTIONS
91 *****************************************************************
92 */
93
94/*****************************************************************
95 * AUDIO STREAM OUT (hdmi_out_*) DEFINITION
96 *****************************************************************
97 */
98
99uint32_t hdmi_out_get_sample_rate(const struct audio_stream *stream)
100{
101 hdmi_out_t *out = (hdmi_out_t*)stream;
102 struct pcm_config *config = &out->config;
103 TRACEM("stream=%p returning %d", stream, config->rate);
104 return config->rate;
105}
106
107/* DEPRECATED API */
108int hdmi_out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
109{
110 TRACE();
111 UNUSED(stream);
112 UNUSED(rate);
113
114 return -EINVAL;
115}
116
117/* Returns bytes for ONE PERIOD */
118size_t hdmi_out_get_buffer_size(const struct audio_stream *stream)
119{
120 const struct audio_stream_out *s = (const struct audio_stream_out *)stream;
121 hdmi_out_t *out = (hdmi_out_t*)stream;
122 struct pcm_config *config = &out->config;
123 size_t ans;
124
125 ans = audio_stream_out_frame_size(s) * config->period_size;
126
127 TRACEM("stream=%p returning %u", stream, ans);
128
129 return ans;
130}
131
132audio_channel_mask_t hdmi_out_get_channels(const struct audio_stream *stream)
133{
134 hdmi_out_t *out = (hdmi_out_t*)stream;
135 TRACEM("stream=%p returning %x", stream, out->android_config.channel_mask);
136 return out->android_config.channel_mask;
137}
138
139audio_format_t hdmi_out_get_format(const struct audio_stream *stream)
140{
141 hdmi_out_t *out = (hdmi_out_t*)stream;
142 TRACEM("stream=%p returning %x", stream, out->android_config.format);
143 return out->android_config.format;
144}
145
146/* DEPRECATED API */
147int hdmi_out_set_format(struct audio_stream *stream, audio_format_t format)
148{
149 TRACE();
150 UNUSED(stream);
151 UNUSED(format);
152
153 return -EINVAL;
154}
155
156int hdmi_out_standby(struct audio_stream *stream)
157{
158 hdmi_out_t *out = (hdmi_out_t*)stream;
159
160 TRACEM("stream=%p", stream);
161
162 if (out->up && out->pcm) {
163 out->up = 0;
164 pcm_close(out->pcm);
165 out->pcm = 0;
166 }
167
168 return 0;
169}
170
171int hdmi_out_dump(const struct audio_stream *stream, int fd)
172{
173 TRACE();
174 UNUSED(stream);
175 UNUSED(fd);
176
177 return 0;
178}
179
180audio_devices_t hdmi_out_get_device(const struct audio_stream *stream)
181{
182 TRACEM("stream=%p", stream);
183 UNUSED(stream);
184
185 return AUDIO_DEVICE_OUT_AUX_DIGITAL;
186}
187
188/* DEPRECATED API */
189int hdmi_out_set_device(struct audio_stream *stream, audio_devices_t device)
190{
191 TRACE();
192 UNUSED(stream);
193 UNUSED(device);
194
195 return 0;
196}
197
198int hdmi_out_set_parameters(struct audio_stream *stream, const char *kv_pairs)
199{
200 TRACEM("stream=%p kv_pairs='%s'", stream, kv_pairs);
201 UNUSED(stream);
202 UNUSED(kv_pairs);
203
204 return 0;
205}
206
207#define MASK_CEA_QUAD ( CEA_SPKR_FLFR | CEA_SPKR_RLRR )
208#define MASK_CEA_SURROUND ( CEA_SPKR_FLFR | CEA_SPKR_FC | CEA_SPKR_RC )
209#define MASK_CEA_5POINT1 ( CEA_SPKR_FLFR | CEA_SPKR_FC | CEA_SPKR_LFE | CEA_SPKR_RLRR )
210#define MASK_CEA_7POINT1 ( CEA_SPKR_FLFR | CEA_SPKR_FC | CEA_SPKR_LFE | CEA_SPKR_RLRR | CEA_SPKR_RLCRRC )
211#define SUPPORTS_ARR(spkalloc, profile) (((spkalloc) & (profile)) == (profile))
212
213char * hdmi_out_get_parameters(const struct audio_stream *stream,
214 const char *keys)
215{
216 struct str_parms *query = str_parms_create_str(keys);
217 char *str;
218 char value[256];
219 struct str_parms *reply = str_parms_create();
220 int status;
221 hdmi_audio_caps_t caps;
222
223 TRACEM("stream=%p keys='%s'", stream, keys);
224 UNUSED(stream);
225
226 if (hdmi_query_audio_caps(&caps)) {
227 ALOGE("Unable to get the HDMI audio capabilities");
228 str = calloc(1, 1);
229 goto end;
230 }
231
232 status = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS,
233 value, sizeof(value));
234 if (status >= 0) {
235 unsigned sa = caps.speaker_alloc;
236 bool first = true;
237
238 /* STEREO is intentionally skipped. This code is only
239 * executed for the 'DIRECT' interface, and we don't
240 * want stereo on a DIRECT thread.
241 */
242 value[0] = '\0';
243 if (SUPPORTS_ARR(sa, MASK_CEA_QUAD)) {
244 if (!first) {
245 strcat(value, "|");
246 }
247 first = false;
248 strcat(value, "AUDIO_CHANNEL_OUT_QUAD");
249 }
250 if (SUPPORTS_ARR(sa, MASK_CEA_SURROUND)) {
251 if (!first) {
252 strcat(value, "|");
253 }
254 first = false;
255 strcat(value, "AUDIO_CHANNEL_OUT_SURROUND");
256 }
257 if (SUPPORTS_ARR(sa, MASK_CEA_5POINT1)) {
258 if (!first) {
259 strcat(value, "|");
260 }
261 first = false;
262 strcat(value, "AUDIO_CHANNEL_OUT_5POINT1");
263 }
264 if (SUPPORTS_ARR(sa, MASK_CEA_7POINT1)) {
265 if (!first) {
266 strcat(value, "|");
267 }
268 first = false;
269 strcat(value, "AUDIO_CHANNEL_OUT_7POINT1");
270 }
271 str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
272 str = strdup(str_parms_to_str(reply));
273 } else {
274 str = strdup(keys);
275 }
276
277 ALOGV("%s() reply: '%s'", __func__, str);
278
279end:
280 str_parms_destroy(query);
281 str_parms_destroy(reply);
282 return str;
283}
284int hdmi_out_add_audio_effect(const struct audio_stream *stream,
285 effect_handle_t effect)
286{
287 TRACE();
288 UNUSED(stream);
289 UNUSED(effect);
290
291 return 0;
292}
293int hdmi_out_remove_audio_effect(const struct audio_stream *stream,
294 effect_handle_t effect)
295{
296 TRACE();
297 UNUSED(stream);
298 UNUSED(effect);
299
300 return 0;
301}
302
303/* returns milliseconds */
304uint32_t hdmi_out_get_latency(const struct audio_stream_out *stream)
305{
306 uint32_t latency;
307 hdmi_out_t *out = (hdmi_out_t*)stream;
308 struct pcm_config *config = &out->config;
309
310 TRACEM("stream=%p", stream);
311
312 return (1000 * config->period_size * config->period_count) / config->rate;
313}
314
315int hdmi_out_set_volume(struct audio_stream_out *stream, float left, float right)
316{
317 TRACE();
318 UNUSED(stream);
319 UNUSED(left);
320 UNUSED(right);
321
322 return -ENOSYS;
323}
324
325static int hdmi_out_open_pcm(hdmi_out_t *out)
326{
327 int card = HDMI_PCM_CARD;
328 int dev = HDMI_PCM_DEV;
329 int ret;
330
331 TRACEM("out=%p", out);
332
333 /* out->up must be 0 (down) */
334 if (out->up) {
335 ALOGE("Trying to open a PCM that's already up. "
336 "This will probably deadlock... so aborting");
337 return 0;
338 }
339
340 out->pcm = pcm_open(card, dev, PCM_OUT, &out->config);
341
342 if(out->pcm && pcm_is_ready(out->pcm)) {
343 out->up = 1;
344 ret = 0;
345 } else {
346 ALOGE("cannot open HDMI pcm card %d dev %d error: %s",
347 card, dev, pcm_get_error(out->pcm));
348 pcm_close(out->pcm);
349 out->pcm = 0;
350 out->up = 0;
351 ret = 1;
352 }
353
354 return ret;
355}
356
357void channel_remap(struct audio_stream_out *stream, const void *buffer,
358 size_t bytes)
359{
360 hdmi_out_t *out = (hdmi_out_t*)stream;
361 hdmi_device_t *adev = out->dev;
362 int x, y, frames;
363 int16_t *buf = (int16_t *)buffer;
364 int16_t *tmp_buf = (int16_t *)out->buffcpy;
365
366 frames = bytes / audio_stream_out_frame_size(stream);
367 while (frames--){
368 for(y = 0; y < (int)out->config.channels; y++){
369 for(x = 0; x < (int)out->config.channels; x++){
370 if (cea_channel_map[y] == adev->map[x]){
371 tmp_buf[y] = buf[x];
372 break;
373 }
374 }
375 }
376 tmp_buf += (int)out->config.channels;
377 buf += (int)out->config.channels;
378 }
379}
380
381ssize_t hdmi_out_write(struct audio_stream_out *stream, const void* buffer,
382 size_t bytes)
383{
384 hdmi_out_t *out = (hdmi_out_t*)stream;
385 hdmi_device_t *adev = out->dev;
386 ssize_t ret;
387
388 TRACEM("stream=%p buffer=%p bytes=%d", stream, buffer, bytes);
389
390 if (!out->up) {
391 if(hdmi_out_open_pcm(out)) {
392 ret = -ENOSYS;
393 goto exit;
394 }
395 }
396
397 if (out->config.channels > 2 && !adev->CEAMap){
398 channel_remap(stream, buffer, bytes);
399 ret = pcm_write(out->pcm, out->buffcpy, bytes);
400 } else {
401 ret = pcm_write(out->pcm, buffer, bytes);
402 }
403exit:
404 if (ret != 0) {
405 ALOGE("Error writing to HDMI pcm: %s",
406 out->pcm ? pcm_get_error(out->pcm) : "failed to open PCM device");
407 hdmi_out_standby((struct audio_stream*)stream);
408 unsigned int usecs = bytes * 1000000 /
409 audio_stream_out_frame_size(stream) /
410 hdmi_out_get_sample_rate((struct audio_stream*)stream);
411 if (usecs >= 1000000L) {
412 usecs = 999999L;
413 }
414 usleep(usecs);
415 }
416
417 return bytes;
418}
419
420
421int hdmi_out_get_render_position(const struct audio_stream_out *stream,
422 uint32_t *dsp_frames)
423{
424 TRACE();
425 UNUSED(stream);
426 UNUSED(dsp_frames);
427
428 return -EINVAL;
429}
430
431int hdmi_out_get_next_write_timestamp(const struct audio_stream_out *stream,
432 int64_t *timestamp)
433{
434 TRACE();
435 UNUSED(stream);
436 UNUSED(timestamp);
437
438 return -EINVAL;
439}
440
441
442
443audio_stream_out_t hdmi_stream_out_descriptor = {
444 .common = {
445 .get_sample_rate = hdmi_out_get_sample_rate,
446 .set_sample_rate = hdmi_out_set_sample_rate,
447 .get_buffer_size = hdmi_out_get_buffer_size,
448 .get_channels = hdmi_out_get_channels,
449 .get_format = hdmi_out_get_format,
450 .set_format = hdmi_out_set_format,
451 .standby = hdmi_out_standby,
452 .dump = hdmi_out_dump,
453 .get_device = hdmi_out_get_device,
454 .set_device = hdmi_out_set_device,
455 .set_parameters = hdmi_out_set_parameters,
456 .get_parameters = hdmi_out_get_parameters,
457 .add_audio_effect = hdmi_out_add_audio_effect,
458 .remove_audio_effect = hdmi_out_remove_audio_effect,
459 },
460 .get_latency = hdmi_out_get_latency,
461 .set_volume = hdmi_out_set_volume,
462 .write = hdmi_out_write,
463 .get_render_position = hdmi_out_get_render_position,
464 .get_next_write_timestamp = hdmi_out_get_next_write_timestamp,
465};
466
467/*****************************************************************
468 * AUDIO DEVICE (hdmi_adev_*) DEFINITION
469 *****************************************************************
470 */
471
472static int hdmi_adev_close(struct hw_device_t *device)
473{
474 TRACE();
475 UNUSED(device);
476
477 return 0;
478}
479
480static uint32_t hdmi_adev_get_supported_devices(const audio_hw_device_t *dev)
481{
482 TRACE();
483 UNUSED(dev);
484
485 return AUDIO_DEVICE_OUT_AUX_DIGITAL;
486}
487
488static int hdmi_adev_init_check(const audio_hw_device_t *dev)
489{
490 TRACE();
491 UNUSED(dev);
492
493 return 0;
494}
495
496static int hdmi_adev_set_voice_volume(audio_hw_device_t *dev, float volume)
497{
498 TRACE();
499 UNUSED(dev);
500 UNUSED(volume);
501
502 return -ENOSYS;
503}
504
505static int hdmi_adev_set_master_volume(audio_hw_device_t *dev, float volume)
506{
507 TRACE();
508 UNUSED(dev);
509 UNUSED(volume);
510
511 return -ENOSYS;
512}
513
514static int hdmi_adev_get_master_volume(audio_hw_device_t *dev, float *volume)
515{
516 TRACE();
517 UNUSED(dev);
518 UNUSED(volume);
519
520 return -ENOSYS;
521}
522
523static int hdmi_adev_set_mode(audio_hw_device_t *dev, audio_mode_t mode)
524{
525 TRACE();
526 UNUSED(dev);
527 UNUSED(mode);
528
529 return 0;
530}
531
532static int hdmi_adev_set_mic_mute(audio_hw_device_t *dev, bool state)
533{
534 TRACE();
535 UNUSED(dev);
536 UNUSED(state);
537
538 return -ENOSYS;
539}
540
541static int hdmi_adev_get_mic_mute(const audio_hw_device_t *dev, bool *state)
542{
543 TRACE();
544 UNUSED(dev);
545 UNUSED(state);
546
547 return -ENOSYS;
548}
549
550static int hdmi_adev_set_parameters(audio_hw_device_t *dev, const char *kv_pairs)
551{
552 TRACEM("dev=%p kv_pairss='%s'", dev, kv_pairs);
553
554 struct str_parms *params;
555 char *str;
556 char value[HDMI_MAX_CHANNELS];
557 int ret, x, val, numMatch = 0;
558 hdmi_device_t *adev = (hdmi_device_t *)dev;
559
560 params = str_parms_create_str(kv_pairs);
561 //Handle maximum of 8 channels
562 ret = str_parms_get_str(params, "channel_map", value, HDMI_MAX_CHANNELS);
563 if (ret >= 0) {
564 val = strtol(value, NULL, 10);
565 for(x = 0; x < HDMI_MAX_CHANNELS; x++) {
566 adev->map[x] = (val & (0xF << x*4)) >> x*4;
567 if (adev->map[x] == cea_channel_map[x])
568 numMatch += 1;
569 }
570 if (numMatch >= 5)
571 adev->CEAMap = true;
572 else
573 adev->CEAMap = false;
574 }
575 return 0;
576}
577
578static char* hdmi_adev_get_parameters(const audio_hw_device_t *dev,
579 const char *keys)
580{
581 TRACEM("dev=%p keys='%s'", dev, keys);
582 UNUSED(dev);
583 UNUSED(keys);
584
585 return NULL;
586}
587
588static size_t hdmi_adev_get_input_buffer_size(const audio_hw_device_t *dev,
589 const struct audio_config *config)
590{
591 TRACE();
592 UNUSED(dev);
593 UNUSED(config);
594
595 return 0;
596}
597
598#define DUMP_FLAG(flags, flag) { \
599 if ((flags) & (flag)) { \
600 ALOGV("set: " #flag); \
601 } else { \
602 ALOGV("unset: " #flag); \
603 } \
604 }
605
606static int hdmi_adev_open_output_stream(audio_hw_device_t *dev,
607 audio_io_handle_t handle,
608 audio_devices_t devices,
609 audio_output_flags_t flags,
610 struct audio_config *config,
611 struct audio_stream_out **stream_out,
612 const char *address)
613{
614 hdmi_out_t *out = 0;
615 struct pcm_config *pcm_config = 0;
616 struct audio_config *a_config = 0;
617
618 TRACE();
619 UNUSED(handle);
620 UNUSED(devices);
621 UNUSED(flags);
622 UNUSED(address);
623
624 out = calloc(1, sizeof(hdmi_out_t));
625 if (!out) {
626 return -ENOMEM;
627 }
628
629 out->dev = (hdmi_device_t *)dev;
630 memcpy(&out->stream_out, &hdmi_stream_out_descriptor,
631 sizeof(audio_stream_out_t));
632 memcpy(&out->android_config, config, sizeof(audio_config_t));
633
634 pcm_config = &out->config;
635 a_config = &out->android_config;
636
637#if defined(LOG_NDEBUG) && (LOG_NDEBUG == 0)
638 /* Analyze flags */
639 if (flags) {
640 DUMP_FLAG(flags, AUDIO_OUTPUT_FLAG_DIRECT)
641 DUMP_FLAG(flags, AUDIO_OUTPUT_FLAG_PRIMARY)
642 DUMP_FLAG(flags, AUDIO_OUTPUT_FLAG_FAST)
643 DUMP_FLAG(flags, AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
644 } else {
645 ALOGV("flags == AUDIO_OUTPUT_FLAG_NONE (0)");
646 }
647#endif /* defined(LOG_NDEBUG) && (LOG_NDEBUG == 0) */
648 /* Initialize the PCM Configuration */
649 pcm_config->period_size = HDMI_PERIOD_SIZE;
650 pcm_config->period_count = HDMI_PERIOD_COUNT;
651
652 if (a_config->sample_rate) {
653 pcm_config->rate = config->sample_rate;
654 } else {
655 pcm_config->rate = HDMI_SAMPLING_RATE;
656 a_config->sample_rate = HDMI_SAMPLING_RATE;
657 }
658
659 switch (a_config->format) {
660 case AUDIO_FORMAT_DEFAULT:
661 a_config->format = AUDIO_FORMAT_PCM_16_BIT;
662 /* fall through */
663 case AUDIO_FORMAT_PCM_16_BIT:
664 pcm_config->format = PCM_FORMAT_S16_LE;
665 break;
666 default:
667 ALOGE("HDMI rejecting format %x", config->format);
668 goto fail;
669 }
670
671 a_config->channel_mask = config->channel_mask;
672 switch (config->channel_mask) {
673 case AUDIO_CHANNEL_OUT_STEREO:
674 pcm_config->channels = 2;
675 break;
676 case AUDIO_CHANNEL_OUT_QUAD:
677 pcm_config->channels = 4;
678 break;
679 case AUDIO_CHANNEL_OUT_5POINT1:
680 pcm_config->channels = 6;
681 break;
682 case AUDIO_CHANNEL_OUT_7POINT1:
683 pcm_config->channels = 8;
684 break;
685 default:
686 ALOGE("HDMI setting a default channel_mask %x -> 8", config->channel_mask);
687 config->channel_mask = AUDIO_CHANNEL_OUT_7POINT1;
688 a_config->channel_mask = AUDIO_CHANNEL_OUT_7POINT1;
689 pcm_config->channels = 8;
690 }
691
692 //Allocating buffer for at most 8 channels
693 out->buffcpy = malloc(pcm_config->period_size * sizeof(int16_t) * HDMI_MAX_CHANNELS);
694 if (!out->buffcpy){
695 ALOGE("Could not allocate memory");
696 goto fail;
697 }
698
699 ALOGV("stream = %p", out);
700 *stream_out = &out->stream_out;
701
702 return 0;
703
704fail:
705 free(out);
706 return -ENOSYS;
707}
708
709static void hdmi_adev_close_output_stream(audio_hw_device_t *dev,
710 struct audio_stream_out* stream_out)
711{
712 hdmi_out_t *out = (hdmi_out_t*)stream_out;
713
714 TRACEM("dev=%p stream_out=%p", dev, stream_out);
715 UNUSED(dev);
716
717 stream_out->common.standby((audio_stream_t*)stream_out);
718 free(out->buffcpy);
719 out->buffcpy = NULL;
720 free(stream_out);
721}
722
723static int hdmi_adev_open_input_stream(audio_hw_device_t *dev,
724 audio_io_handle_t handle,
725 audio_devices_t devices,
726 struct audio_config *config,
727 struct audio_stream_in **stream_in,
728 audio_input_flags_t flags,
729 const char *address,
730 audio_source_t source)
731{
732 TRACE();
733 UNUSED(dev);
734 UNUSED(handle);
735 UNUSED(devices);
736 UNUSED(config);
737 UNUSED(stream_in);
738 UNUSED(flags);
739 UNUSED(address);
740 UNUSED(source);
741
742 return -ENOSYS;
743}
744
745static void hdmi_adev_close_input_stream(audio_hw_device_t *dev,
746 struct audio_stream_in *stream_in)
747{
748 TRACE();
749 UNUSED(dev);
750 UNUSED(stream_in);
751}
752
753static int hdmi_adev_dump(const audio_hw_device_t *dev, int fd)
754{
755 TRACE();
756 UNUSED(dev);
757 UNUSED(fd);
758
759 return 0;
760}
761
762static hdmi_device_t hdmi_adev = {
763 .device = {
764 .common = {
765 .tag = HARDWARE_DEVICE_TAG,
766 .version = AUDIO_DEVICE_API_VERSION_2_0,
767 .module = NULL,
768 .close = hdmi_adev_close,
769 },
770 .get_supported_devices = hdmi_adev_get_supported_devices,
771 .init_check = hdmi_adev_init_check,
772 .set_voice_volume = hdmi_adev_set_voice_volume,
773 .set_master_volume = hdmi_adev_set_master_volume,
774 .get_master_volume = hdmi_adev_get_master_volume,
775 .set_mode = hdmi_adev_set_mode,
776 .set_mic_mute = hdmi_adev_set_mic_mute,
777 .get_mic_mute = hdmi_adev_get_mic_mute,
778 .set_parameters = hdmi_adev_set_parameters,
779 .get_parameters = hdmi_adev_get_parameters,
780 .get_input_buffer_size = hdmi_adev_get_input_buffer_size,
781 .open_output_stream = hdmi_adev_open_output_stream,
782 .close_output_stream = hdmi_adev_close_output_stream,
783 .open_input_stream = hdmi_adev_open_input_stream,
784 .close_input_stream = hdmi_adev_close_input_stream,
785 .dump = hdmi_adev_dump,
786 },
787
788 // Don't reorder channels until a valid CEA mapping has been
789 // explicitly set. IOW, assume default channel mapping is
790 // fine until some other mapping is requested.
791 .CEAMap = true,
792 .map = {0},
793};
794
795static int hdmi_adev_open(const hw_module_t* module,
796 const char* name,
797 hw_device_t** device)
798{
799 TRACE();
800
801 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
802 return -EINVAL;
803
804 hdmi_adev.device.common.module = (struct hw_module_t *) module;
805 *device = &hdmi_adev.device.common;
806
807 return 0;
808}
809
810static struct hw_module_methods_t hal_module_methods = {
811 .open = hdmi_adev_open,
812};
813
814struct audio_module HAL_MODULE_INFO_SYM = {
815 .common = {
816 .tag = HARDWARE_MODULE_TAG,
817 .version_major = 1,
818 .version_minor = 0,
819 .id = AUDIO_HARDWARE_MODULE_ID,
820 .name = "OMAP HDMI audio HW HAL",
821 .author = "Texas Instruments",
822 .methods = &hal_module_methods,
823 },
824};