blob: 3115b14f60e245be53fe7523c7fec6e805831de0 [file] [log] [blame]
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001/*
Susan Wang6dd13092021-01-25 10:27:11 -05002 * Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07003 * Not a Contribution.
4 *
5 * Copyright (C) 2013 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Jitendra Naruka1b6513f2014-11-22 19:34:13 -080018 *
19 * This file was modified by DTS, Inc. The portions of the
20 * code modified by DTS, Inc are copyrighted and
21 * licensed separately, as follows:
22 *
23 * (C) 2014 DTS, Inc.
24 *
25 * Licensed under the Apache License, Version 2.0 (the "License");
26 * you may not use this file except in compliance with the License.
27 * You may obtain a copy of the License at
28 *
29 * http://www.apache.org/licenses/LICENSE-2.0
30 *
31 * Unless required by applicable law or agreed to in writing, software
32 * distributed under the License is distributed on an "AS IS" BASIS,
33 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34 * See the License for the specific language governing permissions and
35 * limitations under the License.
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -070036 */
37
Xu,Baochu235aec62022-02-14 10:20:44 +080038/*
39* Changes from Qualcomm Innovation Center are provided under the following license:
40*
Subhadra Jagadeesan63a1e832023-01-13 11:26:38 +053041* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
Xu,Baochu235aec62022-02-14 10:20:44 +080042*
43* Redistribution and use in source and binary forms, with or without
44* modification, are permitted (subject to the limitations in the
45* disclaimer below) provided that the following conditions are met:
46*
47* * Redistributions of source code must retain the above copyright
48* notice, this list of conditions and the following disclaimer.
49*
50* * Redistributions in binary form must reproduce the above
51* copyright notice, this list of conditions and the following
52* disclaimer in the documentation and/or other materials provided
53* with the distribution.
54*
55* * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
56* contributors may be used to endorse or promote products derived
57* from this software without specific prior written permission.
58*
59* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
60* GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
61* HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
62* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
63* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
64* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
65* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
66* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
67* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
68* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
69* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
70* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
71* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72*/
73
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -070074#define LOG_TAG "audio_hw_extn"
75/*#define LOG_NDEBUG 0*/
76#define LOG_NDDEBUG 0
77
78#include <stdlib.h>
79#include <errno.h>
Sudheer Papothi390bcf32014-12-04 01:25:17 +053080#include <dlfcn.h>
Mingming Yin00611c32015-10-30 17:10:53 -070081#include <fcntl.h>
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -070082#include <cutils/properties.h>
Aalique Grahame22e49102018-12-18 14:23:57 -080083#include <log/log.h>
LuK1337994b0762021-05-28 08:01:40 +020084#include <pthread.h>
Vinay Vermaaddfa4a2018-04-29 14:03:38 +053085#include <unistd.h>
Weiyin Jiang29c08a42019-04-30 17:11:10 +080086#include <sched.h>
Dhanalakshmi Siddani999d5642019-03-22 15:27:44 +053087
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -070088#include "audio_hw.h"
89#include "audio_extn.h"
Arun Mirpurib1bec9c2019-01-29 16:42:45 -080090#include "voice_extn.h"
Ben Rombergerd771a7c2017-02-22 18:05:17 -080091#include "audio_defs.h"
Venkata Narendra Kumar Gutta88fd0bc2014-03-27 19:47:56 +053092#include "platform.h"
93#include "platform_api.h"
Pradnya Chaphekar4403bd72014-09-09 09:50:01 -070094#include "edid.h"
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +053095#include "sound/compress_params.h"
96
Xiaojun Sang782e5b12020-06-29 21:13:06 +080097#ifdef AUDIO_GKI_ENABLED
98#include "sound/audio_compressed_formats.h"
99#endif
100
Revathi Uddaraju1eac8b02017-05-18 17:13:33 +0530101#ifdef DYNAMIC_LOG_ENABLED
102#include <log_xml_parser.h>
103#define LOG_MASK HAL_MOD_FILE_AUDIO_EXTN
104#include <log_utils.h>
105#endif
106
Fei Tongc20ce932021-06-21 16:42:38 +0800107#ifdef LINUX_ENABLED
108#include "audio_stub.h"
109#endif
110
Damir Didjustof1d46c72013-11-06 17:59:04 -0800111#define MAX_SLEEP_RETRY 100
112#define WIFI_INIT_WAIT_SLEEP 50
Surendar Karkaf51b5842018-04-26 11:28:38 +0530113#define MAX_NUM_CHANNELS 8
114#define Q14_GAIN_UNITY 0x4000
Damir Didjustof1d46c72013-11-06 17:59:04 -0800115
Weiyin Jiangd5718bd2019-09-04 16:52:08 +0800116static int vendor_enhanced_info = 0;
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800117static bool is_compress_meta_data_enabled = false;
118
Aalique Grahame22e49102018-12-18 14:23:57 -0800119struct snd_card_split cur_snd_card_split = {
120 .device = {0},
121 .snd_card = {0},
122 .form_factor = {0},
Sujin Panickerb904fbe2019-04-04 13:28:07 +0530123 .variant = {0},
Aalique Grahame22e49102018-12-18 14:23:57 -0800124};
125
126struct snd_card_split *audio_extn_get_snd_card_split()
127{
128 return &cur_snd_card_split;
129}
130
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800131void fm_set_parameters(struct audio_device *adev,
132 struct str_parms *parms);
133void fm_get_parameters(struct str_parms *query, struct str_parms *reply);
134
135void keep_alive_init(struct audio_device *adev);
136void keep_alive_deinit();
137void keep_alive_start(ka_mode_t ka_mode);
138void keep_alive_stop(ka_mode_t ka_mode);
139int keep_alive_set_parameters(struct audio_device *adev,
140 struct str_parms *parms);
141
Arun Mirpurie008ed22019-03-21 11:21:04 -0700142bool cin_applicable_stream(struct stream_in *in);
Dhananjay Kumar7dbe3562019-08-30 05:49:33 +0530143bool cin_attached_usecase(struct stream_in *in);
Arun Mirpurie008ed22019-03-21 11:21:04 -0700144bool cin_format_supported(audio_format_t format);
Dhananjay Kumar7dbe3562019-08-30 05:49:33 +0530145int cin_acquire_usecase(struct stream_in *in);
Arun Mirpurie008ed22019-03-21 11:21:04 -0700146size_t cin_get_buffer_size(struct stream_in *in);
Manish Dewangan46e07982018-12-13 18:18:59 +0530147int cin_open_input_stream(struct stream_in *in);
Arun Mirpurie008ed22019-03-21 11:21:04 -0700148void cin_stop_input_stream(struct stream_in *in);
149void cin_close_input_stream(struct stream_in *in);
Manish Dewangan46e07982018-12-13 18:18:59 +0530150void cin_free_input_stream_resources(struct stream_in *in);
Arun Mirpurie008ed22019-03-21 11:21:04 -0700151int cin_read(struct stream_in *in, void *buffer,
152 size_t bytes, size_t *bytes_read);
Deeraj Soman14230922019-01-30 16:39:30 +0530153int cin_configure_input_stream(struct stream_in *in, struct audio_config *in_config);
Arun Mirpurie008ed22019-03-21 11:21:04 -0700154
Aalique Grahame22e49102018-12-18 14:23:57 -0800155void audio_extn_set_snd_card_split(const char* in_snd_card_name)
156{
157 /* sound card name follows below mentioned convention
158 <target name>-<sound card name>-<form factor>-snd-card
159 parse target name, sound card name and form factor
160 */
Weiyin Jiang2995f662019-04-17 14:25:12 +0800161 char *snd_card_name = NULL;
Aalique Grahame22e49102018-12-18 14:23:57 -0800162 char *tmp = NULL;
163 char *device = NULL;
164 char *snd_card = NULL;
165 char *form_factor = NULL;
Sujin Panickerb904fbe2019-04-04 13:28:07 +0530166 char *variant = NULL;
Aalique Grahame22e49102018-12-18 14:23:57 -0800167
168 if (in_snd_card_name == NULL) {
169 ALOGE("%s: snd_card_name passed is NULL", __func__);
170 goto on_error;
171 }
Weiyin Jiang2995f662019-04-17 14:25:12 +0800172 snd_card_name = strdup(in_snd_card_name);
Aalique Grahame22e49102018-12-18 14:23:57 -0800173
174 device = strtok_r(snd_card_name, "-", &tmp);
175 if (device == NULL) {
176 ALOGE("%s: called on invalid snd card name", __func__);
177 goto on_error;
178 }
179 strlcpy(cur_snd_card_split.device, device, HW_INFO_ARRAY_MAX_SIZE);
180
181 snd_card = strtok_r(NULL, "-", &tmp);
182 if (snd_card == NULL) {
183 ALOGE("%s: called on invalid snd card name", __func__);
184 goto on_error;
185 }
186 strlcpy(cur_snd_card_split.snd_card, snd_card, HW_INFO_ARRAY_MAX_SIZE);
187
188 form_factor = strtok_r(NULL, "-", &tmp);
189 if (form_factor == NULL) {
190 ALOGE("%s: called on invalid snd card name", __func__);
191 goto on_error;
192 }
193 strlcpy(cur_snd_card_split.form_factor, form_factor, HW_INFO_ARRAY_MAX_SIZE);
194
Sujin Panickerb904fbe2019-04-04 13:28:07 +0530195 variant = strtok_r(NULL, "-", &tmp);
196 if (variant != NULL) {
197 strlcpy(cur_snd_card_split.variant, variant, HW_INFO_ARRAY_MAX_SIZE);
198 }
199
Aalique Grahame22e49102018-12-18 14:23:57 -0800200 ALOGI("%s: snd_card_name(%s) device(%s) snd_card(%s) form_factor(%s)",
201 __func__, in_snd_card_name, device, snd_card, form_factor);
202
203on_error:
204 if (snd_card_name)
205 free(snd_card_name);
206}
207
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700208struct audio_extn_module {
209 bool anc_enabled;
210 bool aanc_enabled;
Jitendra Singh Naruka9a6a8d42014-02-10 20:07:12 -0800211 bool custom_stereo_enabled;
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700212 uint32_t proxy_channel_num;
Jitendra Naruka1b6513f2014-11-22 19:34:13 -0800213 bool hpx_enabled;
Banajit Goswami20cdd212015-09-11 01:11:30 -0700214 bool vbat_enabled;
Aditya Bavanari9b589022018-09-20 08:47:55 +0530215 bool bcl_enabled;
Venkata Narendra Kumar Gutta4bd09d02016-01-29 15:31:04 +0530216 bool hifi_audio_enabled;
Srinivas Julakanti1ca769a2017-01-04 23:18:08 -0800217 bool ras_enabled;
Dhanalakshmi Siddani18737932016-11-29 17:33:17 +0530218 struct aptx_dec_bt_addr addr;
Aalique Grahame404a15e2017-05-18 11:28:27 -0700219 struct audio_device *adev;
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700220};
221
Dhanalakshmi Siddani0b1488e2016-09-06 12:58:42 +0530222static struct audio_extn_module aextnmod;
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800223static bool audio_extn_fm_power_opt_enabled = false;
224static bool audio_extn_keep_alive_enabled = false;
225static bool audio_extn_hifi_audio_enabled = false;
226static bool audio_extn_ras_feature_enabled = false;
227static bool audio_extn_kpi_optimize_feature_enabled = false;
228static bool audio_extn_display_port_feature_enabled = false;
229static bool audio_extn_fluence_feature_enabled = false;
230static bool audio_extn_custom_stereo_feature_enabled = false;
231static bool audio_extn_anc_headset_feature_enabled = false;
232static bool audio_extn_vbat_enabled = false;
Sujin Panickerb904fbe2019-04-04 13:28:07 +0530233static bool audio_extn_wsa_enabled = false;
Arun Mirpurie008ed22019-03-21 11:21:04 -0700234static bool audio_extn_record_play_concurrency_enabled = false;
235static bool audio_extn_hdmi_passthru_enabled = false;
236static bool audio_extn_concurrent_capture_enabled = false;
237static bool audio_extn_compress_in_enabled = false;
238static bool audio_extn_battery_listener_enabled = false;
Arun Mirpurid750ac52019-04-12 18:33:55 -0700239static bool audio_extn_maxx_audio_enabled = false;
vivek mehtaba5ed152019-05-03 17:28:25 -0700240static bool audio_extn_audiozoom_enabled = false;
Ramlal Karraab51d042019-08-08 19:02:35 +0530241static bool audio_extn_hifi_filter_enabled = false;
Krishna Kishor Jha0f4d8482022-02-18 10:56:05 +0530242static bool audio_extn_concurrent_pcm_record_enabled = false;
Kogara Naveen Kumarc5758232022-11-07 20:25:40 +0530243static bool audio_extn_concurrent_low_latency_pcm_record_enabled = false;
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700244
Sudheer Papothid63caef2018-05-15 00:41:52 +0530245#define AUDIO_PARAMETER_KEY_AANC_NOISE_LEVEL "aanc_noise_level"
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700246#define AUDIO_PARAMETER_KEY_ANC "anc_enabled"
247#define AUDIO_PARAMETER_KEY_WFD "wfd_channel_cap"
248#define AUDIO_PARAMETER_CAN_OPEN_PROXY "can_open_proxy"
Jitendra Singh Naruka9a6a8d42014-02-10 20:07:12 -0800249#define AUDIO_PARAMETER_CUSTOM_STEREO "stereo_as_dual_mono"
Subhash Chandra Bose Naripeddy16ff4f82014-04-01 21:03:10 -0700250/* Query offload playback instances count */
251#define AUDIO_PARAMETER_OFFLOAD_NUM_ACTIVE "offload_num_active"
Jitendra Naruka1b6513f2014-11-22 19:34:13 -0800252#define AUDIO_PARAMETER_HPX "HPX"
Dhanalakshmi Siddani18737932016-11-29 17:33:17 +0530253#define AUDIO_PARAMETER_APTX_DEC_BT_ADDR "bt_addr"
Jitendra Singh Naruka9a6a8d42014-02-10 20:07:12 -0800254
Mingming Yin00611c32015-10-30 17:10:53 -0700255/*
256* update sysfs node hdmi_audio_cb to enable notification acknowledge feature
257* bit(5) set to 1 to enable this feature
258* bit(4) set to 1 to enable acknowledgement
259* this is done only once at the first connect event
260*
261* bit(0) set to 1 when HDMI cable is connected
262* bit(0) set to 0 when HDMI cable is disconnected
263* this is done when device switch happens by setting audioparamter
264*/
265
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800266#define IS_BIT_SET(NUM, bitno) (NUM & (1 << bitno))
267
Vignesh Kulothungan39fc6a22019-08-01 00:55:59 -0700268#define EXT_DISPLAY_PLUG_STATUS_NOTIFY_ENABLE 0x30
269#define EXT_DISPLAY_PLUG_STATUS_NOTIFY_CONNECT 0x01
270#define EXT_DISPLAY_PLUG_STATUS_NOTIFY_DISCONNECT 0x00
Mingming Yin00611c32015-10-30 17:10:53 -0700271
272static ssize_t update_sysfs_node(const char *path, const char *data, size_t len)
273{
274 ssize_t err = 0;
275 int fd = -1;
276
277 err = access(path, W_OK);
278 if (!err) {
279 fd = open(path, O_WRONLY);
280 errno = 0;
281 err = write(fd, data, len);
282 if (err < 0) {
283 err = -errno;
284 }
285 close(fd);
286 } else {
287 ALOGE("%s: Failed to access path: %s error: %s",
288 __FUNCTION__, path, strerror(errno));
289 err = -errno;
290 }
291
292 return err;
293}
294
Shiv Maliyappanahallic0656402016-09-03 14:13:26 -0700295static int get_ext_disp_sysfs_node_index(int ext_disp_type)
Mingming Yin00611c32015-10-30 17:10:53 -0700296{
Shiv Maliyappanahallic0656402016-09-03 14:13:26 -0700297 int node_index = -1;
Mingming Yin00611c32015-10-30 17:10:53 -0700298 char fbvalue[80] = {0};
299 char fbpath[80] = {0};
300 int i = 0;
Shiv Maliyappanahallic0656402016-09-03 14:13:26 -0700301 FILE *ext_disp_fd = NULL;
Mingming Yin00611c32015-10-30 17:10:53 -0700302
Garmond Leung37850ab2016-10-06 11:42:18 -0700303 while (1) {
Mingming Yin00611c32015-10-30 17:10:53 -0700304 snprintf(fbpath, sizeof(fbpath),
305 "/sys/class/graphics/fb%d/msm_fb_type", i);
Shiv Maliyappanahallic0656402016-09-03 14:13:26 -0700306 ext_disp_fd = fopen(fbpath, "r");
307 if (ext_disp_fd) {
308 if (fread(fbvalue, sizeof(char), 80, ext_disp_fd)) {
309 if(((strncmp(fbvalue, "dtv panel", strlen("dtv panel")) == 0) &&
310 (ext_disp_type == EXT_DISPLAY_TYPE_HDMI)) ||
311 ((strncmp(fbvalue, "dp panel", strlen("dp panel")) == 0) &&
312 (ext_disp_type == EXT_DISPLAY_TYPE_DP))) {
313 node_index = i;
314 ALOGD("%s: Ext Disp:%d is at fb%d", __func__, ext_disp_type, i);
315 fclose(ext_disp_fd);
316 return node_index;
317 }
Mingming Yin00611c32015-10-30 17:10:53 -0700318 }
Shiv Maliyappanahallic0656402016-09-03 14:13:26 -0700319 fclose(ext_disp_fd);
Garmond Leung37850ab2016-10-06 11:42:18 -0700320 i++;
Mingming Yin00611c32015-10-30 17:10:53 -0700321 } else {
Garmond Leung37850ab2016-10-06 11:42:18 -0700322 ALOGE("%s: Scanned till end of fbs or Failed to open fb node %d", __func__, i);
323 break;
Mingming Yin00611c32015-10-30 17:10:53 -0700324 }
325 }
326
327 return -1;
328}
329
Vignesh Kulothungan39fc6a22019-08-01 00:55:59 -0700330static int update_ext_disp_sysfs_node(const struct audio_device *adev,
331 int node_value, int controller, int stream)
Mingming Yin00611c32015-10-30 17:10:53 -0700332{
Shiv Maliyappanahallic0656402016-09-03 14:13:26 -0700333 char ext_disp_ack_path[80] = {0};
334 char ext_disp_ack_value[3] = {0};
Mingming Yin00611c32015-10-30 17:10:53 -0700335 int index, ret = -1;
Vignesh Kulothungan39fc6a22019-08-01 00:55:59 -0700336 int ext_disp_type = platform_get_ext_disp_type_v2(adev->platform, controller,
337 stream);
Mingming Yin00611c32015-10-30 17:10:53 -0700338
Shiv Maliyappanahallic0656402016-09-03 14:13:26 -0700339 if (ext_disp_type < 0) {
340 ALOGE("%s, Unable to get the external display type, err:%d",
341 __func__, ext_disp_type);
342 return -EINVAL;
343 }
Mingming Yin00611c32015-10-30 17:10:53 -0700344
Shiv Maliyappanahallic0656402016-09-03 14:13:26 -0700345 index = get_ext_disp_sysfs_node_index(ext_disp_type);
Mingming Yin00611c32015-10-30 17:10:53 -0700346 if (index >= 0) {
Shiv Maliyappanahallic0656402016-09-03 14:13:26 -0700347 snprintf(ext_disp_ack_value, sizeof(ext_disp_ack_value), "%d", node_value);
348 snprintf(ext_disp_ack_path, sizeof(ext_disp_ack_path),
Mingming Yin00611c32015-10-30 17:10:53 -0700349 "/sys/class/graphics/fb%d/hdmi_audio_cb", index);
350
Shiv Maliyappanahallic0656402016-09-03 14:13:26 -0700351 ret = update_sysfs_node(ext_disp_ack_path, ext_disp_ack_value,
352 sizeof(ext_disp_ack_value));
Mingming Yin00611c32015-10-30 17:10:53 -0700353
354 ALOGI("update hdmi_audio_cb at fb[%d] to:[%d] %s",
355 index, node_value, (ret >= 0) ? "success":"fail");
356 }
357
358 return ret;
359}
360
Vignesh Kulothungan39fc6a22019-08-01 00:55:59 -0700361static int update_audio_ack_state(const struct audio_device *adev,
362 int node_value,
363 int controller,
364 int stream)
Kuirong Wang9426c292017-02-07 10:39:15 -0800365{
Kuirong Wang9426c292017-02-07 10:39:15 -0800366 int ret = 0;
Vignesh Kulothungan39fc6a22019-08-01 00:55:59 -0700367 int ctl_index = 0;
368 struct mixer_ctl *ctl = NULL;
369 const char *ctl_prefix = "External Display";
370 const char *ctl_suffix = "Audio Ack";
371 char mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0};
Kuirong Wang9426c292017-02-07 10:39:15 -0800372
Vignesh Kulothungan39fc6a22019-08-01 00:55:59 -0700373 ctl_index = platform_get_display_port_ctl_index(controller, stream);
374 if (-EINVAL == ctl_index) {
375 ALOGE("%s: Unknown controller/stream %d/%d",
376 __func__, controller, stream);
377 return -EINVAL;
378 }
379
380 if (0 == ctl_index)
381 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
382 "%s %s", ctl_prefix, ctl_suffix);
383 else
384 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
385 "%s%d %s", ctl_prefix, ctl_index, ctl_suffix);
386
387 ALOGV("%s: mixer ctl name: %s", __func__, mixer_ctl_name);
Kuirong Wang9426c292017-02-07 10:39:15 -0800388 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
389 /* If no mixer command support, fall back to sysfs node approach */
390 if (!ctl) {
391 ALOGI("%s: could not get ctl for mixer cmd(%s), use sysfs node instead\n",
392 __func__, mixer_ctl_name);
Vignesh Kulothungan39fc6a22019-08-01 00:55:59 -0700393 ret = update_ext_disp_sysfs_node(adev, node_value, controller, stream);
Kuirong Wang9426c292017-02-07 10:39:15 -0800394 } else {
395 char *ack_str = NULL;
396
397 if (node_value == EXT_DISPLAY_PLUG_STATUS_NOTIFY_ENABLE)
398 ack_str = "Ack_Enable";
Vignesh Kulothungan39fc6a22019-08-01 00:55:59 -0700399 else if (node_value == EXT_DISPLAY_PLUG_STATUS_NOTIFY_CONNECT)
Kuirong Wang9426c292017-02-07 10:39:15 -0800400 ack_str = "Connect";
Vignesh Kulothungan39fc6a22019-08-01 00:55:59 -0700401 else if (node_value == EXT_DISPLAY_PLUG_STATUS_NOTIFY_DISCONNECT)
Kuirong Wang9426c292017-02-07 10:39:15 -0800402 ack_str = "Disconnect";
403 else {
404 ALOGE("%s: Invalid input parameter - 0x%x\n",
405 __func__, node_value);
406 return -EINVAL;
407 }
408
409 ret = mixer_ctl_set_enum_by_string(ctl, ack_str);
410 if (ret)
411 ALOGE("%s: Could not set ctl for mixer cmd - %s ret %d\n",
412 __func__, mixer_ctl_name, ret);
413 }
414 return ret;
415}
416
Garmond Leunge3b6d482016-10-25 16:48:01 -0700417static void audio_extn_ext_disp_set_parameters(const struct audio_device *adev,
Shiv Maliyappanahallic0656402016-09-03 14:13:26 -0700418 struct str_parms *parms)
Mingming Yin00611c32015-10-30 17:10:53 -0700419{
Vignesh Kulothungan39fc6a22019-08-01 00:55:59 -0700420 int controller = 0;
421 int stream = 0;
Mingming Yin00611c32015-10-30 17:10:53 -0700422 char value[32] = {0};
423 static bool is_hdmi_sysfs_node_init = false;
424
425 if (str_parms_get_str(parms, "connect", value, sizeof(value)) >= 0
Shiv Maliyappanahallic0656402016-09-03 14:13:26 -0700426 && (atoi(value) & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
427 //params = "connect=1024" for external display connection.
Vignesh Kulothungan39fc6a22019-08-01 00:55:59 -0700428 platform_get_controller_stream_from_params(parms, &controller, &stream);
Mingming Yin00611c32015-10-30 17:10:53 -0700429 if (is_hdmi_sysfs_node_init == false) {
Shiv Maliyappanahallic0656402016-09-03 14:13:26 -0700430 //check if this is different for dp and hdmi
Mingming Yin00611c32015-10-30 17:10:53 -0700431 is_hdmi_sysfs_node_init = true;
Vignesh Kulothungan39fc6a22019-08-01 00:55:59 -0700432 update_audio_ack_state(adev,
433 EXT_DISPLAY_PLUG_STATUS_NOTIFY_ENABLE,
434 controller, stream);
Mingming Yin00611c32015-10-30 17:10:53 -0700435 }
Vignesh Kulothungan39fc6a22019-08-01 00:55:59 -0700436 update_audio_ack_state(adev, EXT_DISPLAY_PLUG_STATUS_NOTIFY_CONNECT,
437 controller, stream);
Mingming Yin00611c32015-10-30 17:10:53 -0700438 } else if(str_parms_get_str(parms, "disconnect", value, sizeof(value)) >= 0
Shiv Maliyappanahallic0656402016-09-03 14:13:26 -0700439 && (atoi(value) & AUDIO_DEVICE_OUT_AUX_DIGITAL)){
440 //params = "disconnect=1024" for external display disconnection.
Vignesh Kulothungan39fc6a22019-08-01 00:55:59 -0700441 platform_get_controller_stream_from_params(parms, &controller, &stream);
442 update_audio_ack_state(adev, EXT_DISPLAY_PLUG_STATUS_NOTIFY_DISCONNECT,
443 controller, stream);
Garmond Leunge3b6d482016-10-25 16:48:01 -0700444 ALOGV("invalidate cached edid");
Vignesh Kulothungan39fc6a22019-08-01 00:55:59 -0700445 platform_invalidate_hdmi_config_v2(adev->platform, controller, stream);
Mingming Yin00611c32015-10-30 17:10:53 -0700446 } else {
Shiv Maliyappanahallic0656402016-09-03 14:13:26 -0700447 // handle ext disp devices only
Mingming Yin00611c32015-10-30 17:10:53 -0700448 return;
449 }
450}
451
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +0530452static int update_custom_mtmx_coefficients_v2(struct audio_device *adev,
453 struct audio_custom_mtmx_params *params,
454 int pcm_device_id)
Dhananjay Kumar429eb452018-12-10 22:26:53 +0530455{
456 struct mixer_ctl *ctl = NULL;
457 char *mixer_name_prefix = "AudStr";
458 char *mixer_name_suffix = "ChMixer Weight Ch";
459 char mixer_ctl_name[128] = {0};
460 struct audio_custom_mtmx_params_info *pinfo = &params->info;
461 int i = 0, err = 0;
Dhanalakshmi Siddani20628c82019-01-27 17:31:09 +0530462 int cust_ch_mixer_cfg[128], len = 0;
Dhananjay Kumar429eb452018-12-10 22:26:53 +0530463
464 ALOGI("%s: ip_channels %d, op_channels %d, pcm_device_id %d",
465 __func__, pinfo->ip_channels, pinfo->op_channels, pcm_device_id);
466
Dhanalakshmi Siddani20628c82019-01-27 17:31:09 +0530467 if (adev->use_old_pspd_mix_ctrl) {
468 /*
469 * Below code is to ensure backward compatibilty with older
470 * kernel version. Use old mixer control to set mixer coefficients
471 */
472 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
473 "Audio Stream %d Channel Mix Cfg", pcm_device_id);
Dhananjay Kumar429eb452018-12-10 22:26:53 +0530474
Dhanalakshmi Siddani20628c82019-01-27 17:31:09 +0530475 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
476 if (!ctl) {
477 ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
478 __func__, mixer_ctl_name);
479 return -EINVAL;
480 }
481 cust_ch_mixer_cfg[len++] = pinfo->ip_channels;
482 cust_ch_mixer_cfg[len++] = pinfo->op_channels;
483 for (i = 0; i < (int) (pinfo->op_channels * pinfo->ip_channels); i++) {
Avinash Chandrad7296d42021-08-04 15:07:47 +0530484 ALOGV("%s: coeff[%d] %lu", __func__, i, (unsigned long )params->coeffs[i]);
Dhanalakshmi Siddani20628c82019-01-27 17:31:09 +0530485 cust_ch_mixer_cfg[len++] = params->coeffs[i];
486 }
487 err = mixer_ctl_set_array(ctl, cust_ch_mixer_cfg, len);
488 if (err) {
489 ALOGE("%s: ERROR. Mixer ctl set failed", __func__);
490 return -EINVAL;
491 }
492 ALOGD("%s: Mixer ctl set for %s success", __func__, mixer_ctl_name);
493 } else {
494 for (i = 0; i < (int)pinfo->op_channels; i++) {
495 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "%s %d %s %d",
496 mixer_name_prefix, pcm_device_id, mixer_name_suffix, i+1);
497
498 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
499 if (!ctl) {
500 ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
501 __func__, mixer_ctl_name);
502 return -EINVAL;
503 }
504 err = mixer_ctl_set_array(ctl,
505 &params->coeffs[pinfo->ip_channels * i],
506 pinfo->ip_channels);
507 if (err) {
508 ALOGE("%s: ERROR. Mixer ctl set failed", __func__);
509 return -EINVAL;
510 }
511 }
Dhananjay Kumar429eb452018-12-10 22:26:53 +0530512 }
513 return 0;
514}
515
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +0530516static void set_custom_mtmx_params_v2(struct audio_device *adev,
517 struct audio_custom_mtmx_params_info *pinfo,
518 int pcm_device_id, bool enable)
Dhananjay Kumar429eb452018-12-10 22:26:53 +0530519{
520 struct mixer_ctl *ctl = NULL;
521 char *mixer_name_prefix = "AudStr";
522 char *mixer_name_suffix = "ChMixer Cfg";
523 char mixer_ctl_name[128] = {0};
524 int chmixer_cfg[5] = {0}, len = 0;
525 int be_id = -1, err = 0;
526
527 be_id = platform_get_snd_device_backend_index(pinfo->snd_device);
528
529 ALOGI("%s: ip_channels %d,op_channels %d,pcm_device_id %d,be_id %d",
530 __func__, pinfo->ip_channels, pinfo->op_channels, pcm_device_id, be_id);
531
532 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
533 "%s %d %s", mixer_name_prefix, pcm_device_id, mixer_name_suffix);
534 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
535 if (!ctl) {
536 ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
537 __func__, mixer_ctl_name);
538 return;
539 }
540 chmixer_cfg[len++] = enable ? 1 : 0;
541 chmixer_cfg[len++] = 0; /* rule index */
542 chmixer_cfg[len++] = pinfo->ip_channels;
543 chmixer_cfg[len++] = pinfo->op_channels;
544 chmixer_cfg[len++] = be_id + 1;
545
546 err = mixer_ctl_set_array(ctl, chmixer_cfg, len);
547 if (err)
548 ALOGE("%s: ERROR. Mixer ctl set failed", __func__);
549}
550
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +0530551void audio_extn_set_custom_mtmx_params_v2(struct audio_device *adev,
Dhananjay Kumar429eb452018-12-10 22:26:53 +0530552 struct audio_usecase *usecase,
553 bool enable)
554{
555 struct audio_custom_mtmx_params_info info = {0};
556 struct audio_custom_mtmx_params *params = NULL;
557 int num_devices = 0, pcm_device_id = -1, i = 0, ret = 0;
558 snd_device_t new_snd_devices[SND_DEVICE_OUT_END] = {0};
559 struct audio_backend_cfg backend_cfg = {0};
Chaithanya Krishna Bacharaju3e94c912019-05-27 11:25:44 +0530560 uint32_t feature_id = 0, idx = 0;
Dhananjay Kumar429eb452018-12-10 22:26:53 +0530561
562 switch(usecase->type) {
563 case PCM_PLAYBACK:
564 if (usecase->stream.out) {
565 pcm_device_id =
566 platform_get_pcm_device_id(usecase->id, PCM_PLAYBACK);
567 if (platform_split_snd_device(adev->platform,
568 usecase->out_snd_device,
569 &num_devices, new_snd_devices)) {
570 new_snd_devices[0] = usecase->out_snd_device;
571 num_devices = 1;
572 }
573 } else {
574 ALOGE("%s: invalid output stream for playback usecase id:%d",
575 __func__, usecase->id);
576 return;
577 }
578 break;
579 case PCM_CAPTURE:
580 if (usecase->stream.in) {
581 pcm_device_id =
582 platform_get_pcm_device_id(usecase->id, PCM_CAPTURE);
583 if (platform_split_snd_device(adev->platform,
584 usecase->in_snd_device,
585 &num_devices, new_snd_devices)) {
586 new_snd_devices[0] = usecase->in_snd_device;
587 num_devices = 1;
588 }
589 } else {
590 ALOGE("%s: invalid input stream for capture usecase id:%d",
591 __func__, usecase->id);
592 return;
593 }
594 break;
595 default:
596 ALOGV("%s: unsupported usecase id:%d", __func__, usecase->id);
597 return;
598 }
599
600 /*
601 * check and update feature_id before this assignment,
602 * if features like dual_mono is enabled and overrides the default(i.e. 0).
603 */
604 info.id = feature_id;
Chaithanya Krishna Bacharaju3e94c912019-05-27 11:25:44 +0530605 info.usecase_id[0] = usecase->id;
Dhananjay Kumar429eb452018-12-10 22:26:53 +0530606 for (i = 0, ret = 0; i < num_devices; i++) {
Dhanalakshmi Siddani20628c82019-01-27 17:31:09 +0530607 info.snd_device = new_snd_devices[i];
608 platform_get_codec_backend_cfg(adev, info.snd_device, &backend_cfg);
609 if (usecase->type == PCM_PLAYBACK) {
610 info.ip_channels = audio_channel_count_from_out_mask(
611 usecase->stream.out->channel_mask);
612 info.op_channels = backend_cfg.channels;
613 } else {
614 info.ip_channels = backend_cfg.channels;
615 info.op_channels = audio_channel_count_from_in_mask(
616 usecase->stream.in->channel_mask);
617 }
Chaithanya Krishna Bacharaju3e94c912019-05-27 11:25:44 +0530618 params = platform_get_custom_mtmx_params(adev->platform, &info, &idx);
Dhanalakshmi Siddani20628c82019-01-27 17:31:09 +0530619 if (params) {
620 if (enable)
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +0530621 ret = update_custom_mtmx_coefficients_v2(adev, params,
Dhanalakshmi Siddani20628c82019-01-27 17:31:09 +0530622 pcm_device_id);
623 if (ret < 0)
624 ALOGE("%s: error updating mtmx coeffs err:%d", __func__, ret);
625 else
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +0530626 set_custom_mtmx_params_v2(adev, &info, pcm_device_id, enable);
Dhanalakshmi Siddani20628c82019-01-27 17:31:09 +0530627 }
Dhananjay Kumar429eb452018-12-10 22:26:53 +0530628 }
629}
630
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +0530631static int set_custom_mtmx_output_channel_map(struct audio_device *adev,
632 char *mixer_name_prefix,
633 uint32_t ch_count,
634 bool enable)
635{
636 struct mixer_ctl *ctl = NULL;
637 char mixer_ctl_name[128] = {0};
638 int ret = 0;
Vijay Kumar Madduladd0811f2022-09-06 22:30:24 +0530639 int channel_map[AUDIO_MAX_DSP_CHANNELS] = {0};
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +0530640
641 ALOGV("%s channel_count %d", __func__, ch_count);
642
643 if (!enable) {
644 ALOGV("%s: reset output channel map", __func__);
645 goto exit;
646 }
647
648 switch (ch_count) {
649 case 2:
650 channel_map[0] = PCM_CHANNEL_FL;
651 channel_map[1] = PCM_CHANNEL_FR;
652 break;
653 case 4:
654 channel_map[0] = PCM_CHANNEL_FL;
655 channel_map[1] = PCM_CHANNEL_FR;
656 channel_map[2] = PCM_CHANNEL_LS;
657 channel_map[3] = PCM_CHANNEL_RS;
658 break;
659 case 6:
660 channel_map[0] = PCM_CHANNEL_FL;
661 channel_map[1] = PCM_CHANNEL_FR;
662 channel_map[2] = PCM_CHANNEL_FC;
663 channel_map[3] = PCM_CHANNEL_LFE;
664 channel_map[4] = PCM_CHANNEL_LS;
665 channel_map[5] = PCM_CHANNEL_RS;
666 break;
667 case 8:
668 channel_map[0] = PCM_CHANNEL_FL;
669 channel_map[1] = PCM_CHANNEL_FR;
670 channel_map[2] = PCM_CHANNEL_FC;
671 channel_map[3] = PCM_CHANNEL_LFE;
672 channel_map[4] = PCM_CHANNEL_LB;
673 channel_map[5] = PCM_CHANNEL_RB;
674 channel_map[6] = PCM_CHANNEL_LS;
675 channel_map[7] = PCM_CHANNEL_RS;
676 break;
677 case 10:
678 channel_map[0] = PCM_CHANNEL_FL;
679 channel_map[1] = PCM_CHANNEL_FR;
680 channel_map[2] = PCM_CHANNEL_LFE;
681 channel_map[3] = PCM_CHANNEL_FC;
682 channel_map[4] = PCM_CHANNEL_LB;
683 channel_map[5] = PCM_CHANNEL_RB;
684 channel_map[6] = PCM_CHANNEL_LS;
685 channel_map[7] = PCM_CHANNEL_RS;
686 channel_map[8] = PCM_CHANNEL_TFL;
687 channel_map[9] = PCM_CHANNEL_TFR;
688 break;
689 case 12:
690 channel_map[0] = PCM_CHANNEL_FL;
691 channel_map[1] = PCM_CHANNEL_FR;
692 channel_map[2] = PCM_CHANNEL_FC;
693 channel_map[3] = PCM_CHANNEL_LFE;
694 channel_map[4] = PCM_CHANNEL_LB;
695 channel_map[5] = PCM_CHANNEL_RB;
696 channel_map[6] = PCM_CHANNEL_LS;
697 channel_map[7] = PCM_CHANNEL_RS;
698 channel_map[8] = PCM_CHANNEL_TFL;
699 channel_map[9] = PCM_CHANNEL_TFR;
700 channel_map[10] = PCM_CHANNEL_TSL;
701 channel_map[11] = PCM_CHANNEL_TSR;
702 break;
703 case 14:
704 channel_map[0] = PCM_CHANNEL_FL;
705 channel_map[1] = PCM_CHANNEL_FR;
706 channel_map[2] = PCM_CHANNEL_LFE;
707 channel_map[3] = PCM_CHANNEL_FC;
708 channel_map[4] = PCM_CHANNEL_LB;
709 channel_map[5] = PCM_CHANNEL_RB;
710 channel_map[6] = PCM_CHANNEL_LS;
711 channel_map[7] = PCM_CHANNEL_RS;
712 channel_map[8] = PCM_CHANNEL_TFL;
713 channel_map[9] = PCM_CHANNEL_TFR;
714 channel_map[10] = PCM_CHANNEL_TSL;
715 channel_map[11] = PCM_CHANNEL_TSR;
716 channel_map[12] = PCM_CHANNEL_FLC;
717 channel_map[13] = PCM_CHANNEL_FRC;
718 break;
719 case 16:
720 channel_map[0] = PCM_CHANNEL_FL;
721 channel_map[1] = PCM_CHANNEL_FR;
722 channel_map[2] = PCM_CHANNEL_FC;
723 channel_map[3] = PCM_CHANNEL_LFE;
724 channel_map[4] = PCM_CHANNEL_LB;
725 channel_map[5] = PCM_CHANNEL_RB;
726 channel_map[6] = PCM_CHANNEL_LS;
727 channel_map[7] = PCM_CHANNEL_RS;
728 channel_map[8] = PCM_CHANNEL_TFL;
729 channel_map[9] = PCM_CHANNEL_TFR;
730 channel_map[10] = PCM_CHANNEL_TSL;
731 channel_map[11] = PCM_CHANNEL_TSR;
732 channel_map[12] = PCM_CHANNEL_FLC;
733 channel_map[13] = PCM_CHANNEL_FRC;
734 channel_map[14] = PCM_CHANNEL_RLC;
735 channel_map[15] = PCM_CHANNEL_RRC;
736 break;
737 default:
738 ALOGE("%s: unsupported channels(%d) for setting channel map",
739 __func__, ch_count);
740 return -EINVAL;
741 }
742
743exit:
744 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "%s %s",
745 mixer_name_prefix, "Output Channel Map");
746
747 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
748 if (!ctl) {
749 ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
750 __func__, mixer_ctl_name);
751 return -EINVAL;
752 }
753
754 ret = mixer_ctl_set_array(ctl, channel_map, ch_count);
755 return ret;
756}
757
758static int update_custom_mtmx_coefficients_v1(struct audio_device *adev,
759 struct audio_custom_mtmx_params *params,
760 struct audio_custom_mtmx_in_params *in_params,
761 int pcm_device_id,
762 usecase_type_t type,
Chaithanya Krishna Bacharaju3e94c912019-05-27 11:25:44 +0530763 bool enable,
764 uint32_t idx)
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +0530765{
766 struct mixer_ctl *ctl = NULL;
767 char mixer_ctl_name[128] = {0};
768 struct audio_custom_mtmx_params_info *pinfo = &params->info;
769 char mixer_name_prefix[100];
770 int i = 0, err = 0, rule = 0;
771 uint32_t mtrx_row_cnt = 0, mtrx_column_cnt = 0;
772 int reset_coeffs[AUDIO_MAX_DSP_CHANNELS] = {0};
773
774 ALOGI("%s: ip_channels %d, op_channels %d, pcm_device_id %d, usecase type %d, enable %d",
775 __func__, pinfo->ip_channels, pinfo->op_channels, pcm_device_id,
776 type, enable);
777
Chaithanya Krishna Bacharaju3e94c912019-05-27 11:25:44 +0530778 if (pinfo->fe_id[idx] == 0) {
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +0530779 ALOGE("%s: Error. no front end defined", __func__);
780 return -EINVAL;
781 }
782
Chaithanya Krishna Bacharaju3e94c912019-05-27 11:25:44 +0530783 snprintf(mixer_name_prefix, sizeof(mixer_name_prefix), "%s%d",
784 "MultiMedia", pinfo->fe_id[idx]);
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +0530785 /*
786 * Enable/Disable channel mixer.
787 * If enable, use params and in_params to configure mixer.
788 * If disable, reset previously configured mixer.
789 */
790 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "%s %s",
791 mixer_name_prefix, "Channel Mixer");
792
793 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
794 if (!ctl) {
795 ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
796 __func__, mixer_ctl_name);
797 return -EINVAL;
798 }
799
800 if (enable)
801 err = mixer_ctl_set_enum_by_string(ctl, "Enable");
802 else
803 err = mixer_ctl_set_enum_by_string(ctl, "Disable");
804
805 if (err) {
806 ALOGE("%s: ERROR. %s channel mixer failed", __func__,
807 enable ? "Enable" : "Disable");
808 return -EINVAL;
809 }
810
811 /* Configure output channels of channel mixer */
812 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "%s %s",
813 mixer_name_prefix, "Channels");
814
815 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
816 if (!ctl) {
817 ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
818 __func__, mixer_ctl_name);
819 return -EINVAL;
820 }
821
822 mtrx_row_cnt = pinfo->op_channels;
823 mtrx_column_cnt = pinfo->ip_channels;
824
825 if (enable)
826 err = mixer_ctl_set_value(ctl, 0, mtrx_row_cnt);
827 else
828 err = mixer_ctl_set_value(ctl, 0, 0);
829
830 if (err) {
831 ALOGE("%s: ERROR. %s mixer output channels failed", __func__,
832 enable ? "Set" : "Reset");
833 return -EINVAL;
834 }
835
836
837 /* To keep output channel map in sync with asm driver channel mapping */
838 err = set_custom_mtmx_output_channel_map(adev, mixer_name_prefix, mtrx_row_cnt,
839 enable);
840 if (err) {
841 ALOGE("%s: ERROR. %s mtmx output channel map failed", __func__,
842 enable ? "Set" : "Reset");
843 return -EINVAL;
844 }
845
846 /* Send channel mixer rule */
847 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "%s %s",
848 mixer_name_prefix, "Channel Rule");
849
850 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
851 if (!ctl) {
852 ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
853 __func__, mixer_ctl_name);
854 return -EINVAL;
855 }
856
857 mixer_ctl_set_value(ctl, 0, rule);
858
859 /* Send channel coefficients for each output channel */
860 for (i = 0; i < mtrx_row_cnt; i++) {
861 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "%s %s%d",
862 mixer_name_prefix, "Output Channel", i+1);
863 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
864 if (!ctl) {
865 ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
866 __func__, mixer_ctl_name);
867 return -EINVAL;
868 }
869
870 if (enable)
871 err = mixer_ctl_set_array(ctl,
872 &params->coeffs[mtrx_column_cnt * i],
873 mtrx_column_cnt);
874 else
875 err = mixer_ctl_set_array(ctl,
876 reset_coeffs,
877 mtrx_column_cnt);
878 if (err) {
879 ALOGE("%s: ERROR. %s coefficients failed for output channel %d",
880 __func__, enable ? "Set" : "Reset", i);
881 return -EINVAL;
882 }
883 }
884
885 /* Configure backend interfaces with information provided in xml */
886 i = 0;
887 while (in_params->in_ch_info[i].ch_count != 0) {
888 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "%s %s%d",
889 mixer_name_prefix, "Channel", i+1);
890 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
891 if (!ctl) {
892 ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
893 __func__, mixer_ctl_name);
894 return -EINVAL;
895 }
896 if (enable) {
897 ALOGD("%s: mixer %s, interface %s", __func__, mixer_ctl_name,
898 in_params->in_ch_info[i].hw_interface);
899 err = mixer_ctl_set_enum_by_string(ctl,
900 in_params->in_ch_info[i].hw_interface);
901 } else {
902 err = mixer_ctl_set_enum_by_string(ctl, "ZERO");
903 }
904
905 if (err) {
906 ALOGE("%s: ERROR. %s channel backend interface failed", __func__,
907 enable ? "Set" : "Reset");
908 return -EINVAL;
909 }
910 i++;
911 }
912
913 return 0;
914}
915
916
917void audio_extn_set_custom_mtmx_params_v1(struct audio_device *adev,
918 struct audio_usecase *usecase,
919 bool enable)
920{
921 struct audio_custom_mtmx_params_info info = {0};
922 struct audio_custom_mtmx_params *params = NULL;
923 struct audio_custom_mtmx_in_params_info in_info = {0};
924 struct audio_custom_mtmx_in_params *in_params = NULL;
925 int pcm_device_id = -1, ret = 0;
Chaithanya Krishna Bacharaju3e94c912019-05-27 11:25:44 +0530926 uint32_t feature_id = 0, idx = 0;
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +0530927
928 switch(usecase->type) {
929 case PCM_CAPTURE:
930 if (usecase->stream.in) {
931 pcm_device_id =
932 platform_get_pcm_device_id(usecase->id, PCM_CAPTURE);
933 info.snd_device = usecase->in_snd_device;
934 } else {
935 ALOGE("%s: invalid input stream for capture usecase id:%d",
936 __func__, usecase->id);
937 return;
938 }
939 break;
940 case PCM_PLAYBACK:
941 default:
942 ALOGV("%s: unsupported usecase id:%d", __func__, usecase->id);
943 return;
944 }
945
946 ALOGD("%s: snd device %d", __func__, info.snd_device);
947 info.id = feature_id;
Chaithanya Krishna Bacharaju3e94c912019-05-27 11:25:44 +0530948 info.usecase_id[0] = usecase->id;
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +0530949 info.op_channels = audio_channel_count_from_in_mask(
950 usecase->stream.in->channel_mask);
951
Chaithanya Krishna Bacharaju3e94c912019-05-27 11:25:44 +0530952 in_info.usecase_id[0] = info.usecase_id[0];
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +0530953 in_info.op_channels = info.op_channels;
954 in_params = platform_get_custom_mtmx_in_params(adev->platform, &in_info);
955 if (!in_params) {
956 ALOGE("%s: Could not get in params for usecase %d, channels %d",
Chaithanya Krishna Bacharaju3e94c912019-05-27 11:25:44 +0530957 __func__, in_info.usecase_id[0], in_info.op_channels);
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +0530958 return;
959 }
960
961 info.ip_channels = in_params->ip_channels;
962 ALOGD("%s: ip channels %d, op channels %d", __func__, info.ip_channels, info.op_channels);
963
Chaithanya Krishna Bacharaju3e94c912019-05-27 11:25:44 +0530964 params = platform_get_custom_mtmx_params(adev->platform, &info, &idx);
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +0530965 if (params) {
966 ret = update_custom_mtmx_coefficients_v1(adev, params, in_params,
Chaithanya Krishna Bacharaju3e94c912019-05-27 11:25:44 +0530967 pcm_device_id, usecase->type, enable, idx);
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +0530968 if (ret < 0)
969 ALOGE("%s: error updating mtmx coeffs err:%d", __func__, ret);
970 }
971}
972
973snd_device_t audio_extn_get_loopback_snd_device(struct audio_device *adev,
974 struct audio_usecase *usecase,
975 int channel_count)
976{
977 snd_device_t snd_device = SND_DEVICE_NONE;
978 struct audio_custom_mtmx_in_params_info in_info = {0};
979 struct audio_custom_mtmx_in_params *in_params = NULL;
980
981 if (!adev || !usecase) {
982 ALOGE("%s: Invalid params", __func__);
983 return snd_device;
984 }
985
Chaithanya Krishna Bacharaju3e94c912019-05-27 11:25:44 +0530986 in_info.usecase_id[0] = usecase->id;
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +0530987 in_info.op_channels = channel_count;
988 in_params = platform_get_custom_mtmx_in_params(adev->platform, &in_info);
989 if (!in_params) {
990 ALOGE("%s: Could not get in params for usecase %d, channels %d",
Chaithanya Krishna Bacharaju3e94c912019-05-27 11:25:44 +0530991 __func__, in_info.usecase_id[0], in_info.op_channels);
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +0530992 return snd_device;
993 }
994
995 switch(in_params->mic_ch) {
996 case 2:
997 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AND_EC_REF_LOOPBACK;
998 break;
999 case 4:
1000 snd_device = SND_DEVICE_IN_HANDSET_QMIC_AND_EC_REF_LOOPBACK;
1001 break;
1002 case 6:
1003 snd_device = SND_DEVICE_IN_HANDSET_6MIC_AND_EC_REF_LOOPBACK;
1004 break;
1005 case 8:
1006 snd_device = SND_DEVICE_IN_HANDSET_8MIC_AND_EC_REF_LOOPBACK;
1007 break;
1008 default:
1009 ALOGE("%s: Unsupported mic channels %d",
1010 __func__, in_params->mic_ch);
1011 break;
1012 }
1013
1014 ALOGD("%s: return snd device %d", __func__, snd_device);
1015 return snd_device;
1016}
1017
Jitendra Naruka1b6513f2014-11-22 19:34:13 -08001018#ifndef DTS_EAGLE
1019#define audio_extn_hpx_set_parameters(adev, parms) (0)
Alexy Joseph61300e62014-12-11 18:32:26 -08001020#define audio_extn_hpx_get_parameters(query, reply) (0)
Jitendra Naruka1b6513f2014-11-22 19:34:13 -08001021#define audio_extn_check_and_set_dts_hpx_state(adev) (0)
1022#else
1023void audio_extn_hpx_set_parameters(struct audio_device *adev,
1024 struct str_parms *parms)
1025{
1026 int ret = 0;
1027 char value[32]={0};
1028 char prop[PROPERTY_VALUE_MAX] = "false";
1029 bool hpx_state = false;
1030 const char *mixer_ctl_name = "Set HPX OnOff";
1031 struct mixer_ctl *ctl = NULL;
1032 ALOGV("%s", __func__);
1033
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -07001034 property_get("vendor.audio.use.dts_eagle", prop, "0");
Jitendra Naruka1b6513f2014-11-22 19:34:13 -08001035 if (strncmp("true", prop, sizeof("true")))
1036 return;
1037
1038 ret = str_parms_get_str(parms, AUDIO_PARAMETER_HPX, value,
1039 sizeof(value));
1040 if (ret >= 0) {
1041 if (!strncmp("ON", value, sizeof("ON")))
1042 hpx_state = true;
1043
1044 if (hpx_state == aextnmod.hpx_enabled)
1045 return;
1046
1047 aextnmod.hpx_enabled = hpx_state;
1048 /* set HPX state on stream pp */
1049 if (adev->offload_effects_set_hpx_state != NULL)
1050 adev->offload_effects_set_hpx_state(hpx_state);
1051
Dhanalakshmi Siddanieb7d4cd2015-06-03 11:44:16 +05301052 audio_extn_dts_eagle_fade(adev, aextnmod.hpx_enabled, NULL);
Jitendra Naruka1b6513f2014-11-22 19:34:13 -08001053 /* set HPX state on device pp */
1054 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1055 if (ctl)
1056 mixer_ctl_set_value(ctl, 0, aextnmod.hpx_enabled);
1057 }
1058}
1059
Alexy Joseph61300e62014-12-11 18:32:26 -08001060static int audio_extn_hpx_get_parameters(struct str_parms *query,
1061 struct str_parms *reply)
1062{
1063 int ret;
1064 char value[32]={0};
1065
1066 ALOGV("%s: hpx %d", __func__, aextnmod.hpx_enabled);
1067 ret = str_parms_get_str(query, AUDIO_PARAMETER_HPX, value,
1068 sizeof(value));
1069 if (ret >= 0) {
1070 if (aextnmod.hpx_enabled)
1071 str_parms_add_str(reply, AUDIO_PARAMETER_HPX, "ON");
1072 else
1073 str_parms_add_str(reply, AUDIO_PARAMETER_HPX, "OFF");
1074 }
1075 return ret;
1076}
1077
Jitendra Naruka1b6513f2014-11-22 19:34:13 -08001078void audio_extn_check_and_set_dts_hpx_state(const struct audio_device *adev)
1079{
1080 char prop[PROPERTY_VALUE_MAX];
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -07001081 property_get("vendor.audio.use.dts_eagle", prop, "0");
Jitendra Naruka1b6513f2014-11-22 19:34:13 -08001082 if (strncmp("true", prop, sizeof("true")))
1083 return;
1084 if (adev->offload_effects_set_hpx_state)
1085 adev->offload_effects_set_hpx_state(aextnmod.hpx_enabled);
1086}
1087#endif
1088
Dhanalakshmi Siddani999d5642019-03-22 15:27:44 +05301089/* Affine AHAL thread to CPU core */
1090void audio_extn_set_cpu_affinity()
1091{
1092 cpu_set_t cpuset;
1093 struct sched_param sched_param;
1094 int policy = SCHED_FIFO, rc = 0;
1095
1096 ALOGV("%s: Set CPU affinity for read thread", __func__);
1097 CPU_ZERO(&cpuset);
1098 if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0)
1099 ALOGE("%s: CPU Affinity allocation failed for Capture thread",
1100 __func__);
1101
1102 sched_param.sched_priority = sched_get_priority_min(policy);
1103 rc = sched_setscheduler(0, policy, &sched_param);
1104 if (rc != 0)
1105 ALOGE("%s: Failed to set realtime priority", __func__);
1106}
1107
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001108// START: VBAT =============================================================
1109void vbat_feature_init(bool is_feature_enabled)
Venkata Narendra Kumar Gutta4bd09d02016-01-29 15:31:04 +05301110{
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001111 audio_extn_vbat_enabled = is_feature_enabled;
1112 ALOGD(":: %s: ---- Feature VBAT is %s ----",
1113 __func__, is_feature_enabled ? "ENABLED": " NOT ENABLED");
Venkata Narendra Kumar Gutta4bd09d02016-01-29 15:31:04 +05301114}
1115
Banajit Goswami20cdd212015-09-11 01:11:30 -07001116bool audio_extn_is_vbat_enabled(void)
1117{
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001118 if (!audio_extn_vbat_enabled)
1119 return false;
1120
Banajit Goswami20cdd212015-09-11 01:11:30 -07001121 ALOGD("%s: status: %d", __func__, aextnmod.vbat_enabled);
1122 return (aextnmod.vbat_enabled ? true: false);
1123}
1124
1125bool audio_extn_can_use_vbat(void)
1126{
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001127 if (!audio_extn_vbat_enabled)
1128 return false;
1129
Banajit Goswami20cdd212015-09-11 01:11:30 -07001130 char prop_vbat_enabled[PROPERTY_VALUE_MAX] = "false";
1131
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -07001132 property_get("persist.vendor.audio.vbat.enabled", prop_vbat_enabled, "0");
Banajit Goswami20cdd212015-09-11 01:11:30 -07001133 if (!strncmp("true", prop_vbat_enabled, 4)) {
1134 aextnmod.vbat_enabled = 1;
1135 }
1136
1137 ALOGD("%s: vbat.enabled property is set to %s", __func__, prop_vbat_enabled);
1138 return (aextnmod.vbat_enabled ? true: false);
1139}
Aditya Bavanari9b589022018-09-20 08:47:55 +05301140
1141bool audio_extn_is_bcl_enabled(void)
1142{
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001143 if (!audio_extn_vbat_enabled)
1144 return false;
1145
Aditya Bavanari9b589022018-09-20 08:47:55 +05301146 ALOGD("%s: status: %d", __func__, aextnmod.bcl_enabled);
1147 return (aextnmod.bcl_enabled ? true: false);
1148}
1149
1150bool audio_extn_can_use_bcl(void)
1151{
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001152 if (!audio_extn_vbat_enabled)
1153 return false;
1154
Aditya Bavanari9b589022018-09-20 08:47:55 +05301155 char prop_bcl_enabled[PROPERTY_VALUE_MAX] = "false";
1156
1157 property_get("persist.vendor.audio.bcl.enabled", prop_bcl_enabled, "0");
1158 if (!strncmp("true", prop_bcl_enabled, 4)) {
1159 aextnmod.bcl_enabled = 1;
1160 }
1161
1162 ALOGD("%s: bcl.enabled property is set to %s", __func__, prop_bcl_enabled);
1163 return (aextnmod.bcl_enabled ? true: false);
1164}
Banajit Goswami20cdd212015-09-11 01:11:30 -07001165
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001166// START: ANC_HEADSET -------------------------------------------------------
1167void anc_headset_feature_init(bool is_feature_enabled)
Srinivas Julakanti1ca769a2017-01-04 23:18:08 -08001168{
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001169 audio_extn_anc_headset_feature_enabled = is_feature_enabled;
Arun Mirpurie008ed22019-03-21 11:21:04 -07001170 ALOGD(":: %s: ---- Feature ANC_HEADSET is %s----", __func__,
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001171 is_feature_enabled? "ENABLED": "NOT ENABLED");
1172
Srinivas Julakanti1ca769a2017-01-04 23:18:08 -08001173}
1174
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001175bool audio_extn_get_anc_enabled(void)
1176{
Weiyin Jiangd3fc3f92019-08-28 17:27:20 +08001177 ALOGD("%s: anc_enabled:%d", __func__,
1178 (aextnmod.anc_enabled && audio_extn_anc_headset_feature_enabled));
1179 return (aextnmod.anc_enabled &&
1180 audio_extn_anc_headset_feature_enabled);
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001181}
1182
1183bool audio_extn_should_use_handset_anc(int in_channels)
1184{
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001185 if (audio_extn_anc_headset_feature_enabled) {
1186 char prop_aanc[PROPERTY_VALUE_MAX] = "false";
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001187
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001188 property_get("persist.vendor.audio.aanc.enable", prop_aanc, "0");
1189 if (!strncmp("true", prop_aanc, 4)) {
1190 ALOGD("%s: AANC enabled in the property", __func__);
1191 aextnmod.aanc_enabled = 1;
1192 }
1193
1194 return (aextnmod.aanc_enabled && aextnmod.anc_enabled
1195 && (in_channels == 1));
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001196 }
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001197 return false;
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001198}
1199
1200bool audio_extn_should_use_fb_anc(void)
1201{
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001202 char prop_anc[PROPERTY_VALUE_MAX] = "feedforward";
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001203
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001204 if (audio_extn_anc_headset_feature_enabled) {
1205 property_get("persist.vendor.audio.headset.anc.type", prop_anc, "0");
1206 if (!strncmp("feedback", prop_anc, sizeof("feedback"))) {
1207 ALOGD("%s: FB ANC headset type enabled\n", __func__);
1208 return true;
1209 }
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001210 }
1211 return false;
1212}
1213
Sudheer Papothid63caef2018-05-15 00:41:52 +05301214void audio_extn_set_aanc_noise_level(struct audio_device *adev,
1215 struct str_parms *parms)
1216{
1217 int ret;
1218 char value[32] = {0};
1219 struct mixer_ctl *ctl = NULL;
1220 const char *mixer_ctl_name = "AANC Noise Level";
1221
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001222 if(audio_extn_anc_headset_feature_enabled) {
1223 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_AANC_NOISE_LEVEL, value,
Sudheer Papothid63caef2018-05-15 00:41:52 +05301224 sizeof(value));
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001225 if (ret >= 0) {
1226 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1227 if (ctl)
1228 mixer_ctl_set_value(ctl, 0, atoi(value));
1229 else
1230 ALOGW("%s: Not able to get mixer ctl: %s",
1231 __func__, mixer_ctl_name);
1232 }
Sudheer Papothid63caef2018-05-15 00:41:52 +05301233 }
1234}
1235
Apoorv Raghuvanshic0536542013-11-14 16:25:59 -08001236void audio_extn_set_anc_parameters(struct audio_device *adev,
1237 struct str_parms *parms)
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001238{
1239 int ret;
1240 char value[32] ={0};
Apoorv Raghuvanshic0536542013-11-14 16:25:59 -08001241 struct listnode *node;
1242 struct audio_usecase *usecase;
Dhananjay Kumar24a4c7b2015-12-04 21:33:15 +05301243 struct str_parms *query_44_1;
1244 struct str_parms *reply_44_1;
1245 struct str_parms *parms_disable_44_1;
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001246
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001247 if(!audio_extn_anc_headset_feature_enabled)
1248 return;
1249
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001250 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_ANC, value,
1251 sizeof(value));
1252 if (ret >= 0) {
1253 if (strcmp(value, "true") == 0)
1254 aextnmod.anc_enabled = true;
1255 else
1256 aextnmod.anc_enabled = false;
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001257
Dhananjay Kumar24a4c7b2015-12-04 21:33:15 +05301258 /* Store current 44.1 configuration and disable it temporarily before
1259 * changing ANC state.
1260 * Since 44.1 playback is not allowed with anc on.
1261 * If ANC switch is done when 44.1 is active three devices would need
1262 * sequencing 1. "headphones-44.1", 2. "headphones-anc" and
1263 * 3. "headphones".
1264 * Note: Enable/diable of anc would affect other two device's state.
1265 */
1266 query_44_1 = str_parms_create_str(AUDIO_PARAMETER_KEY_NATIVE_AUDIO);
1267 reply_44_1 = str_parms_create();
Alexy Josephaee4fdd2016-01-29 13:02:07 -08001268 if (!query_44_1 || !reply_44_1) {
1269 if (query_44_1) {
1270 str_parms_destroy(query_44_1);
1271 }
1272 if (reply_44_1) {
1273 str_parms_destroy(reply_44_1);
1274 }
1275
1276 ALOGE("%s: param creation failed", __func__);
1277 return;
1278 }
1279
Dhananjay Kumar24a4c7b2015-12-04 21:33:15 +05301280 platform_get_parameters(adev->platform, query_44_1, reply_44_1);
1281
1282 parms_disable_44_1 = str_parms_create();
Alexy Josephaee4fdd2016-01-29 13:02:07 -08001283 if (!parms_disable_44_1) {
1284 str_parms_destroy(query_44_1);
1285 str_parms_destroy(reply_44_1);
1286 ALOGE("%s: param creation failed for parms_disable_44_1", __func__);
1287 return;
1288 }
1289
Dhananjay Kumar24a4c7b2015-12-04 21:33:15 +05301290 str_parms_add_str(parms_disable_44_1, AUDIO_PARAMETER_KEY_NATIVE_AUDIO, "false");
1291 platform_set_parameters(adev->platform, parms_disable_44_1);
1292 str_parms_destroy(parms_disable_44_1);
1293
1294 // Refresh device selection for anc playback
Vimal Puthanveedbe677c32013-12-11 13:34:09 -08001295 list_for_each(node, &adev->usecase_list) {
1296 usecase = node_to_item(node, struct audio_usecase, list);
Sujin Panicker390724d2019-04-26 10:43:36 +05301297 if (usecase->stream.out && usecase->type != PCM_CAPTURE) {
Aniket Kumar Lata0e6e1e52019-11-14 21:43:55 -08001298 if (is_single_device_type_equal(&usecase->stream.out->device_list,
1299 AUDIO_DEVICE_OUT_WIRED_HEADPHONE) ||
1300 is_single_device_type_equal(&usecase->stream.out->device_list,
1301 AUDIO_DEVICE_OUT_WIRED_HEADSET) ||
1302 is_single_device_type_equal(&usecase->stream.out->device_list,
1303 AUDIO_DEVICE_OUT_EARPIECE)) {
Vimal Puthanveedbe677c32013-12-11 13:34:09 -08001304 select_devices(adev, usecase->id);
Dhananjay Kumar24a4c7b2015-12-04 21:33:15 +05301305 ALOGV("%s: switching device completed", __func__);
Vimal Puthanveedbe677c32013-12-11 13:34:09 -08001306 break;
1307 }
Apoorv Raghuvanshic0536542013-11-14 16:25:59 -08001308 }
1309 }
Dhananjay Kumar24a4c7b2015-12-04 21:33:15 +05301310
1311 // Restore 44.1 configuration on top of updated anc state
1312 platform_set_parameters(adev->platform, reply_44_1);
1313 str_parms_destroy(query_44_1);
1314 str_parms_destroy(reply_44_1);
Apoorv Raghuvanshic0536542013-11-14 16:25:59 -08001315 }
1316
Aniket Kumar Latab91e4cf2019-02-11 18:55:23 -08001317 ALOGV("%s: anc_enabled:%d", __func__, aextnmod.anc_enabled);
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001318}
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001319// END: ANC_HEADSET -------------------------------------------------------
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001320
Apoorv Raghuvanshi947cb902013-12-09 13:45:39 -08001321static int32_t afe_proxy_set_channel_mapping(struct audio_device *adev,
Sachin Mohan Gadag3e6e3fd2019-03-14 17:37:05 +05301322 int channel_count,
1323 snd_device_t snd_device)
Apoorv Raghuvanshi947cb902013-12-09 13:45:39 -08001324{
Sachin Mohan Gadag3e6e3fd2019-03-14 17:37:05 +05301325 struct mixer_ctl *ctl = NULL, *be_ctl = NULL;
Fred Ohe0479682015-03-25 16:30:26 -07001326 const char *mixer_ctl_name = "Playback Device Channel Map";
Sachin Mohan Gadag3e6e3fd2019-03-14 17:37:05 +05301327 const char *be_mixer_ctl_name = "Backend Device Channel Map";
1328 long set_values[FCC_8] = {0};
1329 long be_set_values[FCC_8 + 1] = {0};
1330 int ret = -1;
1331 int be_idx = -1;
1332
Apoorv Raghuvanshi947cb902013-12-09 13:45:39 -08001333 ALOGV("%s channel_count:%d",__func__, channel_count);
1334
1335 switch (channel_count) {
Mingming Yin5a7c5d62014-03-05 17:45:03 -08001336 case 2:
1337 set_values[0] = PCM_CHANNEL_FL;
1338 set_values[1] = PCM_CHANNEL_FR;
1339 break;
Shalini Manjunatha43c45c42020-02-17 13:14:37 +05301340 case 4:
1341 set_values[0] = PCM_CHANNEL_FL;
1342 set_values[1] = PCM_CHANNEL_FR;
1343 set_values[2] = PCM_CHANNEL_LS;
1344 set_values[3] = PCM_CHANNEL_LFE;
1345 break;
Apoorv Raghuvanshi947cb902013-12-09 13:45:39 -08001346 case 6:
1347 set_values[0] = PCM_CHANNEL_FL;
1348 set_values[1] = PCM_CHANNEL_FR;
1349 set_values[2] = PCM_CHANNEL_FC;
1350 set_values[3] = PCM_CHANNEL_LFE;
1351 set_values[4] = PCM_CHANNEL_LS;
1352 set_values[5] = PCM_CHANNEL_RS;
1353 break;
1354 case 8:
1355 set_values[0] = PCM_CHANNEL_FL;
1356 set_values[1] = PCM_CHANNEL_FR;
1357 set_values[2] = PCM_CHANNEL_FC;
1358 set_values[3] = PCM_CHANNEL_LFE;
1359 set_values[4] = PCM_CHANNEL_LS;
1360 set_values[5] = PCM_CHANNEL_RS;
1361 set_values[6] = PCM_CHANNEL_LB;
1362 set_values[7] = PCM_CHANNEL_RB;
1363 break;
1364 default:
1365 ALOGE("unsupported channels(%d) for setting channel map",
1366 channel_count);
1367 return -EINVAL;
1368 }
1369
Sachin Mohan Gadag3e6e3fd2019-03-14 17:37:05 +05301370 be_idx = platform_get_snd_device_backend_index(snd_device);
1371
1372 if (be_idx >= 0) {
1373 be_ctl = mixer_get_ctl_by_name(adev->mixer, be_mixer_ctl_name);
1374 if (!be_ctl) {
1375 ALOGD("%s: Could not get ctl for mixer cmd - %s, using default control",
1376 __func__, be_mixer_ctl_name);
1377 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1378 } else
1379 ctl = be_ctl;
1380 } else
1381 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1382
Apoorv Raghuvanshi947cb902013-12-09 13:45:39 -08001383 if (!ctl) {
1384 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1385 __func__, mixer_ctl_name);
1386 return -EINVAL;
1387 }
Sachin Mohan Gadag3e6e3fd2019-03-14 17:37:05 +05301388
Manish Dewangan338c50a2017-09-12 15:22:03 +05301389 ALOGV("AFE: set mapping(%ld %ld %ld %ld %ld %ld %ld %ld) for channel:%d",
Apoorv Raghuvanshi947cb902013-12-09 13:45:39 -08001390 set_values[0], set_values[1], set_values[2], set_values[3], set_values[4],
1391 set_values[5], set_values[6], set_values[7], channel_count);
Sachin Mohan Gadag3e6e3fd2019-03-14 17:37:05 +05301392
1393 if (!be_ctl)
1394 ret = mixer_ctl_set_array(ctl, set_values, channel_count);
1395 else {
1396 be_set_values[0] = be_idx;
1397 memcpy(&be_set_values[1], set_values, sizeof(long) * channel_count);
1398 ret = mixer_ctl_set_array(ctl, be_set_values, ARRAY_SIZE(be_set_values));
1399 }
1400
Apoorv Raghuvanshi947cb902013-12-09 13:45:39 -08001401 return ret;
1402}
1403
Mingming Yin5a7c5d62014-03-05 17:45:03 -08001404int32_t audio_extn_set_afe_proxy_channel_mixer(struct audio_device *adev,
Sachin Mohan Gadag3e6e3fd2019-03-14 17:37:05 +05301405 int channel_count, snd_device_t snd_device)
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001406{
1407 int32_t ret = 0;
1408 const char *channel_cnt_str = NULL;
1409 struct mixer_ctl *ctl = NULL;
1410 const char *mixer_ctl_name = "PROXY_RX Channels";
1411
vivek mehtaae1018c2019-05-09 12:19:57 -07001412 if (!property_get_bool("vendor.audio.feature.afe_proxy.enable", false)) {
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001413 ALOGW("%s: AFE_PROXY is disabled", __func__);
1414 return -ENOSYS;
1415 }
1416
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001417 ALOGD("%s: entry", __func__);
1418 /* use the existing channel count set by hardware params to
1419 configure the back end for stereo as usb/a2dp would be
1420 stereo by default */
Mingming Yin5a7c5d62014-03-05 17:45:03 -08001421 ALOGD("%s: channels = %d", __func__, channel_count);
1422 switch (channel_count) {
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001423 case 8: channel_cnt_str = "Eight"; break;
1424 case 7: channel_cnt_str = "Seven"; break;
1425 case 6: channel_cnt_str = "Six"; break;
1426 case 5: channel_cnt_str = "Five"; break;
1427 case 4: channel_cnt_str = "Four"; break;
1428 case 3: channel_cnt_str = "Three"; break;
1429 default: channel_cnt_str = "Two"; break;
1430 }
1431
Mingming Yin5a7c5d62014-03-05 17:45:03 -08001432 if(channel_count >= 2 && channel_count <= 8) {
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001433 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1434 if (!ctl) {
1435 ALOGE("%s: could not get ctl for mixer cmd - %s",
1436 __func__, mixer_ctl_name);
1437 return -EINVAL;
1438 }
1439 }
1440 mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
1441
Shalini Manjunatha43c45c42020-02-17 13:14:37 +05301442 if (channel_count == 6 || channel_count == 8 || channel_count == 2 || channel_count == 4) {
Sachin Mohan Gadag3e6e3fd2019-03-14 17:37:05 +05301443 ret = afe_proxy_set_channel_mapping(adev, channel_count, snd_device);
Mingming Yin5a7c5d62014-03-05 17:45:03 -08001444 } else {
1445 ALOGE("%s: set unsupported channel count(%d)", __func__, channel_count);
1446 ret = -EINVAL;
1447 }
Apoorv Raghuvanshi947cb902013-12-09 13:45:39 -08001448
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001449 ALOGD("%s: exit", __func__);
1450 return ret;
1451}
1452
Krishnankutty Kolathappilly0b2de1c2014-02-14 14:45:49 -08001453void audio_extn_set_afe_proxy_parameters(struct audio_device *adev,
1454 struct str_parms *parms)
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001455{
1456 int ret, val;
1457 char value[32]={0};
1458
1459 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_WFD, value,
1460 sizeof(value));
1461 if (ret >= 0) {
1462 val = atoi(value);
1463 aextnmod.proxy_channel_num = val;
Krishnankutty Kolathappilly0b2de1c2014-02-14 14:45:49 -08001464 adev->cur_wfd_channels = val;
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001465 ALOGD("%s: channel capability set to: %d", __func__,
1466 aextnmod.proxy_channel_num);
1467 }
1468}
1469
vivek mehta344576a2016-04-12 18:56:03 -07001470int audio_extn_get_afe_proxy_parameters(const struct audio_device *adev,
1471 struct str_parms *query,
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001472 struct str_parms *reply)
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001473{
vivek mehta344576a2016-04-12 18:56:03 -07001474 int ret, val = 0;
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001475 char value[32]={0};
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001476
1477 ret = str_parms_get_str(query, AUDIO_PARAMETER_CAN_OPEN_PROXY, value,
1478 sizeof(value));
1479 if (ret >= 0) {
Kuirong Wanga9f7cee2016-03-07 11:21:52 -08001480 val = (adev->allow_afe_proxy_usage ? 1: 0);
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001481 str_parms_add_int(reply, AUDIO_PARAMETER_CAN_OPEN_PROXY, val);
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001482 }
vivek mehta344576a2016-04-12 18:56:03 -07001483 ALOGV("%s: called ... can_use_proxy %d", __func__, val);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001484 return 0;
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001485}
Apoorv Raghuvanshi947cb902013-12-09 13:45:39 -08001486
1487/* must be called with hw device mutex locked */
1488int32_t audio_extn_read_afe_proxy_channel_masks(struct stream_out *out)
1489{
1490 int ret = 0;
1491 int channels = aextnmod.proxy_channel_num;
1492
vivek mehtaae1018c2019-05-09 12:19:57 -07001493 if (!property_get_bool("vendor.audio.feature.afe_proxy.enable",
1494 false)) {
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001495 ALOGW("%s: AFE_PROXY is disabled", __func__);
1496 return -ENOSYS;
1497 }
1498
Apoorv Raghuvanshi947cb902013-12-09 13:45:39 -08001499 switch (channels) {
1500 /*
1501 * Do not handle stereo output in Multi-channel cases
1502 * Stereo case is handled in normal playback path
1503 */
1504 case 6:
1505 ALOGV("%s: AFE PROXY supports 5.1", __func__);
1506 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1;
1507 break;
1508 case 8:
1509 ALOGV("%s: AFE PROXY supports 5.1 and 7.1 channels", __func__);
1510 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1;
1511 out->supported_channel_masks[1] = AUDIO_CHANNEL_OUT_7POINT1;
1512 break;
1513 default:
1514 ALOGE("AFE PROXY does not support multi channel playback");
1515 ret = -ENOSYS;
1516 break;
1517 }
1518 return ret;
1519}
Mingming Yin5a7c5d62014-03-05 17:45:03 -08001520
1521int32_t audio_extn_get_afe_proxy_channel_count()
1522{
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001523
vivek mehtaae1018c2019-05-09 12:19:57 -07001524 if (!property_get_bool("vendor.audio.feature.afe_proxy.enable",
1525 false)) {
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001526 ALOGW("%s: AFE_PROXY is disabled", __func__);
1527 return -ENOSYS;
1528 }
1529
Mingming Yin5a7c5d62014-03-05 17:45:03 -08001530 return aextnmod.proxy_channel_num;
1531}
1532
Subhash Chandra Bose Naripeddy16ff4f82014-04-01 21:03:10 -07001533static int get_active_offload_usecases(const struct audio_device *adev,
1534 struct str_parms *query,
1535 struct str_parms *reply)
1536{
1537 int ret, count = 0;
1538 char value[32]={0};
1539 struct listnode *node;
1540 struct audio_usecase *usecase;
1541
1542 ALOGV("%s", __func__);
1543 ret = str_parms_get_str(query, AUDIO_PARAMETER_OFFLOAD_NUM_ACTIVE, value,
1544 sizeof(value));
1545 if (ret >= 0) {
1546 list_for_each(node, &adev->usecase_list) {
1547 usecase = node_to_item(node, struct audio_usecase, list);
1548 if (is_offload_usecase(usecase->id))
1549 count++;
1550 }
1551 ALOGV("%s, number of active offload usecases: %d", __func__, count);
1552 str_parms_add_int(reply, AUDIO_PARAMETER_OFFLOAD_NUM_ACTIVE, count);
1553 }
1554 return ret;
1555}
1556
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001557void compress_meta_data_feature_init(bool is_featuer_enabled)
1558{
1559 is_compress_meta_data_enabled = is_featuer_enabled;
1560}
1561
1562bool if_compress_meta_data_feature_enabled()
1563{
1564 return is_compress_meta_data_enabled;
1565}
1566
1567//START: USB_OFFLOAD ==========================================================
1568// LIB is part of hal lib, so no need for dlopen and getting function pointer
1569// rather have function declared here
1570
1571void usb_init(void *adev);
1572void usb_deinit();
1573void usb_add_device(audio_devices_t device, int card);
1574void usb_remove_device(audio_devices_t device, int card);
1575bool usb_is_config_supported(unsigned int *bit_width,
1576 unsigned int *sample_rate,
1577 unsigned int *ch,
1578 bool is_playback);
1579int usb_enable_sidetone(int device, bool enable);
1580void usb_set_sidetone_gain(struct str_parms *parms,
1581 char *value, int len);
1582bool usb_is_capture_supported();
1583int usb_get_max_channels(bool playback);
1584int usb_get_max_bit_width(bool playback);
1585int usb_get_sup_sample_rates(bool type, uint32_t *sr, uint32_t l);
1586bool usb_is_tunnel_supported();
1587bool usb_alive(int card);
1588bool usb_connected(struct str_parms *parms);
Carter Hsu32a62362018-10-15 15:01:42 -07001589char *usb_usbid(void);
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001590unsigned long usb_find_service_interval(bool min, bool playback);
1591int usb_altset_for_service_interval(bool is_playback,
1592 unsigned long service_interval,
1593 uint32_t *bit_width,
1594 uint32_t *sample_rate,
1595 uint32_t *channel_count);
1596int usb_set_service_interval(bool playback,
1597 unsigned long service_interval,
1598 bool *reconfig);
1599int usb_get_service_interval(bool playback,
1600 unsigned long *service_interval);
1601int usb_check_and_set_svc_int(struct audio_usecase *uc_info,
1602 bool starting_output_stream);
1603bool usb_is_reconfig_req();
1604void usb_set_reconfig(bool is_required);
1605
1606static bool is_usb_offload_enabled = false;
1607static bool is_usb_burst_mode_enabled = false;
1608static bool is_usb_sidetone_vol_enabled = false;
1609
1610void usb_offload_feature_init(bool is_feature_enabled)
1611{
1612 ALOGD("%s: Called with feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
1613 is_usb_offload_enabled = is_feature_enabled;
1614}
1615
1616void usb_offload_burst_mode_feature_init(bool is_feature_enabled)
1617{
1618 ALOGD("%s: Called with feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
1619 is_usb_burst_mode_enabled = is_feature_enabled;
1620}
1621
1622void usb_offload_sidetone_volume_feature_init(bool is_feature_enabled)
1623{
1624 ALOGD("%s: Called with feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
1625 is_usb_sidetone_vol_enabled = is_feature_enabled;
1626}
1627
1628bool audio_extn_usb_is_sidetone_volume_enabled()
1629{
1630 return is_usb_sidetone_vol_enabled;
1631}
1632
1633void audio_extn_usb_init(void *adev)
1634{
1635 if (is_usb_offload_enabled)
1636 usb_init(adev);
1637}
1638
1639
1640void audio_extn_usb_deinit()
1641{
1642 if (is_usb_offload_enabled)
1643 usb_deinit();
1644}
1645
1646void audio_extn_usb_add_device(audio_devices_t device, int card)
1647{
1648 if (is_usb_offload_enabled)
1649 usb_add_device(device, card);
1650}
1651
1652void audio_extn_usb_remove_device(audio_devices_t device, int card)
1653{
1654 if (is_usb_offload_enabled)
1655 usb_remove_device(device, card);
1656}
1657
1658bool audio_extn_usb_is_config_supported(unsigned int *bit_width,
1659 unsigned int *sample_rate,
1660 unsigned int *ch,
1661 bool is_playback)
1662{
1663 bool ret_val = false;
1664 if (is_usb_offload_enabled)
1665 ret_val = usb_is_config_supported(bit_width, sample_rate, ch, is_playback);
1666
1667 return ret_val;
1668}
1669
1670int audio_extn_usb_enable_sidetone(int device, bool enable)
1671{
1672 int ret_val = 0;
1673 if (is_usb_offload_enabled)
1674 ret_val = usb_enable_sidetone(device, enable);
1675
1676 return ret_val;
1677}
1678
1679void audio_extn_usb_set_sidetone_gain(struct str_parms *parms,
1680 char *value, int len)
1681{
1682 if (is_usb_offload_enabled)
1683 usb_set_sidetone_gain(parms, value, len);
1684}
1685
1686bool audio_extn_usb_is_capture_supported()
1687{
1688 bool ret_val = false;
1689 if (is_usb_offload_enabled)
1690 ret_val = usb_is_capture_supported();
1691
1692 return ret_val;
1693}
1694
1695int audio_extn_usb_get_max_channels(bool playback)
1696{
1697 int ret_val = 0;
1698 if (is_usb_offload_enabled)
1699 ret_val = usb_get_max_channels(playback);
1700
1701 return ret_val;
1702}
1703
1704int audio_extn_usb_get_max_bit_width(bool playback)
1705{
1706 int ret_val = 0;
1707 if (is_usb_offload_enabled)
1708 ret_val = usb_get_max_bit_width(playback);
1709
1710 return ret_val;
1711}
1712
1713
1714int audio_extn_usb_get_sup_sample_rates(bool type, uint32_t *sr, uint32_t l)
1715{
1716 int ret_val = 0;
1717 if (is_usb_offload_enabled)
1718 ret_val = usb_get_sup_sample_rates(type, sr, l);
1719
1720 return ret_val;
1721}
1722
1723bool audio_extn_usb_is_tunnel_supported()
1724{
1725 bool ret_val = false;
1726 if (is_usb_offload_enabled)
1727 ret_val = usb_is_tunnel_supported();
1728
1729 return ret_val;
1730}
1731
1732bool audio_extn_usb_alive(int card)
1733{
1734 bool ret_val = false;
1735 if (is_usb_offload_enabled)
1736 ret_val = usb_alive(card);
1737
1738 return ret_val;
1739}
1740
1741bool audio_extn_usb_connected(struct str_parms *parms)
1742{
1743 bool ret_val = false;
1744 if (is_usb_offload_enabled)
1745 ret_val = usb_connected(parms);
1746
1747 return ret_val;
1748}
1749
Carter Hsu32a62362018-10-15 15:01:42 -07001750char *audio_extn_usb_usbid(void)
1751{
1752 char *ret_val = NULL;
1753 if (is_usb_offload_enabled)
1754 ret_val = usb_usbid();
1755
1756 return ret_val;
1757}
1758
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001759unsigned long audio_extn_usb_find_service_interval(bool min, bool playback)
1760{
1761 unsigned long ret_val = 0;
1762 if (is_usb_offload_enabled && is_usb_burst_mode_enabled)
1763 ret_val = usb_find_service_interval(min, playback);
1764
1765 return ret_val;
1766}
1767
1768int audio_extn_usb_altset_for_service_interval(bool is_playback,
1769 unsigned long service_interval,
1770 uint32_t *bit_width,
1771 uint32_t *sample_rate,
1772 uint32_t *channel_count)
1773{
1774 int ret_val = 0;
1775 if (is_usb_offload_enabled && is_usb_burst_mode_enabled)
1776 ret_val = usb_altset_for_service_interval(is_playback, service_interval,
1777 bit_width, sample_rate, channel_count);
1778
1779 return ret_val;
1780}
1781
1782int audio_extn_usb_set_service_interval(bool playback,
1783 unsigned long service_interval,
1784 bool *reconfig)
1785{
1786 int ret_val = 0;
1787 if (is_usb_offload_enabled && is_usb_burst_mode_enabled)
1788 ret_val = usb_set_service_interval(playback, service_interval, reconfig);
1789
1790 return ret_val;
1791}
1792
1793int audio_extn_usb_get_service_interval(bool playback,
1794 unsigned long *service_interval)
1795{
1796 int ret_val = 0;
1797 if (is_usb_offload_enabled && is_usb_burst_mode_enabled)
1798 ret_val = usb_get_service_interval(playback, service_interval);
1799
1800 return ret_val;
1801}
1802
1803int audio_extn_usb_check_and_set_svc_int(struct audio_usecase *uc_info,
1804 bool starting_output_stream)
1805{
1806 int ret_val = 0;
1807 if (is_usb_offload_enabled && is_usb_burst_mode_enabled)
1808 ret_val = usb_check_and_set_svc_int(uc_info, starting_output_stream);
1809
1810 return ret_val;
1811}
1812
1813bool audio_extn_usb_is_reconfig_req()
1814{
1815 bool ret_val = 0;
1816 if (is_usb_offload_enabled && is_usb_burst_mode_enabled)
1817 ret_val = usb_is_reconfig_req();
1818
1819 return ret_val;
1820}
1821
1822void audio_extn_usb_set_reconfig(bool is_required)
1823{
1824 if (is_usb_offload_enabled && is_usb_burst_mode_enabled)
1825 usb_set_reconfig(is_required);
1826}
1827
1828//END: USB_OFFLOAD ===========================================================
1829
1830//START: SPEAKER_PROTECTION ==========================================================
1831#ifdef __LP64__
Weiyin Jiangd5718bd2019-09-04 16:52:08 +08001832#define SPKR_PROT_LIB_PATH "/vendor/lib64/libspkrprot.so"
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001833#define CIRRUS_SPKR_PROT_LIB_PATH "/vendor/lib64/libcirrusspkrprot.so"
1834#else
Weiyin Jiangd5718bd2019-09-04 16:52:08 +08001835#define SPKR_PROT_LIB_PATH "/vendor/lib/libspkrprot.so"
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001836#define CIRRUS_SPKR_PROT_LIB_PATH "/vendor/lib/libcirrusspkrprot.so"
1837#endif
1838
Xu,Baochu235aec62022-02-14 10:20:44 +08001839
1840#define STR_CAT(path, extn) (path extn)
1841
1842#if LINUX_ENABLED
1843# define SPKR_PROT_LIB_PATH STR_CAT(LE_LIBDIR, "/audio.spkr.prot.so")
1844# define CIRRUS_SPKR_PROT_LIB_PATH STR_CAT(LE_LIBDIR, "/audio.external.spkr.prot.so")
1845#else
1846# ifdef __LP64__
1847# define SPKR_PROT_LIB_PATH "/vendor/lib64/libspkrprot.so"
1848# define CIRRUS_SPKR_PROT_LIB_PATH "/vendor/lib64/libcirrusspkrprot.so"
1849# else
1850# define SPKR_PROT_LIB_PATH "/vendor/lib/libspkrprot.so"
1851# define CIRRUS_SPKR_PROT_LIB_PATH "/vendor/lib/libcirrusspkrprot.so"
1852# endif
1853#endif
1854
1855
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001856static void *spkr_prot_lib_handle = NULL;
1857
1858typedef void (*spkr_prot_init_t)(void *, spkr_prot_init_config_t);
1859static spkr_prot_init_t spkr_prot_init;
1860
1861typedef int (*spkr_prot_deinit_t)();
1862static spkr_prot_deinit_t spkr_prot_deinit;
1863
1864typedef int (*spkr_prot_start_processing_t)(snd_device_t);
1865static spkr_prot_start_processing_t spkr_prot_start_processing;
1866
1867typedef void (*spkr_prot_stop_processing_t)(snd_device_t);
1868static spkr_prot_stop_processing_t spkr_prot_stop_processing;
1869
1870typedef bool (*spkr_prot_is_enabled_t)();
1871static spkr_prot_is_enabled_t spkr_prot_is_enabled;
1872
1873typedef void (*spkr_prot_calib_cancel_t)(void *);
1874static spkr_prot_calib_cancel_t spkr_prot_calib_cancel;
1875
1876typedef void (*spkr_prot_set_parameters_t)(struct str_parms *,
1877 char *, int);
1878static spkr_prot_set_parameters_t spkr_prot_set_parameters;
1879
1880typedef int (*fbsp_set_parameters_t)(struct str_parms *);
1881static fbsp_set_parameters_t fbsp_set_parameters;
1882
1883typedef int (*fbsp_get_parameters_t)(struct str_parms *,
1884 struct str_parms *);
1885static fbsp_get_parameters_t fbsp_get_parameters;
1886
1887typedef int (*get_spkr_prot_snd_device_t)(snd_device_t);
1888static get_spkr_prot_snd_device_t get_spkr_prot_snd_device;
1889
1890void spkr_prot_feature_init(bool is_feature_enabled)
1891{
Weiyin Jiangd5718bd2019-09-04 16:52:08 +08001892 ALOGD("%s: Called with feature %s, vendor_enhanced_info 0x%x", __func__,
1893 is_feature_enabled ? "Enabled" : "NOT Enabled", vendor_enhanced_info);
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001894 if (is_feature_enabled) {
Weiyin Jiangd5718bd2019-09-04 16:52:08 +08001895 // dlopen lib
Xu,Baochu235aec62022-02-14 10:20:44 +08001896#if LINUX_ENABLED
1897 spkr_prot_lib_handle = dlopen(SPKR_PROT_LIB_PATH, RTLD_NOW);
1898#else
Weiyin Jiangd5718bd2019-09-04 16:52:08 +08001899 if ((vendor_enhanced_info & 0x3) == 0x0) // Pure AOSP
Arun Mirpuri5dc77802019-02-26 16:32:42 -08001900 spkr_prot_lib_handle = dlopen(CIRRUS_SPKR_PROT_LIB_PATH, RTLD_NOW);
Weiyin Jiangd5718bd2019-09-04 16:52:08 +08001901 else
1902 spkr_prot_lib_handle = dlopen(SPKR_PROT_LIB_PATH, RTLD_NOW);
Xu,Baochu235aec62022-02-14 10:20:44 +08001903#endif
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001904
1905 if (spkr_prot_lib_handle == NULL) {
1906 ALOGE("%s: dlopen failed", __func__);
1907 goto feature_disabled;
1908 }
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001909
Weiyin Jiangd5718bd2019-09-04 16:52:08 +08001910 // map each function
1911 // if mandatoy functions are not found, disble feature
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001912 // Mandatory functions
1913 if (((spkr_prot_init =
1914 (spkr_prot_init_t)dlsym(spkr_prot_lib_handle, "spkr_prot_init")) == NULL) ||
1915 ((spkr_prot_deinit =
1916 (spkr_prot_deinit_t)dlsym(spkr_prot_lib_handle, "spkr_prot_deinit")) == NULL) ||
1917 ((spkr_prot_start_processing =
1918 (spkr_prot_start_processing_t)dlsym(spkr_prot_lib_handle, "spkr_prot_start_processing")) == NULL) ||
1919 ((spkr_prot_stop_processing =
1920 (spkr_prot_stop_processing_t)dlsym(spkr_prot_lib_handle, "spkr_prot_stop_processing")) == NULL) ||
1921 ((spkr_prot_is_enabled =
1922 (spkr_prot_is_enabled_t)dlsym(spkr_prot_lib_handle, "spkr_prot_is_enabled")) == NULL) ||
1923 ((spkr_prot_calib_cancel =
1924 (spkr_prot_calib_cancel_t)dlsym(spkr_prot_lib_handle, "spkr_prot_calib_cancel")) == NULL) ||
1925 ((get_spkr_prot_snd_device =
1926 (get_spkr_prot_snd_device_t)dlsym(spkr_prot_lib_handle, "get_spkr_prot_snd_device")) == NULL)) {
1927 ALOGE("%s: dlsym failed", __func__);
1928 goto feature_disabled;
1929 }
1930
Arun Mirpurie008ed22019-03-21 11:21:04 -07001931 // optional functions, can be NULL
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08001932 spkr_prot_set_parameters = NULL;
1933 fbsp_set_parameters = NULL;
1934 fbsp_get_parameters = NULL;
1935 if ((spkr_prot_set_parameters =
1936 (spkr_prot_set_parameters_t)dlsym(spkr_prot_lib_handle, "spkr_prot_set_parameters")) == NULL) {
1937 ALOGW("%s: dlsym failed for spkr_prot_set_parameters", __func__);
1938 }
1939
1940 if ((fbsp_set_parameters =
1941 (fbsp_set_parameters_t)dlsym(spkr_prot_lib_handle, "fbsp_set_parameters")) == NULL) {
1942 ALOGW("%s: dlsym failed for fbsp_set_parameters", __func__);
1943 }
1944
1945 if ((fbsp_get_parameters =
1946 (fbsp_get_parameters_t)dlsym(spkr_prot_lib_handle, "fbsp_get_parameters")) == NULL) {
1947 ALOGW("%s: dlsym failed for fbsp_get_parameters", __func__);
1948 }
1949
1950 ALOGD("%s:: ---- Feature SPKR_PROT is Enabled ----", __func__);
1951 return;
1952 }
1953
1954feature_disabled:
1955 if (spkr_prot_lib_handle) {
1956 dlclose(spkr_prot_lib_handle);
1957 spkr_prot_lib_handle = NULL;
1958 }
1959
1960 spkr_prot_init = NULL;
1961 spkr_prot_deinit = NULL;
1962 spkr_prot_start_processing = NULL;
1963 spkr_prot_stop_processing = NULL;
1964 spkr_prot_is_enabled = NULL;
1965 spkr_prot_calib_cancel = NULL;
1966 spkr_prot_set_parameters = NULL;
1967 fbsp_set_parameters = NULL;
1968 fbsp_get_parameters = NULL;
1969 get_spkr_prot_snd_device = NULL;
1970
1971 ALOGW(":: %s: ---- Feature SPKR_PROT is disabled ----", __func__);
1972 return;
1973}
1974
1975void audio_extn_spkr_prot_init(void *adev) {
1976 if (spkr_prot_init != NULL) {
1977 // init function pointers
1978 spkr_prot_init_config_t spkr_prot_config_val;
1979 spkr_prot_config_val.fp_read_line_from_file = read_line_from_file;
1980 spkr_prot_config_val.fp_get_usecase_from_list = get_usecase_from_list;
1981 spkr_prot_config_val.fp_disable_snd_device = disable_snd_device;
1982 spkr_prot_config_val.fp_enable_snd_device = enable_snd_device;
1983 spkr_prot_config_val.fp_disable_audio_route = disable_audio_route;
1984 spkr_prot_config_val.fp_enable_audio_route = enable_audio_route;
1985 spkr_prot_config_val.fp_platform_set_snd_device_backend = platform_set_snd_device_backend;
1986 spkr_prot_config_val.fp_platform_get_snd_device_name_extn = platform_get_snd_device_name_extn;
1987 spkr_prot_config_val.fp_platform_get_default_app_type_v2 = platform_get_default_app_type_v2;
1988 spkr_prot_config_val.fp_platform_send_audio_calibration = platform_send_audio_calibration;
1989 spkr_prot_config_val.fp_platform_get_pcm_device_id = platform_get_pcm_device_id;
1990 spkr_prot_config_val.fp_platform_get_snd_device_name = platform_get_snd_device_name;
1991 spkr_prot_config_val.fp_platform_spkr_prot_is_wsa_analog_mode = platform_spkr_prot_is_wsa_analog_mode;
1992 spkr_prot_config_val.fp_platform_get_vi_feedback_snd_device = platform_get_vi_feedback_snd_device;
1993 spkr_prot_config_val.fp_platform_get_spkr_prot_snd_device = platform_get_spkr_prot_snd_device;
1994 spkr_prot_config_val.fp_platform_check_and_set_codec_backend_cfg = platform_check_and_set_codec_backend_cfg;
1995 spkr_prot_config_val.fp_audio_extn_get_snd_card_split = audio_extn_get_snd_card_split;
1996 spkr_prot_config_val.fp_audio_extn_is_vbat_enabled = audio_extn_is_vbat_enabled;
1997
1998 spkr_prot_init(adev, spkr_prot_config_val);
1999 }
2000
2001 return;
2002}
2003
2004int audio_extn_spkr_prot_deinit() {
2005 int ret_val = 0;
2006
2007 if (spkr_prot_deinit != NULL)
2008 ret_val = spkr_prot_deinit();
2009
2010 return ret_val;
2011}
2012
2013int audio_extn_spkr_prot_start_processing(snd_device_t snd_device) {
2014 int ret_val = 0;
2015
2016 if (spkr_prot_start_processing != NULL)
2017 ret_val = spkr_prot_start_processing(snd_device);
2018
2019 return ret_val;
2020}
2021
2022void audio_extn_spkr_prot_stop_processing(snd_device_t snd_device)
2023{
2024 if (spkr_prot_stop_processing != NULL)
2025 spkr_prot_stop_processing(snd_device);
2026
2027 return;
2028}
2029
2030bool audio_extn_spkr_prot_is_enabled()
2031{
2032 bool ret_val = false;
2033
2034 if (spkr_prot_is_enabled != NULL)
2035 ret_val = spkr_prot_is_enabled();
2036
2037 return ret_val;
2038}
2039
2040void audio_extn_spkr_prot_calib_cancel(void *adev)
2041{
2042 if (spkr_prot_calib_cancel != NULL)
2043 spkr_prot_calib_cancel(adev);
2044
2045 return;
2046}
2047
2048void audio_extn_spkr_prot_set_parameters(struct str_parms *parms,
2049 char *value, int len)
2050{
2051 if (spkr_prot_set_parameters != NULL)
2052 spkr_prot_set_parameters(parms, value, len);
2053
2054 return;
2055}
2056
2057int audio_extn_fbsp_set_parameters(struct str_parms *parms)
2058{
2059 int ret_val = 0;
2060
2061 if (fbsp_set_parameters != NULL)
2062 ret_val = fbsp_set_parameters(parms);
2063
2064 return ret_val;
2065}
2066
2067int audio_extn_fbsp_get_parameters(struct str_parms *query,
2068 struct str_parms *reply)
2069{
2070 int ret_val = 0;
2071
2072 if (fbsp_get_parameters != NULL)
2073 ret_val = fbsp_get_parameters(query, reply);
2074
2075 return ret_val;
2076}
2077
2078int audio_extn_get_spkr_prot_snd_device(snd_device_t snd_device)
2079{
2080 int ret_val = snd_device;
2081
2082 if (get_spkr_prot_snd_device != NULL)
2083 ret_val = get_spkr_prot_snd_device(snd_device);
2084
2085 return ret_val;
2086}
2087
2088//END: SPEAKER_PROTECTION ==========================================================
2089
2090//START: EXTERNAL_QDSP ================================================================
2091#ifdef __LP64__
2092#define EXTERNAL_QDSP_LIB_PATH "/vendor/lib64/libextqdsp.so"
2093#else
2094#define EXTERNAL_QDSP_LIB_PATH "/vendor/lib/libextqdsp.so"
2095#endif
2096
2097static void *external_qdsp_lib_handle = NULL;
2098
2099typedef void (*external_qdsp_init_t)(void *);
2100static external_qdsp_init_t external_qdsp_init;
2101
2102typedef void (*external_qdsp_deinit_t)(void);
2103static external_qdsp_deinit_t external_qdsp_deinit;
2104
2105typedef bool (*external_qdsp_set_state_t)(struct audio_device *,
2106 int , float , bool);
2107static external_qdsp_set_state_t external_qdsp_set_state;
2108
2109typedef void (*external_qdsp_set_device_t)(struct audio_usecase *);
2110static external_qdsp_set_device_t external_qdsp_set_device;
2111
2112typedef void (*external_qdsp_set_parameter_t)(struct audio_device *,
2113 struct str_parms *);
2114static external_qdsp_set_parameter_t external_qdsp_set_parameter;
2115
2116typedef bool (*external_qdsp_supported_usb_t)(void);
2117static external_qdsp_supported_usb_t external_qdsp_supported_usb;
2118
2119void external_qdsp_feature_init(bool is_feature_enabled)
2120{
2121 ALOGD("%s: Called with feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
2122 if (is_feature_enabled) {
2123 //dlopen lib
2124 external_qdsp_lib_handle = dlopen(EXTERNAL_QDSP_LIB_PATH, RTLD_NOW);
2125 if (external_qdsp_lib_handle == NULL) {
2126 ALOGE("%s: dlopen failed", __func__);
2127 goto feature_disabled;
2128 }
2129 //map each function
2130 //on any faliure to map any function, disble feature
2131 if (((external_qdsp_init =
2132 (external_qdsp_init_t)dlsym(external_qdsp_lib_handle, "ma_init")) == NULL) ||
2133 ((external_qdsp_deinit =
2134 (external_qdsp_deinit_t)dlsym(external_qdsp_lib_handle, "ma_deinit")) == NULL) ||
2135 ((external_qdsp_set_state =
2136 (external_qdsp_set_state_t)dlsym(external_qdsp_lib_handle, "set_state")) == NULL) ||
2137 ((external_qdsp_set_device =
2138 (external_qdsp_set_device_t)dlsym(external_qdsp_lib_handle, "set_device")) == NULL) ||
2139 ((external_qdsp_set_parameter =
2140 (external_qdsp_set_parameter_t)dlsym(external_qdsp_lib_handle, "set_parameters")) == NULL) ||
2141 ((external_qdsp_supported_usb =
2142 (external_qdsp_supported_usb_t)dlsym(external_qdsp_lib_handle, "supported_usb")) == NULL)) {
2143 ALOGE("%s: dlsym failed", __func__);
2144 goto feature_disabled;
2145 }
2146
2147 ALOGD("%s:: ---- Feature EXTERNAL_QDSP is Enabled ----", __func__);
2148 return;
2149 }
2150
2151feature_disabled:
2152 if (external_qdsp_lib_handle) {
2153 dlclose(external_qdsp_lib_handle);
2154 external_qdsp_lib_handle = NULL;
2155 }
2156
2157 external_qdsp_init = NULL;
2158 external_qdsp_deinit = NULL;
2159 external_qdsp_set_state = NULL;
2160 external_qdsp_set_device = NULL;
2161 external_qdsp_set_parameter = NULL;
2162 external_qdsp_supported_usb = NULL;
2163
2164 ALOGW(":: %s: ---- Feature EXTERNAL_QDSP is disabled ----", __func__);
2165 return;
2166}
2167
2168void audio_extn_qdsp_init(void *platform) {
2169 if (external_qdsp_init != NULL)
2170 external_qdsp_init(platform);
2171
2172 return;
2173}
2174
2175void audio_extn_qdsp_deinit() {
2176 if (external_qdsp_deinit != NULL)
2177 external_qdsp_deinit();
2178
2179 return;
2180}
2181
2182bool audio_extn_qdsp_set_state(struct audio_device *adev, int stream_type,
2183 float vol, bool active) {
2184 bool ret_val = false;
2185
2186 if (external_qdsp_set_state != NULL)
2187 ret_val = external_qdsp_set_state(adev, stream_type, vol, active);
2188
2189 return ret_val;
2190}
2191
2192void audio_extn_qdsp_set_device(struct audio_usecase *usecase) {
2193 if (external_qdsp_set_device != NULL)
2194 external_qdsp_set_device(usecase);
2195
2196 return;
2197}
2198
2199void audio_extn_qdsp_set_parameters(struct audio_device *adev,
2200 struct str_parms *parms) {
2201 if (external_qdsp_set_parameter != NULL)
2202 external_qdsp_set_parameter(adev, parms);
2203
2204 return;
2205}
2206
2207bool audio_extn_qdsp_supported_usb() {
2208 bool ret_val = false;
2209
2210 if (external_qdsp_supported_usb != NULL)
2211 ret_val = external_qdsp_supported_usb();
2212
2213 return ret_val;
2214}
2215
2216
2217//END: EXTERNAL_QDSP ================================================================
2218
2219//START: EXTERNAL_SPEAKER ================================================================
2220#ifdef __LP64__
2221#define EXTERNAL_SPKR_LIB_PATH "/vendor/lib64/libextspkr.so"
2222#else
2223#define EXTERNAL_SPKR_LIB_PATH "/vendor/lib/libextspkr.so"
2224#endif
2225
2226static void *external_speaker_lib_handle = NULL;
2227
2228typedef void* (*external_speaker_init_t)(struct audio_device *);
2229static external_speaker_init_t external_speaker_init;
2230
2231typedef void (*external_speaker_deinit_t)(void *);
2232static external_speaker_deinit_t external_speaker_deinit;
2233
2234typedef void (*external_speaker_update_t)(void *);
2235static external_speaker_update_t external_speaker_update;
2236
2237typedef void (*external_speaker_set_mode_t)(void *, audio_mode_t);
2238static external_speaker_set_mode_t external_speaker_set_mode;
2239
2240typedef void (*external_speaker_set_voice_vol_t)(void *, float);
2241static external_speaker_set_voice_vol_t external_speaker_set_voice_vol;
2242
2243
2244void external_speaker_feature_init(bool is_feature_enabled)
2245{
2246 ALOGD("%s: Called with feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
2247 if (is_feature_enabled) {
2248 //dlopen lib
2249 external_speaker_lib_handle = dlopen(EXTERNAL_SPKR_LIB_PATH, RTLD_NOW);
2250 if (external_speaker_lib_handle == NULL) {
2251 ALOGE("%s: dlopen failed", __func__);
2252 goto feature_disabled;
2253 }
2254 //map each function
2255 //on any faliure to map any function, disble feature
2256 if (((external_speaker_init =
2257 (external_speaker_init_t)dlsym(external_speaker_lib_handle, "extspk_init")) == NULL) ||
2258 ((external_speaker_deinit =
2259 (external_speaker_deinit_t)dlsym(external_speaker_lib_handle, "extspk_deinit")) == NULL) ||
2260 ((external_speaker_update =
2261 (external_speaker_update_t)dlsym(external_speaker_lib_handle, "extspk_update")) == NULL) ||
2262 ((external_speaker_set_mode =
2263 (external_speaker_set_mode_t)dlsym(external_speaker_lib_handle, "extspk_set_mode")) == NULL) ||
2264 ((external_speaker_set_voice_vol =
2265 (external_speaker_set_voice_vol_t)dlsym(external_speaker_lib_handle, "extspk_set_voice_vol")) == NULL)) {
2266 ALOGE("%s: dlsym failed", __func__);
2267 goto feature_disabled;
2268 }
2269
2270 ALOGD("%s:: ---- Feature EXTERNAL_SPKR is Enabled ----", __func__);
2271 return;
2272 }
2273
2274feature_disabled:
2275 if (external_speaker_lib_handle) {
2276 dlclose(external_speaker_lib_handle);
2277 external_speaker_lib_handle = NULL;
2278 }
2279
2280 external_speaker_init = NULL;
2281 external_speaker_deinit = NULL;
2282 external_speaker_update = NULL;
2283 external_speaker_set_mode = NULL;
2284 external_speaker_set_voice_vol = NULL;
2285
2286 ALOGW(":: %s: ---- Feature EXTERNAL_SPKR is disabled ----", __func__);
2287 return;
2288}
2289
2290void *audio_extn_extspk_init(struct audio_device *adev) {
2291 void* ret_val = NULL;
2292
2293 if (external_speaker_init != NULL)
2294 ret_val = external_speaker_init(adev);
2295
2296 return ret_val;
2297}
2298
2299void audio_extn_extspk_deinit(void *extn) {
2300 if (external_speaker_deinit != NULL)
2301 external_speaker_deinit(extn);
2302
2303 return;
2304}
2305
2306void audio_extn_extspk_update(void* extn) {
2307 if (external_speaker_update != NULL)
2308 external_speaker_update(extn);
2309
2310 return;
2311}
2312
2313void audio_extn_extspk_set_mode(void* extn, audio_mode_t mode) {
2314 if (external_speaker_set_mode != NULL)
2315 external_speaker_set_mode(extn, mode);
2316
2317 return;
2318}
2319
2320void audio_extn_extspk_set_voice_vol(void* extn, float vol) {
2321 if (external_speaker_set_voice_vol != NULL)
2322 external_speaker_set_voice_vol(extn, vol);
2323
2324 return;
2325}
2326
2327//END: EXTERNAL_SPEAKER ================================================================
2328
2329
2330//START: EXTERNAL_SPEAKER_TFA ================================================================
2331#ifdef __LP64__
2332#define EXTERNAL_SPKR_TFA_LIB_PATH "/vendor/lib64/libextspkr_tfa.so"
2333#else
2334#define EXTERNAL_SPKR_TFA_LIB_PATH "/vendor/lib/libextspkr_tfa.so"
2335#endif
2336
2337static void *external_speaker_tfa_lib_handle = NULL;
2338
2339typedef int (*external_speaker_tfa_enable_t)(void);
2340static external_speaker_tfa_enable_t external_speaker_tfa_enable;
2341
2342typedef void (*external_speaker_tfa_disable_t)(snd_device_t);
2343static external_speaker_tfa_disable_t external_speaker_tfa_disable;
2344
2345typedef void (*external_speaker_tfa_set_mode_t)();
2346static external_speaker_tfa_set_mode_t external_speaker_tfa_set_mode;
2347
2348typedef void (*external_speaker_tfa_set_mode_bt_t)();
2349static external_speaker_tfa_set_mode_bt_t external_speaker_tfa_set_mode_bt;
2350
2351typedef void (*external_speaker_tfa_update_t)(void);
2352static external_speaker_tfa_update_t external_speaker_tfa_update;
2353
2354typedef void (*external_speaker_tfa_set_voice_vol_t)(float);
2355static external_speaker_tfa_set_voice_vol_t external_speaker_tfa_set_voice_vol;
2356
2357typedef int (*external_speaker_tfa_init_t)(struct audio_device *);
2358static external_speaker_tfa_init_t external_speaker_tfa_init;
2359
2360typedef void (*external_speaker_tfa_deinit_t)(void);
2361static external_speaker_tfa_deinit_t external_speaker_tfa_deinit;
2362
2363typedef bool (*external_speaker_tfa_is_supported_t)(void);
2364static external_speaker_tfa_is_supported_t external_speaker_tfa_is_supported;
2365
2366void external_speaker_tfa_feature_init(bool is_feature_enabled)
2367{
2368 ALOGD("%s: Called with feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
2369 if (is_feature_enabled) {
2370 //dlopen lib
2371 external_speaker_tfa_lib_handle = dlopen(EXTERNAL_SPKR_TFA_LIB_PATH, RTLD_NOW);
2372 if (external_speaker_tfa_lib_handle == NULL) {
2373 ALOGE("%s: dlopen failed", __func__);
2374 goto feature_disabled;
2375 }
2376 //map each function
2377 //on any faliure to map any function, disble feature
2378 if (((external_speaker_tfa_enable =
2379 (external_speaker_tfa_enable_t)dlsym(external_speaker_tfa_lib_handle, "tfa_98xx_enable_speaker")) == NULL) ||
2380 ((external_speaker_tfa_disable =
2381 (external_speaker_tfa_disable_t)dlsym(external_speaker_tfa_lib_handle, "tfa_98xx_disable_speaker")) == NULL) ||
2382 ((external_speaker_tfa_set_mode =
2383 (external_speaker_tfa_set_mode_t)dlsym(external_speaker_tfa_lib_handle, "tfa_98xx_set_mode")) == NULL) ||
2384 ((external_speaker_tfa_set_mode_bt =
2385 (external_speaker_tfa_set_mode_bt_t)dlsym(external_speaker_tfa_lib_handle, "tfa_98xx_set_mode_bt")) == NULL) ||
2386 ((external_speaker_tfa_update =
2387 (external_speaker_tfa_update_t)dlsym(external_speaker_tfa_lib_handle, "tfa_98xx_update")) == NULL) ||
2388 ((external_speaker_tfa_set_voice_vol =
2389 (external_speaker_tfa_set_voice_vol_t)dlsym(external_speaker_tfa_lib_handle, "tfa_98xx_set_voice_vol")) == NULL) ||
2390 ((external_speaker_tfa_init =
2391 (external_speaker_tfa_init_t)dlsym(external_speaker_tfa_lib_handle, "tfa_98xx_init")) == NULL) ||
2392 ((external_speaker_tfa_deinit =
2393 (external_speaker_tfa_deinit_t)dlsym(external_speaker_tfa_lib_handle, "tfa_98xx_deinit")) == NULL) ||
2394 ((external_speaker_tfa_is_supported =
2395 (external_speaker_tfa_is_supported_t)dlsym(external_speaker_tfa_lib_handle, "tfa_98xx_is_supported")) == NULL)) {
2396 ALOGE("%s: dlsym failed", __func__);
2397 goto feature_disabled;
2398 }
2399
2400 ALOGD("%s:: ---- Feature EXTERNAL_SPKR is Enabled ----", __func__);
2401 return;
2402 }
2403
2404feature_disabled:
2405 if (external_speaker_tfa_lib_handle) {
2406 dlclose(external_speaker_tfa_lib_handle);
2407 external_speaker_tfa_lib_handle = NULL;
2408 }
2409
2410 external_speaker_tfa_enable = NULL;
2411 external_speaker_tfa_disable = NULL;
2412 external_speaker_tfa_set_mode = NULL;
2413 external_speaker_tfa_update = NULL;
2414 external_speaker_tfa_set_voice_vol = NULL;
2415 external_speaker_tfa_init = NULL;
2416 external_speaker_tfa_deinit = NULL;
2417 external_speaker_tfa_is_supported = NULL;
2418
2419 ALOGW(":: %s: ---- Feature EXTERNAL_SPKR_TFA is disabled ----", __func__);
2420 return;
2421}
2422
2423int audio_extn_external_speaker_tfa_enable_speaker() {
2424 int ret_val = 0;
2425
2426 if (external_speaker_tfa_enable != NULL)
2427 ret_val = external_speaker_tfa_enable();
2428
2429 return ret_val;
2430}
2431
2432void audio_extn_external_speaker_tfa_disable_speaker(snd_device_t snd_device) {
2433 if (external_speaker_tfa_disable != NULL)
2434 external_speaker_tfa_disable(snd_device);
2435
2436 return;
2437}
2438
2439void audio_extn_external_speaker_tfa_set_mode(bool is_mode_bt) {
2440 if (is_mode_bt && (external_speaker_tfa_set_mode_bt != NULL))
2441 external_speaker_tfa_set_mode_bt();
2442 else if (external_speaker_tfa_set_mode != NULL)
2443 external_speaker_tfa_set_mode();
2444
2445 return;
2446}
2447
2448void audio_extn_external_speaker_tfa_update() {
2449 if (external_speaker_tfa_update != NULL)
2450 external_speaker_tfa_update();
2451
2452 return;
2453}
2454
2455void audio_extn_external_speaker_tfa_set_voice_vol(float vol) {
2456 if (external_speaker_tfa_set_voice_vol != NULL)
2457 external_speaker_tfa_set_voice_vol(vol);
2458
2459 return;
2460}
2461
2462int audio_extn_external_tfa_speaker_init(struct audio_device *adev) {
2463 int ret_val = 0;
2464
2465 if (external_speaker_tfa_init != NULL)
2466 ret_val = external_speaker_tfa_init(adev);
2467
2468 return ret_val;
2469}
2470
2471void audio_extn_external_speaker_tfa_deinit() {
2472 if (external_speaker_tfa_deinit != NULL)
2473 external_speaker_tfa_deinit();
2474
2475 return;
2476}
2477
2478bool audio_extn_external_speaker_tfa_is_supported() {
2479 bool ret_val = false;
2480
2481 if (external_speaker_tfa_is_supported != NULL)
2482 ret_val = external_speaker_tfa_is_supported;
2483
2484 return ret_val;
2485}
2486
2487
2488//END: EXTERNAL_SPEAKER_TFA ================================================================
2489
2490
2491//START: HWDEP_CAL ================================================================
2492#ifdef __LP64__
2493#define HWDEP_CAL_LIB_PATH "/vendor/lib64/libhwdepcal.so"
2494#else
2495#define HWDEP_CAL_LIB_PATH "/vendor/lib/libhwdepcal.so"
2496#endif
2497
2498static void *hwdep_cal_lib_handle = NULL;
2499
2500typedef void (*hwdep_cal_send_t)(int, void*);
2501static hwdep_cal_send_t hwdep_cal_send;
2502
Arun Mirpurie008ed22019-03-21 11:21:04 -07002503
2504//If feature is enabled, please copy hwdep_cal.c in the audio_extn dir
2505//Current lib doesn't have any src files
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08002506void hwdep_cal_feature_init(bool is_feature_enabled)
2507{
2508 ALOGD("%s: Called with feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
2509 if (is_feature_enabled) {
2510 //dlopen lib
2511 hwdep_cal_lib_handle = dlopen(HWDEP_CAL_LIB_PATH, RTLD_NOW);
2512 if (hwdep_cal_lib_handle == NULL) {
2513 ALOGE("%s: dlopen failed", __func__);
2514 goto feature_disabled;
2515 }
2516 //map each function
2517 //on any faliure to map any function, disble feature
2518 if ((hwdep_cal_send =
2519 (hwdep_cal_send_t)dlsym(hwdep_cal_lib_handle, "hwdep_cal_send")) == NULL) {
2520 ALOGE("%s: dlsym failed", __func__);
2521 goto feature_disabled;
2522 }
2523
2524 ALOGD("%s:: ---- Feature HWDEP_CAL is Enabled ----", __func__);
2525 return;
2526 }
2527
2528feature_disabled:
2529 if (hwdep_cal_lib_handle) {
2530 dlclose(hwdep_cal_lib_handle);
2531 hwdep_cal_lib_handle = NULL;
2532 }
2533
2534 hwdep_cal_send = NULL;
2535
2536 ALOGW(":: %s: ---- Feature HWDEP_CAL is disabled ----", __func__);
2537 return;
2538}
2539
2540void audio_extn_hwdep_cal_send(int snd_card, void *acdb_handle)
2541{
2542 if (hwdep_cal_send != NULL)
2543 hwdep_cal_send(snd_card, acdb_handle);
2544
2545 return;
2546}
2547
2548
2549//END: HWDEP_CAL =====================================================================
2550
2551
2552//START: DSM_FEEDBACK ================================================================
2553#ifdef __LP64__
2554#define DSM_FEEDBACK_LIB_PATH "/vendor/lib64/libdsmfeedback.so"
2555#else
2556#define DSM_FEEDBACK_LIB_PATH "/vendor/lib/libdsmfeedback.so"
2557#endif
2558
2559static void *dsm_feedback_lib_handle = NULL;
2560
2561typedef void (*dsm_feedback_enable_t)(struct audio_device*, snd_device_t, bool);
2562static dsm_feedback_enable_t dsm_feedback_enable;
2563
2564void dsm_feedback_feature_init (bool is_feature_enabled)
2565{
2566 ALOGD("%s: Called with feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
2567 if (is_feature_enabled) {
2568 //dlopen lib
2569 dsm_feedback_lib_handle = dlopen(DSM_FEEDBACK_LIB_PATH, RTLD_NOW);
2570 if (dsm_feedback_lib_handle == NULL) {
2571 ALOGE("%s: dlopen failed", __func__);
2572 goto feature_disabled;
2573 }
2574 //map each function
2575 //on any faliure to map any function, disble feature
2576 if ((dsm_feedback_enable =
2577 (dsm_feedback_enable_t)dlsym(dsm_feedback_lib_handle, "dsm_feedback_enable")) == NULL) {
2578 ALOGE("%s: dlsym failed", __func__);
2579 goto feature_disabled;
2580 }
2581
2582 ALOGD("%s:: ---- Feature DSM_FEEDBACK is Enabled ----", __func__);
2583 return;
2584 }
2585
2586feature_disabled:
2587 if (dsm_feedback_lib_handle) {
2588 dlclose(dsm_feedback_lib_handle);
2589 dsm_feedback_lib_handle = NULL;
2590 }
2591
2592 dsm_feedback_enable = NULL;
2593
2594 ALOGW(":: %s: ---- Feature DSM_FEEDBACK is disabled ----", __func__);
2595 return;
2596}
2597
2598void audio_extn_dsm_feedback_enable(struct audio_device *adev, snd_device_t snd_device, bool benable)
2599{
2600 if (dsm_feedback_enable != NULL)
2601 dsm_feedback_enable(adev, snd_device, benable);
2602
2603 return;
2604}
2605
2606//END: DSM_FEEDBACK ================================================================
2607
2608//START: SND_MONITOR_FEATURE ================================================================
2609#ifdef __LP64__
2610#define SND_MONITOR_PATH "/vendor/lib64/libsndmonitor.so"
2611#else
2612#define SND_MONITOR_PATH "/vendor/lib/libsndmonitor.so"
2613#endif
2614static void *snd_mnt_lib_handle = NULL;
2615
2616typedef int (*snd_mon_init_t)();
2617static snd_mon_init_t snd_mon_init;
2618typedef int (*snd_mon_deinit_t)();
2619static snd_mon_deinit_t snd_mon_deinit;
2620typedef int (*snd_mon_register_listener_t)(void *, snd_mon_cb);
2621static snd_mon_register_listener_t snd_mon_register_listener;
2622typedef int (*snd_mon_unregister_listener_t)(void *);
2623static snd_mon_unregister_listener_t snd_mon_unregister_listener;
2624
2625void snd_mon_feature_init (bool is_feature_enabled)
2626{
2627 ALOGD("%s: Called with feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
2628 if (is_feature_enabled) {
2629 //dlopen lib
2630 snd_mnt_lib_handle = dlopen(SND_MONITOR_PATH, RTLD_NOW);
2631 if (snd_mnt_lib_handle == NULL) {
2632 ALOGE("%s: dlopen failed", __func__);
2633 goto feature_disabled;
2634 }
2635 //map each function
2636 //on any faliure to map any function, disble feature
2637 if (((snd_mon_init = (snd_mon_init_t)dlsym(snd_mnt_lib_handle,"snd_mon_init")) == NULL) ||
2638 ((snd_mon_deinit = (snd_mon_deinit_t)dlsym(snd_mnt_lib_handle,"snd_mon_deinit")) == NULL) ||
2639 ((snd_mon_register_listener = (snd_mon_register_listener_t)dlsym(snd_mnt_lib_handle,"snd_mon_register_listener")) == NULL) ||
2640 ((snd_mon_unregister_listener = (snd_mon_unregister_listener_t)dlsym(snd_mnt_lib_handle,"snd_mon_unregister_listener")) == NULL)) {
2641 ALOGE("%s: dlsym failed", __func__);
2642 goto feature_disabled;
2643 }
2644 ALOGD("%s:: ---- Feature SND_MONITOR is Enabled ----", __func__);
2645 return;
2646 }
2647
2648feature_disabled:
2649 if (snd_mnt_lib_handle) {
2650 dlclose(snd_mnt_lib_handle);
2651 snd_mnt_lib_handle = NULL;
2652 }
2653
2654 snd_mon_init = NULL;
2655 snd_mon_deinit = NULL;
2656 snd_mon_register_listener = NULL;
2657 snd_mon_unregister_listener = NULL;
2658 ALOGW(":: %s: ---- Feature SND_MONITOR is disabled ----", __func__);
2659 return;
2660}
2661
2662int audio_extn_snd_mon_init()
2663{
2664 int ret = 0;
2665 if (snd_mon_init != NULL)
2666 ret = snd_mon_init();
2667
2668 return ret;
2669}
2670
2671int audio_extn_snd_mon_deinit()
2672{
2673 int ret = 0;
2674 if (snd_mon_deinit != NULL)
2675 ret = snd_mon_deinit();
2676
2677 return ret;
2678}
2679
2680int audio_extn_snd_mon_register_listener(void *stream, snd_mon_cb cb)
2681{
2682 int ret = 0;
2683 if (snd_mon_register_listener != NULL)
2684 ret = snd_mon_register_listener(stream, cb);
2685
2686 return ret;
2687}
2688
2689int audio_extn_snd_mon_unregister_listener(void *stream)
2690{
2691 int ret = 0;
2692 if (snd_mon_unregister_listener != NULL)
2693 ret = snd_mon_unregister_listener(stream);
2694
2695 return ret;
2696}
2697
2698//END: SND_MONITOR_FEATURE ================================================================
2699
2700//START: SOURCE_TRACKING_FEATURE ==============================================
2701int get_soundfocus_data(const struct audio_device *adev,
2702 struct sound_focus_param *payload);
2703int get_sourcetrack_data(const struct audio_device *adev,
2704 struct source_tracking_param *payload);
2705int set_soundfocus_data(struct audio_device *adev,
2706 struct sound_focus_param *payload);
2707void source_track_set_parameters(struct audio_device *adev,
2708 struct str_parms *parms);
2709void source_track_get_parameters(const struct audio_device *adev,
2710 struct str_parms *query,
2711 struct str_parms *reply);
2712
2713static bool is_src_trkn_enabled = false;
2714
2715void src_trkn_feature_init(bool is_feature_enabled) {
2716 is_src_trkn_enabled = is_feature_enabled;
2717
2718 if (is_src_trkn_enabled) {
2719 ALOGD("%s:: ---- Feature SOURCE_TRACKING is Enabled ----", __func__);
2720 return;
2721 }
2722
2723 ALOGW(":: %s: ---- Feature SOURCE_TRACKING is disabled ----", __func__);
2724}
2725
2726int audio_extn_get_soundfocus_data(const struct audio_device *adev,
2727 struct sound_focus_param *payload) {
2728 int ret = 0;
2729
2730 if (is_src_trkn_enabled)
2731 ret = get_soundfocus_data(adev, payload);
2732
2733 return ret;
2734}
2735
2736int audio_extn_get_sourcetrack_data(const struct audio_device *adev,
2737 struct source_tracking_param *payload) {
2738 int ret = 0;
2739
2740 if (is_src_trkn_enabled)
2741 ret = get_sourcetrack_data(adev, payload);
2742
2743 return ret;
2744}
2745
2746int audio_extn_set_soundfocus_data(struct audio_device *adev,
2747 struct sound_focus_param *payload) {
2748 int ret = 0;
2749
2750 if (is_src_trkn_enabled)
2751 ret = set_soundfocus_data(adev, payload);
2752
2753 return ret;
2754}
2755
2756void audio_extn_source_track_set_parameters(struct audio_device *adev,
2757 struct str_parms *parms) {
2758 if (is_src_trkn_enabled)
2759 source_track_set_parameters(adev, parms);
2760}
2761
2762void audio_extn_source_track_get_parameters(const struct audio_device *adev,
2763 struct str_parms *query,
2764 struct str_parms *reply) {
2765 if (is_src_trkn_enabled)
2766 source_track_get_parameters(adev, query, reply);
2767}
2768//END: SOURCE_TRACKING_FEATURE ================================================
2769
2770//START: SSREC_FEATURE ==========================================================
2771#ifdef __LP64__
2772#define SSREC_LIB_PATH "/vendor/lib64/libssrec.so"
2773#else
2774#define SSREC_LIB_PATH "/vendor/lib/libssrec.so"
2775#endif
2776
2777static void *ssrec_lib_handle = NULL;
2778
2779typedef bool (*ssr_check_usecase_t)(struct stream_in *);
2780static ssr_check_usecase_t ssr_check_usecase;
2781
2782typedef int (*ssr_set_usecase_t)(struct stream_in *,
2783 struct audio_config *,
2784 bool *);
2785static ssr_set_usecase_t ssr_set_usecase;
2786
2787typedef int32_t (*ssr_init_t)(struct stream_in *,
2788 int num_out_chan);
2789static ssr_init_t ssr_init;
2790
2791typedef int32_t (*ssr_deinit_t)();
2792static ssr_deinit_t ssr_deinit;
2793
2794typedef void (*ssr_update_enabled_t)();
2795static ssr_update_enabled_t ssr_update_enabled;
2796
2797typedef bool (*ssr_get_enabled_t)();
2798static ssr_get_enabled_t ssr_get_enabled;
2799
2800typedef int32_t (*ssr_read_t)(struct audio_stream_in *,
2801 void *,
2802 size_t);
2803static ssr_read_t ssr_read;
2804
2805typedef void (*ssr_set_parameters_t)(struct audio_device *,
2806 struct str_parms *);
2807static ssr_set_parameters_t ssr_set_parameters;
2808
2809typedef void (*ssr_get_parameters_t)(const struct audio_device *,
2810 struct str_parms *,
2811 struct str_parms *);
2812static ssr_get_parameters_t ssr_get_parameters;
2813
2814typedef struct stream_in *(*ssr_get_stream_t)();
2815static ssr_get_stream_t ssr_get_stream;
2816
2817void ssrec_feature_init(bool is_feature_enabled) {
2818
2819 if (is_feature_enabled) {
2820 ssrec_lib_handle = dlopen(SSREC_LIB_PATH, RTLD_NOW);
2821 if (ssrec_lib_handle == NULL) {
2822 ALOGE("%s: dlopen failed", __func__);
2823 goto feature_disabled;
2824 }
2825
2826 if (((ssr_check_usecase = (ssr_check_usecase_t)dlsym(ssrec_lib_handle, "ssr_check_usecase")) == NULL) ||
2827 ((ssr_set_usecase = (ssr_set_usecase_t)dlsym(ssrec_lib_handle, "ssr_set_usecase")) == NULL) ||
2828 ((ssr_init = (ssr_init_t)dlsym(ssrec_lib_handle, "ssr_init")) == NULL) ||
2829 ((ssr_deinit = (ssr_deinit_t)dlsym(ssrec_lib_handle, "ssr_deinit")) == NULL) ||
2830 ((ssr_update_enabled = (ssr_update_enabled_t)dlsym(ssrec_lib_handle, "ssr_update_enabled")) == NULL) ||
2831 ((ssr_get_enabled = (ssr_get_enabled_t)dlsym(ssrec_lib_handle, "ssr_get_enabled")) == NULL) ||
2832 ((ssr_read = (ssr_read_t)dlsym(ssrec_lib_handle, "ssr_read")) == NULL) ||
2833 ((ssr_set_parameters = (ssr_set_parameters_t)dlsym(ssrec_lib_handle, "ssr_set_parameters")) == NULL) ||
2834 ((ssr_get_parameters = (ssr_get_parameters_t)dlsym(ssrec_lib_handle, "ssr_get_parameters")) == NULL) ||
2835 ((ssr_get_stream = (ssr_get_stream_t)dlsym(ssrec_lib_handle, "ssr_get_stream")) == NULL)) {
2836 ALOGE("%s: dlsym failed", __func__);
2837 goto feature_disabled;
2838 }
2839
2840 ALOGD("%s:: ---- Feature SSREC is Enabled ----", __func__);
2841 return;
2842 }
2843
2844feature_disabled:
2845 if(ssrec_lib_handle) {
2846 dlclose(ssrec_lib_handle);
2847 ssrec_lib_handle = NULL;
2848 }
2849
2850 ssr_check_usecase = NULL;
2851 ssr_set_usecase = NULL;
2852 ssr_init = NULL;
2853 ssr_deinit = NULL;
2854 ssr_update_enabled = NULL;
2855 ssr_get_enabled = NULL;
2856 ssr_read = NULL;
2857 ssr_set_parameters = NULL;
2858 ssr_get_parameters = NULL;
2859 ssr_get_stream = NULL;
2860
2861 ALOGW(":: %s: ---- Feature SSREC is disabled ----", __func__);
2862}
2863
2864bool audio_extn_ssr_check_usecase(struct stream_in *in) {
2865 bool ret = false;
2866
2867 if (ssrec_lib_handle != NULL)
2868 ret = ssr_check_usecase(in);
2869
2870 return ret;
2871}
2872
2873int audio_extn_ssr_set_usecase(struct stream_in *in,
2874 struct audio_config *config,
2875 bool *channel_mask_updated) {
2876 int ret = 0;
2877
2878 if (ssrec_lib_handle != NULL)
2879 ret = ssr_set_usecase(in, config, channel_mask_updated);
2880
2881 return ret;
2882}
2883
2884int32_t audio_extn_ssr_init(struct stream_in *in,
2885 int num_out_chan) {
2886 int32_t ret = 0;
2887
2888 if (ssrec_lib_handle != NULL)
2889 ret = ssr_init(in, num_out_chan);
2890
2891 return ret;
2892}
2893
2894int32_t audio_extn_ssr_deinit() {
2895 int32_t ret = 0;
2896
2897 if (ssrec_lib_handle != NULL)
2898 ret = ssr_deinit();
2899
2900 return ret;
2901}
2902
2903void audio_extn_ssr_update_enabled() {
2904
2905 if (ssrec_lib_handle)
2906 ssr_update_enabled();
2907}
2908
2909bool audio_extn_ssr_get_enabled() {
2910 bool ret = false;
2911
2912 if (ssrec_lib_handle)
2913 ret = ssr_get_enabled();
2914
2915 return ret;
2916}
2917
2918int32_t audio_extn_ssr_read(struct audio_stream_in *stream,
2919 void *buffer,
2920 size_t bytes) {
2921 int32_t ret = 0;
2922
2923 if (ssrec_lib_handle)
2924 ret = ssr_read(stream, buffer, bytes);
2925
2926 return ret;
2927}
2928
2929void audio_extn_ssr_set_parameters(struct audio_device *adev,
2930 struct str_parms *parms) {
2931
2932 if (ssrec_lib_handle)
2933 ssr_set_parameters(adev, parms);
2934}
2935
2936void audio_extn_ssr_get_parameters(const struct audio_device *adev,
2937 struct str_parms *query,
2938 struct str_parms *reply) {
2939
2940 if (ssrec_lib_handle)
2941 ssr_get_parameters(adev, query, reply);
2942}
2943
2944struct stream_in *audio_extn_ssr_get_stream() {
2945 struct stream_in *ret = NULL;
2946
2947 if (ssrec_lib_handle)
2948 ret = ssr_get_stream();
2949
2950 return ret;
2951}
2952//END: SSREC_FEATURE ============================================================
2953
2954//START: COMPRESS_CAPTURE_FEATURE ================================================================
2955#ifdef __LP64__
2956#define COMPRESS_CAPTURE_PATH "/vendor/lib64/libcomprcapture.so"
2957#else
2958#define COMPRESS_CAPTURE_PATH "/vendor/lib/libcomprcapture.so"
2959#endif
2960static void *compr_cap_lib_handle = NULL;
2961
2962typedef void (*compr_cap_init_t)(struct stream_in*);
2963static compr_cap_init_t compr_cap_init;
2964
2965typedef void (*compr_cap_deinit_t)();
2966static compr_cap_deinit_t compr_cap_deinit;
2967
2968typedef bool (*compr_cap_enabled_t)();
2969static compr_cap_enabled_t compr_cap_enabled;
2970
2971typedef bool (*compr_cap_format_supported_t)(audio_format_t);
2972static compr_cap_format_supported_t compr_cap_format_supported;
2973
2974typedef bool (*compr_cap_usecase_supported_t)(audio_usecase_t);
2975static compr_cap_usecase_supported_t compr_cap_usecase_supported;
2976
2977typedef size_t (*compr_cap_get_buffer_size_t)(audio_usecase_t);
2978static compr_cap_get_buffer_size_t compr_cap_get_buffer_size;
2979
2980typedef int (*compr_cap_read_t)(struct stream_in*, void*, size_t);
2981static compr_cap_read_t compr_cap_read;
2982
2983void compr_cap_feature_init(bool is_feature_enabled)
2984{
2985 if(is_feature_enabled) {
2986 //dlopen lib
2987 compr_cap_lib_handle = dlopen(COMPRESS_CAPTURE_PATH, RTLD_NOW);
2988 if (compr_cap_lib_handle == NULL) {
2989 ALOGE("%s: dlopen failed", __func__);
2990 goto feature_disabled;
2991 }
2992 //map each function
2993 //on any faliure to map any function, disble feature
2994 if (((compr_cap_init = (compr_cap_init_t)dlsym(compr_cap_lib_handle,"compr_cap_init")) == NULL) ||
2995 ((compr_cap_deinit = (compr_cap_deinit_t)dlsym(compr_cap_lib_handle,"compr_cap_deinit")) == NULL) ||
2996 ((compr_cap_enabled = (compr_cap_enabled_t)dlsym(compr_cap_lib_handle,"compr_cap_enabled")) == NULL) ||
2997 ((compr_cap_format_supported = (compr_cap_format_supported_t)dlsym(compr_cap_lib_handle,"compr_cap_format_supported")) == NULL) ||
2998 ((compr_cap_usecase_supported = (compr_cap_usecase_supported_t)dlsym(compr_cap_lib_handle,"compr_cap_usecase_supported")) == NULL) ||
2999 ((compr_cap_get_buffer_size = (compr_cap_get_buffer_size_t)dlsym(compr_cap_lib_handle,"compr_cap_get_buffer_size")) == NULL) ||
3000 ((compr_cap_read = (compr_cap_read_t)dlsym(compr_cap_lib_handle,"compr_cap_read")) == NULL)) {
3001 ALOGE("%s: dlsym failed", __func__);
3002 goto feature_disabled;
3003 }
3004
3005 ALOGD("%s:: ---- Feature COMPRESS_CAPTURE is Enabled ----", __func__);
3006 return;
3007 }
3008
3009feature_disabled:
3010 if (compr_cap_lib_handle) {
3011 dlclose(compr_cap_lib_handle);
3012 compr_cap_lib_handle = NULL;
3013 }
3014
3015 compr_cap_init = NULL;
3016 compr_cap_deinit = NULL;
3017 compr_cap_enabled = NULL;
3018 compr_cap_format_supported = NULL;
3019 compr_cap_usecase_supported = NULL;
3020 compr_cap_get_buffer_size = NULL;
3021 compr_cap_read = NULL;
3022
3023 ALOGW(":: %s: ---- Feature COMPRESS_CAPTURE is disabled ----", __func__);
3024 return;
3025}
3026
3027void audio_extn_compr_cap_init(struct stream_in* instream)
3028{
3029 if (compr_cap_init != NULL)
3030 compr_cap_init(instream);
3031
3032 return;
3033}
3034
3035void audio_extn_compr_cap_deinit()
3036{
3037 if(compr_cap_deinit)
3038 compr_cap_deinit();
3039
3040 return;
3041}
3042
3043bool audio_extn_compr_cap_enabled()
3044{
3045 bool ret_val = false;
3046
3047 if (compr_cap_enabled)
3048 ret_val = compr_cap_enabled();
3049
3050 return ret_val;
3051}
3052
3053bool audio_extn_compr_cap_format_supported(audio_format_t format)
3054{
3055 bool ret_val = false;
3056
3057 if (compr_cap_format_supported != NULL)
3058 ret_val = compr_cap_format_supported(format);
3059
3060 return ret_val;
3061}
3062
3063bool audio_extn_compr_cap_usecase_supported(audio_usecase_t usecase)
3064{
3065 bool ret_val = false;
3066
3067 if (compr_cap_usecase_supported != NULL)
3068 ret_val = compr_cap_usecase_supported(usecase);
3069
3070 return ret_val;
3071}
3072
3073size_t audio_extn_compr_cap_get_buffer_size(audio_format_t format)
3074{
3075 size_t ret_val = 0;
3076
3077 if (compr_cap_get_buffer_size != NULL)
3078 ret_val = compr_cap_get_buffer_size(format);
3079
3080 return ret_val;
3081}
3082
3083size_t audio_extn_compr_cap_read(struct stream_in *in,
3084 void *buffer, size_t bytes)
3085{
3086 size_t ret_val = 0;
3087
3088 if (compr_cap_read != NULL)
3089 ret_val = compr_cap_read(in, buffer, bytes);
3090
3091 return ret_val;
3092}
3093
3094
Dhanalakshmi Siddani21be3ac2016-12-29 14:31:08 +05303095void audio_extn_init(struct audio_device *adev)
Dhanalakshmi Siddani0b1488e2016-09-06 12:58:42 +05303096{
3097 aextnmod.anc_enabled = 0;
3098 aextnmod.aanc_enabled = 0;
3099 aextnmod.custom_stereo_enabled = 0;
3100 aextnmod.proxy_channel_num = 2;
3101 aextnmod.hpx_enabled = 0;
3102 aextnmod.vbat_enabled = 0;
Aditya Bavanari9b589022018-09-20 08:47:55 +05303103 aextnmod.bcl_enabled = 0;
Dhanalakshmi Siddani0b1488e2016-09-06 12:58:42 +05303104 aextnmod.hifi_audio_enabled = 0;
Dhanalakshmi Siddani18737932016-11-29 17:33:17 +05303105 aextnmod.addr.nap = 0;
3106 aextnmod.addr.uap = 0;
3107 aextnmod.addr.lap = 0;
Aalique Grahame404a15e2017-05-18 11:28:27 -07003108 aextnmod.adev = adev;
Dhanalakshmi Siddani21be3ac2016-12-29 14:31:08 +05303109
3110 audio_extn_dolby_set_license(adev);
Dhanalakshmi Siddani18737932016-11-29 17:33:17 +05303111 audio_extn_aptx_dec_set_license(adev);
Dhanalakshmi Siddani0b1488e2016-09-06 12:58:42 +05303112}
3113
Meng Wang4c32fb42020-01-16 17:57:11 +08003114#ifdef AUDIO_GKI_ENABLED
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003115static int get_wma_dec_info(struct stream_out *out, struct str_parms *parms) {
Meng Wang4c32fb42020-01-16 17:57:11 +08003116 int ret = 0;
3117 char value[32];
3118
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003119 struct snd_generic_dec_wma *wma_dec = NULL;
3120
3121 /* reserved[0] will contain the WMA decoder type */
3122 if (out->format == AUDIO_FORMAT_WMA) {
3123 out->compr_config.codec->options.generic.reserved[0] = AUDIO_COMP_FORMAT_WMA;
3124 } else if (out->format == AUDIO_FORMAT_WMA_PRO) {
3125 out->compr_config.codec->options.generic.reserved[0] = AUDIO_COMP_FORMAT_WMA_PRO;
3126 } else {
3127 ALOGE("%s: unknown WMA format 0x%x\n", __func__, out->format);
3128 return -EINVAL;
3129 }
3130
3131 /* reserved[1] onwards will contain the WMA decoder format info */
3132 wma_dec = (struct snd_generic_dec_wma *)
3133 &(out->compr_config.codec->options.generic.reserved[1]);
3134 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE,
3135 value, sizeof(value));
Meng Wang4c32fb42020-01-16 17:57:11 +08003136 if (ret >= 0) {
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003137 wma_dec->avg_bit_rate = atoi(value);
Meng Wang4c32fb42020-01-16 17:57:11 +08003138 out->is_compr_metadata_avail = true;
3139 }
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003140 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BLOCK_ALIGN,
3141 value, sizeof(value));
Meng Wang4c32fb42020-01-16 17:57:11 +08003142 if (ret >= 0) {
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003143 wma_dec->super_block_align = atoi(value);
Meng Wang4c32fb42020-01-16 17:57:11 +08003144 out->is_compr_metadata_avail = true;
3145 }
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003146 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BIT_PER_SAMPLE,
3147 value, sizeof(value));
Meng Wang4c32fb42020-01-16 17:57:11 +08003148 if (ret >= 0) {
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003149 wma_dec->bits_per_sample = atoi(value);
Meng Wang4c32fb42020-01-16 17:57:11 +08003150 out->is_compr_metadata_avail = true;
3151 }
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003152 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_CHANNEL_MASK,
3153 value, sizeof(value));
Meng Wang4c32fb42020-01-16 17:57:11 +08003154 if (ret >= 0) {
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003155 wma_dec->channelmask = atoi(value);
Meng Wang4c32fb42020-01-16 17:57:11 +08003156 out->is_compr_metadata_avail = true;
3157 }
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003158 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION,
3159 value, sizeof(value));
Meng Wang4c32fb42020-01-16 17:57:11 +08003160 if (ret >= 0) {
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003161 wma_dec->encodeopt = atoi(value);
Meng Wang4c32fb42020-01-16 17:57:11 +08003162 out->is_compr_metadata_avail = true;
3163 }
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003164 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION1,
3165 value, sizeof(value));
Meng Wang4c32fb42020-01-16 17:57:11 +08003166 if (ret >= 0) {
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003167 wma_dec->encodeopt1 = atoi(value);
Meng Wang4c32fb42020-01-16 17:57:11 +08003168 out->is_compr_metadata_avail = true;
3169 }
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003170 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION2,
3171 value, sizeof(value));
Meng Wang4c32fb42020-01-16 17:57:11 +08003172 if (ret >= 0) {
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003173 wma_dec->encodeopt2 = atoi(value);
Meng Wang4c32fb42020-01-16 17:57:11 +08003174 out->is_compr_metadata_avail = true;
3175 }
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003176
3177 ALOGV("WMA params: fmt 0x%x, id 0x%x, WMA type 0x%x, bit rate 0x%x,"
3178 " balgn 0x%x, sr %d, chmsk 0x%x"
3179 " encop 0x%x, op1 0x%x, op2 0x%x \n",
Meng Wang4c32fb42020-01-16 17:57:11 +08003180 out->compr_config.codec->format,
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003181 out->compr_config.codec->id,
3182 out->compr_config.codec->options.generic.reserved[0],
3183 wma_dec->avg_bit_rate,
3184 wma_dec->super_block_align,
3185 wma_dec->bits_per_sample,
3186 wma_dec->channelmask,
3187 wma_dec->encodeopt,
3188 wma_dec->encodeopt1,
3189 wma_dec->encodeopt2);
Meng Wang4c32fb42020-01-16 17:57:11 +08003190
3191 return ret;
3192}
3193#else
3194int get_wma_info(struct stream_out *out, struct str_parms *parms) {
3195 int ret = 0;
3196 char value[32];
3197
3198 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE, value, sizeof(value));
3199 if (ret >= 0) {
3200 out->compr_config.codec->options.wma.avg_bit_rate = atoi(value);
3201 out->is_compr_metadata_avail = true;
3202 }
3203 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BLOCK_ALIGN, value, sizeof(value));
3204 if (ret >= 0) {
3205 out->compr_config.codec->options.wma.super_block_align = atoi(value);
3206 out->is_compr_metadata_avail = true;
3207 }
3208 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BIT_PER_SAMPLE, value, sizeof(value));
3209 if (ret >= 0) {
3210 out->compr_config.codec->options.wma.bits_per_sample = atoi(value);
3211 out->is_compr_metadata_avail = true;
3212 }
3213 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_CHANNEL_MASK, value, sizeof(value));
3214 if (ret >= 0) {
3215 out->compr_config.codec->options.wma.channelmask = atoi(value);
3216 out->is_compr_metadata_avail = true;
3217 }
3218 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION, value, sizeof(value));
3219 if (ret >= 0) {
3220 out->compr_config.codec->options.wma.encodeopt = atoi(value);
3221 out->is_compr_metadata_avail = true;
3222 }
3223 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION1, value, sizeof(value));
3224 if (ret >= 0) {
3225 out->compr_config.codec->options.wma.encodeopt1 = atoi(value);
3226 out->is_compr_metadata_avail = true;
3227 }
3228 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION2, value, sizeof(value));
3229 if (ret >= 0) {
3230 out->compr_config.codec->options.wma.encodeopt2 = atoi(value);
3231 out->is_compr_metadata_avail = true;
3232 }
3233 ALOGV("WMA params: fmt %x, bit rate %x, balgn %x, sr %d, chmsk %x"
3234 " encop %x, op1 %x, op2 %x",
3235 out->compr_config.codec->format,
3236 out->compr_config.codec->options.wma.avg_bit_rate,
3237 out->compr_config.codec->options.wma.super_block_align,
3238 out->compr_config.codec->options.wma.bits_per_sample,
3239 out->compr_config.codec->options.wma.channelmask,
3240 out->compr_config.codec->options.wma.encodeopt,
3241 out->compr_config.codec->options.wma.encodeopt1,
3242 out->compr_config.codec->options.wma.encodeopt2);
3243
3244 return ret;
3245}
3246#endif
3247
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003248#ifdef AUDIO_GKI_ENABLED
3249static int get_flac_dec_info(struct stream_out *out, struct str_parms *parms) {
3250 int ret = 0;
3251 char value[32];
3252 struct snd_generic_dec_flac *flac_dec = NULL;
3253
3254 /* reserved[0] will contain the FLAC decoder type */
3255 out->compr_config.codec->options.generic.reserved[0] =
3256 AUDIO_COMP_FORMAT_FLAC;
3257 /* reserved[1] onwards will contain the FLAC decoder format info */
3258 flac_dec = (struct snd_generic_dec_flac *)
3259 &(out->compr_config.codec->options.generic.reserved[1]);
3260 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_FLAC_MIN_BLK_SIZE,
3261 value, sizeof(value));
3262 if (ret >= 0) {
3263 flac_dec->min_blk_size = atoi(value);
3264 out->is_compr_metadata_avail = true;
3265 }
3266 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_FLAC_MAX_BLK_SIZE,
3267 value, sizeof(value));
3268 if (ret >= 0) {
3269 flac_dec->max_blk_size = atoi(value);
3270 out->is_compr_metadata_avail = true;
3271 }
3272 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_FLAC_MIN_FRAME_SIZE,
3273 value, sizeof(value));
3274 if (ret >= 0) {
3275 flac_dec->min_frame_size = atoi(value);
3276 out->is_compr_metadata_avail = true;
3277 }
3278 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_FLAC_MAX_FRAME_SIZE,
3279 value, sizeof(value));
3280 if (ret >= 0) {
3281 flac_dec->max_frame_size = atoi(value);
3282 out->is_compr_metadata_avail = true;
3283 }
3284
3285 ALOGV("FLAC metadata: fmt 0x%x, id 0x%x, FLAC type 0x%x min_blk_size %d,"
3286 " max_blk_size %d min_frame_size %d max_frame_size %d \n",
3287 out->compr_config.codec->format,
3288 out->compr_config.codec->id,
3289 out->compr_config.codec->options.generic.reserved[0],
3290 flac_dec->min_blk_size,
3291 flac_dec->max_blk_size,
3292 flac_dec->min_frame_size,
3293 flac_dec->max_frame_size);
3294
3295 return ret;
3296}
3297
3298static int get_alac_dec_info(struct stream_out *out, struct str_parms *parms) {
3299 int ret = 0;
3300 char value[32];
3301 struct snd_generic_dec_alac *alac_dec = NULL;
3302
3303 /* reserved[0] will contain the ALAC decoder type */
3304 out->compr_config.codec->options.generic.reserved[0] =
3305 AUDIO_COMP_FORMAT_ALAC;
3306 /* reserved[1] onwards will contain the ALAC decoder format info */
3307 alac_dec = (struct snd_generic_dec_alac *)
3308 &(out->compr_config.codec->options.generic.reserved[1]);
3309 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_FRAME_LENGTH,
3310 value, sizeof(value));
3311 if (ret >= 0) {
3312 alac_dec->frame_length = atoi(value);
3313 out->is_compr_metadata_avail = true;
3314 }
3315 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_COMPATIBLE_VERSION,
3316 value, sizeof(value));
3317 if (ret >= 0) {
3318 alac_dec->compatible_version = atoi(value);
3319 out->is_compr_metadata_avail = true;
3320 }
3321 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_BIT_DEPTH,
3322 value, sizeof(value));
3323 if (ret >= 0) {
3324 alac_dec->bit_depth = atoi(value);
3325 out->is_compr_metadata_avail = true;
3326 }
3327 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_PB,
3328 value, sizeof(value));
3329 if (ret >= 0) {
3330 alac_dec->pb = atoi(value);
3331 out->is_compr_metadata_avail = true;
3332 }
3333 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_MB,
3334 value, sizeof(value));
3335 if (ret >= 0) {
3336 alac_dec->mb = atoi(value);
3337 out->is_compr_metadata_avail = true;
3338 }
3339 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_KB,
3340 value, sizeof(value));
3341 if (ret >= 0) {
3342 alac_dec->kb = atoi(value);
3343 out->is_compr_metadata_avail = true;
3344 }
3345 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_NUM_CHANNELS,
3346 value, sizeof(value));
3347 if (ret >= 0) {
3348 alac_dec->num_channels = atoi(value);
3349 out->is_compr_metadata_avail = true;
3350 }
3351 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_MAX_RUN,
3352 value, sizeof(value));
3353 if (ret >= 0) {
3354 alac_dec->max_run = atoi(value);
3355 out->is_compr_metadata_avail = true;
3356 }
3357 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_MAX_FRAME_BYTES,
3358 value, sizeof(value));
3359 if (ret >= 0) {
3360 alac_dec->max_frame_bytes = atoi(value);
3361 out->is_compr_metadata_avail = true;
3362 }
3363 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_AVG_BIT_RATE,
3364 value, sizeof(value));
3365 if (ret >= 0) {
3366 alac_dec->avg_bit_rate = atoi(value);
3367 out->is_compr_metadata_avail = true;
3368 }
3369 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_SAMPLING_RATE,
3370 value, sizeof(value));
3371 if (ret >= 0) {
3372 alac_dec->sample_rate = atoi(value);
3373 out->is_compr_metadata_avail = true;
3374 }
3375 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_CHANNEL_LAYOUT_TAG,
3376 value, sizeof(value));
3377 if (ret >= 0) {
3378 alac_dec->channel_layout_tag = atoi(value);
3379 out->is_compr_metadata_avail = true;
3380 }
3381
3382 ALOGV("ALAC CSD values: fmt 0x%x, id 0x%x, ALAC type 0x%x, frameLength %d"
3383 "bitDepth %d numChannels %d"
3384 " maxFrameBytes %d, avgBitRate %d, sampleRate %d \n",
3385 out->compr_config.codec->format,
3386 out->compr_config.codec->id,
3387 out->compr_config.codec->options.generic.reserved[0],
3388 alac_dec->frame_length,
3389 alac_dec->bit_depth,
3390 alac_dec->num_channels,
3391 alac_dec->max_frame_bytes,
3392 alac_dec->avg_bit_rate,
3393 alac_dec->sample_rate);
3394
3395 return ret;
3396}
3397
3398static int get_ape_dec_info(struct stream_out *out, struct str_parms *parms) {
3399 int ret = 0;
3400 char value[32];
3401 struct snd_generic_dec_ape *ape_dec = NULL;
3402
3403 /* reserved[0] will contain the APE decoder type */
3404 out->compr_config.codec->options.generic.reserved[0] =
3405 AUDIO_COMP_FORMAT_APE;
3406
3407 /* reserved[1] onwards will contain the APE decoder format info */
3408 ape_dec = (struct snd_generic_dec_ape *)
3409 &(out->compr_config.codec->options.generic.reserved[1]);
3410
3411 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_COMPATIBLE_VERSION,
3412 value, sizeof(value));
3413 if (ret >= 0) {
3414 ape_dec->compatible_version = atoi(value);
3415 out->is_compr_metadata_avail = true;
3416 }
3417 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_COMPRESSION_LEVEL,
3418 value, sizeof(value));
3419 if (ret >= 0) {
3420 ape_dec->compression_level = atoi(value);
3421 out->is_compr_metadata_avail = true;
3422 }
3423 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_FORMAT_FLAGS,
3424 value, sizeof(value));
3425 if (ret >= 0) {
3426 ape_dec->format_flags = atoi(value);
3427 out->is_compr_metadata_avail = true;
3428 }
3429 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_BLOCKS_PER_FRAME,
3430 value, sizeof(value));
3431 if (ret >= 0) {
3432 ape_dec->blocks_per_frame = atoi(value);
3433 out->is_compr_metadata_avail = true;
3434 }
3435 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_FINAL_FRAME_BLOCKS,
3436 value, sizeof(value));
3437 if (ret >= 0) {
3438 ape_dec->final_frame_blocks = atoi(value);
3439 out->is_compr_metadata_avail = true;
3440 }
3441 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_TOTAL_FRAMES, value,
3442 sizeof(value));
3443 if (ret >= 0) {
3444 ape_dec->total_frames = atoi(value);
3445 out->is_compr_metadata_avail = true;
3446 }
3447 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_BITS_PER_SAMPLE,
3448 value, sizeof(value));
3449 if (ret >= 0) {
3450 ape_dec->bits_per_sample = atoi(value);
3451 out->is_compr_metadata_avail = true;
3452 }
3453 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_NUM_CHANNELS,
3454 value, sizeof(value));
3455 if (ret >= 0) {
3456 ape_dec->num_channels = atoi(value);
3457 out->is_compr_metadata_avail = true;
3458 }
3459 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_SAMPLE_RATE,
3460 value, sizeof(value));
3461 if (ret >= 0) {
3462 ape_dec->sample_rate = atoi(value);
3463 out->is_compr_metadata_avail = true;
3464 }
3465 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_SEEK_TABLE_PRESENT,
3466 value, sizeof(value));
3467 if (ret >= 0) {
3468 ape_dec->seek_table_present = atoi(value);
3469 out->is_compr_metadata_avail = true;
3470 }
3471
3472 ALOGV("APE CSD values: fmt 0x%x, id 0x%x, APE type 0x%x"
3473 " compatibleVersion %d compressionLevel %d"
3474 " formatFlags %d blocksPerFrame %d finalFrameBlocks %d"
3475 " totalFrames %d bitsPerSample %d numChannels %d"
3476 " sampleRate %d seekTablePresent %d",
3477 out->compr_config.codec->format,
3478 out->compr_config.codec->id,
3479 out->compr_config.codec->options.generic.reserved[0],
3480 ape_dec->compatible_version,
3481 ape_dec->compression_level,
3482 ape_dec->format_flags,
3483 ape_dec->blocks_per_frame,
3484 ape_dec->final_frame_blocks,
3485 ape_dec->total_frames,
3486 ape_dec->bits_per_sample,
3487 ape_dec->num_channels,
3488 ape_dec->sample_rate,
3489 ape_dec->seek_table_present);
3490
3491 return ret;
3492}
3493
3494static int get_vorbis_dec_info(struct stream_out *out,
3495 struct str_parms *parms) {
3496 int ret = 0;
3497 char value[32];
3498 struct snd_generic_dec_vorbis *vorbis_dec = NULL;
3499
3500 /* reserved[0] will contain the Vorbis decoder type */
3501 out->compr_config.codec->options.generic.reserved[0] =
3502 AUDIO_COMP_FORMAT_VORBIS;
3503 /* reserved[1] onwards will contain the Vorbis decoder format info */
3504 vorbis_dec = (struct snd_generic_dec_vorbis *)
3505 &(out->compr_config.codec->options.generic.reserved[1]);
3506 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_VORBIS_BITSTREAM_FMT,
3507 value, sizeof(value));
3508 if (ret >= 0) {
3509 // transcoded bitstream mode
3510 vorbis_dec->bit_stream_fmt = (atoi(value) > 0) ? 1 : 0;
3511 out->is_compr_metadata_avail = true;
3512 }
3513
3514 ALOGV("Vorbis values: fmt 0x%x, id 0x%x, Vorbis type 0x%x"
3515 " bitStreamFmt %d\n",
3516 out->compr_config.codec->format,
3517 out->compr_config.codec->id,
3518 out->compr_config.codec->options.generic.reserved[0],
3519 vorbis_dec->bit_stream_fmt);
3520
3521 return ret;
3522}
3523
3524int audio_extn_parse_compress_metadata(struct stream_out *out,
3525 struct str_parms *parms)
3526{
3527 int ret = 0;
3528 char value[32];
3529
3530 if (!if_compress_meta_data_feature_enabled())
3531 return ret;
3532
3533 if (out->format == AUDIO_FORMAT_FLAC) {
3534 ret = get_flac_dec_info(out, parms);
3535 } else if (out->format == AUDIO_FORMAT_ALAC) {
3536 ret = get_alac_dec_info(out, parms);
3537 } else if (out->format == AUDIO_FORMAT_APE) {
3538 ret = get_ape_dec_info(out, parms);
3539 } else if (out->format == AUDIO_FORMAT_VORBIS) {
3540 ret = get_vorbis_dec_info(out, parms);
3541 } else if (out->format == AUDIO_FORMAT_WMA ||
3542 out->format == AUDIO_FORMAT_WMA_PRO) {
3543 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_FORMAT_TAG,
3544 value, sizeof(value));
3545 if (ret >= 0) {
3546 out->compr_config.codec->format = atoi(value);
3547 out->is_compr_metadata_avail = true;
3548 }
3549
3550 ret = get_wma_dec_info(out, parms);
3551 }
3552
3553 return ret;
3554}
3555
3556#else
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303557int audio_extn_parse_compress_metadata(struct stream_out *out,
3558 struct str_parms *parms)
3559{
3560 int ret = 0;
3561 char value[32];
3562
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08003563 if (!if_compress_meta_data_feature_enabled()) {
3564 return ret;
3565 }
3566
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303567 if (out->format == AUDIO_FORMAT_FLAC) {
3568 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_FLAC_MIN_BLK_SIZE, value, sizeof(value));
3569 if (ret >= 0) {
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303570 out->compr_config.codec->options.flac_dec.min_blk_size = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303571 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303572 }
3573 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_FLAC_MAX_BLK_SIZE, value, sizeof(value));
3574 if (ret >= 0) {
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303575 out->compr_config.codec->options.flac_dec.max_blk_size = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303576 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303577 }
3578 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_FLAC_MIN_FRAME_SIZE, value, sizeof(value));
3579 if (ret >= 0) {
3580 out->compr_config.codec->options.flac_dec.min_frame_size = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303581 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303582 }
3583 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_FLAC_MAX_FRAME_SIZE, value, sizeof(value));
3584 if (ret >= 0) {
3585 out->compr_config.codec->options.flac_dec.max_frame_size = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303586 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303587 }
3588 ALOGV("FLAC metadata: min_blk_size %d, max_blk_size %d min_frame_size %d max_frame_size %d",
3589 out->compr_config.codec->options.flac_dec.min_blk_size,
3590 out->compr_config.codec->options.flac_dec.max_blk_size,
3591 out->compr_config.codec->options.flac_dec.min_frame_size,
3592 out->compr_config.codec->options.flac_dec.max_frame_size);
3593 }
3594
3595 else if (out->format == AUDIO_FORMAT_ALAC) {
3596 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_FRAME_LENGTH, value, sizeof(value));
3597 if (ret >= 0) {
3598 out->compr_config.codec->options.alac.frame_length = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303599 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303600 }
3601 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_COMPATIBLE_VERSION, value, sizeof(value));
3602 if (ret >= 0) {
3603 out->compr_config.codec->options.alac.compatible_version = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303604 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303605 }
3606 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_BIT_DEPTH, value, sizeof(value));
3607 if (ret >= 0) {
3608 out->compr_config.codec->options.alac.bit_depth = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303609 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303610 }
3611 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_PB, value, sizeof(value));
3612 if (ret >= 0) {
3613 out->compr_config.codec->options.alac.pb = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303614 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303615 }
3616 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_MB, value, sizeof(value));
3617 if (ret >= 0) {
3618 out->compr_config.codec->options.alac.mb = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303619 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303620 }
3621
3622 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_KB, value, sizeof(value));
3623 if (ret >= 0) {
3624 out->compr_config.codec->options.alac.kb = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303625 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303626 }
3627 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_NUM_CHANNELS, value, sizeof(value));
3628 if (ret >= 0) {
3629 out->compr_config.codec->options.alac.num_channels = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303630 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303631 }
3632 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_MAX_RUN, value, sizeof(value));
3633 if (ret >= 0) {
3634 out->compr_config.codec->options.alac.max_run = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303635 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303636 }
3637 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_MAX_FRAME_BYTES, value, sizeof(value));
3638 if (ret >= 0) {
3639 out->compr_config.codec->options.alac.max_frame_bytes = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303640 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303641 }
3642 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_AVG_BIT_RATE, value, sizeof(value));
3643 if (ret >= 0) {
3644 out->compr_config.codec->options.alac.avg_bit_rate = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303645 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303646 }
3647 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_SAMPLING_RATE, value, sizeof(value));
3648 if (ret >= 0) {
3649 out->compr_config.codec->options.alac.sample_rate = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303650 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303651 }
3652 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_ALAC_CHANNEL_LAYOUT_TAG, value, sizeof(value));
3653 if (ret >= 0) {
3654 out->compr_config.codec->options.alac.channel_layout_tag = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303655 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303656 }
3657 ALOGV("ALAC CSD values: frameLength %d bitDepth %d numChannels %d"
3658 " maxFrameBytes %d, avgBitRate %d, sampleRate %d",
3659 out->compr_config.codec->options.alac.frame_length,
3660 out->compr_config.codec->options.alac.bit_depth,
3661 out->compr_config.codec->options.alac.num_channels,
3662 out->compr_config.codec->options.alac.max_frame_bytes,
3663 out->compr_config.codec->options.alac.avg_bit_rate,
3664 out->compr_config.codec->options.alac.sample_rate);
3665 }
3666
3667 else if (out->format == AUDIO_FORMAT_APE) {
3668 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_COMPATIBLE_VERSION, value, sizeof(value));
3669 if (ret >= 0) {
3670 out->compr_config.codec->options.ape.compatible_version = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303671 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303672 }
3673 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_COMPRESSION_LEVEL, value, sizeof(value));
3674 if (ret >= 0) {
3675 out->compr_config.codec->options.ape.compression_level = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303676 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303677 }
3678 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_FORMAT_FLAGS, value, sizeof(value));
3679 if (ret >= 0) {
3680 out->compr_config.codec->options.ape.format_flags = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303681 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303682 }
3683 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_BLOCKS_PER_FRAME, value, sizeof(value));
3684 if (ret >= 0) {
3685 out->compr_config.codec->options.ape.blocks_per_frame = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303686 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303687 }
3688 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_FINAL_FRAME_BLOCKS, value, sizeof(value));
3689 if (ret >= 0) {
3690 out->compr_config.codec->options.ape.final_frame_blocks = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303691 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303692 }
3693 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_TOTAL_FRAMES, value, sizeof(value));
3694 if (ret >= 0) {
3695 out->compr_config.codec->options.ape.total_frames = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303696 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303697 }
3698 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_BITS_PER_SAMPLE, value, sizeof(value));
3699 if (ret >= 0) {
3700 out->compr_config.codec->options.ape.bits_per_sample = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303701 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303702 }
3703 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_NUM_CHANNELS, value, sizeof(value));
3704 if (ret >= 0) {
3705 out->compr_config.codec->options.ape.num_channels = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303706 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303707 }
3708 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_SAMPLE_RATE, value, sizeof(value));
3709 if (ret >= 0) {
3710 out->compr_config.codec->options.ape.sample_rate = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303711 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303712 }
3713 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_APE_SEEK_TABLE_PRESENT, value, sizeof(value));
3714 if (ret >= 0) {
3715 out->compr_config.codec->options.ape.seek_table_present = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303716 out->is_compr_metadata_avail = true;
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303717 }
3718 ALOGV("APE CSD values: compatibleVersion %d compressionLevel %d"
3719 " formatFlags %d blocksPerFrame %d finalFrameBlocks %d"
3720 " totalFrames %d bitsPerSample %d numChannels %d"
3721 " sampleRate %d seekTablePresent %d",
3722 out->compr_config.codec->options.ape.compatible_version,
3723 out->compr_config.codec->options.ape.compression_level,
3724 out->compr_config.codec->options.ape.format_flags,
3725 out->compr_config.codec->options.ape.blocks_per_frame,
3726 out->compr_config.codec->options.ape.final_frame_blocks,
3727 out->compr_config.codec->options.ape.total_frames,
3728 out->compr_config.codec->options.ape.bits_per_sample,
3729 out->compr_config.codec->options.ape.num_channels,
3730 out->compr_config.codec->options.ape.sample_rate,
3731 out->compr_config.codec->options.ape.seek_table_present);
3732 }
3733
3734 else if (out->format == AUDIO_FORMAT_VORBIS) {
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303735 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_VORBIS_BITSTREAM_FMT, value, sizeof(value));
3736 if (ret >= 0) {
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303737 // transcoded bitstream mode
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303738 out->compr_config.codec->options.vorbis_dec.bit_stream_fmt = (atoi(value) > 0) ? 1 : 0;
3739 out->is_compr_metadata_avail = true;
3740 }
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303741 }
3742
3743 else if (out->format == AUDIO_FORMAT_WMA || out->format == AUDIO_FORMAT_WMA_PRO) {
3744 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_FORMAT_TAG, value, sizeof(value));
3745 if (ret >= 0) {
3746 out->compr_config.codec->format = atoi(value);
Chaithanya Krishna Bacharajua70cb6a2015-07-24 14:15:05 +05303747 out->is_compr_metadata_avail = true;
3748 }
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003749 ret = get_wma_info(out, parms);
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303750 }
3751
3752 return ret;
3753}
Xiaojun Sang782e5b12020-06-29 21:13:06 +08003754#endif
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05303755
Damir Didjustof1d46c72013-11-06 17:59:04 -08003756#ifdef AUXPCM_BT_ENABLED
3757int32_t audio_extn_read_xml(struct audio_device *adev, uint32_t mixer_card,
3758 const char* mixer_xml_path,
3759 const char* mixer_xml_path_auxpcm)
3760{
3761 char bt_soc[128];
3762 bool wifi_init_complete = false;
3763 int sleep_retry = 0;
3764
3765 while (!wifi_init_complete && sleep_retry < MAX_SLEEP_RETRY) {
3766 property_get("qcom.bluetooth.soc", bt_soc, NULL);
3767 if (strncmp(bt_soc, "unknown", sizeof("unknown"))) {
3768 wifi_init_complete = true;
3769 } else {
3770 usleep(WIFI_INIT_WAIT_SLEEP*1000);
3771 sleep_retry++;
3772 }
3773 }
3774
3775 if (!strncmp(bt_soc, "ath3k", sizeof("ath3k")))
3776 adev->audio_route = audio_route_init(mixer_card, mixer_xml_path_auxpcm);
3777 else
3778 adev->audio_route = audio_route_init(mixer_card, mixer_xml_path);
3779
3780 return 0;
3781}
3782#endif /* AUXPCM_BT_ENABLED */
Sudheer Papothi390bcf32014-12-04 01:25:17 +05303783
Divya Narayanan Poojary45f19192016-09-30 18:52:13 +05303784static int audio_extn_set_multichannel_mask(struct audio_device *adev,
3785 struct stream_in *in,
3786 struct audio_config *config,
3787 bool *channel_mask_updated)
3788{
3789 int ret = -EINVAL;
3790 int channel_count = audio_channel_count_from_in_mask(in->channel_mask);
3791 *channel_mask_updated = false;
3792
3793 int max_mic_count = platform_get_max_mic_count(adev->platform);
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +05303794 /* validate input params. Avoid updated channel mask if loopback device */
Avinash Chandrad7296d42021-08-04 15:07:47 +05303795 /* validate input params. Avoid updated channel mask if HDMI or loopback device */
Sandhya Mutha Naga Venkatae85bc822023-03-21 22:31:22 +05303796 if ((channel_count == 6) &&
Chaithanya Krishna Bacharajuc9f99712019-04-16 15:32:52 +05303797 (in->format == AUDIO_FORMAT_PCM_16_BIT) &&
Aniket Kumar Lata0e6e1e52019-11-14 21:43:55 -08003798 (!is_loopback_input_device(get_device_types(&in->device_list)))) {
Divya Narayanan Poojary45f19192016-09-30 18:52:13 +05303799 switch (max_mic_count) {
3800 case 4:
3801 config->channel_mask = AUDIO_CHANNEL_INDEX_MASK_4;
3802 break;
3803 case 3:
3804 config->channel_mask = AUDIO_CHANNEL_INDEX_MASK_3;
3805 break;
3806 case 2:
3807 config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
3808 break;
3809 default:
3810 config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
3811 break;
3812 }
3813 ret = 0;
3814 *channel_mask_updated = true;
3815 }
3816 return ret;
3817}
3818
3819int audio_extn_check_and_set_multichannel_usecase(struct audio_device *adev,
3820 struct stream_in *in,
3821 struct audio_config *config,
3822 bool *update_params)
3823{
3824 bool ssr_supported = false;
Revathi Uddarajud2634032017-12-07 14:42:34 +05303825 in->config.rate = config->sample_rate;
Chaithanya Krishna Bacharajuf5a1ce62018-02-02 11:34:11 +05303826 in->sample_rate = config->sample_rate;
Divya Narayanan Poojary45f19192016-09-30 18:52:13 +05303827 ssr_supported = audio_extn_ssr_check_usecase(in);
3828 if (ssr_supported) {
3829 return audio_extn_ssr_set_usecase(in, config, update_params);
Garmond Leunge2433c32017-09-28 21:51:22 -07003830 } else if (audio_extn_ffv_check_usecase(in)) {
Surendar karka30569792018-05-08 12:02:21 +05303831 char ffv_lic[LICENSE_STR_MAX_LEN + 1] = {0};
3832 int ffv_key = 0;
3833 if(platform_get_license_by_product(adev->platform, PRODUCT_FFV, &ffv_key, ffv_lic))
3834 {
3835 ALOGD("%s: Valid licence not availble for %s ", __func__, PRODUCT_FFV);
3836 return -EINVAL;
3837 }
3838 ALOGD("%s: KEY: %d LICENSE: %s ", __func__, ffv_key, ffv_lic);
3839 return audio_extn_ffv_set_usecase(in, ffv_key, ffv_lic);
Divya Narayanan Poojary45f19192016-09-30 18:52:13 +05303840 } else {
3841 return audio_extn_set_multichannel_mask(adev, in, config,
3842 update_params);
3843 }
3844}
Dhanalakshmi Siddani18737932016-11-29 17:33:17 +05303845
3846#ifdef APTX_DECODER_ENABLED
3847static void audio_extn_aptx_dec_set_license(struct audio_device *adev)
3848{
3849 int ret, key = 0;
3850 char value[128] = {0};
3851 struct mixer_ctl *ctl;
3852 const char *mixer_ctl_name = "APTX Dec License";
3853
3854 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
3855 if (!ctl) {
3856 ALOGE("%s: Could not get ctl for mixer cmd - %s",
3857 __func__, mixer_ctl_name);
3858 return;
3859 }
3860 key = platform_get_meta_info_key_from_list(adev->platform, "aptx");
3861
3862 ALOGD("%s Setting APTX License with key:0x%x",__func__, key);
3863 ret = mixer_ctl_set_value(ctl, 0, key);
3864 if (ret)
3865 ALOGE("%s: cannot set license, error:%d",__func__, ret);
3866}
3867
3868static void audio_extn_set_aptx_dec_bt_addr(struct audio_device *adev, struct str_parms *parms)
3869{
3870 int ret = 0;
3871 char value[256];
3872
3873 ret = str_parms_get_str(parms, AUDIO_PARAMETER_APTX_DEC_BT_ADDR, value,
3874 sizeof(value));
3875 if (ret >= 0) {
3876 audio_extn_parse_aptx_dec_bt_addr(value);
3877 }
3878}
3879
3880int audio_extn_set_aptx_dec_params(struct aptx_dec_param *payload)
3881{
3882 struct aptx_dec_param *aptx_cfg = payload;
3883
3884 aextnmod.addr.nap = aptx_cfg->bt_addr.nap;
3885 aextnmod.addr.uap = aptx_cfg->bt_addr.uap;
3886 aextnmod.addr.lap = aptx_cfg->bt_addr.lap;
3887}
3888
3889static void audio_extn_parse_aptx_dec_bt_addr(char *value)
3890{
3891 int ba[6];
3892 char *str, *tok;
3893 uint32_t addr[3];
3894 int i = 0;
3895
3896 ALOGV("%s: value %s", __func__, value);
3897 tok = strtok_r(value, ":", &str);
3898 while (tok != NULL) {
3899 ba[i] = strtol(tok, NULL, 16);
3900 i++;
3901 tok = strtok_r(NULL, ":", &str);
3902 }
3903 addr[0] = (ba[0] << 8) | ba[1];
3904 addr[1] = ba[2];
3905 addr[2] = (ba[3] << 16) | (ba[4] << 8) | ba[5];
3906
3907 aextnmod.addr.nap = addr[0];
3908 aextnmod.addr.uap = addr[1];
3909 aextnmod.addr.lap = addr[2];
3910}
3911
3912void audio_extn_send_aptx_dec_bt_addr_to_dsp(struct stream_out *out)
3913{
3914 char mixer_ctl_name[128];
3915 struct mixer_ctl *ctl;
3916 uint32_t addr[3];
3917
3918 ALOGV("%s", __func__);
3919 out->compr_config.codec->options.aptx_dec.nap = aextnmod.addr.nap;
3920 out->compr_config.codec->options.aptx_dec.uap = aextnmod.addr.uap;
3921 out->compr_config.codec->options.aptx_dec.lap = aextnmod.addr.lap;
3922}
3923
3924#endif //APTX_DECODER_ENABLED
Ben Rombergerd771a7c2017-02-22 18:05:17 -08003925
3926int audio_extn_out_set_param_data(struct stream_out *out,
3927 audio_extn_param_id param_id,
3928 audio_extn_param_payload *payload) {
3929 int ret = -EINVAL;
3930
3931 if (!out || !payload) {
3932 ALOGE("%s:: Invalid Param",__func__);
3933 return ret;
3934 }
3935
3936 ALOGD("%s: enter: stream (%p) usecase(%d: %s) param_id %d", __func__,
3937 out, out->usecase, use_case_table[out->usecase], param_id);
3938
3939 switch (param_id) {
3940 case AUDIO_EXTN_PARAM_OUT_RENDER_WINDOW:
3941 ret = audio_extn_utils_compress_set_render_window(out,
3942 (struct audio_out_render_window_param *)(payload));
3943 break;
3944 case AUDIO_EXTN_PARAM_OUT_START_DELAY:
3945 ret = audio_extn_utils_compress_set_start_delay(out,
3946 (struct audio_out_start_delay_param *)(payload));
3947 break;
Naresh Tanniru6160c712017-04-17 15:43:48 +05303948 case AUDIO_EXTN_PARAM_OUT_ENABLE_DRIFT_CORRECTION:
3949 ret = audio_extn_utils_compress_enable_drift_correction(out,
3950 (struct audio_out_enable_drift_correction *)(payload));
3951 break;
3952 case AUDIO_EXTN_PARAM_OUT_CORRECT_DRIFT:
3953 ret = audio_extn_utils_compress_correct_drift(out,
3954 (struct audio_out_correct_drift *)(payload));
3955 break;
Ben Rombergerd771a7c2017-02-22 18:05:17 -08003956 case AUDIO_EXTN_PARAM_ADSP_STREAM_CMD:
3957 ret = audio_extn_adsp_hdlr_stream_set_param(out->adsp_hdlr_stream_handle,
3958 ADSP_HDLR_STREAM_CMD_REGISTER_EVENT,
3959 (void *)&payload->adsp_event_params);
3960 break;
Naresh Tanniru29bce4e2017-04-27 17:54:30 +05303961 case AUDIO_EXTN_PARAM_OUT_CHANNEL_MAP:
3962 ret = audio_extn_utils_set_channel_map(out,
3963 (struct audio_out_channel_map_param *)(payload));
3964 break;
Varun Balaraje49253e2017-07-06 19:48:56 +05303965 case AUDIO_EXTN_PARAM_OUT_MIX_MATRIX_PARAMS:
3966 ret = audio_extn_utils_set_pan_scale_params(out,
3967 (struct mix_matrix_params *)(payload));
3968 break;
3969 case AUDIO_EXTN_PARAM_CH_MIX_MATRIX_PARAMS:
3970 ret = audio_extn_utils_set_downmix_params(out,
3971 (struct mix_matrix_params *)(payload));
3972 break;
Naresh Tanniru6160c712017-04-17 15:43:48 +05303973 default:
Ben Rombergerd771a7c2017-02-22 18:05:17 -08003974 ALOGE("%s:: unsupported param_id %d", __func__, param_id);
3975 break;
3976 }
3977 return ret;
3978}
3979
Trinath Thammishetty580f1de2018-09-28 12:43:24 +05303980#ifdef AUDIO_HW_LOOPBACK_ENABLED
3981int audio_extn_hw_loopback_set_param_data(audio_patch_handle_t handle,
3982 audio_extn_loopback_param_id param_id,
3983 audio_extn_loopback_param_payload *payload) {
3984 int ret = -EINVAL;
3985
3986 if (!payload) {
3987 ALOGE("%s:: Invalid Param",__func__);
3988 return ret;
3989 }
3990
3991 ALOGD("%d: %s: param id is %d\n", __LINE__, __func__, param_id);
3992
3993 switch(param_id) {
3994 case AUDIO_EXTN_PARAM_LOOPBACK_RENDER_WINDOW:
3995 ret = audio_extn_hw_loopback_set_render_window(handle, payload);
3996 break;
3997 default:
3998 ALOGE("%s: unsupported param id %d", __func__, param_id);
3999 break;
4000 }
4001
4002 return ret;
4003}
4004#endif
4005
4006
Ben Rombergerd771a7c2017-02-22 18:05:17 -08004007/* API to get playback stream specific config parameters */
4008int audio_extn_out_get_param_data(struct stream_out *out,
4009 audio_extn_param_id param_id,
4010 audio_extn_param_payload *payload)
4011{
4012 int ret = -EINVAL;
4013 struct audio_usecase *uc_info;
4014
4015 if (!out || !payload) {
4016 ALOGE("%s:: Invalid Param",__func__);
4017 return ret;
4018 }
4019
4020 switch (param_id) {
4021 case AUDIO_EXTN_PARAM_AVT_DEVICE_DRIFT:
4022 uc_info = get_usecase_from_list(out->dev, out->usecase);
4023 if (uc_info == NULL) {
4024 ALOGE("%s: Could not find the usecase (%d) in the list",
4025 __func__, out->usecase);
4026 ret = -EINVAL;
4027 } else {
4028 ret = audio_extn_utils_get_avt_device_drift(uc_info,
4029 (struct audio_avt_device_drift_param *)payload);
4030 if(ret)
4031 ALOGE("%s:: avdrift query failed error %d", __func__, ret);
4032 }
4033 break;
Surendar Karka287348c2019-04-10 18:31:46 +05304034 case AUDIO_EXTN_PARAM_OUT_PRESENTATION_POSITION:
4035 ret = audio_ext_get_presentation_position(out,
4036 (struct audio_out_presentation_position_param *)payload);
4037 if (ret < 0)
4038 ALOGE("%s:: presentation position query failed error %d",
4039 __func__, ret);
4040 break;
Ben Rombergerd771a7c2017-02-22 18:05:17 -08004041 default:
4042 ALOGE("%s:: unsupported param_id %d", __func__, param_id);
4043 break;
4044 }
4045
4046 return ret;
4047}
Satish Babu Patakokilac3c5d432017-07-04 22:48:59 +05304048
4049int audio_extn_set_device_cfg_params(struct audio_device *adev,
4050 struct audio_device_cfg_param *payload)
4051{
4052 struct audio_device_cfg_param *device_cfg_params = payload;
4053 int ret = -EINVAL;
4054 struct stream_out out;
4055 uint32_t snd_device = 0, backend_idx = 0;
Varun Balaraj003ee752017-08-07 17:54:55 +05304056 struct audio_device_config_param *adev_device_cfg_ptr;
Satish Babu Patakokilac3c5d432017-07-04 22:48:59 +05304057
4058 ALOGV("%s", __func__);
4059
Varun Balaraj003ee752017-08-07 17:54:55 +05304060 if (!device_cfg_params || !adev || !adev->device_cfg_params) {
Satish Babu Patakokilac3c5d432017-07-04 22:48:59 +05304061 ALOGE("%s:: Invalid Param", __func__);
4062 return ret;
4063 }
4064
4065 /* Config is not supported for combo devices */
4066 if (popcount(device_cfg_params->device) != 1) {
4067 ALOGE("%s:: Invalid Device (%#x) - Config is ignored", __func__, device_cfg_params->device);
4068 return ret;
4069 }
4070
Varun Balaraj003ee752017-08-07 17:54:55 +05304071 adev_device_cfg_ptr = adev->device_cfg_params;
Satish Babu Patakokilac3c5d432017-07-04 22:48:59 +05304072 /* Create an out stream to get snd device from audio device */
Aniket Kumar Lata0e6e1e52019-11-14 21:43:55 -08004073 reassign_device_list(&out.device_list, device_cfg_params->device, "");
Satish Babu Patakokilac3c5d432017-07-04 22:48:59 +05304074 out.sample_rate = device_cfg_params->sample_rate;
Jaideep Sharma477917f2020-03-13 18:13:33 +05304075 snd_device = platform_get_output_snd_device(adev->platform, &out, USECASE_TYPE_MAX);
Satish Babu Patakokilac3c5d432017-07-04 22:48:59 +05304076 backend_idx = platform_get_backend_index(snd_device);
4077
4078 ALOGV("%s:: device %d sample_rate %d snd_device %d backend_idx %d",
Aniket Kumar Lata9c2fd892020-01-22 22:20:00 -08004079 __func__, get_device_types(&out.device_list),
4080 out.sample_rate, snd_device, backend_idx);
Satish Babu Patakokilac3c5d432017-07-04 22:48:59 +05304081
4082 ALOGV("%s:: Device Config Params from Client samplerate %d channels %d"
4083 " bit_width %d format %d device %d channel_map[0] %d channel_map[1] %d"
4084 " channel_map[2] %d channel_map[3] %d channel_map[4] %d channel_map[5] %d"
4085 " channel_allocation %d\n", __func__, device_cfg_params->sample_rate,
4086 device_cfg_params->channels, device_cfg_params->bit_width,
4087 device_cfg_params->format, device_cfg_params->device,
4088 device_cfg_params->channel_map[0], device_cfg_params->channel_map[1],
4089 device_cfg_params->channel_map[2], device_cfg_params->channel_map[3],
4090 device_cfg_params->channel_map[4], device_cfg_params->channel_map[5],
4091 device_cfg_params->channel_allocation);
4092
4093 /* Copy the config values into adev structure variable */
4094 adev_device_cfg_ptr += backend_idx;
4095 adev_device_cfg_ptr->use_client_dev_cfg = true;
4096 memcpy(&adev_device_cfg_ptr->dev_cfg_params, device_cfg_params, sizeof(struct audio_device_cfg_param));
4097
4098 return 0;
4099}
Surendar Karkaf51b5842018-04-26 11:28:38 +05304100
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08004101//START: FM_POWER_OPT_FEATURE ================================================================
4102void fm_feature_init(bool is_feature_enabled)
Aalique Grahame22e49102018-12-18 14:23:57 -08004103{
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08004104 audio_extn_fm_power_opt_enabled = is_feature_enabled;
Arun Mirpurie008ed22019-03-21 11:21:04 -07004105 ALOGD("%s: ---- Feature FM_POWER_OPT is %s----", __func__, is_feature_enabled? "ENABLED": "NOT ENABLED");
Aalique Grahame22e49102018-12-18 14:23:57 -08004106}
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08004107
4108
4109void audio_extn_fm_get_parameters(struct str_parms *query, struct str_parms *reply)
Aalique Grahame22e49102018-12-18 14:23:57 -08004110{
Arun Mirpurie008ed22019-03-21 11:21:04 -07004111 if(audio_extn_fm_power_opt_enabled) {
Aniket Kumar Latad13758f2020-08-06 15:11:36 -07004112 ALOGV("%s: Enter", __func__);
Arun Mirpurie008ed22019-03-21 11:21:04 -07004113 fm_get_parameters(query, reply);
4114 }
Aalique Grahame22e49102018-12-18 14:23:57 -08004115}
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08004116
4117void audio_extn_fm_set_parameters(struct audio_device *adev,
4118 struct str_parms *parms)
Aalique Grahame22e49102018-12-18 14:23:57 -08004119{
Arun Mirpurie008ed22019-03-21 11:21:04 -07004120 if(audio_extn_fm_power_opt_enabled) {
Aniket Kumar Latad13758f2020-08-06 15:11:36 -07004121 ALOGV("%s: Enter", __func__);
Arun Mirpurie008ed22019-03-21 11:21:04 -07004122 fm_set_parameters(adev, parms);
4123 }
Aalique Grahame22e49102018-12-18 14:23:57 -08004124}
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08004125//END: FM_POWER_OPT_FEATURE ================================================================
4126
4127//START: HDMI_EDID =========================================================================
4128#ifdef __LP64__
4129#define HDMI_EDID_LIB_PATH "/vendor/lib64/libhdmiedid.so"
4130#else
4131#define HDMI_EDID_LIB_PATH "/vendor/lib/libhdmiedid.so"
4132#endif
4133
4134static void *hdmi_edid_lib_handle = NULL;
4135
4136typedef bool (*hdmi_edid_is_supported_sr_t)(edid_audio_info*, int);
4137static hdmi_edid_is_supported_sr_t hdmi_edid_is_supported_sr;
4138
4139typedef bool (*hdmi_edid_is_supported_bps_t)(edid_audio_info*, int);
4140static hdmi_edid_is_supported_bps_t hdmi_edid_is_supported_bps;
4141
4142typedef int (*hdmi_edid_get_highest_supported_sr_t)(edid_audio_info*);
4143static hdmi_edid_get_highest_supported_sr_t hdmi_edid_get_highest_supported_sr;
4144
4145typedef bool (*hdmi_edid_get_sink_caps_t)(edid_audio_info*, char*);
4146static hdmi_edid_get_sink_caps_t hdmi_edid_get_sink_caps;
4147
4148void hdmi_edid_feature_init(bool is_feature_enabled)
Aalique Grahame22e49102018-12-18 14:23:57 -08004149{
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08004150 ALOGD("%s: HDMI_EDID feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
4151 if (is_feature_enabled) {
4152 //dlopen lib
4153 hdmi_edid_lib_handle = dlopen(HDMI_EDID_LIB_PATH, RTLD_NOW);
4154 if (hdmi_edid_lib_handle == NULL) {
4155 ALOGE("%s: dlopen failed", __func__);
4156 goto feature_disabled;
4157 }
4158 //map each function
4159 //on any faliure to map any function, disble feature
4160 if (((hdmi_edid_is_supported_sr =
4161 (hdmi_edid_is_supported_sr_t)dlsym(hdmi_edid_lib_handle,
4162 "edid_is_supported_sr")) == NULL) ||
4163 ((hdmi_edid_is_supported_bps =
4164 (hdmi_edid_is_supported_bps_t)dlsym(hdmi_edid_lib_handle,
4165 "edid_is_supported_bps")) == NULL) ||
4166 ((hdmi_edid_get_highest_supported_sr =
4167 (hdmi_edid_get_highest_supported_sr_t)dlsym(hdmi_edid_lib_handle,
4168 "edid_get_highest_supported_sr")) == NULL) ||
4169 ((hdmi_edid_get_sink_caps =
4170 (hdmi_edid_get_sink_caps_t)dlsym(hdmi_edid_lib_handle,
4171 "edid_get_sink_caps")) == NULL)) {
4172 ALOGE("%s: dlsym failed", __func__);
4173 goto feature_disabled;
4174 }
4175
4176 ALOGD("%s:: ---- Feature HDMI_EDID is Enabled ----", __func__);
4177 return;
4178 }
4179
4180feature_disabled:
4181 if (hdmi_edid_lib_handle) {
4182 dlclose(hdmi_edid_lib_handle);
4183 hdmi_edid_lib_handle = NULL;
4184 }
4185
4186 hdmi_edid_is_supported_sr = NULL;
4187 hdmi_edid_is_supported_bps = NULL;
4188 hdmi_edid_get_highest_supported_sr = NULL;
4189 hdmi_edid_get_sink_caps = NULL;
4190 ALOGW(":: %s: ---- Feature HDMI_EDID is disabled ----", __func__);
4191 return;
Aalique Grahame22e49102018-12-18 14:23:57 -08004192}
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08004193
4194bool audio_extn_edid_is_supported_sr(edid_audio_info* info, int sr)
Aalique Grahame22e49102018-12-18 14:23:57 -08004195{
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08004196 bool ret = false;
4197
4198 if(hdmi_edid_is_supported_sr != NULL)
4199 ret = hdmi_edid_is_supported_sr(info, sr);
4200 return ret;
4201}
4202
4203bool audio_extn_edid_is_supported_bps(edid_audio_info* info, int bps)
4204{
4205 bool ret = false;
4206
4207 if(hdmi_edid_is_supported_bps != NULL)
4208 ret = hdmi_edid_is_supported_bps(info, bps);
4209 return ret;
4210}
4211int audio_extn_edid_get_highest_supported_sr(edid_audio_info* info)
4212{
4213 int ret = -1;
4214
4215 if(hdmi_edid_get_highest_supported_sr != NULL)
4216 ret = hdmi_edid_get_highest_supported_sr(info);
4217 return ret;
4218}
4219
4220bool audio_extn_edid_get_sink_caps(edid_audio_info* info, char *edid_data)
4221{
4222 bool ret = false;
4223
4224 if(hdmi_edid_get_sink_caps != NULL)
4225 ret = hdmi_edid_get_sink_caps(info, edid_data);
4226 return ret;
4227}
4228
4229//END: HDMI_EDID =========================================================================
4230
4231
4232//START: KEEP_ALIVE =========================================================================
4233
4234void keep_alive_feature_init(bool is_feature_enabled)
4235{
4236 audio_extn_keep_alive_enabled = is_feature_enabled;
4237 ALOGD(":: %s: ---- Feature KEEP_ALIVE is %s ----", __func__, is_feature_enabled? "ENABLED": " NOT ENABLED");
4238}
4239
4240void audio_extn_keep_alive_init(struct audio_device *adev)
4241{
4242 if(audio_extn_keep_alive_enabled)
4243 keep_alive_init(adev);
4244}
4245
4246void audio_extn_keep_alive_deinit()
4247{
4248 if(audio_extn_keep_alive_enabled)
4249 keep_alive_deinit();
4250}
4251
4252void audio_extn_keep_alive_start(ka_mode_t ka_mode)
4253{
4254 if(audio_extn_keep_alive_enabled)
4255 keep_alive_start(ka_mode);
4256}
4257
4258void audio_extn_keep_alive_stop(ka_mode_t ka_mode)
4259{
4260 if(audio_extn_keep_alive_enabled)
4261 keep_alive_stop(ka_mode);
4262}
4263
4264bool audio_extn_keep_alive_is_active()
4265{
4266 bool ret = false;
4267 return ret;
4268}
4269
4270int audio_extn_keep_alive_set_parameters(struct audio_device *adev,
4271 struct str_parms *parms)
4272{
4273 int ret = -1;
4274 if(audio_extn_keep_alive_enabled)
4275 return keep_alive_set_parameters(adev, parms);
4276 return ret;
4277}
4278//END: KEEP_ALIVE =========================================================================
4279
4280//START: HIFI_AUDIO =========================================================================
4281void hifi_audio_feature_init(bool is_feature_enabled)
4282{
4283 audio_extn_hifi_audio_enabled = is_feature_enabled;
4284 ALOGD(":: %s: ---- Feature HIFI_AUDIO is %s ----", __func__, is_feature_enabled? "ENABLED": " NOT ENABLED");
4285}
4286
4287bool audio_extn_is_hifi_audio_enabled(void)
4288{
4289 bool ret = false;
4290 if(audio_extn_hifi_audio_enabled)
4291 {
4292 ALOGV("%s: status: %d", __func__, aextnmod.hifi_audio_enabled);
4293 return (aextnmod.hifi_audio_enabled ? true: false);
4294 }
4295 return ret;
4296}
4297
4298bool audio_extn_is_hifi_audio_supported(void)
4299{
4300 bool ret = false;
4301
4302 if(audio_extn_hifi_audio_enabled)
4303 {
4304 /*
4305 * for internal codec, check for hifiaudio property to enable hifi audio
4306 */
4307 if (property_get_bool("persist.vendor.audio.hifi.int_codec", false))
4308 {
4309 ALOGD("%s: hifi audio supported on internal codec", __func__);
4310 aextnmod.hifi_audio_enabled = 1;
4311 }
4312 return (aextnmod.hifi_audio_enabled ? true: false);
4313 }
4314 return ret;
4315}
4316
4317//END: HIFI_AUDIO =========================================================================
4318
4319//START: RAS =============================================================================
4320void ras_feature_init(bool is_feature_enabled)
4321{
4322 audio_extn_ras_feature_enabled = is_feature_enabled;
4323 ALOGD(":: %s: ---- Feature RAS_FEATURE is %s ----", __func__, is_feature_enabled? "ENABLED": " NOT ENABLED");
4324}
4325
4326bool audio_extn_is_ras_enabled(void)
4327{
4328 bool ret = false;
4329
4330 if(audio_extn_ras_feature_enabled)
4331 {
4332 ALOGD("%s: status: %d", __func__, aextnmod.ras_enabled);
4333 return (aextnmod.ras_enabled ? true: false);
4334 }
4335 return ret;
4336}
4337
4338bool audio_extn_can_use_ras(void)
4339{
4340 bool ret = false;
4341
4342 if(audio_extn_ras_feature_enabled)
4343 {
4344 if (property_get_bool("persist.vendor.audio.ras.enabled", false))
4345 aextnmod.ras_enabled = 1;
4346 ALOGD("%s: ras.enabled property is set to %d", __func__, aextnmod.ras_enabled);
4347 return (aextnmod.ras_enabled ? true: false);
4348 }
4349 return ret;
4350}
4351
4352//END: RAS ===============================================================================
4353
4354//START: KPI_OPTIMIZE =============================================================================
4355void kpi_optimize_feature_init(bool is_feature_enabled)
4356{
4357 audio_extn_kpi_optimize_feature_enabled = is_feature_enabled;
4358 ALOGD(":: %s: ---- Feature KPI_OPTIMIZE is %s ----", __func__, is_feature_enabled? "ENABLED": " NOT ENABLED");
4359}
4360
4361typedef int (*perf_lock_acquire_t)(int, int, int*, int);
4362typedef int (*perf_lock_release_t)(int);
4363
4364static void *qcopt_handle;
4365static perf_lock_acquire_t perf_lock_acq;
4366static perf_lock_release_t perf_lock_rel;
4367
4368char opt_lib_path[512] = {0};
4369
4370int audio_extn_perf_lock_init(void)
4371{
4372 int ret = 0;
4373
4374 //if feature is disabled, exit immediately
4375 if(!audio_extn_kpi_optimize_feature_enabled)
4376 goto err;
4377
4378 if (qcopt_handle == NULL) {
4379 if (property_get("ro.vendor.extension_library",
4380 opt_lib_path, NULL) <= 0) {
4381 ALOGE("%s: Failed getting perf property \n", __func__);
4382 ret = -EINVAL;
4383 goto err;
4384 }
4385 if ((qcopt_handle = dlopen(opt_lib_path, RTLD_NOW)) == NULL) {
4386 ALOGE("%s: Failed to open perf handle \n", __func__);
4387 ret = -EINVAL;
4388 goto err;
4389 } else {
4390 perf_lock_acq = (perf_lock_acquire_t)dlsym(qcopt_handle,
4391 "perf_lock_acq");
4392 if (perf_lock_acq == NULL) {
4393 ALOGE("%s: Perf lock Acquire NULL \n", __func__);
4394 dlclose(qcopt_handle);
4395 ret = -EINVAL;
4396 goto err;
4397 }
4398 perf_lock_rel = (perf_lock_release_t)dlsym(qcopt_handle,
4399 "perf_lock_rel");
4400 if (perf_lock_rel == NULL) {
4401 ALOGE("%s: Perf lock Release NULL \n", __func__);
4402 dlclose(qcopt_handle);
4403 ret = -EINVAL;
4404 goto err;
4405 }
4406 ALOGE("%s: Perf lock handles Success \n", __func__);
4407 }
4408 }
4409err:
4410 return ret;
4411}
4412
4413void audio_extn_perf_lock_acquire(int *handle, int duration,
4414 int *perf_lock_opts, int size)
4415{
4416 if (audio_extn_kpi_optimize_feature_enabled)
4417 {
4418 if (!perf_lock_opts || !size || !perf_lock_acq || !handle) {
4419 ALOGE("%s: Incorrect params, Failed to acquire perf lock, err ",
4420 __func__);
4421 return;
4422 }
4423 /*
4424 * Acquire performance lock for 1 sec during device path bringup.
4425 * Lock will be released either after 1 sec or when perf_lock_release
4426 * function is executed.
4427 */
4428 *handle = perf_lock_acq(*handle, duration, perf_lock_opts, size);
4429 if (*handle <= 0)
4430 ALOGE("%s: Failed to acquire perf lock, err: %d\n",
4431 __func__, *handle);
4432 }
4433}
4434
4435void audio_extn_perf_lock_release(int *handle)
4436{
4437 if (audio_extn_kpi_optimize_feature_enabled) {
4438 if (perf_lock_rel && handle && (*handle > 0)) {
4439 perf_lock_rel(*handle);
4440 *handle = 0;
4441 } else
4442 ALOGE("%s: Perf lock release error \n", __func__);
4443 }
4444}
4445
4446//END: KPI_OPTIMIZE =============================================================================
4447
4448//START: DISPLAY_PORT =============================================================================
4449void display_port_feature_init(bool is_feature_enabled)
4450{
4451 audio_extn_display_port_feature_enabled = is_feature_enabled;
4452 ALOGD(":: %s: ---- Feature DISPLAY_PORT is %s ----", __func__, is_feature_enabled? "ENABLED": " NOT ENABLED");
4453}
4454
4455bool audio_extn_is_display_port_enabled()
4456{
4457 return audio_extn_display_port_feature_enabled;
4458}
4459//END: DISPLAY_PORT ===============================================================================
4460//START: FLUENCE =============================================================================
4461void fluence_feature_init(bool is_feature_enabled)
4462{
4463 audio_extn_fluence_feature_enabled = is_feature_enabled;
4464 ALOGD(":: %s: ---- Feature FLUENCE is %s ----", __func__, is_feature_enabled? "ENABLED": " NOT ENABLED");
4465}
4466
4467bool audio_extn_is_fluence_enabled()
4468{
4469 return audio_extn_fluence_feature_enabled;
4470}
4471
4472void audio_extn_set_fluence_parameters(struct audio_device *adev,
4473 struct str_parms *parms)
4474{
4475 int ret = 0, err;
4476 char value[32];
4477 struct listnode *node;
4478 struct audio_usecase *usecase;
4479
4480 if (audio_extn_is_fluence_enabled()) {
4481 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_FLUENCE,
4482 value, sizeof(value));
4483 ALOGV_IF(err >= 0, "%s: Set Fluence Type to %s", __func__, value);
4484 if (err >= 0) {
4485 ret = platform_set_fluence_type(adev->platform, value);
4486 if (ret != 0) {
4487 ALOGE("platform_set_fluence_type returned error: %d", ret);
4488 } else {
4489 /*
4490 *If the fluence is manually set/reset, devices
4491 *need to get updated for all the usecases
4492 *i.e. audio and voice.
4493 */
4494 list_for_each(node, &adev->usecase_list) {
4495 usecase = node_to_item(node, struct audio_usecase, list);
4496 select_devices(adev, usecase->id);
4497 }
4498 }
4499 }
4500
4501 }
4502}
4503
4504int audio_extn_get_fluence_parameters(const struct audio_device *adev,
4505 struct str_parms *query, struct str_parms *reply)
4506{
4507 int ret = -1, err;
4508 char value[256] = {0};
4509
4510 if (audio_extn_is_fluence_enabled()) {
4511 err = str_parms_get_str(query, AUDIO_PARAMETER_KEY_FLUENCE, value,
4512 sizeof(value));
4513 if (err >= 0) {
4514 ret = platform_get_fluence_type(adev->platform, value, sizeof(value));
4515 if (ret >= 0) {
4516 ALOGV("%s: Fluence Type is %s", __func__, value);
4517 str_parms_add_str(reply, AUDIO_PARAMETER_KEY_FLUENCE, value);
4518 } else
4519 goto done;
4520 }
4521 }
4522done:
4523 return ret;
4524}
4525//END: FLUENCE ===============================================================================
Sujin Panickerb904fbe2019-04-04 13:28:07 +05304526//START: WSA =============================================================================
4527void wsa_feature_init(bool is_feature_enabled)
4528{
4529 audio_extn_wsa_enabled = is_feature_enabled;
4530}
4531
4532bool audio_extn_is_wsa_enabled()
4533{
4534 return audio_extn_wsa_enabled;
4535}
4536//END: WSA ===============================================================================
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08004537//START: CUSTOM_STEREO =============================================================================
4538void custom_stereo_feature_init(bool is_feature_enabled)
4539{
4540 audio_extn_custom_stereo_feature_enabled = is_feature_enabled;
4541 ALOGD(":: %s: ---- Feature CUSTOM_STEREO is %s ----", __func__, is_feature_enabled? "ENABLED": " NOT ENABLED");
4542}
4543
4544bool audio_extn_is_custom_stereo_enabled()
4545{
4546 return audio_extn_custom_stereo_feature_enabled;
4547}
4548
4549void audio_extn_customstereo_set_parameters(struct audio_device *adev,
4550 struct str_parms *parms)
4551{
4552 int ret = 0;
4553 char value[32]={0};
4554 bool custom_stereo_state = false;
4555 const char *mixer_ctl_name = "Set Custom Stereo OnOff";
4556 struct mixer_ctl *ctl;
4557
4558 ALOGV("%s", __func__);
4559
4560 if (audio_extn_custom_stereo_feature_enabled) {
4561 ret = str_parms_get_str(parms, AUDIO_PARAMETER_CUSTOM_STEREO, value,
4562 sizeof(value));
4563 if (ret >= 0) {
4564 if (!strncmp("true", value, sizeof("true")) || atoi(value))
4565 custom_stereo_state = true;
4566
4567 if (custom_stereo_state == aextnmod.custom_stereo_enabled)
4568 return;
4569
4570 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
4571 if (!ctl) {
4572 ALOGE("%s: Could not get ctl for mixer cmd - %s",
4573 __func__, mixer_ctl_name);
4574 return;
4575 }
4576 if (mixer_ctl_set_value(ctl, 0, custom_stereo_state) < 0) {
4577 ALOGE("%s: Could not set custom stereo state %d",
4578 __func__, custom_stereo_state);
4579 return;
4580 }
4581 aextnmod.custom_stereo_enabled = custom_stereo_state;
4582 ALOGV("%s: Setting custom stereo state success", __func__);
4583 }
4584 }
4585}
4586
4587void audio_extn_send_dual_mono_mixing_coefficients(struct stream_out *out)
4588{
4589 struct audio_device *adev = out->dev;
4590 struct mixer_ctl *ctl;
4591 char mixer_ctl_name[128];
4592 int cust_ch_mixer_cfg[128], len = 0;
4593 int ip_channel_cnt = audio_channel_count_from_out_mask(out->channel_mask);
4594 int pcm_device_id = platform_get_pcm_device_id(out->usecase, PCM_PLAYBACK);
4595 int op_channel_cnt= 2;
4596 int i, j, err;
4597
4598 ALOGV("%s", __func__);
4599
4600 if (audio_extn_custom_stereo_feature_enabled) {
4601 if (!out->started) {
4602 out->set_dual_mono = true;
4603 goto exit;
4604 }
4605
4606 ALOGD("%s: i/p channel count %d, o/p channel count %d, pcm id %d", __func__,
4607 ip_channel_cnt, op_channel_cnt, pcm_device_id);
4608
4609 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
4610 "Audio Stream %d Channel Mix Cfg", pcm_device_id);
4611 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
4612 if (!ctl) {
4613 ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
4614 __func__, mixer_ctl_name);
4615 goto exit;
4616 }
4617
4618 /* Output channel count corresponds to backend configuration channels.
4619 * Input channel count corresponds to ASM session channels.
4620 * Set params is called with channels that need to be selected from
4621 * input to generate output.
4622 * ex: "8,2" to downmix from 8 to 2 i.e. to downmix from 8 to 2,
4623 *
4624 * This mixer control takes values in the following sequence:
4625 * - input channel count(m)
4626 * - output channel count(n)
4627 * - weight coeff for [out ch#1, in ch#1]
4628 * ....
4629 * - weight coeff for [out ch#1, in ch#m]
4630 *
4631 * - weight coeff for [out ch#2, in ch#1]
4632 * ....
4633 * - weight coeff for [out ch#2, in ch#m]
4634 *
4635 * - weight coeff for [out ch#n, in ch#1]
4636 * ....
4637 * - weight coeff for [out ch#n, in ch#m]
4638 *
4639 * To get dualmono ouptu weightage coeff is calculated as Unity gain
4640 * divided by number of input channels.
4641 */
4642 cust_ch_mixer_cfg[len++] = ip_channel_cnt;
4643 cust_ch_mixer_cfg[len++] = op_channel_cnt;
4644 for (i = 0; i < op_channel_cnt; i++) {
4645 for (j = 0; j < ip_channel_cnt; j++) {
4646 cust_ch_mixer_cfg[len++] = Q14_GAIN_UNITY/ip_channel_cnt;
4647 }
4648 }
4649
4650 err = mixer_ctl_set_array(ctl, cust_ch_mixer_cfg, len);
4651 if (err)
4652 ALOGE("%s: ERROR. Mixer ctl set failed", __func__);
4653
4654 }
4655exit:
4656 return;
4657}
4658//END: CUSTOM_STEREO =============================================================================
4659// START: A2DP_OFFLOAD ===================================================================
4660#ifdef __LP64__
4661#define A2DP_OFFLOAD_LIB_PATH "/vendor/lib64/liba2dpoffload.so"
4662#else
4663#define A2DP_OFFLOAD_LIB_PATH "/vendor/lib/liba2dpoffload.so"
4664#endif
4665
4666static void *a2dp_lib_handle = NULL;
4667
Aalique Grahame6e763712019-01-31 16:18:17 -08004668typedef void (*a2dp_init_t)(void *, a2dp_offload_init_config_t);
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08004669static a2dp_init_t a2dp_init;
4670
4671typedef int (*a2dp_start_playback_t)();
4672static a2dp_start_playback_t a2dp_start_playback;
4673
4674typedef int (*a2dp_stop_playback_t)();
4675static a2dp_stop_playback_t a2dp_stop_playback;
4676
4677typedef int (*a2dp_set_parameters_t)(struct str_parms *,
4678 bool *);
4679static a2dp_set_parameters_t a2dp_set_parameters;
4680
4681typedef int (*a2dp_get_parameters_t)(struct str_parms *,
4682 struct str_parms *);
4683static a2dp_get_parameters_t a2dp_get_parameters;
4684
4685typedef bool (*a2dp_is_force_device_switch_t)();
4686static a2dp_is_force_device_switch_t a2dp_is_force_device_switch;
4687
4688typedef void (*a2dp_set_handoff_mode_t)(bool);
4689static a2dp_set_handoff_mode_t a2dp_set_handoff_mode;
4690
4691typedef void (*a2dp_get_enc_sample_rate_t)(int *);
4692static a2dp_get_enc_sample_rate_t a2dp_get_enc_sample_rate;
4693
4694typedef void (*a2dp_get_dec_sample_rate_t)(int *);
4695static a2dp_get_dec_sample_rate_t a2dp_get_dec_sample_rate;
4696
4697typedef uint32_t (*a2dp_get_encoder_latency_t)();
4698static a2dp_get_encoder_latency_t a2dp_get_encoder_latency;
4699
4700typedef bool (*a2dp_sink_is_ready_t)();
4701static a2dp_sink_is_ready_t a2dp_sink_is_ready;
4702
4703typedef bool (*a2dp_source_is_ready_t)();
4704static a2dp_source_is_ready_t a2dp_source_is_ready;
4705
4706typedef bool (*a2dp_source_is_suspended_t)();
4707static a2dp_source_is_suspended_t a2dp_source_is_suspended;
4708
4709typedef int (*a2dp_start_capture_t)();
4710static a2dp_start_capture_t a2dp_start_capture;
4711
4712typedef int (*a2dp_stop_capture_t)();
4713static a2dp_stop_capture_t a2dp_stop_capture;
4714
Aniket Kumar Lata990de552019-07-11 14:20:23 -07004715typedef bool (*a2dp_set_source_backend_cfg_t)();
4716static a2dp_set_source_backend_cfg_t a2dp_set_source_backend_cfg;
4717
Zhou Song12c29502019-03-16 10:37:18 +08004718typedef int (*sco_start_configuration_t)();
4719static sco_start_configuration_t sco_start_configuration;
4720
4721typedef void (*sco_reset_configuration_t)();
4722static sco_reset_configuration_t sco_reset_configuration;
4723
4724
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08004725int a2dp_offload_feature_init(bool is_feature_enabled)
4726{
4727 ALOGD("%s: Called with feature %s", __func__,
4728 is_feature_enabled ? "Enabled" : "NOT Enabled");
4729 if (is_feature_enabled) {
4730 // dlopen lib
4731 a2dp_lib_handle = dlopen(A2DP_OFFLOAD_LIB_PATH, RTLD_NOW);
4732
4733 if (!a2dp_lib_handle) {
4734 ALOGE("%s: dlopen failed", __func__);
4735 goto feature_disabled;
4736 }
4737
4738 if (!(a2dp_init = (a2dp_init_t)dlsym(a2dp_lib_handle, "a2dp_init")) ||
4739 !(a2dp_start_playback =
4740 (a2dp_start_playback_t)dlsym(a2dp_lib_handle, "a2dp_start_playback")) ||
4741 !(a2dp_stop_playback =
4742 (a2dp_stop_playback_t)dlsym(a2dp_lib_handle, "a2dp_stop_playback")) ||
4743 !(a2dp_set_parameters =
4744 (a2dp_set_parameters_t)dlsym(a2dp_lib_handle, "a2dp_set_parameters")) ||
4745 !(a2dp_get_parameters =
4746 (a2dp_get_parameters_t)dlsym(a2dp_lib_handle, "a2dp_get_parameters")) ||
4747 !(a2dp_is_force_device_switch =
4748 (a2dp_is_force_device_switch_t)dlsym(
4749 a2dp_lib_handle, "a2dp_is_force_device_switch")) ||
4750 !(a2dp_set_handoff_mode =
4751 (a2dp_set_handoff_mode_t)dlsym(
4752 a2dp_lib_handle, "a2dp_set_handoff_mode")) ||
4753 !(a2dp_get_enc_sample_rate =
4754 (a2dp_get_enc_sample_rate_t)dlsym(
4755 a2dp_lib_handle, "a2dp_get_enc_sample_rate")) ||
4756 !(a2dp_get_dec_sample_rate =
4757 (a2dp_get_dec_sample_rate_t)dlsym(
4758 a2dp_lib_handle, "a2dp_get_dec_sample_rate")) ||
4759 !(a2dp_get_encoder_latency =
4760 (a2dp_get_encoder_latency_t)dlsym(
4761 a2dp_lib_handle, "a2dp_get_encoder_latency")) ||
4762 !(a2dp_sink_is_ready =
4763 (a2dp_sink_is_ready_t)dlsym(a2dp_lib_handle, "a2dp_sink_is_ready")) ||
4764 !(a2dp_source_is_ready =
4765 (a2dp_source_is_ready_t)dlsym(a2dp_lib_handle, "a2dp_source_is_ready")) ||
4766 !(a2dp_source_is_suspended =
4767 (a2dp_source_is_suspended_t)dlsym(
4768 a2dp_lib_handle, "a2dp_source_is_suspended")) ||
4769 !(a2dp_start_capture =
4770 (a2dp_start_capture_t)dlsym(a2dp_lib_handle, "a2dp_start_capture")) ||
4771 !(a2dp_stop_capture =
Aniket Kumar Lata990de552019-07-11 14:20:23 -07004772 (a2dp_stop_capture_t)dlsym(a2dp_lib_handle, "a2dp_stop_capture")) ||
4773 !(a2dp_set_source_backend_cfg =
4774 (a2dp_set_source_backend_cfg_t)dlsym(
4775 a2dp_lib_handle, "a2dp_set_source_backend_cfg"))) {
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08004776 ALOGE("%s: dlsym failed", __func__);
4777 goto feature_disabled;
4778 }
Zhou Song12c29502019-03-16 10:37:18 +08004779 // initialize APIs for SWB extension
4780 if (!(sco_start_configuration =
4781 (sco_start_configuration_t)dlsym(a2dp_lib_handle, "sco_start_configuration")) ||
4782 !(sco_reset_configuration =
4783 (sco_reset_configuration_t)dlsym(a2dp_lib_handle, "sco_reset_configuration"))) {
4784 ALOGE("%s: dlsym failed for swb APIs", __func__);
4785 sco_start_configuration = NULL;
4786 sco_reset_configuration = NULL;
4787 }
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08004788 ALOGD("%s:: ---- Feature A2DP_OFFLOAD is Enabled ----", __func__);
4789 return 0;
4790 }
4791
4792feature_disabled:
4793 if (a2dp_lib_handle) {
4794 dlclose(a2dp_lib_handle);
4795 a2dp_lib_handle = NULL;
4796 }
4797
4798 a2dp_init = NULL;
4799 a2dp_start_playback= NULL;
4800 a2dp_stop_playback = NULL;
4801 a2dp_set_parameters = NULL;
4802 a2dp_get_parameters = NULL;
4803 a2dp_is_force_device_switch = NULL;
4804 a2dp_set_handoff_mode = NULL;
4805 a2dp_get_enc_sample_rate = NULL;
4806 a2dp_get_dec_sample_rate = NULL;
4807 a2dp_get_encoder_latency = NULL;
4808 a2dp_sink_is_ready = NULL;
4809 a2dp_source_is_ready = NULL;
4810 a2dp_source_is_suspended = NULL;
4811 a2dp_start_capture = NULL;
4812 a2dp_stop_capture = NULL;
Aniket Kumar Lata990de552019-07-11 14:20:23 -07004813 a2dp_set_source_backend_cfg = NULL;
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08004814
4815 ALOGW(":: %s: ---- Feature A2DP_OFFLOAD is disabled ----", __func__);
4816 return -ENOSYS;
4817}
4818
4819void audio_extn_a2dp_init(void *adev)
4820{
4821 if (a2dp_init) {
Aalique Grahame6e763712019-01-31 16:18:17 -08004822 a2dp_offload_init_config_t a2dp_init_config;
4823 a2dp_init_config.fp_platform_get_pcm_device_id = platform_get_pcm_device_id;
Weiyin Jiang280ea742020-09-08 20:28:22 +08004824 a2dp_init_config.fp_check_a2dp_restore_l = check_a2dp_restore_l;
Gautam Manamfbb3ebc2020-10-08 18:06:45 +05304825 a2dp_init_config.fp_platform_switch_voice_call_device_post = platform_switch_voice_call_device_post;
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08004826
4827 a2dp_init(adev, a2dp_init_config);
4828 }
4829}
4830
4831int audio_extn_a2dp_start_playback()
4832{
4833 return (a2dp_start_playback ? a2dp_start_playback() : 0);
4834}
4835
4836int audio_extn_a2dp_stop_playback()
4837{
4838 return (a2dp_stop_playback ? a2dp_stop_playback() : 0);
4839}
4840
4841int audio_extn_a2dp_set_parameters(struct str_parms *parms,
4842 bool *reconfig)
4843{
4844 return (a2dp_set_parameters ?
4845 a2dp_set_parameters(parms, reconfig) : 0);
4846}
4847
4848int audio_extn_a2dp_get_parameters(struct str_parms *query,
4849 struct str_parms *reply)
4850{
4851 return (a2dp_get_parameters ?
4852 a2dp_get_parameters(query, reply) : 0);
4853}
4854
4855bool audio_extn_a2dp_is_force_device_switch()
4856{
4857 return (a2dp_is_force_device_switch ?
4858 a2dp_is_force_device_switch() : false);
4859}
4860
4861void audio_extn_a2dp_set_handoff_mode(bool is_on)
4862{
4863 if (a2dp_set_handoff_mode)
4864 a2dp_set_handoff_mode(is_on);
4865}
4866
4867void audio_extn_a2dp_get_enc_sample_rate(int *sample_rate)
4868{
4869 if (a2dp_get_enc_sample_rate)
4870 a2dp_get_enc_sample_rate(sample_rate);
4871}
4872
4873void audio_extn_a2dp_get_dec_sample_rate(int *sample_rate)
4874{
4875 if (a2dp_get_dec_sample_rate)
4876 a2dp_get_dec_sample_rate(sample_rate);
4877}
4878
4879uint32_t audio_extn_a2dp_get_encoder_latency()
4880{
4881 return (a2dp_get_encoder_latency ?
4882 a2dp_get_encoder_latency() : 0);
4883}
4884
Kakanaboina Ramanjaneyulu8cedb092021-03-15 15:55:29 +05304885uint32_t audio_extn_a2dp_get_decoder_latency()
4886{
4887 return (a2dp_get_encoder_latency ?
4888 a2dp_get_encoder_latency() : 0);
4889}
4890
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08004891bool audio_extn_a2dp_sink_is_ready()
4892{
4893 return (a2dp_sink_is_ready ?
4894 a2dp_sink_is_ready() : false);
4895}
4896
4897bool audio_extn_a2dp_source_is_ready()
4898{
4899 return (a2dp_source_is_ready ?
4900 a2dp_source_is_ready() : false);
4901}
4902
4903bool audio_extn_a2dp_source_is_suspended()
4904{
4905 return (a2dp_source_is_suspended ?
4906 a2dp_source_is_suspended() : false);
4907}
4908
4909int audio_extn_a2dp_start_capture()
4910{
4911 return (a2dp_start_capture ? a2dp_start_capture() : 0);
4912}
4913
4914int audio_extn_a2dp_stop_capture()
4915{
4916 return (a2dp_stop_capture ? a2dp_stop_capture() : 0);
4917}
4918
Aniket Kumar Lata990de552019-07-11 14:20:23 -07004919bool audio_extn_a2dp_set_source_backend_cfg()
4920{
4921 return (a2dp_set_source_backend_cfg ?
4922 a2dp_set_source_backend_cfg() : false);
4923}
4924
Zhou Song12c29502019-03-16 10:37:18 +08004925int audio_extn_sco_start_configuration()
4926{
4927 return (sco_start_configuration? sco_start_configuration() : 0);
4928}
4929
4930void audio_extn_sco_reset_configuration()
4931{
4932 return (sco_reset_configuration? sco_reset_configuration() : 0);
4933}
4934
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08004935// END: A2DP_OFFLOAD =====================================================================
Arun Mirpurie008ed22019-03-21 11:21:04 -07004936
4937// START: HFP ======================================================================
4938#ifdef __LP64__
Fei Tongc20ce932021-06-21 16:42:38 +08004939#ifdef LINUX_ENABLED
4940#define HFP_LIB_PATH "/usr/lib64/libhfp.so"
Shuai Zhang437b2122022-04-25 15:30:08 +05304941#define LINUX_PATH true
4942#ifdef HAL_LIBRARY_PATH
4943#define HFP_LIB_PATH HAL_LIBRARY_PATH
4944#endif
Fei Tongc20ce932021-06-21 16:42:38 +08004945#else
Arun Mirpurie008ed22019-03-21 11:21:04 -07004946#define HFP_LIB_PATH "/vendor/lib64/libhfp.so"
Shuai Zhang437b2122022-04-25 15:30:08 +05304947#define LINUX_PATH false
Fei Tongc20ce932021-06-21 16:42:38 +08004948#endif
4949#else
4950#ifdef LINUX_ENABLED
4951#define HFP_LIB_PATH "/usr/lib/libhfp.so"
Shuai Zhang437b2122022-04-25 15:30:08 +05304952#define LINUX_PATH true
4953#ifdef HAL_LIBRARY_PATH
4954#define HFP_LIB_PATH HAL_LIBRARY_PATH
4955#endif
Arun Mirpurie008ed22019-03-21 11:21:04 -07004956#else
4957#define HFP_LIB_PATH "/vendor/lib/libhfp.so"
Shuai Zhang437b2122022-04-25 15:30:08 +05304958#define LINUX_PATH false
Arun Mirpurie008ed22019-03-21 11:21:04 -07004959#endif
Fei Tongc20ce932021-06-21 16:42:38 +08004960#endif
Arun Mirpurie008ed22019-03-21 11:21:04 -07004961
4962static void *hfp_lib_handle = NULL;
4963
4964typedef void (*hfp_init_t)(hfp_init_config_t);
4965static hfp_init_t hfp_init;
4966
4967typedef bool (*hfp_is_active_t)(struct audio_device *adev);
4968static hfp_is_active_t hfp_is_active;
4969
4970typedef audio_usecase_t (*hfp_get_usecase_t)();
4971static hfp_get_usecase_t hfp_get_usecase;
4972
4973typedef int (*hfp_set_mic_mute_t)(struct audio_device *dev, bool state);
4974static hfp_set_mic_mute_t hfp_set_mic_mute;
4975
4976typedef void (*hfp_set_parameters_t)(struct audio_device *adev,
4977 struct str_parms *parms);
4978static hfp_set_parameters_t hfp_set_parameters;
4979
4980typedef int (*hfp_set_mic_mute2_t)(struct audio_device *adev, bool state);
4981static hfp_set_mic_mute2_t hfp_set_mic_mute2;
4982
4983int hfp_feature_init(bool is_feature_enabled)
4984{
4985 ALOGD("%s: Called with feature %s", __func__,
4986 is_feature_enabled ? "Enabled" : "NOT Enabled");
4987 if (is_feature_enabled) {
4988 // dlopen lib
Shuai Zhang437b2122022-04-25 15:30:08 +05304989 if (LINUX_PATH) {
4990 char libhfp_path[100];
4991 snprintf(libhfp_path, sizeof(libhfp_path), "%s/libhfp.so", HFP_LIB_PATH);
4992 hfp_lib_handle = dlopen(libhfp_path, RTLD_NOW);
4993 } else
4994 hfp_lib_handle = dlopen(HFP_LIB_PATH , RTLD_NOW);
Arun Mirpurie008ed22019-03-21 11:21:04 -07004995 if (!hfp_lib_handle) {
4996 ALOGE("%s: dlopen failed", __func__);
4997 goto feature_disabled;
4998 }
4999 if (!(hfp_init = (hfp_init_t)dlsym(
5000 hfp_lib_handle, "hfp_init")) ||
5001 !(hfp_is_active =
5002 (hfp_is_active_t)dlsym(
5003 hfp_lib_handle, "hfp_is_active")) ||
5004 !(hfp_get_usecase =
5005 (hfp_get_usecase_t)dlsym(
5006 hfp_lib_handle, "hfp_get_usecase")) ||
5007 !(hfp_set_mic_mute =
5008 (hfp_set_mic_mute_t)dlsym(
5009 hfp_lib_handle, "hfp_set_mic_mute")) ||
5010 !(hfp_set_mic_mute2 =
5011 (hfp_set_mic_mute2_t)dlsym(
5012 hfp_lib_handle, "hfp_set_mic_mute2")) ||
5013 !(hfp_set_parameters =
5014 (hfp_set_parameters_t)dlsym(
5015 hfp_lib_handle, "hfp_set_parameters"))) {
5016 ALOGE("%s: dlsym failed", __func__);
5017 goto feature_disabled;
5018 }
5019 hfp_init_config_t init_config;
5020 init_config.fp_platform_set_mic_mute = platform_set_mic_mute;
5021 init_config.fp_platform_get_pcm_device_id = platform_get_pcm_device_id;
5022 init_config.fp_platform_set_echo_reference = platform_set_echo_reference;
5023 init_config.fp_platform_set_mic_mute = platform_set_mic_mute;
5024 init_config.fp_select_devices = select_devices;
5025 init_config.fp_audio_extn_ext_hw_plugin_usecase_start =
5026 audio_extn_ext_hw_plugin_usecase_start;
5027 init_config.fp_audio_extn_ext_hw_plugin_usecase_stop =
5028 audio_extn_ext_hw_plugin_usecase_stop;
5029 init_config.fp_get_usecase_from_list = get_usecase_from_list;
5030 init_config.fp_disable_audio_route = disable_audio_route;
5031 init_config.fp_disable_snd_device = disable_snd_device;
5032 init_config.fp_voice_get_mic_mute = voice_get_mic_mute;
Derek Chenf7092792017-05-23 12:23:53 -04005033 init_config.fp_audio_extn_auto_hal_start_hfp_downlink =
5034 audio_extn_auto_hal_start_hfp_downlink;
5035 init_config.fp_audio_extn_auto_hal_stop_hfp_downlink =
5036 audio_extn_auto_hal_stop_hfp_downlink;
Arun Mirpurie008ed22019-03-21 11:21:04 -07005037
5038 hfp_init(init_config);
5039 ALOGD("%s:: ---- Feature HFP is Enabled ----", __func__);
5040 return 0;
5041 }
5042
5043feature_disabled:
5044 if (hfp_lib_handle) {
5045 dlclose(hfp_lib_handle);
5046 hfp_lib_handle = NULL;
5047 }
5048
5049 hfp_init = NULL;
5050 hfp_is_active = NULL;
5051 hfp_get_usecase = NULL;
5052 hfp_set_mic_mute = NULL;
5053 hfp_set_mic_mute2 = NULL;
5054 hfp_set_parameters = NULL;
Arun Mirpurie008ed22019-03-21 11:21:04 -07005055 ALOGW(":: %s: ---- Feature HFP is disabled ----", __func__);
5056 return -ENOSYS;
5057}
5058
5059bool audio_extn_hfp_is_active(struct audio_device *adev)
5060{
5061 return ((hfp_is_active) ?
5062 hfp_is_active(adev): false);
5063}
5064
5065audio_usecase_t audio_extn_hfp_get_usecase()
5066{
5067 return ((hfp_get_usecase) ?
5068 hfp_get_usecase(): -1);
5069}
5070
5071int audio_extn_hfp_set_mic_mute(struct audio_device *adev, bool state)
5072{
5073 return ((hfp_set_mic_mute) ?
5074 hfp_set_mic_mute(adev, state): -1);
5075}
5076
5077void audio_extn_hfp_set_parameters(struct audio_device *adev,
5078 struct str_parms *parms)
5079{
5080 ((hfp_set_parameters) ?
5081 hfp_set_parameters(adev, parms): NULL);
5082}
5083
5084int audio_extn_hfp_set_mic_mute2(struct audio_device *adev, bool state)
5085{
5086 return ((hfp_set_mic_mute2) ?
5087 hfp_set_mic_mute2(adev, state): -1);
5088}
5089// END: HFP ========================================================================
5090
Derek Chena30a5f42019-12-03 11:17:09 -05005091// START: ICC ======================================================================
5092#ifdef __LP64__
5093#define ICC_LIB_PATH "/vendor/lib64/libicc.so"
5094#else
5095#define ICC_LIB_PATH "/vendor/lib/libicc.so"
5096#endif
5097
5098static void *icc_lib_handle = NULL;
5099
5100typedef void (*icc_init_t)(icc_init_config_t);
5101static icc_init_t icc_init;
5102
5103typedef bool (*icc_is_active_t)(struct audio_device *adev);
5104static icc_is_active_t icc_is_active;
5105
5106typedef audio_usecase_t (*icc_get_usecase_t)();
5107static icc_get_usecase_t icc_get_usecase;
5108
5109typedef void (*icc_set_parameters_t)(struct audio_device *adev,
5110 struct str_parms *parms);
5111static icc_set_parameters_t icc_set_parameters;
5112
5113int icc_feature_init(bool is_feature_enabled)
5114{
5115 ALOGD("%s: Called with feature %s", __func__,
5116 is_feature_enabled ? "Enabled" : "NOT Enabled");
5117 if (is_feature_enabled) {
5118 // dlopen lib
5119 icc_lib_handle = dlopen(ICC_LIB_PATH, RTLD_NOW);
5120
5121 if (!icc_lib_handle) {
5122 ALOGE("%s: dlopen failed", __func__);
5123 goto feature_disabled;
5124 }
5125 if (!(icc_init = (icc_init_t)dlsym(
5126 icc_lib_handle, "icc_init")) ||
5127 !(icc_is_active =
5128 (icc_is_active_t)dlsym(
5129 icc_lib_handle, "icc_is_active")) ||
5130 !(icc_get_usecase =
5131 (icc_get_usecase_t)dlsym(
5132 icc_lib_handle, "icc_get_usecase")) ||
5133 !(icc_set_parameters =
5134 (icc_set_parameters_t)dlsym(
5135 icc_lib_handle, "icc_set_parameters"))) {
5136 ALOGE("%s: dlsym failed", __func__);
5137 goto feature_disabled;
5138 }
5139 icc_init_config_t init_config;
5140 init_config.fp_platform_get_pcm_device_id = platform_get_pcm_device_id;
5141 init_config.fp_platform_set_echo_reference = platform_set_echo_reference;
5142 init_config.fp_select_devices = select_devices;
5143 init_config.fp_audio_extn_ext_hw_plugin_usecase_start =
5144 audio_extn_ext_hw_plugin_usecase_start;
5145 init_config.fp_audio_extn_ext_hw_plugin_usecase_stop =
5146 audio_extn_ext_hw_plugin_usecase_stop;
5147 init_config.fp_get_usecase_from_list = get_usecase_from_list;
5148 init_config.fp_disable_audio_route = disable_audio_route;
5149 init_config.fp_disable_snd_device = disable_snd_device;
5150
5151 icc_init(init_config);
5152 ALOGD("%s:: ---- Feature ICC is Enabled ----", __func__);
5153 return 0;
5154 }
5155
5156feature_disabled:
5157 if (icc_lib_handle) {
5158 dlclose(icc_lib_handle);
5159 icc_lib_handle = NULL;
5160 }
5161
5162 icc_init = NULL;
5163 icc_is_active = NULL;
5164 icc_get_usecase = NULL;
5165 icc_set_parameters = NULL;
5166
5167 ALOGW(":: %s: ---- Feature ICC is disabled ----", __func__);
5168 return -ENOSYS;
5169}
5170
5171bool audio_extn_icc_is_active(struct audio_device *adev)
5172{
5173 return ((icc_is_active) ?
5174 icc_is_active(adev): false);
5175}
5176
5177audio_usecase_t audio_extn_icc_get_usecase()
5178{
5179 return ((icc_get_usecase) ?
5180 icc_get_usecase(): -1);
5181}
5182
5183void audio_extn_icc_set_parameters(struct audio_device *adev,
5184 struct str_parms *parms)
5185{
5186 ((icc_set_parameters) ?
5187 icc_set_parameters(adev, parms): NULL);
5188}
5189
5190// END: ICC ========================================================================
5191
Arun Mirpurie008ed22019-03-21 11:21:04 -07005192// START: EXT_HW_PLUGIN ===================================================================
5193#ifdef __LP64__
5194#define EXT_HW_PLUGIN_LIB_PATH "/vendor/lib64/libexthwplugin.so"
5195#else
5196#define EXT_HW_PLUGIN_LIB_PATH "/vendor/lib/libexthwplugin.so"
5197#endif
5198
5199static void *ext_hw_plugin_lib_handle = NULL;
5200
5201typedef void* (*ext_hw_plugin_init_t)(struct audio_device*,
5202 ext_hw_plugin_init_config_t init_config);
5203static ext_hw_plugin_init_t ext_hw_plugin_init;
5204
5205typedef int (*ext_hw_plugin_deinit_t)(void*);
5206static ext_hw_plugin_deinit_t ext_hw_plugin_deinit;
5207
5208typedef int(*ext_hw_plugin_usecase_start_t)(void*, struct audio_usecase*);
5209static ext_hw_plugin_usecase_start_t ext_hw_plugin_usecase_start;
5210
5211typedef int(*ext_hw_plugin_usecase_stop_t)(void*, struct audio_usecase*);
5212static ext_hw_plugin_usecase_stop_t ext_hw_plugin_usecase_stop;
5213
5214typedef int(*ext_hw_plugin_set_parameters_t)(void*, struct str_parms*);
5215static ext_hw_plugin_set_parameters_t ext_hw_plugin_set_parameters;
5216
5217typedef int(*ext_hw_plugin_get_parameters_t)(void*,
5218 struct str_parms*, struct str_parms*);
5219static ext_hw_plugin_get_parameters_t ext_hw_plugin_get_parameters;
5220
5221typedef int(*ext_hw_plugin_set_mic_mute_t)(void*, bool);
5222static ext_hw_plugin_set_mic_mute_t ext_hw_plugin_set_mic_mute;
5223
5224typedef int(*ext_hw_plugin_get_mic_mute_t)(void*, bool*);
5225static ext_hw_plugin_get_mic_mute_t ext_hw_plugin_get_mic_mute;
5226
5227typedef int(*ext_hw_plugin_set_audio_gain_t)(void*, struct audio_usecase*, uint32_t);
5228static ext_hw_plugin_set_audio_gain_t ext_hw_plugin_set_audio_gain;
5229
5230
5231int ext_hw_plugin_feature_init(bool is_feature_enabled)
5232{
5233 ALOGD("%s: Called with feature %s", __func__,
5234 is_feature_enabled ? "Enabled" : "NOT Enabled");
5235 if (is_feature_enabled) {
5236 // dlopen lib
5237 ext_hw_plugin_lib_handle = dlopen(EXT_HW_PLUGIN_LIB_PATH, RTLD_NOW);
5238
5239 if (!ext_hw_plugin_lib_handle) {
5240 ALOGE("%s: dlopen failed", __func__);
5241 goto feature_disabled;
5242 }
5243 if (!(ext_hw_plugin_init = (ext_hw_plugin_init_t)dlsym(
5244 ext_hw_plugin_lib_handle, "ext_hw_plugin_init")) ||
5245 !(ext_hw_plugin_deinit =
5246 (ext_hw_plugin_deinit_t)dlsym(
5247 ext_hw_plugin_lib_handle, "ext_hw_plugin_deinit")) ||
5248 !(ext_hw_plugin_usecase_start =
5249 (ext_hw_plugin_usecase_start_t)dlsym(
5250 ext_hw_plugin_lib_handle, "ext_hw_plugin_usecase_start")) ||
5251 !(ext_hw_plugin_usecase_stop =
5252 (ext_hw_plugin_usecase_stop_t)dlsym(
5253 ext_hw_plugin_lib_handle, "ext_hw_plugin_usecase_stop")) ||
5254 !(ext_hw_plugin_set_parameters =
5255 (ext_hw_plugin_set_parameters_t)dlsym(
5256 ext_hw_plugin_lib_handle, "ext_hw_plugin_set_parameters")) ||
5257 !(ext_hw_plugin_get_parameters =
5258 (ext_hw_plugin_get_parameters_t)dlsym(
5259 ext_hw_plugin_lib_handle, "ext_hw_plugin_get_parameters")) ||
5260 !(ext_hw_plugin_set_mic_mute =
5261 (ext_hw_plugin_set_mic_mute_t)dlsym(
5262 ext_hw_plugin_lib_handle, "ext_hw_plugin_set_mic_mute")) ||
5263 !(ext_hw_plugin_get_mic_mute =
5264 (ext_hw_plugin_get_mic_mute_t)dlsym(
5265 ext_hw_plugin_lib_handle, "ext_hw_plugin_get_mic_mute")) ||
5266 !(ext_hw_plugin_set_audio_gain =
5267 (ext_hw_plugin_set_audio_gain_t)dlsym(
5268 ext_hw_plugin_lib_handle, "ext_hw_plugin_set_audio_gain"))) {
5269 ALOGE("%s: dlsym failed", __func__);
5270 goto feature_disabled;
5271 }
5272 ALOGD("%s:: ---- Feature EXT_HW_PLUGIN is Enabled ----", __func__);
5273 return 0;
5274 }
5275
5276feature_disabled:
5277 if (ext_hw_plugin_lib_handle) {
5278 dlclose(ext_hw_plugin_lib_handle);
5279 ext_hw_plugin_lib_handle = NULL;
5280 }
5281
5282 ext_hw_plugin_init = NULL;
5283 ext_hw_plugin_deinit = NULL;
5284 ext_hw_plugin_usecase_start = NULL;
5285 ext_hw_plugin_usecase_stop = NULL;
5286 ext_hw_plugin_set_parameters = NULL;
5287 ext_hw_plugin_get_parameters = NULL;
5288 ext_hw_plugin_set_mic_mute = NULL;
5289 ext_hw_plugin_get_mic_mute = NULL;
5290 ext_hw_plugin_set_audio_gain = NULL;
5291
5292 ALOGW(":: %s: ---- Feature EXT_HW_PLUGIN is disabled ----", __func__);
5293 return -ENOSYS;
5294}
5295
5296void* audio_extn_ext_hw_plugin_init(struct audio_device *adev)
5297{
5298 if(ext_hw_plugin_init) {
5299 ext_hw_plugin_init_config_t ext_hw_plugin_init_config;
Derek Chenf082fdb2019-07-24 13:27:20 -07005300 ext_hw_plugin_init_config.fp_b64decode = b64decode;
5301 ext_hw_plugin_init_config.fp_b64encode = b64encode;
Arun Mirpurie008ed22019-03-21 11:21:04 -07005302 return ext_hw_plugin_init(adev, ext_hw_plugin_init_config);
5303 }
5304 else
5305 return NULL;
5306}
5307
5308int audio_extn_ext_hw_plugin_deinit(void *plugin)
5309{
5310 return ((ext_hw_plugin_deinit) ?
Aalique Grahame6dde1a42019-06-10 14:22:46 -07005311 ext_hw_plugin_deinit(plugin): 0);
Arun Mirpurie008ed22019-03-21 11:21:04 -07005312}
5313
5314int audio_extn_ext_hw_plugin_usecase_start(void *plugin, struct audio_usecase *usecase)
5315{
5316 return ((ext_hw_plugin_usecase_start) ?
Aalique Grahame6dde1a42019-06-10 14:22:46 -07005317 ext_hw_plugin_usecase_start(plugin, usecase): 0);
Arun Mirpurie008ed22019-03-21 11:21:04 -07005318}
5319
5320int audio_extn_ext_hw_plugin_usecase_stop(void *plugin, struct audio_usecase *usecase)
5321{
5322 return ((ext_hw_plugin_usecase_stop) ?
Aalique Grahame6dde1a42019-06-10 14:22:46 -07005323 ext_hw_plugin_usecase_stop(plugin, usecase): 0);
Arun Mirpurie008ed22019-03-21 11:21:04 -07005324}
5325
5326int audio_extn_ext_hw_plugin_set_parameters(void *plugin,
5327 struct str_parms *parms)
5328{
5329 return ((ext_hw_plugin_set_parameters) ?
Aalique Grahame6dde1a42019-06-10 14:22:46 -07005330 ext_hw_plugin_set_parameters(plugin, parms): 0);
Arun Mirpurie008ed22019-03-21 11:21:04 -07005331}
5332
5333int audio_extn_ext_hw_plugin_get_parameters(void *plugin,
5334 struct str_parms *query, struct str_parms *reply)
5335{
5336 return ((ext_hw_plugin_get_parameters) ?
Aalique Grahame6dde1a42019-06-10 14:22:46 -07005337 ext_hw_plugin_get_parameters(plugin, query, reply): 0);
Arun Mirpurie008ed22019-03-21 11:21:04 -07005338}
5339
5340int audio_extn_ext_hw_plugin_set_mic_mute(void *plugin, bool mute)
5341{
5342 return ((ext_hw_plugin_set_mic_mute) ?
Aalique Grahame6dde1a42019-06-10 14:22:46 -07005343 ext_hw_plugin_set_mic_mute(plugin, mute): 0);
Arun Mirpurie008ed22019-03-21 11:21:04 -07005344}
5345
5346int audio_extn_ext_hw_plugin_get_mic_mute(void *plugin, bool *mute)
5347{
5348 return ((ext_hw_plugin_get_mic_mute) ?
Aalique Grahame6dde1a42019-06-10 14:22:46 -07005349 ext_hw_plugin_get_mic_mute(plugin, mute): 0);
Arun Mirpurie008ed22019-03-21 11:21:04 -07005350}
5351
5352int audio_extn_ext_hw_plugin_set_audio_gain(void *plugin,
5353 struct audio_usecase *usecase, uint32_t gain)
5354{
5355 return ((ext_hw_plugin_set_audio_gain) ?
Aalique Grahame6dde1a42019-06-10 14:22:46 -07005356 ext_hw_plugin_set_audio_gain(plugin, usecase, gain): 0);
Arun Mirpurie008ed22019-03-21 11:21:04 -07005357}
5358// END: EXT_HW_PLUGIN ===================================================================
5359
5360// START: RECORD_PLAY_CONCURRENCY =======================================================
5361void record_play_concurency_feature_init(bool is_feature_enabled)
5362{
5363 audio_extn_record_play_concurrency_enabled = is_feature_enabled;
5364 ALOGD("%s: ---- Feature RECORD_PLAY_CONCURRENCY is %s----", __func__,
5365 is_feature_enabled? "ENABLED": "NOT ENABLED");
5366}
5367
5368bool audio_extn_is_record_play_concurrency_enabled()
5369{
5370 return audio_extn_record_play_concurrency_enabled;
5371}
5372// END: RECORD_PLAY_CONCURRENCY =========================================================
5373
5374// START: HDMI_PASSTHROUGH ==================================================
5375#ifdef __LP64__
5376#define HDMI_PASSTHRU_LIB_PATH "/vendor/lib64/libhdmipassthru.so"
5377#else
5378#define HDMI_PASSTHRU_LIB_PATH "/vendor/lib/libhdmipassthru.so"
5379#endif
5380
5381static void *hdmi_passthru_lib_handle = NULL;
5382
5383typedef bool (*passthru_is_convert_supported_t)(struct audio_device *,
5384 struct stream_out *);
5385static passthru_is_convert_supported_t passthru_is_convert_supported;
5386
5387typedef bool (*passthru_is_passt_supported_t)(struct stream_out *);
5388static passthru_is_passt_supported_t passthru_is_passt_supported;
5389
5390typedef void (*passthru_update_stream_configuration_t)(
5391 struct audio_device *, struct stream_out *, const void *, size_t);
5392static passthru_update_stream_configuration_t passthru_update_stream_configuration;
5393
5394typedef bool (*passthru_is_passthrough_stream_t)(struct stream_out *);
5395static passthru_is_passthrough_stream_t passthru_is_passthrough_stream;
5396
5397typedef int (*passthru_get_buffer_size_t)(audio_offload_info_t*);
5398static passthru_get_buffer_size_t passthru_get_buffer_size;
5399
5400typedef int (*passthru_set_volume_t)(struct stream_out *, int);
5401static passthru_set_volume_t passthru_set_volume;
5402
5403typedef int (*passthru_set_latency_t)(struct stream_out *, int);
5404static passthru_set_latency_t passthru_set_latency;
5405
5406typedef bool (*passthru_is_supported_format_t)(audio_format_t);
5407static passthru_is_supported_format_t passthru_is_supported_format;
5408
5409typedef bool (*passthru_should_drop_data_t)(struct stream_out * out);
5410static passthru_should_drop_data_t passthru_should_drop_data;
5411
5412typedef void (*passthru_on_start_t)(struct stream_out *out);
5413static passthru_on_start_t passthru_on_start;
5414
5415typedef void (*passthru_on_stop_t)(struct stream_out *out);
5416static passthru_on_stop_t passthru_on_stop;
5417
5418typedef void (*passthru_on_pause_t)(struct stream_out *out);
5419static passthru_on_pause_t passthru_on_pause;
5420
5421typedef int (*passthru_set_parameters_t)(struct audio_device *adev,
5422 struct str_parms *parms);
5423static passthru_set_parameters_t passthru_set_parameters;
5424
5425typedef bool (*passthru_is_enabled_t)();
5426static passthru_is_enabled_t passthru_is_enabled;
5427
5428typedef bool (*passthru_is_active_t)();
5429static passthru_is_active_t passthru_is_active;
5430
5431typedef void (*passthru_init_t)(passthru_init_config_t);
5432static passthru_init_t passthru_init;
5433
5434typedef bool (*passthru_should_standby_t)(struct stream_out *out);
5435static passthru_should_standby_t passthru_should_standby;
5436
5437typedef int (*passthru_get_channel_count_t)(struct stream_out *out);
5438static passthru_get_channel_count_t passthru_get_channel_count;
5439
5440typedef int (*passthru_update_dts_stream_configuration_t)(struct stream_out *out,
5441 const void *buffer, size_t bytes);
5442static passthru_update_dts_stream_configuration_t passthru_update_dts_stream_configuration;
5443
5444typedef bool (*passthru_is_direct_passthrough_t)(struct stream_out *out);
5445static passthru_is_direct_passthrough_t passthru_is_direct_passthrough;
5446
5447typedef bool (*passthru_is_supported_backend_edid_cfg_t)(struct audio_device *adev,
5448 struct stream_out *out);
5449static passthru_is_supported_backend_edid_cfg_t passthru_is_supported_backend_edid_cfg;
5450
5451bool audio_extn_passthru_is_convert_supported(struct audio_device *adev,
5452 struct stream_out *out)
5453{
5454 return (passthru_is_convert_supported ? passthru_is_convert_supported(adev, out) : false);
5455}
5456
5457bool audio_extn_passthru_is_passthrough_stream(struct stream_out *out)
5458{
5459 return (passthru_is_passthrough_stream ?
5460 passthru_is_passthrough_stream(out) : false);
5461}
5462
5463void audio_extn_passthru_update_stream_configuration(
5464 struct audio_device *adev, struct stream_out *out,
5465 const void *buffer, size_t bytes)
5466{
5467 (passthru_update_stream_configuration ?
5468 passthru_update_stream_configuration(adev, out, buffer, bytes) : 0);
5469}
5470
5471bool audio_extn_passthru_is_passt_supported(struct stream_out *out)
5472{
5473 return (passthru_is_passt_supported)? passthru_is_passt_supported(out): false;
5474}
5475
5476int audio_extn_passthru_get_buffer_size(audio_offload_info_t* info)
5477{
5478 return (passthru_get_buffer_size)? passthru_get_buffer_size(info): 0;
5479}
5480
5481int audio_extn_passthru_set_volume(struct stream_out *out, int mute)
5482{
5483 return (passthru_set_volume)? passthru_set_volume(out, mute): 0;
5484}
5485
5486int audio_extn_passthru_set_latency(struct stream_out *out, int latency)
5487{
5488 return (passthru_set_latency)? passthru_set_latency(out, latency): 0;
5489}
5490
5491bool audio_extn_passthru_is_supported_format(audio_format_t format)
5492{
5493 return (passthru_is_supported_format)? passthru_is_supported_format(format): false;
5494}
5495
5496bool audio_extn_passthru_should_drop_data(struct stream_out * out)
5497{
5498 return (passthru_should_drop_data)? passthru_should_drop_data(out): false;
5499}
5500
5501void audio_extn_passthru_on_start(struct stream_out *out)
5502{
5503 (passthru_on_start)? passthru_on_start(out): 0;
5504}
5505
5506void audio_extn_passthru_on_stop(struct stream_out *out)
5507{
5508 (passthru_on_stop)? passthru_on_stop(out): 0;
5509}
5510
5511void audio_extn_passthru_on_pause(struct stream_out *out)
5512{
5513 (passthru_on_pause)? passthru_on_pause(out): 0;
5514}
5515
5516int audio_extn_passthru_set_parameters(struct audio_device *adev,
5517 struct str_parms *parms)
5518{
5519 return (passthru_set_parameters)?
5520 passthru_set_parameters(adev, parms): false;
5521}
5522
5523bool audio_extn_passthru_is_enabled()
5524{
5525 return (passthru_is_enabled)? passthru_is_enabled(): false;
5526}
5527
5528bool audio_extn_passthru_is_active()
5529{
5530 return (passthru_is_active)? passthru_is_active(): false;
5531}
5532
5533bool audio_extn_passthru_should_standby(struct stream_out *out)
5534{
5535 return (passthru_should_standby)? passthru_should_standby(out): false;
5536}
5537int audio_extn_passthru_get_channel_count(struct stream_out *out)
5538{
5539 return (passthru_get_channel_count)? passthru_get_channel_count(out): 0;
5540}
5541
5542int audio_extn_passthru_update_dts_stream_configuration(struct stream_out *out,
5543 const void *buffer, size_t bytes)
5544{
5545 return (passthru_update_dts_stream_configuration)?
5546 passthru_update_dts_stream_configuration(out, buffer, bytes): 0;
5547}
5548
5549bool audio_extn_passthru_is_direct_passthrough(struct stream_out *out)
5550{
5551 return (passthru_is_direct_passthrough)? passthru_is_direct_passthrough(out): false;
5552}
5553
5554bool audio_extn_passthru_is_supported_backend_edid_cfg(struct audio_device *adev,
5555 struct stream_out *out)
5556{
5557 return (passthru_is_supported_backend_edid_cfg)?
5558 passthru_is_supported_backend_edid_cfg(adev, out): false;
5559}
5560bool audio_extn_is_hdmi_passthru_enabled()
5561{
5562 return audio_extn_hdmi_passthru_enabled;
5563}
5564
5565void hdmi_passthrough_feature_init(bool is_feature_enabled)
5566{
5567 ALOGD("%s: Called with feature %s", __func__,
5568 is_feature_enabled ? "Enabled" : "NOT Enabled");
5569
5570 audio_extn_hdmi_passthru_enabled = is_feature_enabled;
5571 if (is_feature_enabled) {
5572 // dlopen lib
5573 hdmi_passthru_lib_handle = dlopen(HDMI_PASSTHRU_LIB_PATH, RTLD_NOW);
5574
5575 if (!hdmi_passthru_lib_handle) {
5576 ALOGE("%s: dlopen failed", __func__);
5577 goto feature_disabled;
5578 }
5579 if (!(passthru_init = (passthru_init_t)dlsym(
5580 hdmi_passthru_lib_handle, "passthru_init")) ||
5581 !(passthru_is_convert_supported =
5582 (passthru_is_convert_supported_t)dlsym(
5583 hdmi_passthru_lib_handle, "passthru_is_convert_supported")) ||
5584 !(passthru_is_passthrough_stream =
5585 (passthru_is_passthrough_stream_t)dlsym(
5586 hdmi_passthru_lib_handle, "passthru_is_passthrough_stream")) ||
5587 !(passthru_get_buffer_size =
5588 (passthru_get_buffer_size_t)dlsym(
5589 hdmi_passthru_lib_handle, "passthru_get_buffer_size")) ||
5590 !(passthru_set_volume =
5591 (passthru_set_volume_t)dlsym(
5592 hdmi_passthru_lib_handle, "passthru_set_volume")) ||
5593 !(passthru_set_latency =
5594 (passthru_set_latency_t)dlsym(
5595 hdmi_passthru_lib_handle, "passthru_set_latency")) ||
5596 !(passthru_is_supported_format =
5597 (passthru_is_supported_format_t)dlsym(
5598 hdmi_passthru_lib_handle, "passthru_is_supported_format")) ||
5599 !(passthru_should_drop_data =
5600 (passthru_should_drop_data_t)dlsym(
5601 hdmi_passthru_lib_handle, "passthru_should_drop_data")) ||
5602 !(passthru_on_start =
5603 (passthru_on_start_t)dlsym(
5604 hdmi_passthru_lib_handle, "passthru_on_start")) ||
5605 !(passthru_on_stop =
5606 (passthru_on_stop_t)dlsym(
5607 hdmi_passthru_lib_handle, "passthru_on_stop")) ||
5608 !(passthru_on_pause =
5609 (passthru_on_pause_t)dlsym(
5610 hdmi_passthru_lib_handle, "passthru_on_pause")) ||
5611 !(passthru_set_parameters =
5612 (passthru_set_parameters_t)dlsym(
5613 hdmi_passthru_lib_handle, "passthru_set_parameters")) ||
5614 (passthru_is_enabled =
5615 (passthru_is_enabled_t)dlsym(
5616 hdmi_passthru_lib_handle, "passthru_is_enabled")) ||
5617 (passthru_is_active =
5618 (passthru_is_active_t)dlsym(
5619 hdmi_passthru_lib_handle, "passthru_is_active")) ||
5620 (passthru_should_standby =
5621 (passthru_should_standby_t)dlsym(
5622 hdmi_passthru_lib_handle, "passthru_should_standby")) ||
5623 (passthru_get_channel_count =
5624 (passthru_get_channel_count_t)dlsym(
5625 hdmi_passthru_lib_handle, "passthru_get_channel_count")) ||
5626 (passthru_update_dts_stream_configuration =
5627 (passthru_update_dts_stream_configuration_t)dlsym(
5628 hdmi_passthru_lib_handle,
5629 "passthru_update_dts_stream_configuration")) ||
5630 (passthru_is_direct_passthrough =
5631 (passthru_is_direct_passthrough_t)dlsym(
5632 hdmi_passthru_lib_handle, "passthru_is_direct_passthrough")) ||
5633 (passthru_is_supported_backend_edid_cfg =
5634 (passthru_is_supported_backend_edid_cfg_t)dlsym(
5635 hdmi_passthru_lib_handle,
5636 "passthru_is_supported_backend_edid_cfg"))) {
5637 ALOGE("%s: dlsym failed", __func__);
5638 goto feature_disabled;
5639 }
5640
5641 passthru_init_config_t init_config;
5642 init_config.fp_platform_is_edid_supported_format =
5643 platform_is_edid_supported_format;
5644 init_config.fp_platform_set_device_params = platform_set_device_params;
5645 init_config.fp_platform_edid_get_max_channels = platform_edid_get_max_channels;
5646 init_config.fp_platform_get_output_snd_device = platform_get_output_snd_device;
5647 init_config.fp_platform_get_codec_backend_cfg = platform_get_codec_backend_cfg;
5648 init_config.fp_platform_get_snd_device_name = platform_get_snd_device_name;
5649 init_config.fp_platform_is_edid_supported_sample_rate =
5650 platform_is_edid_supported_sample_rate;
5651 init_config.fp_audio_extn_keep_alive_start = audio_extn_keep_alive_start;
5652 init_config.fp_audio_extn_keep_alive_stop = audio_extn_keep_alive_stop;
5653 init_config.fp_audio_extn_utils_is_dolby_format =
5654 audio_extn_utils_is_dolby_format;
5655 passthru_init(init_config);
5656 ALOGD("%s:: ---- Feature HDMI_PASSTHROUGH is Enabled ----", __func__);
Dallas Delaneyb2d060c2019-06-11 16:30:35 -07005657 return;
Arun Mirpurie008ed22019-03-21 11:21:04 -07005658 }
5659
5660feature_disabled:
5661 if (hdmi_passthru_lib_handle) {
5662 dlclose(hdmi_passthru_lib_handle);
5663 hdmi_passthru_lib_handle = NULL;
5664 }
5665
5666 passthru_init = NULL;
5667 passthru_is_convert_supported = NULL;
5668 passthru_is_passthrough_stream = NULL;
5669 passthru_get_buffer_size = NULL;
5670 passthru_set_volume = NULL;
5671 passthru_set_latency = NULL;
5672 passthru_is_supported_format = NULL;
5673 passthru_should_drop_data = NULL;
5674 passthru_on_start = NULL;
5675 passthru_on_stop = NULL;
5676 passthru_on_pause = NULL;
5677 passthru_set_parameters = NULL;
5678 passthru_is_enabled = NULL;
5679 passthru_is_active = NULL;
5680 passthru_should_standby = NULL;
5681 passthru_get_channel_count = NULL;
5682 passthru_update_dts_stream_configuration = NULL;
5683 passthru_is_direct_passthrough = NULL;
5684 passthru_is_supported_backend_edid_cfg = NULL;
5685
5686 ALOGW(":: %s: ---- Feature HDMI_PASSTHROUGH is disabled ----", __func__);
5687}
5688// END: HDMI_PASSTHROUGH ==================================================
5689
5690// START: CONCURRENT_CAPTURE ==================================================
5691bool audio_extn_is_concurrent_capture_enabled()
5692{
5693 return audio_extn_concurrent_capture_enabled;
5694}
5695
5696void concurrent_capture_feature_init(bool is_feature_enabled)
5697{
5698 audio_extn_concurrent_capture_enabled = is_feature_enabled;
5699 ALOGD("%s: ---- Feature CONCURRENT_CAPTURE is %s----", __func__, is_feature_enabled? "ENABLED": "NOT ENABLED");
5700}
5701// END: CONCURRENT_CAPTURE ====================================================
5702
Krishna Kishor Jha0f4d8482022-02-18 10:56:05 +05305703// START: CONCURRENT_PCM_RECORD ===============================================
5704bool audio_extn_is_concurrent_pcm_record_enabled()
5705{
5706 return audio_extn_concurrent_pcm_record_enabled;
5707}
5708
5709void concurrent_pcm_record_feature_init(bool is_feature_enabled)
5710{
5711 audio_extn_concurrent_pcm_record_enabled = is_feature_enabled;
5712 ALOGD("%s: ---- Feature CONCURRENT_PCM_RECORD is %s----", __func__, is_feature_enabled? "ENABLED": "NOT ENABLED");
5713}
5714// END: CONCURRENT_PCM_RECORD =================================================
5715
Kogara Naveen Kumarc5758232022-11-07 20:25:40 +05305716// START: CONCURRENT_LOW_LATENCY_PCM_RECORD ===============================================
5717bool audio_extn_is_concurrent_low_latency_pcm_record_enabled()
5718{
5719 return audio_extn_concurrent_low_latency_pcm_record_enabled;
5720}
5721
5722void concurrent_low_latency_pcm_record_feature_init(bool is_feature_enabled)
5723{
5724 audio_extn_concurrent_low_latency_pcm_record_enabled = is_feature_enabled;
5725 ALOGD("%s: ---- Feature CONCURRENT_LOW_LATENCY_PCM_RECORD is %s----", __func__, is_feature_enabled? "ENABLED": "NOT ENABLED");
5726}
5727// END: CONCURRENT_LOW_LATENCY_PCM_RECORD =================================================
5728
Arun Mirpurie008ed22019-03-21 11:21:04 -07005729// START: COMPRESS_IN ==================================================
5730void compress_in_feature_init(bool is_feature_enabled)
5731{
5732 audio_extn_compress_in_enabled = is_feature_enabled;
5733 ALOGD("%s: ---- Feature COMPRESS_IN is %s----", __func__, is_feature_enabled? "ENABLED": "NOT ENABLED");
5734}
5735
5736bool audio_extn_cin_applicable_stream(struct stream_in *in)
5737{
5738 return (audio_extn_compress_in_enabled? cin_applicable_stream(in): false);
5739}
Dhananjay Kumar7dbe3562019-08-30 05:49:33 +05305740bool audio_extn_cin_attached_usecase(struct stream_in *in)
Arun Mirpurie008ed22019-03-21 11:21:04 -07005741{
Dhananjay Kumar7dbe3562019-08-30 05:49:33 +05305742 return (audio_extn_compress_in_enabled? cin_attached_usecase(in): false);
Arun Mirpurie008ed22019-03-21 11:21:04 -07005743}
5744bool audio_extn_cin_format_supported(audio_format_t format)
5745{
5746 return (audio_extn_compress_in_enabled? cin_format_supported(format): false);
5747}
Dhananjay Kumar7dbe3562019-08-30 05:49:33 +05305748int audio_extn_cin_acquire_usecase(struct stream_in *in)
5749{
5750 return (audio_extn_compress_in_enabled? cin_acquire_usecase(in): 0);
5751}
Arun Mirpurie008ed22019-03-21 11:21:04 -07005752size_t audio_extn_cin_get_buffer_size(struct stream_in *in)
5753{
5754 return (audio_extn_compress_in_enabled? cin_get_buffer_size(in): 0);
5755}
Manish Dewangan46e07982018-12-13 18:18:59 +05305756int audio_extn_cin_open_input_stream(struct stream_in *in)
Arun Mirpurie008ed22019-03-21 11:21:04 -07005757{
Manish Dewangan46e07982018-12-13 18:18:59 +05305758 return (audio_extn_compress_in_enabled? cin_open_input_stream(in): -1);
Arun Mirpurie008ed22019-03-21 11:21:04 -07005759}
5760void audio_extn_cin_stop_input_stream(struct stream_in *in)
5761{
5762 (audio_extn_compress_in_enabled? cin_stop_input_stream(in): NULL);
5763}
5764void audio_extn_cin_close_input_stream(struct stream_in *in)
5765{
5766 (audio_extn_compress_in_enabled? cin_close_input_stream(in): NULL);
5767}
Manish Dewangan46e07982018-12-13 18:18:59 +05305768void audio_extn_cin_free_input_stream_resources(struct stream_in *in)
5769{
5770 return (audio_extn_compress_in_enabled? cin_free_input_stream_resources(in): NULL);
5771}
Arun Mirpurie008ed22019-03-21 11:21:04 -07005772int audio_extn_cin_read(struct stream_in *in, void *buffer,
5773 size_t bytes, size_t *bytes_read)
5774{
5775 return (audio_extn_compress_in_enabled?
5776 cin_read(in, buffer, bytes, bytes_read): -1);
5777}
Deeraj Soman14230922019-01-30 16:39:30 +05305778int audio_extn_cin_configure_input_stream(struct stream_in *in, struct audio_config *in_config)
Arun Mirpurie008ed22019-03-21 11:21:04 -07005779{
Deeraj Soman14230922019-01-30 16:39:30 +05305780 return (audio_extn_compress_in_enabled? cin_configure_input_stream(in, in_config): -1);
Arun Mirpurie008ed22019-03-21 11:21:04 -07005781}
5782// END: COMPRESS_IN ====================================================
5783
5784// START: BATTERY_LISTENER ==================================================
5785#ifdef __LP64__
5786#define BATTERY_LISTENER_LIB_PATH "/vendor/lib64/libbatterylistener.so"
5787#else
5788#define BATTERY_LISTENER_LIB_PATH "/vendor/lib/libbatterylistener.so"
5789#endif
5790
5791static void *batt_listener_lib_handle = NULL;
5792
5793typedef void (*batt_listener_init_t)(battery_status_change_fn_t);
5794static batt_listener_init_t batt_listener_init;
5795
Sujin Panicker90f923d2021-07-14 15:04:43 +05305796typedef void (*batt_listener_deinit_t)(void);
Arun Mirpurie008ed22019-03-21 11:21:04 -07005797static batt_listener_deinit_t batt_listener_deinit;
5798
Sujin Panicker90f923d2021-07-14 15:04:43 +05305799typedef bool (*batt_prop_is_charging_t)(void);
Arun Mirpurie008ed22019-03-21 11:21:04 -07005800static batt_prop_is_charging_t batt_prop_is_charging;
5801
5802void battery_listener_feature_init(bool is_feature_enabled)
5803{
5804 audio_extn_battery_listener_enabled = is_feature_enabled;
Arun Mirpurie008ed22019-03-21 11:21:04 -07005805 if (is_feature_enabled) {
5806 // dlopen lib
5807 batt_listener_lib_handle = dlopen(BATTERY_LISTENER_LIB_PATH, RTLD_NOW);
5808
5809 if (!batt_listener_lib_handle) {
5810 ALOGE("%s: dlopen failed", __func__);
5811 goto feature_disabled;
5812 }
5813 if (!(batt_listener_init = (batt_listener_init_t)dlsym(
5814 batt_listener_lib_handle, "battery_properties_listener_init")) ||
5815 !(batt_listener_deinit =
5816 (batt_listener_deinit_t)dlsym(
5817 batt_listener_lib_handle, "battery_properties_listener_deinit")) ||
5818 !(batt_prop_is_charging =
5819 (batt_prop_is_charging_t)dlsym(
5820 batt_listener_lib_handle, "battery_properties_is_charging"))) {
5821 ALOGE("%s: dlsym failed", __func__);
5822 goto feature_disabled;
5823 }
Dallas Delaneyb2d060c2019-06-11 16:30:35 -07005824 ALOGD("%s: ---- Feature BATTERY_LISTENER is enabled ----", __func__);
5825 return;
Arun Mirpurie008ed22019-03-21 11:21:04 -07005826 }
5827
5828 feature_disabled:
5829 if (batt_listener_lib_handle) {
5830 dlclose(batt_listener_lib_handle);
5831 batt_listener_lib_handle = NULL;
5832 }
5833
5834 batt_listener_init = NULL;
5835 batt_listener_deinit = NULL;
5836 batt_prop_is_charging = NULL;
5837 ALOGW(":: %s: ---- Feature BATTERY_LISTENER is disabled ----", __func__);
5838}
5839
5840void audio_extn_battery_properties_listener_init(battery_status_change_fn_t fn)
5841{
5842 if(batt_listener_init)
5843 batt_listener_init(fn);
5844}
5845void audio_extn_battery_properties_listener_deinit()
5846{
5847 if(batt_listener_deinit)
5848 batt_listener_deinit();
5849}
5850bool audio_extn_battery_properties_is_charging()
5851{
5852 return (batt_prop_is_charging)? batt_prop_is_charging(): false;
5853}
Arun Mirpurid750ac52019-04-12 18:33:55 -07005854// END: BATTERY_LISTENER ================================================================
5855
Ramlal Karraab51d042019-08-08 19:02:35 +05305856// START: HiFi Filter Feature ============================================================
5857void audio_extn_enable_hifi_filter(struct audio_device *adev, bool value)
5858{
5859 const char *mixer_ctl_name = "HiFi Filter";
5860 struct mixer_ctl *ctl = NULL;
5861 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
5862 if (!ctl) {
5863 ALOGE("%s: Could not get ctl for mixer cmd - %s, using default control",
5864 __func__, mixer_ctl_name);
5865 return;
5866 } else {
5867 mixer_ctl_set_value(ctl, 0, value);
Aniket Kumar Latad13758f2020-08-06 15:11:36 -07005868 ALOGV("%s: mixer_value set %d", __func__, value);
Ramlal Karraab51d042019-08-08 19:02:35 +05305869 }
5870 return;
5871}
5872
5873void audio_extn_hifi_filter_set_params(struct str_parms *parms,
5874 char *value, int len)
5875{
5876 int ret = 0;
5877 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HIFI_AUDIO_FILTER, value,len);
5878 if (ret >= 0) {
5879 if (value && !strncmp(value, "true", sizeof("true")))
5880 audio_extn_hifi_filter_enabled = true;
5881 else
5882 audio_extn_hifi_filter_enabled = false;
5883 str_parms_del(parms, AUDIO_PARAMETER_KEY_HIFI_AUDIO_FILTER);
5884 }
5885}
5886
5887bool audio_extn_hifi_check_usecase_params(int sample_rate, int usecase)
5888{
5889 if (sample_rate != 48000 && sample_rate != 44100)
5890 return false;
5891 if (usecase == USECASE_AUDIO_PLAYBACK_LOW_LATENCY || usecase == USECASE_AUDIO_PLAYBACK_ULL)
5892 return false;
5893 return true;
5894}
5895
5896bool audio_extn_is_hifi_filter_enabled(struct audio_device* adev, struct stream_out *out,
5897 snd_device_t snd_device, char *codec_variant,
5898 int channels, int usecase_init)
5899{
5900 int na_mode = platform_get_native_support();
5901 struct audio_usecase *uc = NULL;
5902 struct listnode *node = NULL;
5903 bool hifi_active = false;
5904
5905 if (audio_extn_hifi_filter_enabled) {
5906 /*Restricting the feature for Tavil and WCD9375 codecs only*/
5907 if ((strstr(codec_variant, "WCD9385") || strstr(codec_variant, "WCD9375"))
Prasad Kumpatla0e90ba82020-02-04 15:12:26 +05305908 && (na_mode == NATIVE_AUDIO_MODE_MULTIPLE_MIX_IN_DSP || na_mode ==
5909 NATIVE_AUDIO_MODE_TRUE_44_1) && channels <=2) {
Ramlal Karraab51d042019-08-08 19:02:35 +05305910 /*Upsampling 8 time should be restricited to headphones playback only */
5911 if (snd_device == SND_DEVICE_OUT_HEADPHONES
5912 || snd_device == SND_DEVICE_OUT_HEADPHONES_44_1
5913 || snd_device == SND_DEVICE_OUT_HEADPHONES_HIFI_FILTER
5914 || usecase_init) {
5915 if (audio_extn_hifi_check_usecase_params(out->sample_rate,
5916 out->usecase) && !usecase_init)
5917 return true;
5918
5919 list_for_each(node, &adev->usecase_list) {
5920 /* checking if hifi_filter is already active to set */
5921 /* concurrent playback sessions with hifi_filter enabled*/
5922 uc = node_to_item(node, struct audio_usecase, list);
5923 struct stream_out *curr_out = (struct stream_out*) uc->stream.out;
5924 if (uc->type == PCM_PLAYBACK && curr_out
5925 && audio_extn_hifi_check_usecase_params(
5926 curr_out->sample_rate, curr_out->usecase) &&
5927 (curr_out->channel_mask == AUDIO_CHANNEL_OUT_STEREO ||
5928 curr_out->channel_mask == AUDIO_CHANNEL_OUT_MONO))
5929 hifi_active = true;
5930 }
5931 }
5932 }
5933 }
5934 return hifi_active;
5935}
5936// END: HiFi Filter Feature ==============================================================
5937
vivek mehtaba5ed152019-05-03 17:28:25 -07005938// START: AUDIOZOOM_FEATURE =====================================================================
5939#ifdef __LP64__
5940#define AUDIOZOOM_LIB_PATH "/vendor/lib64/libaudiozoom.so"
5941#else
5942#define AUDIOZOOM_LIB_PATH "/vendor/lib/libaudiozoom.so"
5943#endif
5944
5945static void *audiozoom_lib_handle = NULL;
5946
5947typedef int (*audiozoom_init_t)(audiozoom_init_config_t);
5948static audiozoom_init_t audiozoom_init;
5949
5950typedef int (*audiozoom_set_microphone_direction_t)(struct stream_in *,
5951 audio_microphone_direction_t);
5952static audiozoom_set_microphone_direction_t audiozoom_set_microphone_direction;
5953
5954typedef int (*audiozoom_set_microphone_field_dimension_t)(struct stream_in *, float);
5955static audiozoom_set_microphone_field_dimension_t audiozoom_set_microphone_field_dimension;
5956
5957int audiozoom_feature_init(bool is_feature_enabled)
5958{
5959 audio_extn_audiozoom_enabled = is_feature_enabled;
5960 ALOGD("%s: Called with feature %s", __func__,
5961 is_feature_enabled ? "Enabled" : "NOT Enabled");
5962 if (is_feature_enabled) {
5963 // dlopen lib
5964 audiozoom_lib_handle = dlopen(AUDIOZOOM_LIB_PATH, RTLD_NOW);
5965
5966 if (!audiozoom_lib_handle) {
5967 ALOGE("%s: dlopen failed", __func__);
5968 goto feature_disabled;
5969 }
5970
5971 if (!(audiozoom_init =
5972 (audiozoom_init_t)dlsym(audiozoom_lib_handle, "audiozoom_init")) ||
5973 !(audiozoom_set_microphone_direction =
5974 (audiozoom_set_microphone_direction_t)dlsym(audiozoom_lib_handle,
5975 "audiozoom_set_microphone_direction")) ||
5976 !(audiozoom_set_microphone_field_dimension =
5977 (audiozoom_set_microphone_field_dimension_t)dlsym(audiozoom_lib_handle,
5978 "audiozoom_set_microphone_field_dimension"))) {
5979 ALOGE("%s: dlsym failed", __func__);
5980 goto feature_disabled;
5981 }
5982
5983 ALOGD("%s:: ---- Feature AUDIOZOOM is Enabled ----", __func__);
5984 return 0;
5985 }
5986feature_disabled:
5987 if (audiozoom_lib_handle) {
5988 dlclose(audiozoom_lib_handle);
5989 audiozoom_lib_handle = NULL;
5990 }
5991
5992 audiozoom_init = NULL;
5993 audiozoom_set_microphone_direction = NULL;
5994 audiozoom_set_microphone_field_dimension = NULL;
5995 ALOGW(":: %s: ---- Feature AUDIOZOOM is disabled ----", __func__);
5996 return -ENOSYS;
5997}
5998
5999bool audio_extn_is_audiozoom_enabled()
6000{
6001 return audio_extn_audiozoom_enabled;
6002}
6003
6004int audio_extn_audiozoom_init()
6005{
6006 int ret_val = 0;
6007 if (audiozoom_init) {
6008 audiozoom_init_config_t init_config;
6009 init_config.fp_platform_set_parameters = platform_set_parameters;
6010 ret_val = audiozoom_init(init_config);
6011 }
6012
6013 return ret_val;
6014}
6015
6016int audio_extn_audiozoom_set_microphone_direction(struct stream_in *stream,
6017 audio_microphone_direction_t dir)
6018{
6019 int ret_val = -ENOSYS;
6020 if (audiozoom_set_microphone_direction)
6021 ret_val = audiozoom_set_microphone_direction(stream, dir);
6022
6023 return ret_val;
6024}
6025
6026int audio_extn_audiozoom_set_microphone_field_dimension(struct stream_in *stream,
6027 float zoom)
6028{
6029 int ret_val = -ENOSYS;
6030 if (audiozoom_set_microphone_field_dimension)
6031 ret_val = audiozoom_set_microphone_field_dimension(stream, zoom);
6032
6033 return ret_val;
6034}
6035// END: AUDIOZOOM_FEATURE =====================================================================
6036
Arun Mirpurid750ac52019-04-12 18:33:55 -07006037// START: MAXX_AUDIO =====================================================================
6038#ifdef __LP64__
6039#define MAXX_AUDIO_LIB_PATH "/vendor/lib64/libmaxxaudio.so"
6040#else
6041#define MAXX_AUDIO_LIB_PATH "/vendor/lib/libmaxxaudio.so"
6042#endif
6043
6044static void *maxxaudio_lib_handle = NULL;
6045
6046typedef void (*maxxaudio_init_t)(void *, maxx_audio_init_config_t);
6047static maxxaudio_init_t maxxaudio_init;
6048
6049typedef void (*maxxaudio_deinit_t)();
6050static maxxaudio_deinit_t maxxaudio_deinit;
6051
6052typedef bool (*maxxaudio_set_state_t)(struct audio_device*, int,
6053 float, bool);
6054static maxxaudio_set_state_t maxxaudio_set_state;
6055
6056typedef void (*maxxaudio_set_device_t)(struct audio_usecase *);
6057static maxxaudio_set_device_t maxxaudio_set_device;
6058
6059typedef void (*maxxaudio_set_parameters_t)(struct audio_device *,
6060 struct str_parms *);
6061static maxxaudio_set_parameters_t maxxaudio_set_parameters;
6062
justinwengd5395152019-11-04 12:23:09 +08006063typedef void (*maxxaudio_get_parameters_t)(struct audio_device *,
6064 struct str_parms *,
6065 struct str_parms *);
6066static maxxaudio_get_parameters_t maxxaudio_get_parameters;
6067
Arun Mirpurid750ac52019-04-12 18:33:55 -07006068typedef bool (*maxxaudio_supported_usb_t)();
6069static maxxaudio_supported_usb_t maxxaudio_supported_usb;
6070
6071int maxx_audio_feature_init(bool is_feature_enabled)
6072{
6073 audio_extn_maxx_audio_enabled = is_feature_enabled;
6074 ALOGD("%s: Called with feature %s", __func__,
6075 is_feature_enabled ? "Enabled" : "NOT Enabled");
6076 if (is_feature_enabled) {
6077 // dlopen lib
6078 maxxaudio_lib_handle = dlopen(MAXX_AUDIO_LIB_PATH, RTLD_NOW);
6079
6080 if (!maxxaudio_lib_handle) {
6081 ALOGE("%s: dlopen failed", __func__);
6082 goto feature_disabled;
6083 }
6084
6085 if (!(maxxaudio_init =
6086 (maxxaudio_init_t)dlsym(maxxaudio_lib_handle, "ma_init")) ||
6087 !(maxxaudio_deinit =
6088 (maxxaudio_deinit_t)dlsym(maxxaudio_lib_handle, "ma_deinit")) ||
6089 !(maxxaudio_set_state =
6090 (maxxaudio_set_state_t)dlsym(maxxaudio_lib_handle, "ma_set_state")) ||
6091 !(maxxaudio_set_device =
6092 (maxxaudio_set_device_t)dlsym(maxxaudio_lib_handle, "ma_set_device")) ||
6093 !(maxxaudio_set_parameters =
6094 (maxxaudio_set_parameters_t)dlsym(maxxaudio_lib_handle, "ma_set_parameters")) ||
justinwengd5395152019-11-04 12:23:09 +08006095 !(maxxaudio_get_parameters =
6096 (maxxaudio_get_parameters_t)dlsym(maxxaudio_lib_handle, "ma_get_parameters")) ||
Arun Mirpurid750ac52019-04-12 18:33:55 -07006097 !(maxxaudio_supported_usb =
6098 (maxxaudio_supported_usb_t)dlsym(
6099 maxxaudio_lib_handle, "ma_supported_usb"))) {
6100 ALOGE("%s: dlsym failed", __func__);
6101 goto feature_disabled;
6102 }
6103 ALOGD("%s:: ---- Feature MAXX_AUDIO is Enabled ----", __func__);
6104 return 0;
6105 }
6106
6107feature_disabled:
6108 if (maxxaudio_lib_handle) {
6109 dlclose(maxxaudio_lib_handle);
6110 maxxaudio_lib_handle = NULL;
6111 }
6112
6113 maxxaudio_init = NULL;
6114 maxxaudio_deinit = NULL;
6115 maxxaudio_set_state = NULL;
6116 maxxaudio_set_device = NULL;
6117 maxxaudio_set_parameters = NULL;
justinwengd5395152019-11-04 12:23:09 +08006118 maxxaudio_get_parameters = NULL;
Arun Mirpurid750ac52019-04-12 18:33:55 -07006119 maxxaudio_supported_usb = NULL;
6120 ALOGW(":: %s: ---- Feature MAXX_AUDIO is disabled ----", __func__);
6121 return -ENOSYS;
6122}
6123
6124bool audio_extn_is_maxx_audio_enabled()
6125{
6126 return audio_extn_maxx_audio_enabled;
6127}
6128
6129void audio_extn_ma_init(void *platform)
6130{
6131
6132 if (maxxaudio_init) {
6133 maxx_audio_init_config_t init_config;
6134 init_config.fp_platform_set_parameters = platform_set_parameters;
6135 init_config.fp_audio_extn_get_snd_card_split = audio_extn_get_snd_card_split;
6136 maxxaudio_init(platform, init_config);
6137 }
6138}
6139
6140void audio_extn_ma_deinit()
6141{
6142 if (maxxaudio_deinit)
6143 maxxaudio_deinit();
6144}
6145
6146bool audio_extn_ma_set_state(struct audio_device *adev, int stream_type,
6147 float vol, bool active)
6148{
6149 return (maxxaudio_set_state ?
6150 maxxaudio_set_state(adev, stream_type, vol, active): false);
6151}
6152
6153void audio_extn_ma_set_device(struct audio_usecase *usecase)
6154{
6155 if (maxxaudio_set_device)
6156 maxxaudio_set_device(usecase);
6157}
6158
6159void audio_extn_ma_set_parameters(struct audio_device *adev,
6160 struct str_parms *parms)
6161{
6162 if (maxxaudio_set_parameters)
6163 maxxaudio_set_parameters(adev, parms);
6164}
6165
justinwengd5395152019-11-04 12:23:09 +08006166void audio_extn_ma_get_parameters(struct audio_device *adev,
6167 struct str_parms *query,
6168 struct str_parms *reply)
6169{
6170 if (maxxaudio_get_parameters)
6171 maxxaudio_get_parameters(adev, query, reply);
6172}
6173
Arun Mirpurid750ac52019-04-12 18:33:55 -07006174bool audio_extn_ma_supported_usb()
6175{
6176 return (maxxaudio_supported_usb ? maxxaudio_supported_usb(): false);
6177}
6178// END: MAXX_AUDIO =====================================================================
Arun Mirpurie008ed22019-03-21 11:21:04 -07006179
Derek Chenf082fdb2019-07-24 13:27:20 -07006180// START: AUTO_HAL ===================================================================
Fei Tongc20ce932021-06-21 16:42:38 +08006181#ifdef LINUX_ENABLED
6182#ifdef __LP64__
6183#define AUTO_HAL_LIB_PATH "/usr/lib64/libautohal.so"
6184#else
6185#define AUTO_HAL_LIB_PATH "/usr/lib/libautohal.so"
6186#endif
6187#else
Derek Chenf082fdb2019-07-24 13:27:20 -07006188#ifdef __LP64__
6189#define AUTO_HAL_LIB_PATH "/vendor/lib64/libautohal.so"
6190#else
6191#define AUTO_HAL_LIB_PATH "/vendor/lib/libautohal.so"
6192#endif
Fei Tongc20ce932021-06-21 16:42:38 +08006193#endif
Derek Chenf082fdb2019-07-24 13:27:20 -07006194
6195static void *auto_hal_lib_handle = NULL;
6196
6197typedef int (*auto_hal_init_t)(struct audio_device*,
6198 auto_hal_init_config_t);
6199static auto_hal_init_t auto_hal_init;
6200
6201typedef void (*auto_hal_deinit_t)();
6202static auto_hal_deinit_t auto_hal_deinit;
6203
6204typedef int (*auto_hal_create_audio_patch_t)(struct audio_hw_device*,
6205 unsigned int,
6206 const struct audio_port_config*,
6207 unsigned int,
6208 const struct audio_port_config*,
6209 audio_patch_handle_t*);
6210static auto_hal_create_audio_patch_t auto_hal_create_audio_patch;
6211
6212typedef int (*auto_hal_release_audio_patch_t)(struct audio_hw_device*,
6213 audio_patch_handle_t);
6214static auto_hal_release_audio_patch_t auto_hal_release_audio_patch;
6215
6216typedef int (*auto_hal_get_car_audio_stream_from_address_t)(const char*);
6217static auto_hal_get_car_audio_stream_from_address_t auto_hal_get_car_audio_stream_from_address;
6218
6219typedef int (*auto_hal_open_output_stream_t)(struct stream_out*);
6220static auto_hal_open_output_stream_t auto_hal_open_output_stream;
6221
Huicheng Liu1404ba12020-09-11 01:03:25 -04006222typedef int (*auto_hal_open_input_stream_t)(struct stream_in*);
6223static auto_hal_open_input_stream_t auto_hal_open_input_stream;
6224
Susan Wange3959562021-03-11 11:50:26 -05006225typedef int (*auto_hal_open_echo_reference_stream_t)(struct stream_in*);
6226static auto_hal_open_echo_reference_stream_t auto_hal_open_echo_reference_stream;
6227
Derek Chenf082fdb2019-07-24 13:27:20 -07006228typedef bool (*auto_hal_is_bus_device_usecase_t)(audio_usecase_t);
6229static auto_hal_is_bus_device_usecase_t auto_hal_is_bus_device_usecase;
6230
Derek Chenf082fdb2019-07-24 13:27:20 -07006231typedef int (*auto_hal_get_audio_port_t)(struct audio_hw_device*,
6232 struct audio_port*);
6233static auto_hal_get_audio_port_t auto_hal_get_audio_port;
6234
6235typedef int (*auto_hal_set_audio_port_config_t)(struct audio_hw_device*,
6236 const struct audio_port_config*);
6237static auto_hal_set_audio_port_config_t auto_hal_set_audio_port_config;
6238
6239typedef void (*auto_hal_set_parameters_t)(struct audio_device*,
6240 struct str_parms*);
6241static auto_hal_set_parameters_t auto_hal_set_parameters;
6242
Derek Chenf7092792017-05-23 12:23:53 -04006243typedef int (*auto_hal_start_hfp_downlink_t)(struct audio_device*,
6244 struct audio_usecase*);
6245static auto_hal_start_hfp_downlink_t auto_hal_start_hfp_downlink;
6246
6247typedef int (*auto_hal_stop_hfp_downlink_t)(struct audio_device*,
6248 struct audio_usecase*);
6249static auto_hal_stop_hfp_downlink_t auto_hal_stop_hfp_downlink;
6250
Guodong Hu267bdf82019-08-12 19:22:32 +08006251typedef snd_device_t (*auto_hal_get_input_snd_device_t)(struct audio_device*,
6252 audio_usecase_t);
6253static auto_hal_get_input_snd_device_t auto_hal_get_input_snd_device;
6254
6255typedef snd_device_t (*auto_hal_get_output_snd_device_t)(struct audio_device*,
6256 audio_usecase_t);
6257static auto_hal_get_output_snd_device_t auto_hal_get_output_snd_device;
6258
Huicheng Liu1404ba12020-09-11 01:03:25 -04006259typedef snd_device_t (*auto_hal_get_snd_device_for_car_audio_stream_t)(int
6260 car_audio_stream);
6261static auto_hal_get_snd_device_for_car_audio_stream_t auto_hal_get_snd_device_for_car_audio_stream;
6262
Susan Wang727dd6b2021-03-26 11:28:59 -04006263typedef bool (*auto_hal_overwrite_priority_for_auto_t)(struct stream_in*);
6264static auto_hal_overwrite_priority_for_auto_t auto_hal_overwrite_priority_for_auto;
6265
Derek Chenf082fdb2019-07-24 13:27:20 -07006266int auto_hal_feature_init(bool is_feature_enabled)
6267{
6268 ALOGD("%s: Called with feature %s", __func__,
6269 is_feature_enabled ? "Enabled" : "NOT Enabled");
Fei Tongc20ce932021-06-21 16:42:38 +08006270
6271#ifdef LINUX_ENABLED
6272 is_feature_enabled = true;
6273#endif
6274
Derek Chenf082fdb2019-07-24 13:27:20 -07006275 if (is_feature_enabled) {
6276 // dlopen lib
6277 auto_hal_lib_handle = dlopen(AUTO_HAL_LIB_PATH, RTLD_NOW);
6278
6279 if (!auto_hal_lib_handle) {
6280 ALOGE("%s: dlopen failed", __func__);
6281 goto feature_disabled;
6282 }
6283 if (!(auto_hal_init = (auto_hal_init_t)dlsym(
6284 auto_hal_lib_handle, "auto_hal_init")) ||
6285 !(auto_hal_deinit =
6286 (auto_hal_deinit_t)dlsym(
6287 auto_hal_lib_handle, "auto_hal_deinit")) ||
6288 !(auto_hal_create_audio_patch =
6289 (auto_hal_create_audio_patch_t)dlsym(
6290 auto_hal_lib_handle, "auto_hal_create_audio_patch")) ||
6291 !(auto_hal_release_audio_patch =
6292 (auto_hal_release_audio_patch_t)dlsym(
6293 auto_hal_lib_handle, "auto_hal_release_audio_patch")) ||
6294 !(auto_hal_get_car_audio_stream_from_address =
6295 (auto_hal_get_car_audio_stream_from_address_t)dlsym(
6296 auto_hal_lib_handle, "auto_hal_get_car_audio_stream_from_address")) ||
6297 !(auto_hal_open_output_stream =
6298 (auto_hal_open_output_stream_t)dlsym(
6299 auto_hal_lib_handle, "auto_hal_open_output_stream")) ||
Huicheng Liu1404ba12020-09-11 01:03:25 -04006300 !(auto_hal_open_input_stream =
6301 (auto_hal_open_input_stream_t)dlsym(
6302 auto_hal_lib_handle, "auto_hal_open_input_stream")) ||
Susan Wange3959562021-03-11 11:50:26 -05006303 !(auto_hal_open_echo_reference_stream =
6304 (auto_hal_open_echo_reference_stream_t)dlsym(
6305 auto_hal_lib_handle, "auto_hal_open_echo_reference_stream")) ||
Derek Chenf082fdb2019-07-24 13:27:20 -07006306 !(auto_hal_is_bus_device_usecase =
6307 (auto_hal_is_bus_device_usecase_t)dlsym(
6308 auto_hal_lib_handle, "auto_hal_is_bus_device_usecase")) ||
Derek Chenf082fdb2019-07-24 13:27:20 -07006309 !(auto_hal_get_audio_port =
6310 (auto_hal_get_audio_port_t)dlsym(
6311 auto_hal_lib_handle, "auto_hal_get_audio_port")) ||
6312 !(auto_hal_set_audio_port_config =
6313 (auto_hal_set_audio_port_config_t)dlsym(
6314 auto_hal_lib_handle, "auto_hal_set_audio_port_config")) ||
6315 !(auto_hal_set_parameters =
6316 (auto_hal_set_parameters_t)dlsym(
Derek Chenf7092792017-05-23 12:23:53 -04006317 auto_hal_lib_handle, "auto_hal_set_parameters")) ||
6318 !(auto_hal_start_hfp_downlink =
6319 (auto_hal_start_hfp_downlink_t)dlsym(
6320 auto_hal_lib_handle, "auto_hal_start_hfp_downlink")) ||
6321 !(auto_hal_stop_hfp_downlink =
6322 (auto_hal_stop_hfp_downlink_t)dlsym(
Guodong Hu267bdf82019-08-12 19:22:32 +08006323 auto_hal_lib_handle, "auto_hal_stop_hfp_downlink")) ||
6324 !(auto_hal_get_input_snd_device =
6325 (auto_hal_get_input_snd_device_t)dlsym(
6326 auto_hal_lib_handle, "auto_hal_get_input_snd_device")) ||
6327 !(auto_hal_get_output_snd_device =
6328 (auto_hal_get_output_snd_device_t)dlsym(
Huicheng Liu1404ba12020-09-11 01:03:25 -04006329 auto_hal_lib_handle, "auto_hal_get_output_snd_device")) ||
6330 !(auto_hal_get_snd_device_for_car_audio_stream =
6331 (auto_hal_get_snd_device_for_car_audio_stream_t)dlsym(
Susan Wang727dd6b2021-03-26 11:28:59 -04006332 auto_hal_lib_handle, "auto_hal_get_snd_device_for_car_audio_stream")) ||
6333 !(auto_hal_overwrite_priority_for_auto =
6334 (auto_hal_overwrite_priority_for_auto_t)dlsym(
6335 auto_hal_lib_handle, "auto_hal_overwrite_priority_for_auto"))) {
Derek Chenf082fdb2019-07-24 13:27:20 -07006336 ALOGE("%s: dlsym failed", __func__);
6337 goto feature_disabled;
6338 }
6339 ALOGD("%s:: ---- Feature AUTO_HAL is Enabled ----", __func__);
6340 return 0;
6341 }
6342
6343feature_disabled:
6344 if (auto_hal_lib_handle) {
6345 dlclose(auto_hal_lib_handle);
6346 auto_hal_lib_handle = NULL;
6347 }
6348
6349 auto_hal_init = NULL;
6350 auto_hal_deinit = NULL;
6351 auto_hal_create_audio_patch = NULL;
6352 auto_hal_release_audio_patch = NULL;
6353 auto_hal_get_car_audio_stream_from_address = NULL;
6354 auto_hal_open_output_stream = NULL;
Huicheng Liu1404ba12020-09-11 01:03:25 -04006355 auto_hal_open_input_stream = NULL;
Susan Wange3959562021-03-11 11:50:26 -05006356 auto_hal_open_echo_reference_stream = NULL;
Derek Chenf082fdb2019-07-24 13:27:20 -07006357 auto_hal_is_bus_device_usecase = NULL;
Derek Chenf082fdb2019-07-24 13:27:20 -07006358 auto_hal_get_audio_port = NULL;
6359 auto_hal_set_audio_port_config = NULL;
6360 auto_hal_set_parameters = NULL;
Derek Chenf7092792017-05-23 12:23:53 -04006361 auto_hal_start_hfp_downlink = NULL;
6362 auto_hal_stop_hfp_downlink = NULL;
Guodong Hu267bdf82019-08-12 19:22:32 +08006363 auto_hal_get_input_snd_device = NULL;
6364 auto_hal_get_output_snd_device = NULL;
Huicheng Liu1404ba12020-09-11 01:03:25 -04006365 auto_hal_get_snd_device_for_car_audio_stream = NULL;
Susan Wang727dd6b2021-03-26 11:28:59 -04006366 auto_hal_overwrite_priority_for_auto = NULL;
Derek Chenf082fdb2019-07-24 13:27:20 -07006367
6368 ALOGW(":: %s: ---- Feature AUTO_HAL is disabled ----", __func__);
6369 return -ENOSYS;
6370}
6371
6372int audio_extn_auto_hal_init(struct audio_device *adev)
6373{
6374 if(auto_hal_init) {
6375 auto_hal_init_config_t auto_hal_init_config;
Derek Chenf082fdb2019-07-24 13:27:20 -07006376 auto_hal_init_config.fp_audio_extn_ext_hw_plugin_usecase_start = audio_extn_ext_hw_plugin_usecase_start;
6377 auto_hal_init_config.fp_audio_extn_ext_hw_plugin_usecase_stop = audio_extn_ext_hw_plugin_usecase_stop;
6378 auto_hal_init_config.fp_get_usecase_from_list = get_usecase_from_list;
6379 auto_hal_init_config.fp_get_output_period_size = get_output_period_size;
6380 auto_hal_init_config.fp_audio_extn_ext_hw_plugin_set_audio_gain = audio_extn_ext_hw_plugin_set_audio_gain;
Derek Chenf7092792017-05-23 12:23:53 -04006381 auto_hal_init_config.fp_select_devices = select_devices;
6382 auto_hal_init_config.fp_disable_audio_route = disable_audio_route;
6383 auto_hal_init_config.fp_disable_snd_device = disable_snd_device;
Guodong Hu267bdf82019-08-12 19:22:32 +08006384 auto_hal_init_config.fp_adev_get_active_input = adev_get_active_input;
6385 auto_hal_init_config.fp_platform_set_echo_reference = platform_set_echo_reference;
Guodong Huf5e614d2019-06-24 18:42:03 +08006386 auto_hal_init_config.fp_platform_get_eccarstate = platform_get_eccarstate;
Derek Chen6c0f3de2020-02-26 00:30:42 -08006387 auto_hal_init_config.fp_generate_patch_handle = generate_patch_handle;
Tahir Dawson7fabad42022-06-21 12:37:55 -04006388 auto_hal_init_config.fp_platform_get_pcm_device_id = platform_get_pcm_device_id;
Derek Chenf082fdb2019-07-24 13:27:20 -07006389 return auto_hal_init(adev, auto_hal_init_config);
6390 }
6391 else
6392 return 0;
6393}
6394
6395void audio_extn_auto_hal_deinit()
6396{
6397 if (auto_hal_deinit)
6398 auto_hal_deinit();
6399}
6400
6401int audio_extn_auto_hal_create_audio_patch(struct audio_hw_device *dev,
6402 unsigned int num_sources,
6403 const struct audio_port_config *sources,
6404 unsigned int num_sinks,
6405 const struct audio_port_config *sinks,
6406 audio_patch_handle_t *handle)
6407{
6408 return ((auto_hal_create_audio_patch) ?
6409 auto_hal_create_audio_patch(dev,
6410 num_sources,
6411 sources,
6412 num_sinks,
6413 sinks,
6414 handle): 0);
6415}
6416
6417int audio_extn_auto_hal_release_audio_patch(struct audio_hw_device *dev,
6418 audio_patch_handle_t handle)
6419{
6420 return ((auto_hal_release_audio_patch) ?
6421 auto_hal_release_audio_patch(dev, handle): 0);
6422}
6423
6424int audio_extn_auto_hal_get_car_audio_stream_from_address(const char *address)
6425{
6426 return ((auto_hal_get_car_audio_stream_from_address) ?
Guodong Hu267bdf82019-08-12 19:22:32 +08006427 auto_hal_get_car_audio_stream_from_address(address): -ENOSYS);
Derek Chenf082fdb2019-07-24 13:27:20 -07006428}
6429
6430int audio_extn_auto_hal_open_output_stream(struct stream_out *out)
6431{
6432 return ((auto_hal_open_output_stream) ?
Guodong Hu267bdf82019-08-12 19:22:32 +08006433 auto_hal_open_output_stream(out): -ENOSYS);
Derek Chenf082fdb2019-07-24 13:27:20 -07006434}
6435
Huicheng Liu1404ba12020-09-11 01:03:25 -04006436int audio_extn_auto_hal_open_input_stream(struct stream_in *in)
6437{
6438 return ((auto_hal_open_input_stream) ?
6439 auto_hal_open_input_stream(in): -ENOSYS);
6440}
6441
Susan Wange3959562021-03-11 11:50:26 -05006442int audio_extn_auto_hal_open_echo_reference_stream(struct stream_in *in)
6443{
6444 return ((auto_hal_open_echo_reference_stream) ?
6445 auto_hal_open_echo_reference_stream(in): 0);
6446}
6447
Derek Chenf082fdb2019-07-24 13:27:20 -07006448bool audio_extn_auto_hal_is_bus_device_usecase(audio_usecase_t uc_id)
6449{
6450 return ((auto_hal_is_bus_device_usecase) ?
Guodong Hu267bdf82019-08-12 19:22:32 +08006451 auto_hal_is_bus_device_usecase(uc_id): false);
Derek Chenf082fdb2019-07-24 13:27:20 -07006452}
6453
6454int audio_extn_auto_hal_get_audio_port(struct audio_hw_device *dev,
6455 struct audio_port *config)
6456{
6457 return ((auto_hal_get_audio_port) ?
6458 auto_hal_get_audio_port(dev, config): 0);
6459}
6460
6461int audio_extn_auto_hal_set_audio_port_config(struct audio_hw_device *dev,
6462 const struct audio_port_config *config)
6463{
6464 return ((auto_hal_set_audio_port_config) ?
6465 auto_hal_set_audio_port_config(dev, config): 0);
6466}
6467
6468void audio_extn_auto_hal_set_parameters(struct audio_device *adev,
6469 struct str_parms *parms)
6470{
6471 if (auto_hal_set_parameters)
6472 auto_hal_set_parameters(adev, parms);
6473}
Derek Chenf7092792017-05-23 12:23:53 -04006474
6475int audio_extn_auto_hal_start_hfp_downlink(struct audio_device *adev,
6476 struct audio_usecase *uc_info)
6477{
6478 return ((auto_hal_start_hfp_downlink) ?
6479 auto_hal_start_hfp_downlink(adev, uc_info): 0);
6480}
6481
6482int audio_extn_auto_hal_stop_hfp_downlink(struct audio_device *adev,
6483 struct audio_usecase *uc_info)
6484{
6485 return ((auto_hal_stop_hfp_downlink) ?
6486 auto_hal_stop_hfp_downlink(adev, uc_info): 0);
6487}
Guodong Hu267bdf82019-08-12 19:22:32 +08006488
6489snd_device_t audio_extn_auto_hal_get_input_snd_device(struct audio_device *adev,
6490 audio_usecase_t uc_id)
6491{
6492 return ((auto_hal_get_input_snd_device) ?
6493 auto_hal_get_input_snd_device(adev, uc_id): SND_DEVICE_NONE);
6494}
6495
6496snd_device_t audio_extn_auto_hal_get_output_snd_device(struct audio_device *adev,
6497 audio_usecase_t uc_id)
6498{
6499 return ((auto_hal_get_output_snd_device) ?
6500 auto_hal_get_output_snd_device(adev, uc_id): SND_DEVICE_NONE);
6501}
Huicheng Liu1404ba12020-09-11 01:03:25 -04006502
6503snd_device_t audio_extn_auto_hal_get_snd_device_for_car_audio_stream(int car_audio_stream)
6504{
6505 return ((auto_hal_get_snd_device_for_car_audio_stream) ?
6506 auto_hal_get_snd_device_for_car_audio_stream(car_audio_stream): SND_DEVICE_NONE);
6507}
Susan Wang727dd6b2021-03-26 11:28:59 -04006508
6509bool audio_extn_auto_hal_overwrite_priority_for_auto(struct stream_in *in)
6510{
6511 return ((auto_hal_overwrite_priority_for_auto) ?
6512 auto_hal_overwrite_priority_for_auto(in): false);
6513}
6514
Derek Chenf082fdb2019-07-24 13:27:20 -07006515// END: AUTO_HAL ===================================================================
6516
Fei Tongaffdf732020-02-20 20:39:05 +08006517// START: Synth ======================================================================
6518#ifdef __LP64__
6519#define SYNTH_LIB_PATH "/vendor/lib64/libsynth.so"
6520#else
6521#define SYNTH_LIB_PATH "/vendor/lib/libsynth.so"
6522#endif
6523
6524static void *synth_lib_handle = NULL;
6525
6526typedef void (*synth_init_t)(synth_init_config_t);
6527static synth_init_t synth_init;
6528
6529typedef bool (*synth_is_active_t)(struct audio_device *adev);
6530static synth_is_active_t synth_is_active;
6531
6532typedef void (*synth_set_parameters_t)(struct audio_device *adev,
6533 struct str_parms *parms);
6534static synth_set_parameters_t synth_set_parameters;
6535
6536int synth_feature_init(bool is_feature_enabled)
6537{
6538 ALOGD("%s: Called with feature %s", __func__,
6539 is_feature_enabled ? "Enabled" : "NOT Enabled");
6540 if (is_feature_enabled) {
6541 // dlopen lib
6542 synth_lib_handle = dlopen(SYNTH_LIB_PATH, RTLD_NOW);
6543
6544 if (!synth_lib_handle) {
6545 ALOGE("%s: dlopen failed", __func__);
6546 goto feature_disabled;
6547 }
6548 if (!(synth_init = (synth_init_t)dlsym(
6549 synth_lib_handle, "synth_init")) ||
6550 !(synth_is_active =
6551 (synth_is_active_t)dlsym(
6552 synth_lib_handle, "synth_is_active")) ||
6553 !(synth_set_parameters =
6554 (synth_set_parameters_t)dlsym(
6555 synth_lib_handle, "synth_set_parameters"))) {
6556 ALOGE("%s: dlsym failed", __func__);
6557 goto feature_disabled;
6558 }
6559 synth_init_config_t init_config;
6560 init_config.fp_platform_get_pcm_device_id = platform_get_pcm_device_id;
6561 init_config.fp_get_usecase_from_list = get_usecase_from_list;
6562 init_config.fp_select_devices = select_devices;
6563 init_config.fp_disable_audio_route = disable_audio_route;
6564 init_config.fp_disable_snd_device = disable_snd_device;
6565
6566 synth_init(init_config);
6567 ALOGD("%s:: ---- Feature Synth is Enabled ----", __func__);
6568 return 0;
6569 }
6570
6571feature_disabled:
6572 if (synth_lib_handle) {
6573 dlclose(synth_lib_handle);
6574 synth_lib_handle = NULL;
6575 }
6576
6577 synth_init = NULL;
6578 synth_is_active = NULL;
6579 synth_set_parameters = NULL;
6580
6581 ALOGW(":: %s: ---- Feature Synth is disabled ----", __func__);
6582 return -ENOSYS;
6583}
6584
6585bool audio_extn_synth_is_active(struct audio_device *adev)
6586{
6587 return ((synth_is_active) ?
6588 synth_is_active(adev): false);
6589}
6590
6591void audio_extn_synth_set_parameters(struct audio_device *adev,
6592 struct str_parms *parms)
6593{
6594 ((synth_set_parameters) ?
6595 synth_set_parameters(adev, parms): NULL);
6596}
6597
6598// END: Synth ========================================================================
6599
Tahir Dawsoncaaf0992021-03-11 13:31:23 -05006600// START: Power Policy Client ======================================================================
6601#ifdef __LP64__
6602#define POWER_POLICY_LIB_PATH "/vendor/lib64/libaudiopowerpolicy.so"
6603#else
6604#define POWER_POLICY_LIB_PATH "/vendor/lib/libaudiopowerpolicy.so"
6605#endif
Fei Tongaffdf732020-02-20 20:39:05 +08006606
Tahir Dawsoncaaf0992021-03-11 13:31:23 -05006607static void* power_policy_lib_handle;
Subhadra Jagadeesan63a1e832023-01-13 11:26:38 +05306608typedef int (*launch_power_policy_t) (power_policy_init_config_t);
Tahir Dawsoncaaf0992021-03-11 13:31:23 -05006609static launch_power_policy_t launch_power_policy;
6610
6611static void* power_policy_thread_func(void* arg __unused) {
6612 if (launch_power_policy == NULL) {
6613 ALOGE("%s: Power Policy launcher is NULL", __func__);
6614 goto exit;
6615 }
6616 ALOGD("%s: Launching Power Policy Client", __func__);
Shubhasini Sugumaran3fde6582022-01-19 15:54:50 -05006617 power_policy_init_config_t init_config;
6618 init_config.fp_in_set_power_policy = in_set_power_policy;
6619 init_config.fp_out_set_power_policy = out_set_power_policy;
6620 launch_power_policy(init_config);
Tahir Dawsoncaaf0992021-03-11 13:31:23 -05006621
6622exit:
Shubhasini Sugumaran3fde6582022-01-19 15:54:50 -05006623 return NULL;
Tahir Dawsoncaaf0992021-03-11 13:31:23 -05006624}
6625
6626static int power_policy_feature_init(bool is_feature_enabled)
6627{
6628 pthread_t tid;
6629 pthread_attr_t attr;
6630
6631 ALOGD("%s: Called with feature %s", __func__,
6632 is_feature_enabled ? "Enabled" : "NOT Enabled");
6633 if (is_feature_enabled) {
6634 // dlopen lib
6635 power_policy_lib_handle = dlopen(POWER_POLICY_LIB_PATH, RTLD_NOW);
6636
6637 if (!power_policy_lib_handle) {
6638 ALOGE("%s: dlopen failed", __func__);
6639 goto feature_disabled;
6640 }
6641 if (!(launch_power_policy = (launch_power_policy_t)dlsym(
6642 power_policy_lib_handle, "launchPowerPolicyClient")))
6643 {
6644 ALOGE("%s: dlsym failed", __func__);
6645 goto feature_disabled;
6646 }
6647
6648 pthread_attr_init(&attr);
6649 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
6650 if (pthread_create(&tid, &attr, power_policy_thread_func, NULL))
6651 {
6652 ALOGE("%s: Failed to create power policy thread", __func__);
6653 goto feature_disabled;
6654 }
6655 ALOGD("%s:: ---- Feature Power Policy Client is Enabled ----", __func__);
6656 return 0;
6657 }
6658
6659feature_disabled:
6660 if (power_policy_lib_handle) {
6661 dlclose(power_policy_lib_handle);
6662 power_policy_lib_handle = NULL;
6663 }
6664
6665 launch_power_policy = NULL;
6666
6667 ALOGW(":: %s: ---- Feature Power Policy Client is disabled ----", __func__);
6668 return -ENOSYS;
6669
6670// END: Power Policy Client ======================================================================
6671}
vivek mehtaae1018c2019-05-09 12:19:57 -07006672void audio_extn_feature_init()
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08006673{
Weiyin Jiangd5718bd2019-09-04 16:52:08 +08006674 vendor_enhanced_info = audio_extn_utils_get_vendor_enhanced_info();
vivek mehtaae1018c2019-05-09 12:19:57 -07006675 // register feature init functions here
6676 // each feature needs a vendor property
6677 // default value added is for GSI (non vendor modified images)
6678 snd_mon_feature_init(
6679 property_get_bool("vendor.audio.feature.snd_mon.enable",
vivek mehtaf6e6b962019-06-21 15:08:51 -07006680 false));
vivek mehtaae1018c2019-05-09 12:19:57 -07006681 compr_cap_feature_init(
6682 property_get_bool("vendor.audio.feature.compr_cap.enable",
6683 false));
6684 dsm_feedback_feature_init(
6685 property_get_bool("vendor.audio.feature.dsm_feedback.enable",
6686 false));
6687 ssrec_feature_init(
6688 property_get_bool("vendor.audio.feature.ssrec.enable",
6689 false));
6690 src_trkn_feature_init(
6691 property_get_bool("vendor.audio.feature.src_trkn.enable",
6692 false));
6693 hdmi_edid_feature_init(
6694 property_get_bool("vendor.audio.feature.hdmi_edid.enable",
6695 false));
6696 keep_alive_feature_init(
6697 property_get_bool("vendor.audio.feature.keep_alive.enable",
6698 false));
6699 hifi_audio_feature_init(
6700 property_get_bool("vendor.audio.feature.hifi_audio.enable",
6701 false));
6702 ras_feature_init(
6703 property_get_bool("vendor.audio.feature.ras.enable",
6704 false));
6705 kpi_optimize_feature_init(
6706 property_get_bool("vendor.audio.feature.kpi_optimize.enable",
6707 false));
6708 usb_offload_feature_init(
6709 property_get_bool("vendor.audio.feature.usb_offload.enable",
vivek mehtaf6e6b962019-06-21 15:08:51 -07006710 false));
vivek mehtaae1018c2019-05-09 12:19:57 -07006711 usb_offload_burst_mode_feature_init(
6712 property_get_bool("vendor.audio.feature.usb_offload_burst_mode.enable",
6713 false));
6714 usb_offload_sidetone_volume_feature_init(
6715 property_get_bool("vendor.audio.feature.usb_offload_sidetone_volume.enable",
6716 false));
6717 a2dp_offload_feature_init(
6718 property_get_bool("vendor.audio.feature.a2dp_offload.enable",
6719 false));
6720 wsa_feature_init(
6721 property_get_bool("vendor.audio.feature.wsa.enable",
6722 false));
6723 compress_meta_data_feature_init(
6724 property_get_bool("vendor.audio.feature.compress_meta_data.enable",
6725 false));
6726 vbat_feature_init(
6727 property_get_bool("vendor.audio.feature.vbat.enable",
6728 false));
6729 display_port_feature_init(
6730 property_get_bool("vendor.audio.feature.display_port.enable",
6731 false));
6732 fluence_feature_init(
6733 property_get_bool("vendor.audio.feature.fluence.enable",
6734 false));
6735 custom_stereo_feature_init(
6736 property_get_bool("vendor.audio.feature.custom_stereo.enable",
6737 false));
6738 anc_headset_feature_init(
6739 property_get_bool("vendor.audio.feature.anc_headset.enable",
6740 false));
6741 spkr_prot_feature_init(
6742 property_get_bool("vendor.audio.feature.spkr_prot.enable",
vivek mehtaf6e6b962019-06-21 15:08:51 -07006743 false));
vivek mehtaae1018c2019-05-09 12:19:57 -07006744 fm_feature_init(
6745 property_get_bool("vendor.audio.feature.fm.enable",
6746 false));
6747 external_qdsp_feature_init(
6748 property_get_bool("vendor.audio.feature.external_dsp.enable",
vivek mehtaf6e6b962019-06-21 15:08:51 -07006749 false));
vivek mehtaae1018c2019-05-09 12:19:57 -07006750 external_speaker_feature_init(
6751 property_get_bool("vendor.audio.feature.external_speaker.enable",
vivek mehtaf6e6b962019-06-21 15:08:51 -07006752 false));
vivek mehtaae1018c2019-05-09 12:19:57 -07006753 external_speaker_tfa_feature_init(
6754 property_get_bool("vendor.audio.feature.external_speaker_tfa.enable",
6755 false));
6756 hwdep_cal_feature_init(
6757 property_get_bool("vendor.audio.feature.hwdep_cal.enable",
vivek mehtaf6e6b962019-06-21 15:08:51 -07006758 false));
Fei Tongc20ce932021-06-21 16:42:38 +08006759 #ifdef LINUX_ENABLED
6760 #ifdef HFP_ENABLED
6761 hfp_feature_init(true);
6762 #else
6763 hfp_feature_init(false);
6764 #endif
6765 #else
vivek mehtaae1018c2019-05-09 12:19:57 -07006766 hfp_feature_init(
6767 property_get_bool("vendor.audio.feature.hfp.enable",
Fei Tongc20ce932021-06-21 16:42:38 +08006768 false));
6769 #endif
Derek Chena30a5f42019-12-03 11:17:09 -05006770 icc_feature_init(
6771 property_get_bool("vendor.audio.feature.icc.enable",
6772 false));
vivek mehtaae1018c2019-05-09 12:19:57 -07006773 ext_hw_plugin_feature_init(
6774 property_get_bool("vendor.audio.feature.ext_hw_plugin.enable",
6775 false));
6776 record_play_concurency_feature_init(
6777 property_get_bool("vendor.audio.feature.record_play_concurency.enable",
6778 false));
6779 hdmi_passthrough_feature_init(
6780 property_get_bool("vendor.audio.feature.hdmi_passthrough.enable",
6781 false));
6782 concurrent_capture_feature_init(
6783 property_get_bool("vendor.audio.feature.concurrent_capture.enable",
vivek mehtaf6e6b962019-06-21 15:08:51 -07006784 false));
vivek mehtaae1018c2019-05-09 12:19:57 -07006785 compress_in_feature_init(
6786 property_get_bool("vendor.audio.feature.compress_in.enable",
6787 false));
6788 battery_listener_feature_init(
6789 property_get_bool("vendor.audio.feature.battery_listener.enable",
6790 false));
6791 maxx_audio_feature_init(
6792 property_get_bool("vendor.audio.feature.maxx_audio.enable",
vivek mehtaf6e6b962019-06-21 15:08:51 -07006793 false));
vivek mehtaae1018c2019-05-09 12:19:57 -07006794 audiozoom_feature_init(
6795 property_get_bool("vendor.audio.feature.audiozoom.enable",
vivek mehtaf6e6b962019-06-21 15:08:51 -07006796 false));
Derek Chenf082fdb2019-07-24 13:27:20 -07006797 auto_hal_feature_init(
6798 property_get_bool("vendor.audio.feature.auto_hal.enable",
6799 false));
Fei Tongaffdf732020-02-20 20:39:05 +08006800 synth_feature_init(
6801 property_get_bool("vendor.audio.feature.synth.enable",
6802 false));
Tahir Dawsoncaaf0992021-03-11 13:31:23 -05006803 power_policy_feature_init(
6804 property_get_bool("vendor.audio.feature.powerpolicy.enable",
6805 false));
Krishna Kishor Jha0f4d8482022-02-18 10:56:05 +05306806 concurrent_pcm_record_feature_init(
6807 property_get_bool("vendor.audio.feature.concurrent_pcm_record.enable",
6808 false));
Kogara Naveen Kumarc5758232022-11-07 20:25:40 +05306809 concurrent_low_latency_pcm_record_feature_init(
6810 property_get_bool("vendor.audio.feature.concurrent_low_latency_pcm_record.enable",
6811 false));
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08006812}
6813
6814void audio_extn_set_parameters(struct audio_device *adev,
6815 struct str_parms *parms)
6816{
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08006817 audio_extn_set_aanc_noise_level(adev, parms);
6818 audio_extn_set_anc_parameters(adev, parms);
6819 audio_extn_set_fluence_parameters(adev, parms);
6820 audio_extn_set_afe_proxy_parameters(adev, parms);
6821 audio_extn_fm_set_parameters(adev, parms);
6822 audio_extn_sound_trigger_set_parameters(adev, parms);
6823 audio_extn_listen_set_parameters(adev, parms);
6824 audio_extn_ssr_set_parameters(adev, parms);
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08006825 audio_extn_dts_eagle_set_parameters(adev, parms);
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08006826 audio_extn_ddp_set_parameters(adev, parms);
6827 audio_extn_ds2_set_parameters(adev, parms);
6828 audio_extn_customstereo_set_parameters(adev, parms);
6829 audio_extn_hpx_set_parameters(adev, parms);
6830 audio_extn_pm_set_parameters(parms);
6831 audio_extn_source_track_set_parameters(adev, parms);
6832 audio_extn_fbsp_set_parameters(parms);
6833 audio_extn_keep_alive_set_parameters(adev, parms);
6834 audio_extn_passthru_set_parameters(adev, parms);
6835 audio_extn_ext_disp_set_parameters(adev, parms);
6836 audio_extn_qaf_set_parameters(adev, parms);
Sidipotu Ashokd2f10ba2019-05-06 15:41:56 +05306837 if (audio_extn_qap_is_enabled())
6838 audio_extn_qap_set_parameters(adev, parms);
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08006839 if (adev->offload_effects_set_parameters != NULL)
6840 adev->offload_effects_set_parameters(parms);
6841 audio_extn_set_aptx_dec_bt_addr(adev, parms);
6842 audio_extn_ffv_set_parameters(adev, parms);
6843 audio_extn_ext_hw_plugin_set_parameters(adev->ext_hw_plugin, parms);
Derek Chena30a5f42019-12-03 11:17:09 -05006844 audio_extn_icc_set_parameters(adev, parms);
Fei Tongaffdf732020-02-20 20:39:05 +08006845 audio_extn_synth_set_parameters(adev, parms);
Arun Mirpurib1bec9c2019-01-29 16:42:45 -08006846}
6847
6848void audio_extn_get_parameters(const struct audio_device *adev,
6849 struct str_parms *query,
6850 struct str_parms *reply)
6851{
6852 char *kv_pairs = NULL;
6853 audio_extn_get_afe_proxy_parameters(adev, query, reply);
6854 audio_extn_get_fluence_parameters(adev, query, reply);
6855 audio_extn_ssr_get_parameters(adev, query, reply);
6856 get_active_offload_usecases(adev, query, reply);
6857 audio_extn_dts_eagle_get_parameters(adev, query, reply);
6858 audio_extn_hpx_get_parameters(query, reply);
6859 audio_extn_source_track_get_parameters(adev, query, reply);
6860 audio_extn_fbsp_get_parameters(query, reply);
6861 audio_extn_sound_trigger_get_parameters(adev, query, reply);
6862 audio_extn_fm_get_parameters(query, reply);
6863 if (adev->offload_effects_get_parameters != NULL)
6864 adev->offload_effects_get_parameters(query, reply);
6865 audio_extn_ext_hw_plugin_get_parameters(adev->ext_hw_plugin, query, reply);
6866
6867 kv_pairs = str_parms_to_str(reply);
6868 ALOGD_IF(kv_pairs != NULL, "%s: returns %s", __func__, kv_pairs);
6869 free(kv_pairs);
Aalique Grahame22e49102018-12-18 14:23:57 -08006870}
Surendar Karka287348c2019-04-10 18:31:46 +05306871
6872int audio_ext_get_presentation_position(struct stream_out *out,
6873 struct audio_out_presentation_position_param *pos_param)
6874{
6875 int ret = -ENODATA;
6876
6877 if (!out) {
6878 ALOGE("%s:: Invalid stream",__func__);
6879 return ret;
6880 }
6881
6882 if (is_offload_usecase(out->usecase)) {
6883 if (out->compr != NULL)
6884 ret = audio_extn_utils_compress_get_dsp_presentation_pos(out,
6885 &pos_param->frames, &pos_param->timestamp, pos_param->clock_id);
6886 } else {
6887 if (out->pcm)
6888 ret = audio_extn_utils_pcm_get_dsp_presentation_pos(out,
6889 &pos_param->frames, &pos_param->timestamp, pos_param->clock_id);
6890 }
6891
6892 ALOGV("%s frames %lld timestamp %lld", __func__, (long long int)pos_param->frames,
6893 pos_param->timestamp.tv_sec*1000000000LL + pos_param->timestamp.tv_nsec);
6894
6895 return ret;
6896}