14765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* 24765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Copyright (C) 2011 The Android Open Source Project 34765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. 44765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * 54765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Licensed under the Apache License, Version 2.0 (the "License"); 64765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * you may not use this file except in compliance with the License. 74765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * You may obtain a copy of the License at 84765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * 94765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * http://www.apache.org/licenses/LICENSE-2.0 104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * 114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Unless required by applicable law or agreed to in writing, software 124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * distributed under the License is distributed on an "AS IS" BASIS, 134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * See the License for the specific language governing permissions and 154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * limitations under the License. 164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */ 174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 189746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#define LOG_TAG "qcom_audio_hw_hal" 194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev//#define LOG_NDEBUG 0 204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <stdint.h> 224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <hardware/hardware.h> 244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <system/audio.h> 254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <hardware/audio.h> 264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <hardware_legacy/AudioHardwareInterface.h> 284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <hardware_legacy/AudioSystemLegacy.h> 294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevnamespace android_audio_legacy { 314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevextern "C" { 334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstruct qcom_audio_module { 354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct audio_module module; 364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}; 374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstruct qcom_audio_device { 394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct audio_hw_device device; 404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct AudioHardwareInterface *hwif; 424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}; 434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstruct qcom_stream_out { 454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct audio_stream_out stream; 464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev AudioStreamOut *qcom_out; 484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}; 494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstruct qcom_stream_in { 514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct audio_stream_in stream; 524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev AudioStreamIn *qcom_in; 544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}; 554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 567801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent 577801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurentenum { 587801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent HAL_API_REV_1_0, 597801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent HAL_API_REV_2_0, 607801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent HAL_API_REV_NUM 617801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent} hal_api_rev; 627801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent 637801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurentstatic uint32_t audio_device_conv_table[][HAL_API_REV_NUM] = 647801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent{ 657801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent /* output devices */ 667801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_EARPIECE, AUDIO_DEVICE_OUT_EARPIECE }, 677801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_SPEAKER, AUDIO_DEVICE_OUT_SPEAKER }, 687801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_WIRED_HEADSET, AUDIO_DEVICE_OUT_WIRED_HEADSET }, 697801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_WIRED_HEADPHONE, AUDIO_DEVICE_OUT_WIRED_HEADPHONE }, 707801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO, AUDIO_DEVICE_OUT_BLUETOOTH_SCO }, 717801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET }, 727801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT }, 737801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP }, 747801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES }, 757801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER }, 767801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_AUX_DIGITAL, AUDIO_DEVICE_OUT_AUX_DIGITAL }, 777801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET, AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET }, 787801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET, AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET }, 797801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_DEFAULT, AUDIO_DEVICE_OUT_DEFAULT }, 807801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent#ifdef QCOM_ANC_HEADSET_ENABLED 817801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_ANC_HEADSET, AUDIO_DEVICE_OUT_ANC_HEADSET }, 827801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_ANC_HEADPHONE, AUDIO_DEVICE_OUT_ANC_HEADPHONE }, 837801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent#endif 847801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent#ifdef QCOM_FM_ENABLED 857801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_FM, AUDIO_DEVICE_OUT_FM }, 867801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent#endif 877801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent#ifdef QCOM_FM_TX_ENABLED 887801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_FM_TX, AUDIO_DEVICE_OUT_FM_TX }, 897801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent#endif 907801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent#ifdef QCOM_VOIP_ENABLED 917801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_DIRECTOUTPUT, AUDIO_DEVICE_OUT_DIRECTOUTPUT }, 927801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent#endif 937801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent#ifdef QCOM_PROXY_DEVICE_ENABLED 947801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_OUT_PROXY, AUDIO_DEVICE_OUT_PROXY }, 957801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent#endif 967801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent /* input devices */ 977801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_IN_COMMUNICATION, AUDIO_DEVICE_IN_COMMUNICATION }, 987801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_IN_AMBIENT, AUDIO_DEVICE_IN_AMBIENT }, 997801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_IN_BUILTIN_MIC, AUDIO_DEVICE_IN_BUILTIN_MIC }, 1007801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET }, 1017801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_WIRED_HEADSET }, 1027801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_IN_AUX_DIGITAL, AUDIO_DEVICE_IN_AUX_DIGITAL }, 1037801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_IN_VOICE_CALL, AUDIO_DEVICE_IN_VOICE_CALL }, 1047801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_IN_BACK_MIC, AUDIO_DEVICE_IN_BACK_MIC }, 1057801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_IN_DEFAULT, AUDIO_DEVICE_IN_DEFAULT }, 1067801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent#ifdef QCOM_ANC_HEADSET_ENABLED 1077801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_IN_ANC_HEADSET, AUDIO_DEVICE_IN_ANC_HEADSET }, 1087801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent#endif 1097801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent#ifdef QCOM_FM_ENABLED 1107801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_IN_FM_RX, AUDIO_DEVICE_IN_FM_RX }, 1117801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent { AudioSystem::DEVICE_IN_FM_RX_A2DP, AUDIO_DEVICE_IN_FM_RX_A2DP }, 1127801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent#endif 1137801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent}; 1147801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent 1157801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurentstatic uint32_t convert_audio_device(uint32_t from_device, int from_rev, int to_rev) 1167801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent{ 1177801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent const uint32_t k_num_devices = sizeof(audio_device_conv_table)/sizeof(uint32_t)/HAL_API_REV_NUM; 1187801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent uint32_t to_device = AUDIO_DEVICE_NONE; 1197801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent uint32_t in_bit = 0; 1207801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent 1217801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent if (from_rev != HAL_API_REV_1_0) { 1227801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent in_bit = from_device & AUDIO_DEVICE_BIT_IN; 1237801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent from_device &= ~AUDIO_DEVICE_BIT_IN; 1247801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent } 1257801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent 1267801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent while (from_device) { 1277801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent uint32_t i = 31 - __builtin_clz(from_device); 1287801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent uint32_t cur_device = (1 << i) | in_bit; 1297801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent 1307801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent for (i = 0; i < k_num_devices; i++) { 1317801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent if (audio_device_conv_table[i][from_rev] == cur_device) { 1327801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent to_device |= audio_device_conv_table[i][to_rev]; 1337801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent break; 1347801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent } 1357801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent } 1367801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent from_device &= ~cur_device; 1377801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent } 1387801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent return to_device; 1397801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent} 1407801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent 1414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/** audio_stream_out implementation **/ 1424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic uint32_t out_get_sample_rate(const struct audio_stream *stream) 1434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 1444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_stream_out *out = 1454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<const struct qcom_stream_out *>(stream); 1464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return out->qcom_out->sampleRate(); 1474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 1484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) 1504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 1514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_stream_out *out = 1524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<struct qcom_stream_out *>(stream); 1534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1544113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); 1554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev /* TODO: implement this */ 1564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return 0; 1574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 1584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic size_t out_get_buffer_size(const struct audio_stream *stream) 1604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 1614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_stream_out *out = 1624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<const struct qcom_stream_out *>(stream); 1634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return out->qcom_out->bufferSize(); 1644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 1654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic audio_channel_mask_t out_get_channels(const struct audio_stream *stream) 1674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 1684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_stream_out *out = 1694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<const struct qcom_stream_out *>(stream); 1704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return out->qcom_out->channels(); 1714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 1724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic audio_format_t out_get_format(const struct audio_stream *stream) 1744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 1754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_stream_out *out = 1764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<const struct qcom_stream_out *>(stream); 1774113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev return (audio_format_t)out->qcom_out->format(); 1784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 1794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int out_set_format(struct audio_stream *stream, audio_format_t format) 1814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 1824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_stream_out *out = 1834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<struct qcom_stream_out *>(stream); 1844113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); 1854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev /* TODO: implement me */ 1864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return 0; 1874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 1884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int out_standby(struct audio_stream *stream) 1904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 1914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_stream_out *out = 1924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<struct qcom_stream_out *>(stream); 1934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return out->qcom_out->standby(); 1944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 1954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int out_dump(const struct audio_stream *stream, int fd) 1974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 1984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_stream_out *out = 1994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<const struct qcom_stream_out *>(stream); 2004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev Vector<String16> args; 2014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return out->qcom_out->dump(fd, args); 2024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 2034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int out_set_parameters(struct audio_stream *stream, const char *kvpairs) 2054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 2064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_stream_out *out = 2074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<struct qcom_stream_out *>(stream); 2087801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent int val; 2097801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent String8 s8 = String8(kvpairs); 2107801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent AudioParameter parms = AudioParameter(String8(kvpairs)); 2117801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent 2127801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) { 2137801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent val = convert_audio_device(val, HAL_API_REV_2_0, HAL_API_REV_1_0); 2147801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING)); 2157801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val); 2167801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent s8 = parms.toString(); 2177801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent } 2187801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent 2197801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent return out->qcom_out->setParameters(s8); 2204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 2214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic char * out_get_parameters(const struct audio_stream *stream, const char *keys) 2234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 2244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_stream_out *out = 2254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<const struct qcom_stream_out *>(stream); 2264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev String8 s8; 2277801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent int val; 2287801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent 2294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev s8 = out->qcom_out->getParameters(String8(keys)); 2307801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent 2317801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent AudioParameter parms = AudioParameter(s8); 2327801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) { 2337801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent val = convert_audio_device(val, HAL_API_REV_1_0, HAL_API_REV_2_0); 2347801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING)); 2357801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val); 2367801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent s8 = parms.toString(); 2377801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent } 2387801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent 2394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return strdup(s8.string()); 2404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 2414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic uint32_t out_get_latency(const struct audio_stream_out *stream) 2434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 2444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_stream_out *out = 2454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<const struct qcom_stream_out *>(stream); 2464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return out->qcom_out->latency(); 2474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 2484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int out_set_volume(struct audio_stream_out *stream, float left, 2504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev float right) 2514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 2524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_stream_out *out = 2534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<struct qcom_stream_out *>(stream); 2544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return out->qcom_out->setVolume(left, right); 2554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 2564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic ssize_t out_write(struct audio_stream_out *stream, const void* buffer, 2584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev size_t bytes) 2594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 2604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_stream_out *out = 2614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<struct qcom_stream_out *>(stream); 2624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return out->qcom_out->write(buffer, bytes); 2634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 2644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int out_get_render_position(const struct audio_stream_out *stream, 2664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t *dsp_frames) 2674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 2684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_stream_out *out = 2694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<const struct qcom_stream_out *>(stream); 2704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return out->qcom_out->getRenderPosition(dsp_frames); 2714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 2724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 2744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 2754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return 0; 2764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 2774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 2794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 2804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return 0; 2814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 2824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int out_get_next_write_timestamp(const struct audio_stream_out *stream, 2844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int64_t *timestamp) 2854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 2869746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani const struct qcom_stream_out *out = 2879746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani reinterpret_cast<const struct qcom_stream_out *>(stream); 2889746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani return out->qcom_out->getNextWriteTimestamp(timestamp); 2894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 2904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/** audio_stream_in implementation **/ 2924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic uint32_t in_get_sample_rate(const struct audio_stream *stream) 2934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 2944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_stream_in *in = 2954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<const struct qcom_stream_in *>(stream); 2964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return in->qcom_in->sampleRate(); 2974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 2984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int in_set_sample_rate(struct audio_stream *stream, uint32_t rate) 3004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 3014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_stream_in *in = 3024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<struct qcom_stream_in *>(stream); 3034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3044113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); 3054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev /* TODO: implement this */ 3064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return 0; 3074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 3084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic size_t in_get_buffer_size(const struct audio_stream *stream) 3104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 3114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_stream_in *in = 3124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<const struct qcom_stream_in *>(stream); 3134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return in->qcom_in->bufferSize(); 3144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 3154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic audio_channel_mask_t in_get_channels(const struct audio_stream *stream) 3174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 3184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_stream_in *in = 3194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<const struct qcom_stream_in *>(stream); 3204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return in->qcom_in->channels(); 3214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 3224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic audio_format_t in_get_format(const struct audio_stream *stream) 3244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 3254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_stream_in *in = 3264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<const struct qcom_stream_in *>(stream); 3274113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev return (audio_format_t)in->qcom_in->format(); 3284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 3294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int in_set_format(struct audio_stream *stream, audio_format_t format) 3314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 3324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_stream_in *in = 3334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<struct qcom_stream_in *>(stream); 3344113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); 3354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev /* TODO: implement me */ 3364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return 0; 3374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 3384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int in_standby(struct audio_stream *stream) 3404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 3414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_stream_in *in = reinterpret_cast<struct qcom_stream_in *>(stream); 3424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return in->qcom_in->standby(); 3434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 3444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int in_dump(const struct audio_stream *stream, int fd) 3464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 3474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_stream_in *in = 3484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<const struct qcom_stream_in *>(stream); 3494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev Vector<String16> args; 3504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return in->qcom_in->dump(fd, args); 3514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 3524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int in_set_parameters(struct audio_stream *stream, const char *kvpairs) 3544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 3554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_stream_in *in = 3564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<struct qcom_stream_in *>(stream); 3577801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent int val; 3587801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent AudioParameter parms = AudioParameter(String8(kvpairs)); 3597801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent String8 s8 = String8(kvpairs); 3607801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent 3617801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) { 3627801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent val = convert_audio_device(val, HAL_API_REV_2_0, HAL_API_REV_1_0); 3637801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING)); 3647801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val); 3657801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent s8 = parms.toString(); 3667801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent } 3677801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent 3687801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent return in->qcom_in->setParameters(s8); 3694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 3704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic char * in_get_parameters(const struct audio_stream *stream, 3724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const char *keys) 3734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 3744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_stream_in *in = 3754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<const struct qcom_stream_in *>(stream); 3764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev String8 s8; 3777801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent int val; 3787801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent 3794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev s8 = in->qcom_in->getParameters(String8(keys)); 3807801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent 3817801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent AudioParameter parms = AudioParameter(s8); 3827801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) { 3837801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent val = convert_audio_device(val, HAL_API_REV_1_0, HAL_API_REV_2_0); 3847801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING)); 3857801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val); 3867801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent s8 = parms.toString(); 3877801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent } 3887801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent 3894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return strdup(s8.string()); 3904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 3914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int in_set_gain(struct audio_stream_in *stream, float gain) 3934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 3944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_stream_in *in = 3954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<struct qcom_stream_in *>(stream); 3964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return in->qcom_in->setGain(gain); 3974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 3984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic ssize_t in_read(struct audio_stream_in *stream, void* buffer, 4004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev size_t bytes) 4014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 4024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_stream_in *in = 4034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<struct qcom_stream_in *>(stream); 4044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return in->qcom_in->read(buffer, bytes); 4054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 4064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic uint32_t in_get_input_frames_lost(struct audio_stream_in *stream) 4084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 4094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_stream_in *in = 4104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<struct qcom_stream_in *>(stream); 4114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return in->qcom_in->getInputFramesLost(); 4124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 4134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 4154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 4164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_stream_in *in = 4174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<const struct qcom_stream_in *>(stream); 4184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return in->qcom_in->addAudioEffect(effect); 4194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 4204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 4224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 4234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_stream_in *in = 4244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<const struct qcom_stream_in *>(stream); 4254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return in->qcom_in->removeAudioEffect(effect); 4264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 4274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/** audio_hw_device implementation **/ 4294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic inline struct qcom_audio_device * to_ladev(struct audio_hw_device *dev) 4304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 4314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return reinterpret_cast<struct qcom_audio_device *>(dev); 4324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 4334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic inline const struct qcom_audio_device * to_cladev(const struct audio_hw_device *dev) 4354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 4364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return reinterpret_cast<const struct qcom_audio_device *>(dev); 4374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 4384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int adev_init_check(const struct audio_hw_device *dev) 4404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 4414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_audio_device *qadev = to_cladev(dev); 4424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return qadev->hwif->initCheck(); 4444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 4454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int adev_set_voice_volume(struct audio_hw_device *dev, float volume) 4474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 4484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_audio_device *qadev = to_ladev(dev); 4494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return qadev->hwif->setVoiceVolume(volume); 4504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 4514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int adev_set_master_volume(struct audio_hw_device *dev, float volume) 4534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 4544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_audio_device *qadev = to_ladev(dev); 4554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return qadev->hwif->setMasterVolume(volume); 4564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 4574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int adev_get_master_volume(struct audio_hw_device *dev, float *volume) { 4594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4604113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev struct qcom_audio_device *qadev = to_ladev(dev); 4614113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev return qadev->hwif->getMasterVolume(volume); 4624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 4639746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani 4649746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_FM_ENABLED 4654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int adev_set_fm_volume(struct audio_hw_device *dev, float volume) 4664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 4674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_audio_device *qadev = to_ladev(dev); 4684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return qadev->hwif->setFmVolume(volume); 4694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 4704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 4714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode) 4734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 4744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_audio_device *qadev = to_ladev(dev); 4754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return qadev->hwif->setMode(mode); 4764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 4774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int adev_set_mic_mute(struct audio_hw_device *dev, bool state) 4794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 4804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_audio_device *qadev = to_ladev(dev); 4814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return qadev->hwif->setMicMute(state); 4824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 4834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) 4854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 4864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_audio_device *qadev = to_cladev(dev); 4874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return qadev->hwif->getMicMute(state); 4884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 4894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) 4914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 4924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_audio_device *qadev = to_ladev(dev); 4934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return qadev->hwif->setParameters(String8(kvpairs)); 4944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 4954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic char * adev_get_parameters(const struct audio_hw_device *dev, 4974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const char *keys) 4984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 4994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_audio_device *qadev = to_cladev(dev); 5004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev String8 s8; 5014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev s8 = qadev->hwif->getParameters(String8(keys)); 5034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return strdup(s8.string()); 5044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 5054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, 5074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct audio_config *config) 5084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 5094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_audio_device *qadev = to_cladev(dev); 510ed3c0fdecb72890240d52a8ba3b5ecd05331736aSathishKumar Mani uint8_t channelCount = popcount(config->channel_mask); 511ed3c0fdecb72890240d52a8ba3b5ecd05331736aSathishKumar Mani return qadev->hwif->getInputBufferSize(config->sample_rate, config->format, channelCount); 5124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 5134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5149746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_TUNNEL_LPA_ENABLED 5154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int adev_open_output_session(struct audio_hw_device *dev, 5164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t devices, 5174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int *format, 5184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int sessionId, 5194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t samplingRate, 5204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t channels, 5214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct audio_stream_out **stream_out) 5224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 5234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_audio_device *qadev = to_ladev(dev); 5244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev status_t status; 5254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_stream_out *out; 5264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int ret; 5274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out = (struct qcom_stream_out *)calloc(1, sizeof(*out)); 5294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!out) 5304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -ENOMEM; 5314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->qcom_out = qadev->hwif->openOutputSession(devices, format,&status,sessionId,samplingRate,channels); 5334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!out->qcom_out) { 5344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ret = status; 5354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev goto err_open; 5364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.common.standby = out_standby; 5394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.common.set_parameters = out_set_parameters; 5404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.set_volume = out_set_volume; 5414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *stream_out = &out->stream; 5434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return 0; 5444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malcheverr_open: 5464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev free(out); 5474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *stream_out = NULL; 5484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return ret; 5494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 5504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 5514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int adev_open_output_stream(struct audio_hw_device *dev, 5534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev audio_io_handle_t handle, 5544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev audio_devices_t devices, 5554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev audio_output_flags_t flags, 5564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct audio_config *config, 5574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct audio_stream_out **stream_out) 5584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 5594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_audio_device *qadev = to_ladev(dev); 5604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev status_t status; 5614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_stream_out *out; 5624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int ret; 5634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out = (struct qcom_stream_out *)calloc(1, sizeof(*out)); 5654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!out) 5664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -ENOMEM; 5674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5687801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0); 5698861338c2a520669a870ee5f3e0c740e438c99bcSathishKumar Mani status = static_cast<audio_output_flags_t> (flags); 5707801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent 5714113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev out->qcom_out = qadev->hwif->openOutputStream(devices, 5724113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev (int *)&config->format, 5734113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev &config->channel_mask, 5744113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev &config->sample_rate, 5754113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev &status); 5764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!out->qcom_out) { 5774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ret = status; 5784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev goto err_open; 5794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.common.get_sample_rate = out_get_sample_rate; 5824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.common.set_sample_rate = out_set_sample_rate; 5834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.common.get_buffer_size = out_get_buffer_size; 5844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.common.get_channels = out_get_channels; 5854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.common.get_format = out_get_format; 5864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.common.set_format = out_set_format; 5874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.common.standby = out_standby; 5884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.common.dump = out_dump; 5894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.common.set_parameters = out_set_parameters; 5904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.common.get_parameters = out_get_parameters; 5914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.common.add_audio_effect = out_add_audio_effect; 5924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.common.remove_audio_effect = out_remove_audio_effect; 5934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.get_latency = out_get_latency; 5944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.set_volume = out_set_volume; 5954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.write = out_write; 5964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.get_render_position = out_get_render_position; 5974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev out->stream.get_next_write_timestamp = out_get_next_write_timestamp; 5984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *stream_out = &out->stream; 6004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return 0; 6014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malcheverr_open: 6034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev free(out); 6044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *stream_out = NULL; 6054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return ret; 6064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 6074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void adev_close_output_stream(struct audio_hw_device *dev, 6094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct audio_stream_out* stream) 6104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 6114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_audio_device *qadev = to_ladev(dev); 6124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_stream_out *out = reinterpret_cast<struct qcom_stream_out *>(stream); 6134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->hwif->closeOutputStream(out->qcom_out); 6154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev free(out); 6164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 6174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/** This method creates and opens the audio hardware input stream */ 6194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int adev_open_input_stream(struct audio_hw_device *dev, 6204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev audio_io_handle_t handle, 6214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev audio_devices_t devices, 6224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev audio_config *config, 6234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev audio_stream_in **stream_in) 6244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 6254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_audio_device *qadev = to_ladev(dev); 6264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev status_t status; 6274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_stream_in *in; 6284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int ret; 6294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev in = (struct qcom_stream_in *)calloc(1, sizeof(*in)); 6314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!in) 6324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -ENOMEM; 6334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6347801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0); 6357801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent 6364113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev in->qcom_in = qadev->hwif->openInputStream(devices, (int *)&config->format, 6374113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev &config->channel_mask, 6384113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev &config->sample_rate, 6394113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev &status, 6404113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev (AudioSystem::audio_in_acoustics)0); 6414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!in->qcom_in) { 6424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ret = status; 6434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev goto err_open; 6444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 6454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev in->stream.common.get_sample_rate = in_get_sample_rate; 6474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev in->stream.common.set_sample_rate = in_set_sample_rate; 6484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev in->stream.common.get_buffer_size = in_get_buffer_size; 6494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev in->stream.common.get_channels = in_get_channels; 6504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev in->stream.common.get_format = in_get_format; 6514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev in->stream.common.set_format = in_set_format; 6524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev in->stream.common.standby = in_standby; 6534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev in->stream.common.dump = in_dump; 6544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev in->stream.common.set_parameters = in_set_parameters; 6554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev in->stream.common.get_parameters = in_get_parameters; 6564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev in->stream.common.add_audio_effect = in_add_audio_effect; 6574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev in->stream.common.remove_audio_effect = in_remove_audio_effect; 6584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev in->stream.set_gain = in_set_gain; 6594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev in->stream.read = in_read; 6604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev in->stream.get_input_frames_lost = in_get_input_frames_lost; 6614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *stream_in = &in->stream; 6634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return 0; 6644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malcheverr_open: 6664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev free(in); 6674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *stream_in = NULL; 6684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return ret; 6694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 6704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void adev_close_input_stream(struct audio_hw_device *dev, 6724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct audio_stream_in *stream) 6734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 6744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_audio_device *qadev = to_ladev(dev); 6754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_stream_in *in = 6764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<struct qcom_stream_in *>(stream); 6774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->hwif->closeInputStream(in->qcom_in); 6794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev free(in); 6804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 6814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int adev_dump(const struct audio_hw_device *dev, int fd) 6834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 6844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev const struct qcom_audio_device *qadev = to_cladev(dev); 6854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev Vector<String16> args; 6864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return qadev->hwif->dumpState(fd, args); 6884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 6894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int qcom_adev_close(hw_device_t* device) 6914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 6924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct audio_hw_device *hwdev = 6934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reinterpret_cast<struct audio_hw_device *>(device); 6944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_audio_device *qadev = to_ladev(hwdev); 6954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!qadev) 6974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return 0; 6984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (qadev->hwif) 7004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev delete qadev->hwif; 7014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev free(qadev); 7034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return 0; 7044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 7054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int qcom_adev_open(const hw_module_t* module, const char* name, 7074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev hw_device_t** device) 7084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 7094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct qcom_audio_device *qadev; 7104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int ret; 7114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) 7134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -EINVAL; 7144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev = (struct qcom_audio_device *)calloc(1, sizeof(*qadev)); 7164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!qadev) 7174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -ENOMEM; 7184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.common.tag = HARDWARE_DEVICE_TAG; 7207801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent qadev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0; 7214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.common.module = const_cast<hw_module_t*>(module); 7224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.common.close = qcom_adev_close; 7234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.init_check = adev_init_check; 7254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.set_voice_volume = adev_set_voice_volume; 7264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.set_master_volume = adev_set_master_volume; 7274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.get_master_volume = adev_get_master_volume; 7289746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_FM_ENABLED 7294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.set_fm_volume = adev_set_fm_volume; 7304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 7314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.set_mode = adev_set_mode; 7324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.set_mic_mute = adev_set_mic_mute; 7334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.get_mic_mute = adev_get_mic_mute; 7344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.set_parameters = adev_set_parameters; 7354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.get_parameters = adev_get_parameters; 7364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.get_input_buffer_size = adev_get_input_buffer_size; 7374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.open_output_stream = adev_open_output_stream; 7389746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_TUNNEL_LPA_ENABLED 7394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.open_output_session = adev_open_output_session; 7404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 7414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.close_output_stream = adev_close_output_stream; 7424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.open_input_stream = adev_open_input_stream; 7434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.close_input_stream = adev_close_input_stream; 7444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->device.dump = adev_dump; 7454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev qadev->hwif = createAudioHardware(); 7474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!qadev->hwif) { 7484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ret = -EIO; 7494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev goto err_create_audio_hw; 7504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 7514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *device = &qadev->device.common; 7534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return 0; 7554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malcheverr_create_audio_hw: 7574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev free(qadev); 7584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return ret; 7594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 7604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic struct hw_module_methods_t qcom_audio_module_methods = { 7624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev open: qcom_adev_open 7634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}; 7644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstruct qcom_audio_module HAL_MODULE_INFO_SYM = { 7664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev module: { 7674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev common: { 7684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev tag: HARDWARE_MODULE_TAG, 7697801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent module_api_version: AUDIO_MODULE_API_VERSION_0_1, 7707801df9b35653562139ddaaa5c29c61f0eddc92fEric Laurent hal_api_version: HARDWARE_HAL_API_VERSION, 7714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev id: AUDIO_HARDWARE_MODULE_ID, 7724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev name: "QCOM Audio HW HAL", 7734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev author: "Code Aurora Forum", 7744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev methods: &qcom_audio_module_methods, 7754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev dso : NULL, 7764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev reserved : {0}, 7774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev }, 7784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev }, 7794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}; 7804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}; // extern "C" 7824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 7834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}; // namespace android_audio_legacy 784