OSDN Git Service

23b71cb7d706d1614441c045e91dbad94f248448
[android-x86/hardware-intel-audio_media.git] / hdmi / tinyaudio_hw.c
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
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
177 static enum pcm_format Get_SinkSupported_format()
178 {
179    /*TODO : query sink supported formats*/
180    return PCM_FORMAT_S24_LE;
181 }
182
183 static int format_to_bits(enum pcm_format pcmformat)
184 {
185   switch (pcmformat) {
186     case PCM_FORMAT_S32_LE:
187          return 32;
188     case PCM_FORMAT_S24_LE:
189          return 24;
190     default:
191     case PCM_FORMAT_S16_LE:
192          return 16;
193   };
194 }
195
196 static int make_sinkcompliant_buffers(void* input, void *output, int ipbytes)
197 {
198   int i = 0,outbytes = 0;
199   enum pcm_format in_pcmformat;
200   enum pcm_format out_pcmformat;
201   int *src = (int*)input;
202   int *dst = (int*)output;
203
204   /*by default android currently support only
205     16 bit signed PCM*/
206   in_pcmformat = PCM_FORMAT_S16_LE;
207   out_pcmformat = Get_SinkSupported_format();
208
209   switch (out_pcmformat) {
210     default:
211     case PCM_FORMAT_S24_LE:
212     {
213        ALOGV("convert 16 to 24 bits for %d",ipbytes);
214        /*convert 16 bit input to 24 bit output
215          in a 32 bit sample*/
216        if(0 == ipbytes)
217           break;
218
219        for(i = 0; i < (ipbytes/4); i++){
220           int x = (int)((int*)src)[i];
221           dst[i*2] = ((int)( x & 0x0000FFFF)) << 8;
222           // trying to sign exdent
223           dst[i*2] = dst[i*2] << 8;
224           dst[i*2] = dst[i*2] >> 8;
225           //shift to middle
226           dst[i*2 + 1] = (int)(( x & 0xFFFF0000) >> 8);
227           dst[i*2 + 1] = dst[i*2 + 1] << 8;
228           dst[i*2 + 1] = dst[i*2 + 1] >> 8;
229         }
230         outbytes=ipbytes * 2;
231
232     }//case
233   };//switch
234
235   return outbytes;
236 }
237
238 /* must be called with hw device and output stream mutexes locked */
239 static int start_output_stream(struct stream_out *out)
240 {
241     struct audio_device *adev = out->dev;
242     int hdmicard = 0;
243
244     ALOGV("%s enter",__func__);
245
246     if ((adev->card < 0) || (adev->device < 0)){
247         /*this will be updated once the hot plug intent
248           sends these information.*/
249         adev->card = DEFAULT_CARD;
250         adev->device = DEFAULT_DEVICE;
251         ALOGV("%s : Setting default card/ device %d,%d",__func__,adev->card,adev->device);
252     }
253
254     ALOGV("%s enter %d,%d,%d,%d,%d",__func__,
255           out->pcm_config.channels,
256           out->pcm_config.rate,
257           out->pcm_config.period_size,
258           out->pcm_config.period_count,
259           out->pcm_config.format);
260
261     out->pcm_config.start_threshold = 0;
262     out->pcm_config.stop_threshold = 0;
263     out->pcm_config.silence_threshold = 0;
264
265     if(activePcm){
266       ALOGV("Closing already open tiny alsa stream running state %d",(int)(activePcm));
267       pcm_close(activePcm);
268       activePcm = NULL;
269     }
270
271     /*TODO - this needs to be updated once the device connect intent sends
272       card, device id*/
273     adev->card = get_card_number_by_name("IntelHDMI");
274     ALOGD("%s: HDMI card number = %d, device = %d",__func__,adev->card,adev->device);
275
276     out->pcm = pcm_open(adev->card, adev->device, PCM_OUT, &out->pcm_config);
277
278     if (out->pcm && !pcm_is_ready(out->pcm)) {
279         ALOGE("pcm_open() failed: %s", pcm_get_error(out->pcm));
280         pcm_close(out->pcm);
281         activePcm = NULL;
282         return -ENOMEM;
283     }
284
285     activePcm = out->pcm;
286     activeChannel = out->pcm_config.channels;
287
288     ALOGV("Initialized PCM device for channels %d handle = %d",out->pcm_config.channels, (int)activePcm);
289     ALOGV("%s exit",__func__);
290     return 0;
291 }
292
293 /* API functions */
294
295 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
296 {
297     struct stream_out *out = (struct stream_out *)stream;
298     return out->pcm_config.rate;
299 }
300
301 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
302 {
303     UNUSED_PARAMETER(stream);
304     UNUSED_PARAMETER(rate);
305
306     return 0;
307 }
308
309 static size_t out_get_buffer_size(const struct audio_stream *stream)
310 {
311     struct stream_out *out = (struct stream_out *)stream;
312     size_t buf_size;
313
314     if(out->channel_mask > 2){
315        buf_size = out->pcm_config.period_size *
316                   audio_stream_out_frame_size((struct audio_stream_out *)stream);
317     }
318     else{
319        buf_size = out->pcm_config.period_size *
320                   out->pcm_config.period_count *
321                   audio_stream_out_frame_size((struct audio_stream_out *)stream);
322
323        /*latency of audio flinger is based on this
324          buffer size. modifying the buffer size to avoid
325          starvation*/
326        buf_size/=LATENCY_TO_BUFFER_SIZE_RATIO;
327     }
328
329     ALOGV("%s : %d, period_size : %d, frame_size : %d",
330         __func__,
331         buf_size,
332         out->pcm_config.period_size,
333         audio_stream_out_frame_size((struct audio_stream_out *)stream));
334
335     return buf_size;
336
337 }
338
339 static uint32_t out_get_channels(const struct audio_stream *stream)
340 {
341     struct stream_out *out = (struct stream_out *)stream;
342     ALOGV("%s channel mask : %x",__func__,out->channel_mask);
343     return out->channel_mask;
344 }
345
346 static audio_format_t out_get_format(const struct audio_stream *stream)
347 {
348     UNUSED_PARAMETER(stream);
349
350     return AUDIO_FORMAT_PCM_16_BIT;
351 }
352
353 static int out_set_format(struct audio_stream *stream, audio_format_t format)
354 {
355     UNUSED_PARAMETER(stream);
356     UNUSED_PARAMETER(format);
357
358     return 0;
359 }
360
361 static int out_standby(struct audio_stream *stream)
362 {
363     struct stream_out *out = (struct stream_out *)stream;
364
365     ALOGV("%s enter standby = %d",__func__,out->standby);
366
367     pthread_mutex_lock(&out->dev->lock);
368     pthread_mutex_lock(&out->lock);
369
370     if (!out->standby && activePcm) {
371         pcm_close(activePcm);
372         out->pcm = NULL;
373         out->standby = true;
374         activePcm = NULL;
375         ALOGV("%s PCM device closed",__func__);
376     }
377
378     pthread_mutex_unlock(&out->lock);
379     pthread_mutex_unlock(&out->dev->lock);
380
381     ALOGV("%s exit",__func__);
382     return 0;
383 }
384
385 static int out_dump(const struct audio_stream *stream, int fd)
386 {
387     UNUSED_PARAMETER(stream);
388     UNUSED_PARAMETER(fd);
389     return 0;
390 }
391
392 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
393 {
394     struct stream_out *out = (struct stream_out *)stream;
395     struct audio_device *adev = out->dev;
396     struct str_parms *parms;
397     char value[32];
398     int ret;
399     int routing = 0;
400     ALOGV("%s enter",__func__);
401
402     parms = str_parms_create_str(kvpairs);
403
404     pthread_mutex_lock(&adev->lock);
405
406     if (parms == NULL) {
407         ALOGE("couldn't extract string params from key value pairs");
408         pthread_mutex_unlock(&adev->lock);
409         return 0;
410     }
411
412     ret = str_parms_get_str(parms, "card", value, sizeof(value));
413     if (ret >= 0)
414         adev->card = atoi(value);
415
416     ret = str_parms_get_str(parms, "device", value, sizeof(value));
417     if (ret >= 0)
418         adev->device = atoi(value);
419
420     pthread_mutex_unlock(&adev->lock);
421     str_parms_destroy(parms);
422
423     ALOGV("%s exit",__func__);
424     return 0;
425 }
426
427 static int parse_channel_map()
428 {
429     struct mixer *mixer;
430     int card = 0;
431     struct mixer_ctl *ctl;
432     enum mixer_ctl_type type;
433     unsigned int num_values;
434     unsigned int i,id;
435     int chcount=0, chmap=0;
436
437     card = get_card_number_by_name("IntelHDMI");
438     mixer = mixer_open(card);
439     if (!mixer) {
440         ALOGE("[EDID] Failed to open mixer\n");
441         goto chmap_error;
442     }
443
444     id = CHANNEL_MAP_REQUEST;
445     if (id >= mixer_get_num_ctls(mixer)) {
446         ALOGE("[EDID] Invalid request for channel map %d",id);
447         goto chmap_error;
448     }
449
450     ctl = mixer_get_ctl_by_name(mixer, "Playback Channel Map");
451
452     //ctl = mixer_get_ctl(mixer, id);
453
454     type = mixer_ctl_get_type(ctl);
455     num_values = mixer_ctl_get_num_values(ctl);
456
457     ALOGV("[EDID]id = %d",id);
458     ALOGV("[EDID]type = %d",type);
459     ALOGV("[EDID]count = %d",num_values);
460
461     for (i = 0; i < num_values; i++) {
462       switch (type)
463       {
464        case MIXER_CTL_TYPE_INT:
465             chmap = mixer_ctl_get_value(ctl, i);
466             ALOGD("[EDID]chmap = %d", chmap);
467             if(chmap > 0)  ++chcount;
468             break;
469        default:
470             printf(" unknown");
471             break;
472       };
473     }//for
474
475     ALOGD("[EDID]valid number of channels supported by sink = %d",chcount);
476
477     mixer_close(mixer);
478
479     return chcount;
480
481 chmap_error:
482     mixer_close(mixer);
483     return 2;//stereo by default
484
485 }
486
487 static int out_read_edid(const struct stream_out *stream)
488 {
489     struct stream_out *out = (struct stream_out *)stream;
490     struct audio_device *adev = out->dev;
491
492     /**read the channel max param from the sink*/
493     adev->sink_sup_channels = parse_channel_map();
494
495     if(adev->sink_sup_channels == 8) {
496       adev->sup_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1;
497       adev->sup_channel_masks[1] = AUDIO_CHANNEL_OUT_7POINT1;
498     }
499     else if((adev->sink_sup_channels == 6) || (adev->sink_sup_channels > 2)) {
500       adev->sup_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1;
501     }
502     else {
503       adev->sup_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
504     }
505
506     ALOGV("%s sink supports 0x%x max channels", __func__,adev->sink_sup_channels);
507     return 0;
508 }
509
510 static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
511 {
512     struct stream_out *out = (struct stream_out *)stream;
513     struct audio_device *adev = out->dev;
514     struct str_parms *params_in = str_parms_create_str(keys);
515     char *str = NULL;
516     char value[256] = {0};
517     int ret;
518     size_t i, j;
519     bool append = false;
520
521     struct str_parms *params_out = str_parms_create();
522
523     ALOGV("%s Entered %s", __func__,keys);
524
525     if (params_in) {
526         ret = str_parms_get_str(params_in, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
527         if (ret >= 0) {
528             /*read the channel support from sink*/
529             out_read_edid(out);
530
531             value[0] = '\0';
532             for (i = 0; i < CHANNEL_MASK_MAX; i++) {
533                for (j = 0; j < ARRAY_SIZE(channel_list_table); j++) {
534                    if (channel_list_table[j].value == adev->sup_channel_masks[i]) {
535                       if (append) {
536                           strcat(value, "|");
537                       }
538                       strcat(value, channel_list_table[j].name);
539                       append = true;
540                       break;
541                    }
542                }
543             }
544         }
545     }
546     if (params_out) {
547         str_parms_add_str(params_out, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
548         str = str_parms_to_str(params_out);
549     } else {
550         str = strdup(keys);
551     }
552
553     ALOGV("%s AUDIO_PARAMETER_STREAM_SUP_CHANNELS %s", __func__,str);
554     if (params_in) {
555         str_parms_destroy(params_in);
556     }
557     if (params_out) {
558         str_parms_destroy(params_out);
559     }
560
561     return str;
562 }
563
564 static uint32_t out_get_latency(const struct audio_stream_out *stream)
565 {
566     struct stream_out *out = (struct stream_out *)stream;
567     return (out->pcm_config.period_size * out->pcm_config.period_count * 1000) /
568             out_get_sample_rate(&stream->common);
569 }
570
571 static int out_set_volume(struct audio_stream_out *stream, float left,
572                           float right)
573 {
574     UNUSED_PARAMETER(stream);
575     UNUSED_PARAMETER(left);
576     UNUSED_PARAMETER(right);
577
578     return -ENOSYS;
579 }
580
581 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
582                          size_t bytes)
583 {
584     int ret = 0;
585     struct stream_out *out = (struct stream_out *)stream;
586     int32_t* dstbuff = NULL;
587     int outbytes = 0;
588
589     ALOGV("%s enter for bytes = %d channels = %d",__func__,bytes, out->pcm_config.channels);
590
591     pthread_mutex_lock(&out->dev->lock);
592     pthread_mutex_lock(&out->lock);
593
594     if(activePcm == NULL) {
595        ALOGV("%s: previous stream closed- open again",__func__);
596        out->standby = true;
597     }
598
599     if (out->standby) {
600         ret = start_output_stream(out);
601         if (ret != 0) {
602             goto err;
603         }
604         out->standby = false;
605     }
606
607     if((!out->pcm) || (activeChannel != out->pcm_config.channels)){
608        ALOGD("%s: null handle to write - device already closed",__func__);
609        goto err;
610     }
611
612     if(Get_SinkSupported_format() == out->pcm_config.format){
613
614        /*16 bit data will be converted to 24 bit over 32 bit data type
615        hence the multiplier 2*/
616        dstbuff = (int32_t*)malloc(bytes* 2);
617        if (!dstbuff) {
618            pthread_mutex_unlock(&out->lock);
619            pthread_mutex_unlock(&out->dev->lock);
620            ALOGE("%s : memory allocation failed",__func__);
621            return -ENOMEM;
622        }
623
624        memset(dstbuff,0,bytes * 2);
625
626        outbytes = make_sinkcompliant_buffers((void*)buffer, (void*)dstbuff,bytes);
627      } //if()for conversion
628
629     if(dstbuff){
630       ret = pcm_write(out->pcm, (void *)dstbuff, outbytes);
631     }
632     else
633       ret = pcm_write(out->pcm, (void *)buffer, bytes);
634
635     ALOGV("pcm_write: %s done for %d input bytes, output bytes = %d ", pcm_get_error(out->pcm),bytes,outbytes);
636
637     free(dstbuff);
638
639 err:
640     pthread_mutex_unlock(&out->lock);
641     pthread_mutex_unlock(&out->dev->lock);
642
643    if(ret !=0){
644     uint64_t duration_ms = ((bytes * 1000)/
645                             (audio_stream_out_frame_size(stream)) /
646                             (out_get_sample_rate(&stream->common)));
647     ALOGV("%s : silence written", __func__);
648     usleep(duration_ms * 1000);
649    }
650
651     ALOGV("%s exit",__func__);
652     return bytes;
653 }
654
655 static int out_get_render_position(const struct audio_stream_out *stream,
656                                    uint32_t *dsp_frames)
657 {
658     UNUSED_PARAMETER(stream);
659     UNUSED_PARAMETER(dsp_frames);
660
661     return -EINVAL;
662 }
663
664 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
665 {
666     UNUSED_PARAMETER(stream);
667     UNUSED_PARAMETER(effect);
668
669     return 0;
670 }
671
672 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
673 {
674     UNUSED_PARAMETER(stream);
675     UNUSED_PARAMETER(effect);
676
677     return 0;
678 }
679
680 static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
681                                         int64_t *timestamp)
682 {
683     UNUSED_PARAMETER(stream);
684     UNUSED_PARAMETER(timestamp);
685
686     return -EINVAL;
687 }
688
689 static int adev_open_output_stream(struct audio_hw_device *dev,
690                                    audio_io_handle_t handle,
691                                    audio_devices_t devices,
692                                    audio_output_flags_t flags,
693                                    struct audio_config *config,
694                                    struct audio_stream_out **stream_out,
695                                    const char *address)
696 {
697     UNUSED_PARAMETER(devices);
698     UNUSED_PARAMETER(handle);
699     UNUSED_PARAMETER(address);
700
701     struct audio_device *adev = (struct audio_device *)dev;
702     struct stream_out *out;
703     int ret;
704     ALOGV("%s enter",__func__);
705
706     out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
707     if (!out)
708         return -ENOMEM;
709
710
711     out->dev = adev;
712     out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
713     adev->sup_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
714
715     if (flags & AUDIO_OUTPUT_FLAG_DIRECT) {
716         ALOGV("%s: HDMI Multichannel",__func__);
717         if (config->sample_rate == 0)
718             config->sample_rate = pcm_config_default.rate;
719         if (config->channel_mask == 0){
720             /*read the channel support from sink*/
721             out_read_edid(out);
722             if(config->channel_mask == 0)
723                config->channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
724         }
725     } else {
726         ALOGV("%s: HDMI Stereo",__func__);
727         if (config->sample_rate == 0)
728             config->sample_rate = pcm_config_default.rate;
729         if (config->channel_mask == 0)
730             config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
731     }
732
733     out->channel_mask                      = config->channel_mask;
734
735     out->pcm_config.channels               = popcount(config->channel_mask);
736     out->pcm_config.rate                   = config->sample_rate;
737     out->pcm_config.period_size            = pcm_config_default.period_size;
738     out->pcm_config.period_count           = pcm_config_default.period_count;
739     out->pcm_config.format                 = pcm_config_default.format;
740
741     out->stream.common.get_sample_rate     = out_get_sample_rate;
742     out->stream.common.set_sample_rate     = out_set_sample_rate;
743     out->stream.common.get_buffer_size     = out_get_buffer_size;
744     out->stream.common.get_channels        = out_get_channels;
745     out->stream.common.get_format          = out_get_format;
746     out->stream.common.set_format          = out_set_format;
747     out->stream.common.standby             = out_standby;
748     out->stream.common.dump                = out_dump;
749     out->stream.common.set_parameters      = out_set_parameters;
750     out->stream.common.get_parameters      = out_get_parameters;
751     out->stream.common.add_audio_effect    = out_add_audio_effect;
752     out->stream.common.remove_audio_effect = out_remove_audio_effect;
753     out->stream.get_latency                = out_get_latency;
754     out->stream.set_volume                 = out_set_volume;
755     out->stream.write                      = out_write;
756     out->stream.get_render_position        = out_get_render_position;
757     out->stream.get_next_write_timestamp   = out_get_next_write_timestamp;
758
759     config->format = out_get_format(&out->stream.common);
760     config->channel_mask = out_get_channels(&out->stream.common);
761     config->sample_rate = out_get_sample_rate(&out->stream.common);
762
763     out->standby = true;
764
765     adev->card = -1;
766     adev->device = -1;
767
768     pthread_mutex_lock(&out->dev->lock);
769     pthread_mutex_lock(&out->lock);
770
771     if(activePcm){
772       ALOGV("Closing already open tiny alsa stream %d",(int)out->pcm);
773       pcm_close(activePcm);
774       activePcm = NULL;
775     }
776     ret = start_output_stream(out);
777     if (ret != 0) {
778         ALOGV("%s: stream start failed", __func__);
779         goto err_open;
780     }
781
782     out->standby = false;
783
784     *stream_out = &out->stream;
785
786     pthread_mutex_unlock(&out->lock);
787     pthread_mutex_unlock(&out->dev->lock);
788
789     ALOGV("%s exit",__func__);
790     return 0;
791
792 err_open:
793     ALOGE("%s exit with error",__func__);
794     pthread_mutex_unlock(&out->lock);
795     pthread_mutex_unlock(&out->dev->lock);
796     free(out);
797     *stream_out = NULL;
798     return ret;
799 }
800
801 static void adev_close_output_stream(struct audio_hw_device *dev,
802                                      struct audio_stream_out *stream)
803 {
804     UNUSED_PARAMETER(dev);
805
806     struct stream_out *out = (struct stream_out *)stream;
807
808     ALOGV("%s enter",__func__);
809     out->standby = false;
810     out_standby(&stream->common);
811     free(stream);
812     ALOGV("%s exit",__func__);
813 }
814
815 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
816 {
817     UNUSED_PARAMETER(dev);
818     UNUSED_PARAMETER(kvpairs);
819
820     return 0;
821 }
822
823 static char * adev_get_parameters(const struct audio_hw_device *dev,
824                                   const char *keys)
825 {
826     UNUSED_PARAMETER(dev);
827     UNUSED_PARAMETER(keys);
828
829     return strdup("");
830 }
831
832 static int adev_init_check(const struct audio_hw_device *dev)
833 {
834     UNUSED_PARAMETER(dev);
835
836     return 0;
837 }
838
839 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
840 {
841     UNUSED_PARAMETER(dev);
842     UNUSED_PARAMETER(volume);
843
844     return -ENOSYS;
845 }
846
847 static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
848 {
849     UNUSED_PARAMETER(dev);
850     UNUSED_PARAMETER(volume);
851
852     return -ENOSYS;
853 }
854
855 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
856 {
857     UNUSED_PARAMETER(dev);
858     UNUSED_PARAMETER(mode);
859
860     return 0;
861 }
862
863 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
864 {
865     UNUSED_PARAMETER(dev);
866     UNUSED_PARAMETER(state);
867
868     return -ENOSYS;
869 }
870
871 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
872 {
873     UNUSED_PARAMETER(dev);
874     UNUSED_PARAMETER(state);
875
876     return -ENOSYS;
877 }
878
879 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
880                                          const struct audio_config *config)
881 {
882     UNUSED_PARAMETER(dev);
883     UNUSED_PARAMETER(config);
884
885     return 0;
886 }
887
888 static int adev_open_input_stream(struct audio_hw_device *dev,
889                                   audio_io_handle_t handle,
890                                   audio_devices_t devices,
891                                   struct audio_config *config,
892                                   struct audio_stream_in **stream_in,
893                                   audio_input_flags_t flags,
894                                   const char *address,
895                                   audio_source_t source)
896 {
897     UNUSED_PARAMETER(dev);
898     UNUSED_PARAMETER(handle);
899     UNUSED_PARAMETER(devices);
900     UNUSED_PARAMETER(config);
901     UNUSED_PARAMETER(stream_in);
902     UNUSED_PARAMETER(flags);
903     UNUSED_PARAMETER(address);
904     UNUSED_PARAMETER(source);
905
906     return -ENOSYS;
907 }
908
909 static void adev_close_input_stream(struct audio_hw_device *dev,
910                                    struct audio_stream_in *stream)
911 {
912     UNUSED_PARAMETER(dev);
913     UNUSED_PARAMETER(stream);
914 }
915
916 static int adev_dump(const audio_hw_device_t *device, int fd)
917 {
918     UNUSED_PARAMETER(device);
919     UNUSED_PARAMETER(fd);
920
921     return 0;
922 }
923
924 static int adev_close(hw_device_t *device)
925 {
926     struct audio_device *adev = (struct audio_device *)device;
927
928     free(device);
929     return 0;
930 }
931
932 static int adev_open(const hw_module_t* module, const char* name,
933                      hw_device_t** device)
934 {
935     struct audio_device *adev;
936     int ret;
937
938     ALOGV("%s enter",__func__);
939
940     if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
941         return -EINVAL;
942
943     adev = calloc(1, sizeof(struct audio_device));
944     if (!adev)
945         return -ENOMEM;
946
947     adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
948     adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
949     adev->hw_device.common.module = (struct hw_module_t *) module;
950     adev->hw_device.common.close = adev_close;
951
952     adev->hw_device.init_check = adev_init_check;
953     adev->hw_device.set_voice_volume = adev_set_voice_volume;
954     adev->hw_device.set_master_volume = adev_set_master_volume;
955     adev->hw_device.set_mode = adev_set_mode;
956     adev->hw_device.set_mic_mute = adev_set_mic_mute;
957     adev->hw_device.get_mic_mute = adev_get_mic_mute;
958     adev->hw_device.set_parameters = adev_set_parameters;
959     adev->hw_device.get_parameters = adev_get_parameters;
960     adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size;
961     adev->hw_device.open_output_stream = adev_open_output_stream;
962     adev->hw_device.close_output_stream = adev_close_output_stream;
963     adev->hw_device.open_input_stream = adev_open_input_stream;
964     adev->hw_device.close_input_stream = adev_close_input_stream;
965     adev->hw_device.dump = adev_dump;
966
967     *device = &adev->hw_device.common;
968
969     ALOGV("%s exit",__func__);
970
971     return 0;
972 }
973
974 static struct hw_module_methods_t hal_module_methods = {
975     .open = adev_open,
976 };
977
978 struct audio_module HAL_MODULE_INFO_SYM = {
979     .common = {
980         .tag = HARDWARE_MODULE_TAG,
981         .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
982         .hal_api_version = HARDWARE_HAL_API_VERSION,
983         .id = AUDIO_HARDWARE_MODULE_ID,
984         .name = "tiny_hdmi audio HW HAL",
985         .author = "The Android Open Source Project",
986         .methods = &hal_module_methods,
987     },
988 };