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