1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #define LOG_TAG "qcom_audio_hw_hal" 19 //#define LOG_NDEBUG 0 20 21 #include <stdint.h> 22 23 #include <hardware/hardware.h> 24 #include <system/audio.h> 25 #include <hardware/audio.h> 26 27 #include <hardware_legacy/AudioHardwareInterface.h> 28 #include <hardware_legacy/AudioSystemLegacy.h> 29 30 namespace android_audio_legacy { 31 32 extern "C" { 33 34 struct qcom_audio_module { 35 struct audio_module module; 36 }; 37 38 struct qcom_audio_device { 39 struct audio_hw_device device; 40 41 struct AudioHardwareInterface *hwif; 42 }; 43 44 struct qcom_stream_out { 45 struct audio_stream_out stream; 46 47 AudioStreamOut *qcom_out; 48 }; 49 50 struct qcom_stream_in { 51 struct audio_stream_in stream; 52 53 AudioStreamIn *qcom_in; 54 }; 55 56 57 enum { 58 HAL_API_REV_1_0, 59 HAL_API_REV_2_0, 60 HAL_API_REV_NUM 61 } hal_api_rev; 62 63 static uint32_t audio_device_conv_table[][HAL_API_REV_NUM] = 64 { 65 /* output devices */ 66 { AudioSystem::DEVICE_OUT_EARPIECE, AUDIO_DEVICE_OUT_EARPIECE }, 67 { AudioSystem::DEVICE_OUT_SPEAKER, AUDIO_DEVICE_OUT_SPEAKER }, 68 { AudioSystem::DEVICE_OUT_WIRED_HEADSET, AUDIO_DEVICE_OUT_WIRED_HEADSET }, 69 { AudioSystem::DEVICE_OUT_WIRED_HEADPHONE, AUDIO_DEVICE_OUT_WIRED_HEADPHONE }, 70 { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO, AUDIO_DEVICE_OUT_BLUETOOTH_SCO }, 71 { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET }, 72 { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT }, 73 { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP }, 74 { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES }, 75 { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER }, 76 { AudioSystem::DEVICE_OUT_AUX_DIGITAL, AUDIO_DEVICE_OUT_AUX_DIGITAL }, 77 { AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET, AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET }, 78 { AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET, AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET }, 79 { AudioSystem::DEVICE_OUT_DEFAULT, AUDIO_DEVICE_OUT_DEFAULT }, 80 #ifdef QCOM_ANC_HEADSET_ENABLED 81 { AudioSystem::DEVICE_OUT_ANC_HEADSET, AUDIO_DEVICE_OUT_ANC_HEADSET }, 82 { AudioSystem::DEVICE_OUT_ANC_HEADPHONE, AUDIO_DEVICE_OUT_ANC_HEADPHONE }, 83 #endif 84 #ifdef QCOM_FM_ENABLED 85 { AudioSystem::DEVICE_OUT_FM, AUDIO_DEVICE_OUT_FM }, 86 #endif 87 #ifdef QCOM_FM_TX_ENABLED 88 { AudioSystem::DEVICE_OUT_FM_TX, AUDIO_DEVICE_OUT_FM_TX }, 89 #endif 90 #ifdef QCOM_VOIP_ENABLED 91 { AudioSystem::DEVICE_OUT_DIRECTOUTPUT, AUDIO_DEVICE_OUT_DIRECTOUTPUT }, 92 #endif 93 #ifdef QCOM_PROXY_DEVICE_ENABLED 94 { AudioSystem::DEVICE_OUT_PROXY, AUDIO_DEVICE_OUT_PROXY }, 95 #endif 96 /* input devices */ 97 { AudioSystem::DEVICE_IN_COMMUNICATION, AUDIO_DEVICE_IN_COMMUNICATION }, 98 { AudioSystem::DEVICE_IN_AMBIENT, AUDIO_DEVICE_IN_AMBIENT }, 99 { AudioSystem::DEVICE_IN_BUILTIN_MIC, AUDIO_DEVICE_IN_BUILTIN_MIC }, 100 { AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET }, 101 { AudioSystem::DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_WIRED_HEADSET }, 102 { AudioSystem::DEVICE_IN_AUX_DIGITAL, AUDIO_DEVICE_IN_AUX_DIGITAL }, 103 { AudioSystem::DEVICE_IN_VOICE_CALL, AUDIO_DEVICE_IN_VOICE_CALL }, 104 { AudioSystem::DEVICE_IN_BACK_MIC, AUDIO_DEVICE_IN_BACK_MIC }, 105 { AudioSystem::DEVICE_IN_DEFAULT, AUDIO_DEVICE_IN_DEFAULT }, 106 #ifdef QCOM_ANC_HEADSET_ENABLED 107 { AudioSystem::DEVICE_IN_ANC_HEADSET, AUDIO_DEVICE_IN_ANC_HEADSET }, 108 #endif 109 #ifdef QCOM_FM_ENABLED 110 { AudioSystem::DEVICE_IN_FM_RX, AUDIO_DEVICE_IN_FM_RX }, 111 { AudioSystem::DEVICE_IN_FM_RX_A2DP, AUDIO_DEVICE_IN_FM_RX_A2DP }, 112 #endif 113 }; 114 115 static uint32_t convert_audio_device(uint32_t from_device, int from_rev, int to_rev) 116 { 117 const uint32_t k_num_devices = sizeof(audio_device_conv_table)/sizeof(uint32_t)/HAL_API_REV_NUM; 118 uint32_t to_device = AUDIO_DEVICE_NONE; 119 uint32_t in_bit = 0; 120 121 if (from_rev != HAL_API_REV_1_0) { 122 in_bit = from_device & AUDIO_DEVICE_BIT_IN; 123 from_device &= ~AUDIO_DEVICE_BIT_IN; 124 } 125 126 while (from_device) { 127 uint32_t i = 31 - __builtin_clz(from_device); 128 uint32_t cur_device = (1 << i) | in_bit; 129 130 for (i = 0; i < k_num_devices; i++) { 131 if (audio_device_conv_table[i][from_rev] == cur_device) { 132 to_device |= audio_device_conv_table[i][to_rev]; 133 break; 134 } 135 } 136 from_device &= ~cur_device; 137 } 138 return to_device; 139 } 140 141 /** audio_stream_out implementation **/ 142 static uint32_t out_get_sample_rate(const struct audio_stream *stream) 143 { 144 const struct qcom_stream_out *out = 145 reinterpret_cast<const struct qcom_stream_out *>(stream); 146 return out->qcom_out->sampleRate(); 147 } 148 149 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) 150 { 151 struct qcom_stream_out *out = 152 reinterpret_cast<struct qcom_stream_out *>(stream); 153 154 ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); 155 /* TODO: implement this */ 156 return 0; 157 } 158 159 static size_t out_get_buffer_size(const struct audio_stream *stream) 160 { 161 const struct qcom_stream_out *out = 162 reinterpret_cast<const struct qcom_stream_out *>(stream); 163 return out->qcom_out->bufferSize(); 164 } 165 166 static audio_channel_mask_t out_get_channels(const struct audio_stream *stream) 167 { 168 const struct qcom_stream_out *out = 169 reinterpret_cast<const struct qcom_stream_out *>(stream); 170 return out->qcom_out->channels(); 171 } 172 173 static audio_format_t out_get_format(const struct audio_stream *stream) 174 { 175 const struct qcom_stream_out *out = 176 reinterpret_cast<const struct qcom_stream_out *>(stream); 177 return (audio_format_t)out->qcom_out->format(); 178 } 179 180 static int out_set_format(struct audio_stream *stream, audio_format_t format) 181 { 182 struct qcom_stream_out *out = 183 reinterpret_cast<struct qcom_stream_out *>(stream); 184 ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); 185 /* TODO: implement me */ 186 return 0; 187 } 188 189 static int out_standby(struct audio_stream *stream) 190 { 191 struct qcom_stream_out *out = 192 reinterpret_cast<struct qcom_stream_out *>(stream); 193 return out->qcom_out->standby(); 194 } 195 196 static int out_dump(const struct audio_stream *stream, int fd) 197 { 198 const struct qcom_stream_out *out = 199 reinterpret_cast<const struct qcom_stream_out *>(stream); 200 Vector<String16> args; 201 return out->qcom_out->dump(fd, args); 202 } 203 204 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) 205 { 206 struct qcom_stream_out *out = 207 reinterpret_cast<struct qcom_stream_out *>(stream); 208 int val; 209 String8 s8 = String8(kvpairs); 210 AudioParameter parms = AudioParameter(String8(kvpairs)); 211 212 if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) { 213 val = convert_audio_device(val, HAL_API_REV_2_0, HAL_API_REV_1_0); 214 parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING)); 215 parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val); 216 s8 = parms.toString(); 217 } 218 219 return out->qcom_out->setParameters(s8); 220 } 221 222 static char * out_get_parameters(const struct audio_stream *stream, const char *keys) 223 { 224 const struct qcom_stream_out *out = 225 reinterpret_cast<const struct qcom_stream_out *>(stream); 226 String8 s8; 227 int val; 228 229 s8 = out->qcom_out->getParameters(String8(keys)); 230 231 AudioParameter parms = AudioParameter(s8); 232 if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) { 233 val = convert_audio_device(val, HAL_API_REV_1_0, HAL_API_REV_2_0); 234 parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING)); 235 parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val); 236 s8 = parms.toString(); 237 } 238 239 return strdup(s8.string()); 240 } 241 242 static uint32_t out_get_latency(const struct audio_stream_out *stream) 243 { 244 const struct qcom_stream_out *out = 245 reinterpret_cast<const struct qcom_stream_out *>(stream); 246 return out->qcom_out->latency(); 247 } 248 249 static int out_set_volume(struct audio_stream_out *stream, float left, 250 float right) 251 { 252 struct qcom_stream_out *out = 253 reinterpret_cast<struct qcom_stream_out *>(stream); 254 return out->qcom_out->setVolume(left, right); 255 } 256 257 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, 258 size_t bytes) 259 { 260 struct qcom_stream_out *out = 261 reinterpret_cast<struct qcom_stream_out *>(stream); 262 return out->qcom_out->write(buffer, bytes); 263 } 264 265 static int out_get_render_position(const struct audio_stream_out *stream, 266 uint32_t *dsp_frames) 267 { 268 const struct qcom_stream_out *out = 269 reinterpret_cast<const struct qcom_stream_out *>(stream); 270 return out->qcom_out->getRenderPosition(dsp_frames); 271 } 272 273 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 274 { 275 return 0; 276 } 277 278 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 279 { 280 return 0; 281 } 282 283 static int out_get_next_write_timestamp(const struct audio_stream_out *stream, 284 int64_t *timestamp) 285 { 286 const struct qcom_stream_out *out = 287 reinterpret_cast<const struct qcom_stream_out *>(stream); 288 return out->qcom_out->getNextWriteTimestamp(timestamp); 289 } 290 291 /** audio_stream_in implementation **/ 292 static uint32_t in_get_sample_rate(const struct audio_stream *stream) 293 { 294 const struct qcom_stream_in *in = 295 reinterpret_cast<const struct qcom_stream_in *>(stream); 296 return in->qcom_in->sampleRate(); 297 } 298 299 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate) 300 { 301 struct qcom_stream_in *in = 302 reinterpret_cast<struct qcom_stream_in *>(stream); 303 304 ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); 305 /* TODO: implement this */ 306 return 0; 307 } 308 309 static size_t in_get_buffer_size(const struct audio_stream *stream) 310 { 311 const struct qcom_stream_in *in = 312 reinterpret_cast<const struct qcom_stream_in *>(stream); 313 return in->qcom_in->bufferSize(); 314 } 315 316 static audio_channel_mask_t in_get_channels(const struct audio_stream *stream) 317 { 318 const struct qcom_stream_in *in = 319 reinterpret_cast<const struct qcom_stream_in *>(stream); 320 return in->qcom_in->channels(); 321 } 322 323 static audio_format_t in_get_format(const struct audio_stream *stream) 324 { 325 const struct qcom_stream_in *in = 326 reinterpret_cast<const struct qcom_stream_in *>(stream); 327 return (audio_format_t)in->qcom_in->format(); 328 } 329 330 static int in_set_format(struct audio_stream *stream, audio_format_t format) 331 { 332 struct qcom_stream_in *in = 333 reinterpret_cast<struct qcom_stream_in *>(stream); 334 ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); 335 /* TODO: implement me */ 336 return 0; 337 } 338 339 static int in_standby(struct audio_stream *stream) 340 { 341 struct qcom_stream_in *in = reinterpret_cast<struct qcom_stream_in *>(stream); 342 return in->qcom_in->standby(); 343 } 344 345 static int in_dump(const struct audio_stream *stream, int fd) 346 { 347 const struct qcom_stream_in *in = 348 reinterpret_cast<const struct qcom_stream_in *>(stream); 349 Vector<String16> args; 350 return in->qcom_in->dump(fd, args); 351 } 352 353 static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) 354 { 355 struct qcom_stream_in *in = 356 reinterpret_cast<struct qcom_stream_in *>(stream); 357 int val; 358 AudioParameter parms = AudioParameter(String8(kvpairs)); 359 String8 s8 = String8(kvpairs); 360 361 if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) { 362 val = convert_audio_device(val, HAL_API_REV_2_0, HAL_API_REV_1_0); 363 parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING)); 364 parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val); 365 s8 = parms.toString(); 366 } 367 368 return in->qcom_in->setParameters(s8); 369 } 370 371 static char * in_get_parameters(const struct audio_stream *stream, 372 const char *keys) 373 { 374 const struct qcom_stream_in *in = 375 reinterpret_cast<const struct qcom_stream_in *>(stream); 376 String8 s8; 377 int val; 378 379 s8 = in->qcom_in->getParameters(String8(keys)); 380 381 AudioParameter parms = AudioParameter(s8); 382 if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) { 383 val = convert_audio_device(val, HAL_API_REV_1_0, HAL_API_REV_2_0); 384 parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING)); 385 parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val); 386 s8 = parms.toString(); 387 } 388 389 return strdup(s8.string()); 390 } 391 392 static int in_set_gain(struct audio_stream_in *stream, float gain) 393 { 394 struct qcom_stream_in *in = 395 reinterpret_cast<struct qcom_stream_in *>(stream); 396 return in->qcom_in->setGain(gain); 397 } 398 399 static ssize_t in_read(struct audio_stream_in *stream, void* buffer, 400 size_t bytes) 401 { 402 struct qcom_stream_in *in = 403 reinterpret_cast<struct qcom_stream_in *>(stream); 404 return in->qcom_in->read(buffer, bytes); 405 } 406 407 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream) 408 { 409 struct qcom_stream_in *in = 410 reinterpret_cast<struct qcom_stream_in *>(stream); 411 return in->qcom_in->getInputFramesLost(); 412 } 413 414 static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 415 { 416 const struct qcom_stream_in *in = 417 reinterpret_cast<const struct qcom_stream_in *>(stream); 418 return in->qcom_in->addAudioEffect(effect); 419 } 420 421 static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 422 { 423 const struct qcom_stream_in *in = 424 reinterpret_cast<const struct qcom_stream_in *>(stream); 425 return in->qcom_in->removeAudioEffect(effect); 426 } 427 428 /** audio_hw_device implementation **/ 429 static inline struct qcom_audio_device * to_ladev(struct audio_hw_device *dev) 430 { 431 return reinterpret_cast<struct qcom_audio_device *>(dev); 432 } 433 434 static inline const struct qcom_audio_device * to_cladev(const struct audio_hw_device *dev) 435 { 436 return reinterpret_cast<const struct qcom_audio_device *>(dev); 437 } 438 439 static int adev_init_check(const struct audio_hw_device *dev) 440 { 441 const struct qcom_audio_device *qadev = to_cladev(dev); 442 443 return qadev->hwif->initCheck(); 444 } 445 446 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) 447 { 448 struct qcom_audio_device *qadev = to_ladev(dev); 449 return qadev->hwif->setVoiceVolume(volume); 450 } 451 452 static int adev_set_master_volume(struct audio_hw_device *dev, float volume) 453 { 454 struct qcom_audio_device *qadev = to_ladev(dev); 455 return qadev->hwif->setMasterVolume(volume); 456 } 457 458 static int adev_get_master_volume(struct audio_hw_device *dev, float *volume) { 459 460 struct qcom_audio_device *qadev = to_ladev(dev); 461 return qadev->hwif->getMasterVolume(volume); 462 } 463 464 #ifdef QCOM_FM_ENABLED 465 static int adev_set_fm_volume(struct audio_hw_device *dev, float volume) 466 { 467 struct qcom_audio_device *qadev = to_ladev(dev); 468 return qadev->hwif->setFmVolume(volume); 469 } 470 #endif 471 472 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode) 473 { 474 struct qcom_audio_device *qadev = to_ladev(dev); 475 return qadev->hwif->setMode(mode); 476 } 477 478 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state) 479 { 480 struct qcom_audio_device *qadev = to_ladev(dev); 481 return qadev->hwif->setMicMute(state); 482 } 483 484 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) 485 { 486 const struct qcom_audio_device *qadev = to_cladev(dev); 487 return qadev->hwif->getMicMute(state); 488 } 489 490 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) 491 { 492 struct qcom_audio_device *qadev = to_ladev(dev); 493 return qadev->hwif->setParameters(String8(kvpairs)); 494 } 495 496 static char * adev_get_parameters(const struct audio_hw_device *dev, 497 const char *keys) 498 { 499 const struct qcom_audio_device *qadev = to_cladev(dev); 500 String8 s8; 501 502 s8 = qadev->hwif->getParameters(String8(keys)); 503 return strdup(s8.string()); 504 } 505 506 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, 507 const struct audio_config *config) 508 { 509 const struct qcom_audio_device *qadev = to_cladev(dev); 510 uint8_t channelCount = popcount(config->channel_mask); 511 return qadev->hwif->getInputBufferSize(config->sample_rate, config->format, channelCount); 512 } 513 514 #ifdef QCOM_TUNNEL_LPA_ENABLED 515 static int adev_open_output_session(struct audio_hw_device *dev, 516 uint32_t devices, 517 int *format, 518 int sessionId, 519 uint32_t samplingRate, 520 uint32_t channels, 521 struct audio_stream_out **stream_out) 522 { 523 struct qcom_audio_device *qadev = to_ladev(dev); 524 status_t status; 525 struct qcom_stream_out *out; 526 int ret; 527 528 out = (struct qcom_stream_out *)calloc(1, sizeof(*out)); 529 if (!out) 530 return -ENOMEM; 531 532 out->qcom_out = qadev->hwif->openOutputSession(devices, format,&status,sessionId,samplingRate,channels); 533 if (!out->qcom_out) { 534 ret = status; 535 goto err_open; 536 } 537 538 out->stream.common.standby = out_standby; 539 out->stream.common.set_parameters = out_set_parameters; 540 out->stream.set_volume = out_set_volume; 541 542 *stream_out = &out->stream; 543 return 0; 544 545 err_open: 546 free(out); 547 *stream_out = NULL; 548 return ret; 549 } 550 #endif 551 552 static int adev_open_output_stream(struct audio_hw_device *dev, 553 audio_io_handle_t handle, 554 audio_devices_t devices, 555 audio_output_flags_t flags, 556 struct audio_config *config, 557 struct audio_stream_out **stream_out, 558 const char *address __unused) 559 { 560 struct qcom_audio_device *qadev = to_ladev(dev); 561 status_t status; 562 struct qcom_stream_out *out; 563 int ret; 564 565 out = (struct qcom_stream_out *)calloc(1, sizeof(*out)); 566 if (!out) 567 return -ENOMEM; 568 569 devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0); 570 status = static_cast<audio_output_flags_t> (flags); 571 572 out->qcom_out = qadev->hwif->openOutputStream(devices, 573 (int *)&config->format, 574 &config->channel_mask, 575 &config->sample_rate, 576 &status); 577 if (!out->qcom_out) { 578 ret = status; 579 goto err_open; 580 } 581 582 out->stream.common.get_sample_rate = out_get_sample_rate; 583 out->stream.common.set_sample_rate = out_set_sample_rate; 584 out->stream.common.get_buffer_size = out_get_buffer_size; 585 out->stream.common.get_channels = out_get_channels; 586 out->stream.common.get_format = out_get_format; 587 out->stream.common.set_format = out_set_format; 588 out->stream.common.standby = out_standby; 589 out->stream.common.dump = out_dump; 590 out->stream.common.set_parameters = out_set_parameters; 591 out->stream.common.get_parameters = out_get_parameters; 592 out->stream.common.add_audio_effect = out_add_audio_effect; 593 out->stream.common.remove_audio_effect = out_remove_audio_effect; 594 out->stream.get_latency = out_get_latency; 595 out->stream.set_volume = out_set_volume; 596 out->stream.write = out_write; 597 out->stream.get_render_position = out_get_render_position; 598 out->stream.get_next_write_timestamp = out_get_next_write_timestamp; 599 600 *stream_out = &out->stream; 601 return 0; 602 603 err_open: 604 free(out); 605 *stream_out = NULL; 606 return ret; 607 } 608 609 static void adev_close_output_stream(struct audio_hw_device *dev, 610 struct audio_stream_out* stream) 611 { 612 struct qcom_audio_device *qadev = to_ladev(dev); 613 struct qcom_stream_out *out = reinterpret_cast<struct qcom_stream_out *>(stream); 614 615 qadev->hwif->closeOutputStream(out->qcom_out); 616 free(out); 617 } 618 619 /** This method creates and opens the audio hardware input stream */ 620 static int adev_open_input_stream(struct audio_hw_device *dev, 621 audio_io_handle_t handle, 622 audio_devices_t devices, 623 audio_config *config, 624 audio_stream_in **stream_in, 625 audio_input_flags_t flags __unused, 626 const char *address __unused, 627 audio_source_t source __unused) 628 { 629 struct qcom_audio_device *qadev = to_ladev(dev); 630 status_t status; 631 struct qcom_stream_in *in; 632 int ret; 633 634 in = (struct qcom_stream_in *)calloc(1, sizeof(*in)); 635 if (!in) 636 return -ENOMEM; 637 638 devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0); 639 640 in->qcom_in = qadev->hwif->openInputStream(devices, (int *)&config->format, 641 &config->channel_mask, 642 &config->sample_rate, 643 &status, 644 (AudioSystem::audio_in_acoustics)0); 645 if (!in->qcom_in) { 646 ret = status; 647 goto err_open; 648 } 649 650 in->stream.common.get_sample_rate = in_get_sample_rate; 651 in->stream.common.set_sample_rate = in_set_sample_rate; 652 in->stream.common.get_buffer_size = in_get_buffer_size; 653 in->stream.common.get_channels = in_get_channels; 654 in->stream.common.get_format = in_get_format; 655 in->stream.common.set_format = in_set_format; 656 in->stream.common.standby = in_standby; 657 in->stream.common.dump = in_dump; 658 in->stream.common.set_parameters = in_set_parameters; 659 in->stream.common.get_parameters = in_get_parameters; 660 in->stream.common.add_audio_effect = in_add_audio_effect; 661 in->stream.common.remove_audio_effect = in_remove_audio_effect; 662 in->stream.set_gain = in_set_gain; 663 in->stream.read = in_read; 664 in->stream.get_input_frames_lost = in_get_input_frames_lost; 665 666 *stream_in = &in->stream; 667 return 0; 668 669 err_open: 670 free(in); 671 *stream_in = NULL; 672 return ret; 673 } 674 675 static void adev_close_input_stream(struct audio_hw_device *dev, 676 struct audio_stream_in *stream) 677 { 678 struct qcom_audio_device *qadev = to_ladev(dev); 679 struct qcom_stream_in *in = 680 reinterpret_cast<struct qcom_stream_in *>(stream); 681 682 qadev->hwif->closeInputStream(in->qcom_in); 683 free(in); 684 } 685 686 static int adev_dump(const struct audio_hw_device *dev, int fd) 687 { 688 const struct qcom_audio_device *qadev = to_cladev(dev); 689 Vector<String16> args; 690 691 return qadev->hwif->dumpState(fd, args); 692 } 693 694 static int qcom_adev_close(hw_device_t* device) 695 { 696 struct audio_hw_device *hwdev = 697 reinterpret_cast<struct audio_hw_device *>(device); 698 struct qcom_audio_device *qadev = to_ladev(hwdev); 699 700 if (!qadev) 701 return 0; 702 703 if (qadev->hwif) 704 delete qadev->hwif; 705 706 free(qadev); 707 return 0; 708 } 709 710 static int qcom_adev_open(const hw_module_t* module, const char* name, 711 hw_device_t** device) 712 { 713 struct qcom_audio_device *qadev; 714 int ret; 715 716 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) 717 return -EINVAL; 718 719 qadev = (struct qcom_audio_device *)calloc(1, sizeof(*qadev)); 720 if (!qadev) 721 return -ENOMEM; 722 723 qadev->device.common.tag = HARDWARE_DEVICE_TAG; 724 qadev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0; 725 qadev->device.common.module = const_cast<hw_module_t*>(module); 726 qadev->device.common.close = qcom_adev_close; 727 728 qadev->device.init_check = adev_init_check; 729 qadev->device.set_voice_volume = adev_set_voice_volume; 730 qadev->device.set_master_volume = adev_set_master_volume; 731 qadev->device.get_master_volume = adev_get_master_volume; 732 #ifdef QCOM_FM_ENABLED 733 qadev->device.set_fm_volume = adev_set_fm_volume; 734 #endif 735 qadev->device.set_mode = adev_set_mode; 736 qadev->device.set_mic_mute = adev_set_mic_mute; 737 qadev->device.get_mic_mute = adev_get_mic_mute; 738 qadev->device.set_parameters = adev_set_parameters; 739 qadev->device.get_parameters = adev_get_parameters; 740 qadev->device.get_input_buffer_size = adev_get_input_buffer_size; 741 qadev->device.open_output_stream = adev_open_output_stream; 742 #ifdef QCOM_TUNNEL_LPA_ENABLED 743 qadev->device.open_output_session = adev_open_output_session; 744 #endif 745 qadev->device.close_output_stream = adev_close_output_stream; 746 qadev->device.open_input_stream = adev_open_input_stream; 747 qadev->device.close_input_stream = adev_close_input_stream; 748 qadev->device.dump = adev_dump; 749 750 qadev->hwif = createAudioHardware(); 751 if (!qadev->hwif) { 752 ret = -EIO; 753 goto err_create_audio_hw; 754 } 755 756 *device = &qadev->device.common; 757 758 return 0; 759 760 err_create_audio_hw: 761 free(qadev); 762 return ret; 763 } 764 765 static struct hw_module_methods_t qcom_audio_module_methods = { 766 open: qcom_adev_open 767 }; 768 769 struct qcom_audio_module HAL_MODULE_INFO_SYM = { 770 module: { 771 common: { 772 tag: HARDWARE_MODULE_TAG, 773 module_api_version: AUDIO_MODULE_API_VERSION_0_1, 774 hal_api_version: HARDWARE_HAL_API_VERSION, 775 id: AUDIO_HARDWARE_MODULE_ID, 776 name: "QCOM Audio HW HAL", 777 author: "Code Aurora Forum", 778 methods: &qcom_audio_module_methods, 779 dso : NULL, 780 reserved : {0}, 781 }, 782 }, 783 }; 784 785 }; // extern "C" 786 787 }; // namespace android_audio_legacy 788