1 /*
2 * Copyright (C) 2012 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 * Copyright (C) 2012 The Android Open Source Project
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 */
23
24 /*
25 * This code has modified by Intel Corporation
26 */
27
28 /*
29 * Copyright (c) 2014, Intel Corporation
30 *
31 * Licensed under the Apache License, Version 2.0 (the "License");
32 * you may not use this file except in compliance with the License.
33 * You may obtain a copy of the License at
34 *
35 * http://www.apache.org/licenses/LICENSE-2.0
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
38 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
44 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
46 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47 */
48
49 #define LOG_TAG "tiny_hdmi_audio_hw"
50 //#define LOG_NDEBUG 0
51
52 #include <errno.h>
53 #include <pthread.h>
54 #include <stdint.h>
55 #include <sys/time.h>
56 #include <stdlib.h>
57
58 #include <cutils/log.h>
59 #include <cutils/str_parms.h>
60 #include <cutils/properties.h>
61
62 #include <hardware/hardware.h>
63 #include <system/audio.h>
64 #include <hardware/audio.h>
65
66 #include <sound/asound.h>
67 #include <tinyalsa/asoundlib.h>
68
69 #define UNUSED_PARAMETER(x) (void)(x)
70
71 #define DEFAULT_CARD 0
72 #define DEFAULT_DEVICE 0
73
74 /*this is used to avoid starvation*/
75 #define LATENCY_TO_BUFFER_SIZE_RATIO 2
76
77 /*Playback Channel Map*/
78 #define CHANNEL_MAP_REQUEST 2
79
80 /*global - keep track of the active device.
81 This is needed since we are supporting more
82 than one profile for HDMI. The Flinger
83 assumes we can suport multiple streams
84 at the same time. This makes sure only one stream
85 is active at a time.*/
86 struct pcm * activePcm = NULL;
87 /*TODO - move active channel inside activepcm*/
88 static unsigned int activeChannel;
89
90 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
91
92 #define STRING_TO_ENUM(string) { #string, string }
93
94 struct channel_list {
95 const char *name;
96 uint32_t value;
97 };
98
99 const struct channel_list channel_list_table[] = {
100 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO),
101 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
102 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
103 };
104
105 struct pcm_config pcm_config_default = {
106 .channels = 2,
107 .rate = 44100,
108 .period_size = 1024,
109 .period_count = 4,
110 .format = PCM_FORMAT_S24_LE,
111 };
112
113 #define CHANNEL_MASK_MAX 3
114 struct audio_device {
115 struct audio_hw_device hw_device;
116
117 pthread_mutex_t lock;
118 int card;
119 int device;
120 bool standby;
121 int sink_sup_channels;
122 audio_channel_mask_t sup_channel_masks[CHANNEL_MASK_MAX];
123 };
124
125 struct stream_out {
126 struct audio_stream_out stream;
127
128 pthread_mutex_t lock;
129 struct pcm *pcm;
130 bool standby;
131
132 /* PCM Stream Configurations */
133 struct pcm_config pcm_config;
134 uint32_t channel_mask;
135
136 /* ALSA PCM Configurations */
137 uint32_t sample_rate;
138 uint32_t buffer_size;
139 uint32_t channels;
140 uint32_t latency;
141
142 struct audio_device *dev;
143 };
144
145 /**
146 * NOTE: when multiple mutexes have to be acquired, always respect the
147 * following order: hw device > out stream
148 */
149
150 /* Helper functions */
151
152 // This function return the card number associated with the card ID (name)
153 // passed as argument
get_card_number_by_name(const char * name)154 static int get_card_number_by_name(const char* name)
155 {
156 char id_filepath[PATH_MAX] = {0};
157 char number_filepath[PATH_MAX] = {0};
158 ssize_t written;
159
160 snprintf(id_filepath, sizeof(id_filepath), "/proc/asound/%s", name);
161
162 written = readlink(id_filepath, number_filepath, sizeof(number_filepath));
163 if (written < 0) {
164 ALOGE("Sound card %s does not exist - setting default", name);
165 return DEFAULT_CARD;
166 } else if (written >= (ssize_t)sizeof(id_filepath)) {
167 ALOGE("Sound card %s name is too long - setting default", name);
168 return DEFAULT_CARD;
169 }
170
171 // We are assured, because of the check in the previous elseif, that this
172 // buffer is null-terminated. So this call is safe.
173 // 4 == strlen("card")
174 return atoi(number_filepath + 4);
175 }
176
Get_SinkSupported_format()177 static enum pcm_format Get_SinkSupported_format()
178 {
179 /*TODO : query sink supported formats*/
180 return PCM_FORMAT_S24_LE;
181 }
182
make_sinkcompliant_buffers(void * input,void * output,int ipbytes)183 static int make_sinkcompliant_buffers(void* input, void *output, int ipbytes)
184 {
185 int i = 0,outbytes = 0;
186 enum pcm_format out_pcmformat;
187 int *src = (int*)input;
188 int *dst = (int*)output;
189
190 /*by default android currently support only
191 16 bit signed PCM*/
192 out_pcmformat = Get_SinkSupported_format();
193
194 switch (out_pcmformat) {
195 default:
196 case PCM_FORMAT_S24_LE:
197 {
198 ALOGV("convert 16 to 24 bits for %d",ipbytes);
199 /*convert 16 bit input to 24 bit output
200 in a 32 bit sample*/
201 if(0 == ipbytes)
202 break;
203
204 for(i = 0; i < (ipbytes/4); i++){
205 int x = (int)((int*)src)[i];
206 dst[i*2] = ((int)( x & 0x0000FFFF)) << 8;
207 // trying to sign exdent
208 dst[i*2] = dst[i*2] << 8;
209 dst[i*2] = dst[i*2] >> 8;
210 //shift to middle
211 dst[i*2 + 1] = (int)(( x & 0xFFFF0000) >> 8);
212 dst[i*2 + 1] = dst[i*2 + 1] << 8;
213 dst[i*2 + 1] = dst[i*2 + 1] >> 8;
214 }
215 outbytes=ipbytes * 2;
216
217 }//case
218 };//switch
219
220 return outbytes;
221 }
222
223 /* must be called with hw device and output stream mutexes locked */
start_output_stream(struct stream_out * out)224 static int start_output_stream(struct stream_out *out)
225 {
226 struct audio_device *adev = out->dev;
227
228 ALOGV("%s enter",__func__);
229
230 if ((adev->card < 0) || (adev->device < 0)){
231 /*this will be updated once the hot plug intent
232 sends these information.*/
233 adev->card = DEFAULT_CARD;
234 adev->device = DEFAULT_DEVICE;
235 ALOGV("%s : Setting default card/ device %d,%d",__func__,adev->card,adev->device);
236 }
237
238 ALOGV("%s enter %d,%d,%d,%d,%d",__func__,
239 out->pcm_config.channels,
240 out->pcm_config.rate,
241 out->pcm_config.period_size,
242 out->pcm_config.period_count,
243 out->pcm_config.format);
244
245 out->pcm_config.start_threshold = 0;
246 out->pcm_config.stop_threshold = 0;
247 out->pcm_config.silence_threshold = 0;
248
249 if(activePcm){
250 ALOGV("Closing already open tiny alsa stream running state %d",(int)(activePcm));
251 pcm_close(activePcm);
252 activePcm = NULL;
253 }
254
255 /*TODO - this needs to be updated once the device connect intent sends
256 card, device id*/
257 adev->card = get_card_number_by_name("IntelHDMI");
258 ALOGD("%s: HDMI card number = %d, device = %d",__func__,adev->card,adev->device);
259
260 out->pcm = pcm_open(adev->card, adev->device, PCM_OUT, &out->pcm_config);
261
262 if (out->pcm && !pcm_is_ready(out->pcm)) {
263 ALOGE("pcm_open() failed: %s", pcm_get_error(out->pcm));
264 pcm_close(out->pcm);
265 activePcm = NULL;
266 return -ENOMEM;
267 }
268
269 activePcm = out->pcm;
270 activeChannel = out->pcm_config.channels;
271
272 ALOGV("Initialized PCM device for channels %d handle = %d",out->pcm_config.channels, (int)activePcm);
273 ALOGV("%s exit",__func__);
274 return 0;
275 }
276
277 /* API functions */
278
out_get_sample_rate(const struct audio_stream * stream)279 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
280 {
281 struct stream_out *out = (struct stream_out *)stream;
282 return out->pcm_config.rate;
283 }
284
out_set_sample_rate(struct audio_stream * stream,uint32_t rate)285 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
286 {
287 UNUSED_PARAMETER(stream);
288 UNUSED_PARAMETER(rate);
289
290 return 0;
291 }
292
out_get_buffer_size(const struct audio_stream * stream)293 static size_t out_get_buffer_size(const struct audio_stream *stream)
294 {
295 struct stream_out *out = (struct stream_out *)stream;
296 size_t buf_size;
297
298 if(out->channel_mask > 2){
299 buf_size = out->pcm_config.period_size *
300 audio_stream_out_frame_size((struct audio_stream_out *)stream);
301 }
302 else{
303 buf_size = out->pcm_config.period_size *
304 out->pcm_config.period_count *
305 audio_stream_out_frame_size((struct audio_stream_out *)stream);
306
307 /*latency of audio flinger is based on this
308 buffer size. modifying the buffer size to avoid
309 starvation*/
310 buf_size/=LATENCY_TO_BUFFER_SIZE_RATIO;
311 }
312
313 ALOGV("%s : %d, period_size : %d, frame_size : %d",
314 __func__,
315 buf_size,
316 out->pcm_config.period_size,
317 audio_stream_out_frame_size((struct audio_stream_out *)stream));
318
319 return buf_size;
320
321 }
322
out_get_channels(const struct audio_stream * stream)323 static uint32_t out_get_channels(const struct audio_stream *stream)
324 {
325 struct stream_out *out = (struct stream_out *)stream;
326 ALOGV("%s channel mask : %x",__func__,out->channel_mask);
327 return out->channel_mask;
328 }
329
out_get_format(const struct audio_stream * stream)330 static audio_format_t out_get_format(const struct audio_stream *stream)
331 {
332 UNUSED_PARAMETER(stream);
333
334 return AUDIO_FORMAT_PCM_16_BIT;
335 }
336
out_set_format(struct audio_stream * stream,audio_format_t format)337 static int out_set_format(struct audio_stream *stream, audio_format_t format)
338 {
339 UNUSED_PARAMETER(stream);
340 UNUSED_PARAMETER(format);
341
342 return 0;
343 }
344
out_standby(struct audio_stream * stream)345 static int out_standby(struct audio_stream *stream)
346 {
347 struct stream_out *out = (struct stream_out *)stream;
348
349 ALOGV("%s enter standby = %d",__func__,out->standby);
350
351 pthread_mutex_lock(&out->dev->lock);
352 pthread_mutex_lock(&out->lock);
353
354 if (!out->standby && activePcm) {
355 pcm_close(activePcm);
356 out->pcm = NULL;
357 out->standby = true;
358 activePcm = NULL;
359 ALOGV("%s PCM device closed",__func__);
360 }
361
362 pthread_mutex_unlock(&out->lock);
363 pthread_mutex_unlock(&out->dev->lock);
364
365 ALOGV("%s exit",__func__);
366 return 0;
367 }
368
out_dump(const struct audio_stream * stream,int fd)369 static int out_dump(const struct audio_stream *stream, int fd)
370 {
371 UNUSED_PARAMETER(stream);
372 UNUSED_PARAMETER(fd);
373 return 0;
374 }
375
out_set_parameters(struct audio_stream * stream,const char * kvpairs)376 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
377 {
378 struct stream_out *out = (struct stream_out *)stream;
379 struct audio_device *adev = out->dev;
380 struct str_parms *parms;
381 char value[32];
382 int ret;
383 ALOGV("%s enter",__func__);
384
385 parms = str_parms_create_str(kvpairs);
386
387 pthread_mutex_lock(&adev->lock);
388
389 if (parms == NULL) {
390 ALOGE("couldn't extract string params from key value pairs");
391 pthread_mutex_unlock(&adev->lock);
392 return 0;
393 }
394
395 ret = str_parms_get_str(parms, "card", value, sizeof(value));
396 if (ret >= 0)
397 adev->card = atoi(value);
398
399 ret = str_parms_get_str(parms, "device", value, sizeof(value));
400 if (ret >= 0)
401 adev->device = atoi(value);
402
403 pthread_mutex_unlock(&adev->lock);
404 str_parms_destroy(parms);
405
406 ALOGV("%s exit",__func__);
407 return 0;
408 }
409
parse_channel_map()410 static int parse_channel_map()
411 {
412 struct mixer *mixer;
413 int card = 0;
414 struct mixer_ctl *ctl;
415 enum mixer_ctl_type type;
416 unsigned int num_values;
417 unsigned int i,id;
418 int chcount=0, chmap=0;
419
420 card = get_card_number_by_name("IntelHDMI");
421 mixer = mixer_open(card);
422 if (!mixer) {
423 ALOGE("[EDID] Failed to open mixer\n");
424 goto chmap_error;
425 }
426
427 id = CHANNEL_MAP_REQUEST;
428 if (id >= mixer_get_num_ctls(mixer)) {
429 ALOGE("[EDID] Invalid request for channel map %d",id);
430 goto chmap_error;
431 }
432
433 ctl = mixer_get_ctl_by_name(mixer, "Playback Channel Map");
434
435 //ctl = mixer_get_ctl(mixer, id);
436
437 type = mixer_ctl_get_type(ctl);
438 num_values = mixer_ctl_get_num_values(ctl);
439
440 ALOGV("[EDID]id = %d",id);
441 ALOGV("[EDID]type = %d",type);
442 ALOGV("[EDID]count = %d",num_values);
443
444 for (i = 0; i < num_values; i++) {
445 switch (type)
446 {
447 case MIXER_CTL_TYPE_INT:
448 chmap = mixer_ctl_get_value(ctl, i);
449 ALOGD("[EDID]chmap = %d", chmap);
450 if(chmap > 0) ++chcount;
451 break;
452 default:
453 printf(" unknown");
454 break;
455 };
456 }//for
457
458 ALOGD("[EDID]valid number of channels supported by sink = %d",chcount);
459
460 mixer_close(mixer);
461
462 return chcount;
463
464 chmap_error:
465 mixer_close(mixer);
466 return 2;//stereo by default
467
468 }
469
out_read_edid(const struct stream_out * stream)470 static int out_read_edid(const struct stream_out *stream)
471 {
472 struct stream_out *out = (struct stream_out *)stream;
473 struct audio_device *adev = out->dev;
474
475 /**read the channel max param from the sink*/
476 adev->sink_sup_channels = parse_channel_map();
477
478 if(adev->sink_sup_channels == 8) {
479 adev->sup_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1;
480 adev->sup_channel_masks[1] = AUDIO_CHANNEL_OUT_7POINT1;
481 }
482 else if((adev->sink_sup_channels == 6) || (adev->sink_sup_channels > 2)) {
483 adev->sup_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1;
484 }
485 else {
486 adev->sup_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
487 }
488
489 ALOGV("%s sink supports 0x%x max channels", __func__,adev->sink_sup_channels);
490 return 0;
491 }
492
out_get_parameters(const struct audio_stream * stream,const char * keys)493 static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
494 {
495 struct stream_out *out = (struct stream_out *)stream;
496 struct audio_device *adev = out->dev;
497 struct str_parms *params_in = str_parms_create_str(keys);
498 char *str = NULL;
499 char value[256] = {0};
500 int ret;
501 size_t i, j;
502 bool append = false;
503
504 struct str_parms *params_out = str_parms_create();
505
506 ALOGV("%s Entered %s", __func__,keys);
507
508 if (params_in) {
509 ret = str_parms_get_str(params_in, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
510 if (ret >= 0) {
511 /*read the channel support from sink*/
512 out_read_edid(out);
513
514 value[0] = '\0';
515 for (i = 0; i < CHANNEL_MASK_MAX; i++) {
516 for (j = 0; j < ARRAY_SIZE(channel_list_table); j++) {
517 if (channel_list_table[j].value == adev->sup_channel_masks[i]) {
518 if (append) {
519 strcat(value, "|");
520 }
521 strcat(value, channel_list_table[j].name);
522 append = true;
523 break;
524 }
525 }
526 }
527 }
528 }
529 if (params_out) {
530 str_parms_add_str(params_out, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
531 str = str_parms_to_str(params_out);
532 } else {
533 str = strdup(keys);
534 }
535
536 ALOGV("%s AUDIO_PARAMETER_STREAM_SUP_CHANNELS %s", __func__,str);
537 if (params_in) {
538 str_parms_destroy(params_in);
539 }
540 if (params_out) {
541 str_parms_destroy(params_out);
542 }
543
544 return str;
545 }
546
out_get_latency(const struct audio_stream_out * stream)547 static uint32_t out_get_latency(const struct audio_stream_out *stream)
548 {
549 struct stream_out *out = (struct stream_out *)stream;
550 return (out->pcm_config.period_size * out->pcm_config.period_count * 1000) /
551 out_get_sample_rate(&stream->common);
552 }
553
out_set_volume(struct audio_stream_out * stream,float left,float right)554 static int out_set_volume(struct audio_stream_out *stream, float left,
555 float right)
556 {
557 UNUSED_PARAMETER(stream);
558 UNUSED_PARAMETER(left);
559 UNUSED_PARAMETER(right);
560
561 return -ENOSYS;
562 }
563
out_write(struct audio_stream_out * stream,const void * buffer,size_t bytes)564 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
565 size_t bytes)
566 {
567 int ret = 0;
568 struct stream_out *out = (struct stream_out *)stream;
569 int32_t* dstbuff = NULL;
570 int outbytes = 0;
571
572 ALOGV("%s enter for bytes = %d channels = %d",__func__,bytes, out->pcm_config.channels);
573
574 pthread_mutex_lock(&out->dev->lock);
575 pthread_mutex_lock(&out->lock);
576
577 if(activePcm == NULL) {
578 ALOGV("%s: previous stream closed- open again",__func__);
579 out->standby = true;
580 }
581
582 if (out->standby) {
583 ret = start_output_stream(out);
584 if (ret != 0) {
585 goto err;
586 }
587 out->standby = false;
588 }
589
590 if((!out->pcm) || (activeChannel != out->pcm_config.channels)){
591 ALOGD("%s: null handle to write - device already closed",__func__);
592 goto err;
593 }
594
595 if(Get_SinkSupported_format() == out->pcm_config.format){
596
597 /*16 bit data will be converted to 24 bit over 32 bit data type
598 hence the multiplier 2*/
599 dstbuff = (int32_t*)malloc(bytes* 2);
600 if (!dstbuff) {
601 pthread_mutex_unlock(&out->lock);
602 pthread_mutex_unlock(&out->dev->lock);
603 ALOGE("%s : memory allocation failed",__func__);
604 return -ENOMEM;
605 }
606
607 memset(dstbuff,0,bytes * 2);
608
609 outbytes = make_sinkcompliant_buffers((void*)buffer, (void*)dstbuff,bytes);
610 } //if()for conversion
611
612 if(dstbuff){
613 ret = pcm_write(out->pcm, (void *)dstbuff, outbytes);
614 }
615 else
616 ret = pcm_write(out->pcm, (void *)buffer, bytes);
617
618 ALOGV("pcm_write: %s done for %d input bytes, output bytes = %d ", pcm_get_error(out->pcm),bytes,outbytes);
619
620 free(dstbuff);
621
622 err:
623 pthread_mutex_unlock(&out->lock);
624 pthread_mutex_unlock(&out->dev->lock);
625
626 if(ret !=0){
627 uint64_t duration_ms = ((bytes * 1000)/
628 (audio_stream_out_frame_size(stream)) /
629 (out_get_sample_rate(&stream->common)));
630 ALOGV("%s : silence written", __func__);
631 usleep(duration_ms * 1000);
632 }
633
634 ALOGV("%s exit",__func__);
635 return bytes;
636 }
637
out_get_render_position(const struct audio_stream_out * stream,uint32_t * dsp_frames)638 static int out_get_render_position(const struct audio_stream_out *stream,
639 uint32_t *dsp_frames)
640 {
641 UNUSED_PARAMETER(stream);
642 UNUSED_PARAMETER(dsp_frames);
643
644 return -EINVAL;
645 }
646
out_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)647 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
648 {
649 UNUSED_PARAMETER(stream);
650 UNUSED_PARAMETER(effect);
651
652 return 0;
653 }
654
out_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)655 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
656 {
657 UNUSED_PARAMETER(stream);
658 UNUSED_PARAMETER(effect);
659
660 return 0;
661 }
662
out_get_next_write_timestamp(const struct audio_stream_out * stream,int64_t * timestamp)663 static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
664 int64_t *timestamp)
665 {
666 UNUSED_PARAMETER(stream);
667 UNUSED_PARAMETER(timestamp);
668
669 return -EINVAL;
670 }
671
adev_open_output_stream(struct audio_hw_device * dev,audio_io_handle_t handle,audio_devices_t devices,audio_output_flags_t flags,struct audio_config * config,struct audio_stream_out ** stream_out,const char * address)672 static int adev_open_output_stream(struct audio_hw_device *dev,
673 audio_io_handle_t handle,
674 audio_devices_t devices,
675 audio_output_flags_t flags,
676 struct audio_config *config,
677 struct audio_stream_out **stream_out,
678 const char *address)
679 {
680 UNUSED_PARAMETER(devices);
681 UNUSED_PARAMETER(handle);
682 UNUSED_PARAMETER(address);
683
684 struct audio_device *adev = (struct audio_device *)dev;
685 struct stream_out *out;
686 int ret;
687 ALOGV("%s enter",__func__);
688
689 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
690 if (!out)
691 return -ENOMEM;
692
693
694 out->dev = adev;
695 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
696 adev->sup_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
697
698 if (flags & AUDIO_OUTPUT_FLAG_DIRECT) {
699 ALOGV("%s: HDMI Multichannel",__func__);
700 if (config->sample_rate == 0)
701 config->sample_rate = pcm_config_default.rate;
702 if (config->channel_mask == 0){
703 /*read the channel support from sink*/
704 out_read_edid(out);
705 if(config->channel_mask == 0)
706 config->channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
707 }
708 } else {
709 ALOGV("%s: HDMI Stereo",__func__);
710 if (config->sample_rate == 0)
711 config->sample_rate = pcm_config_default.rate;
712 if (config->channel_mask == 0)
713 config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
714 }
715
716 out->channel_mask = config->channel_mask;
717
718 out->pcm_config.channels = popcount(config->channel_mask);
719 out->pcm_config.rate = config->sample_rate;
720 out->pcm_config.period_size = pcm_config_default.period_size;
721 out->pcm_config.period_count = pcm_config_default.period_count;
722 out->pcm_config.format = pcm_config_default.format;
723
724 out->stream.common.get_sample_rate = out_get_sample_rate;
725 out->stream.common.set_sample_rate = out_set_sample_rate;
726 out->stream.common.get_buffer_size = out_get_buffer_size;
727 out->stream.common.get_channels = out_get_channels;
728 out->stream.common.get_format = out_get_format;
729 out->stream.common.set_format = out_set_format;
730 out->stream.common.standby = out_standby;
731 out->stream.common.dump = out_dump;
732 out->stream.common.set_parameters = out_set_parameters;
733 out->stream.common.get_parameters = out_get_parameters;
734 out->stream.common.add_audio_effect = out_add_audio_effect;
735 out->stream.common.remove_audio_effect = out_remove_audio_effect;
736 out->stream.get_latency = out_get_latency;
737 out->stream.set_volume = out_set_volume;
738 out->stream.write = out_write;
739 out->stream.get_render_position = out_get_render_position;
740 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
741
742 config->format = out_get_format(&out->stream.common);
743 config->channel_mask = out_get_channels(&out->stream.common);
744 config->sample_rate = out_get_sample_rate(&out->stream.common);
745
746 out->standby = true;
747
748 adev->card = -1;
749 adev->device = -1;
750
751 pthread_mutex_lock(&out->dev->lock);
752 pthread_mutex_lock(&out->lock);
753
754 if(activePcm){
755 ALOGV("Closing already open tiny alsa stream %d",(int)out->pcm);
756 pcm_close(activePcm);
757 activePcm = NULL;
758 }
759 ret = start_output_stream(out);
760 if (ret != 0) {
761 ALOGV("%s: stream start failed", __func__);
762 goto err_open;
763 }
764
765 out->standby = false;
766
767 *stream_out = &out->stream;
768
769 pthread_mutex_unlock(&out->lock);
770 pthread_mutex_unlock(&out->dev->lock);
771
772 ALOGV("%s exit",__func__);
773 return 0;
774
775 err_open:
776 ALOGE("%s exit with error",__func__);
777 pthread_mutex_unlock(&out->lock);
778 pthread_mutex_unlock(&out->dev->lock);
779 free(out);
780 *stream_out = NULL;
781 return ret;
782 }
783
adev_close_output_stream(struct audio_hw_device * dev,struct audio_stream_out * stream)784 static void adev_close_output_stream(struct audio_hw_device *dev,
785 struct audio_stream_out *stream)
786 {
787 UNUSED_PARAMETER(dev);
788
789 struct stream_out *out = (struct stream_out *)stream;
790
791 ALOGV("%s enter",__func__);
792 out->standby = false;
793 out_standby(&stream->common);
794 free(stream);
795 ALOGV("%s exit",__func__);
796 }
797
adev_set_parameters(struct audio_hw_device * dev,const char * kvpairs)798 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
799 {
800 UNUSED_PARAMETER(dev);
801 UNUSED_PARAMETER(kvpairs);
802
803 return 0;
804 }
805
adev_get_parameters(const struct audio_hw_device * dev,const char * keys)806 static char * adev_get_parameters(const struct audio_hw_device *dev,
807 const char *keys)
808 {
809 UNUSED_PARAMETER(dev);
810 UNUSED_PARAMETER(keys);
811
812 return strdup("");
813 }
814
adev_init_check(const struct audio_hw_device * dev)815 static int adev_init_check(const struct audio_hw_device *dev)
816 {
817 UNUSED_PARAMETER(dev);
818
819 return 0;
820 }
821
adev_set_voice_volume(struct audio_hw_device * dev,float volume)822 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
823 {
824 UNUSED_PARAMETER(dev);
825 UNUSED_PARAMETER(volume);
826
827 return -ENOSYS;
828 }
829
adev_set_master_volume(struct audio_hw_device * dev,float volume)830 static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
831 {
832 UNUSED_PARAMETER(dev);
833 UNUSED_PARAMETER(volume);
834
835 return -ENOSYS;
836 }
837
adev_set_mode(struct audio_hw_device * dev,audio_mode_t mode)838 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
839 {
840 UNUSED_PARAMETER(dev);
841 UNUSED_PARAMETER(mode);
842
843 return 0;
844 }
845
adev_set_mic_mute(struct audio_hw_device * dev,bool state)846 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
847 {
848 UNUSED_PARAMETER(dev);
849 UNUSED_PARAMETER(state);
850
851 return -ENOSYS;
852 }
853
adev_get_mic_mute(const struct audio_hw_device * dev,bool * state)854 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
855 {
856 UNUSED_PARAMETER(dev);
857 UNUSED_PARAMETER(state);
858
859 return -ENOSYS;
860 }
861
adev_get_input_buffer_size(const struct audio_hw_device * dev,const struct audio_config * config)862 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
863 const struct audio_config *config)
864 {
865 UNUSED_PARAMETER(dev);
866 UNUSED_PARAMETER(config);
867
868 return 0;
869 }
870
adev_open_input_stream(struct audio_hw_device * dev,audio_io_handle_t handle,audio_devices_t devices,struct audio_config * config,struct audio_stream_in ** stream_in,audio_input_flags_t flags,const char * address,audio_source_t source)871 static int adev_open_input_stream(struct audio_hw_device *dev,
872 audio_io_handle_t handle,
873 audio_devices_t devices,
874 struct audio_config *config,
875 struct audio_stream_in **stream_in,
876 audio_input_flags_t flags,
877 const char *address,
878 audio_source_t source)
879 {
880 UNUSED_PARAMETER(dev);
881 UNUSED_PARAMETER(handle);
882 UNUSED_PARAMETER(devices);
883 UNUSED_PARAMETER(config);
884 UNUSED_PARAMETER(stream_in);
885 UNUSED_PARAMETER(flags);
886 UNUSED_PARAMETER(address);
887 UNUSED_PARAMETER(source);
888
889 return -ENOSYS;
890 }
891
adev_close_input_stream(struct audio_hw_device * dev,struct audio_stream_in * stream)892 static void adev_close_input_stream(struct audio_hw_device *dev,
893 struct audio_stream_in *stream)
894 {
895 UNUSED_PARAMETER(dev);
896 UNUSED_PARAMETER(stream);
897 }
898
adev_dump(const audio_hw_device_t * device,int fd)899 static int adev_dump(const audio_hw_device_t *device, int fd)
900 {
901 UNUSED_PARAMETER(device);
902 UNUSED_PARAMETER(fd);
903
904 return 0;
905 }
906
adev_close(hw_device_t * device)907 static int adev_close(hw_device_t *device)
908 {
909 free(device);
910 return 0;
911 }
912
adev_open(const hw_module_t * module,const char * name,hw_device_t ** device)913 static int adev_open(const hw_module_t* module, const char* name,
914 hw_device_t** device)
915 {
916 struct audio_device *adev;
917
918 ALOGV("%s enter",__func__);
919
920 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
921 return -EINVAL;
922
923 adev = calloc(1, sizeof(struct audio_device));
924 if (!adev)
925 return -ENOMEM;
926
927 adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
928 adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
929 adev->hw_device.common.module = (struct hw_module_t *) module;
930 adev->hw_device.common.close = adev_close;
931
932 adev->hw_device.init_check = adev_init_check;
933 adev->hw_device.set_voice_volume = adev_set_voice_volume;
934 adev->hw_device.set_master_volume = adev_set_master_volume;
935 adev->hw_device.set_mode = adev_set_mode;
936 adev->hw_device.set_mic_mute = adev_set_mic_mute;
937 adev->hw_device.get_mic_mute = adev_get_mic_mute;
938 adev->hw_device.set_parameters = adev_set_parameters;
939 adev->hw_device.get_parameters = adev_get_parameters;
940 adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size;
941 adev->hw_device.open_output_stream = adev_open_output_stream;
942 adev->hw_device.close_output_stream = adev_close_output_stream;
943 adev->hw_device.open_input_stream = adev_open_input_stream;
944 adev->hw_device.close_input_stream = adev_close_input_stream;
945 adev->hw_device.dump = adev_dump;
946
947 *device = &adev->hw_device.common;
948
949 ALOGV("%s exit",__func__);
950
951 return 0;
952 }
953
954 static struct hw_module_methods_t hal_module_methods = {
955 .open = adev_open,
956 };
957
958 struct audio_module HAL_MODULE_INFO_SYM = {
959 .common = {
960 .tag = HARDWARE_MODULE_TAG,
961 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
962 .hal_api_version = HARDWARE_HAL_API_VERSION,
963 .id = AUDIO_HARDWARE_MODULE_ID,
964 .name = "tiny_hdmi audio HW HAL",
965 .author = "The Android Open Source Project",
966 .methods = &hal_module_methods,
967 },
968 };
969