OSDN Git Service

Hdmi: Remove unused variables and functions
[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 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 */
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
815 static int adev_init_check(const struct audio_hw_device *dev)
816 {
817     UNUSED_PARAMETER(dev);
818
819     return 0;
820 }
821
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
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
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
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
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
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
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
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
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
907 static int adev_close(hw_device_t *device)
908 {
909     free(device);
910     return 0;
911 }
912
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 };