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 }; 969