blob: 4b1ef31d6117334649f52d28b0c9b1922945a605 [file] [log] [blame]
Vignesh Kulothungan55396882017-04-20 14:37:02 -07001/*
Saurav Kumardba3caf2020-05-29 20:53:55 +05302 * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
Vignesh Kulothungan55396882017-04-20 14:37:02 -07003 * Not a Contribution.
4 *
5 * Copyright (C) 2013 The Android Open Source Project
6 *
Sandhya Mutha Naga Venkata4c6fc9f2022-10-14 19:38:02 +05307 * Changes from Qualcomm Innovation Center are provided under the following license:
8 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
9 * SPDX-License-Identifier: BSD-3-Clause-Clear
10 *
Vignesh Kulothungan55396882017-04-20 14:37:02 -070011 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 */
23
24#define LOG_TAG "audio_hw_acdb"
25//#define LOG_NDEBUG 0
26#define LOG_NDDEBUG 0
27
28#include <stdlib.h>
29#include <dlfcn.h>
Weiyin Jiang2995f662019-04-17 14:25:12 +080030#include <log/log.h>
Vignesh Kulothungan55396882017-04-20 14:37:02 -070031#include <cutils/list.h>
Vinay Vermaaddfa4a2018-04-29 14:03:38 +053032#include <time.h>
Vignesh Kulothungan55396882017-04-20 14:37:02 -070033#include "acdb.h"
34#include "platform_api.h"
Arun Mirpuria13495c2019-04-11 16:08:12 -070035#include "audio_extn.h"
36#include <platform.h>
Vignesh Kulothungan55396882017-04-20 14:37:02 -070037
Aditya Bavanari29bcea22017-10-03 20:10:35 +053038#ifdef INSTANCE_ID_ENABLED
39int check_and_set_instance_id_support(struct mixer* mixer, bool acdb_support)
40{
41 const char *mixer_ctl_name = "Instance ID Support";
42 struct mixer_ctl* ctl;
43
44 ALOGV("%s", __func__);
45
46 /* Check for ACDB and property instance ID support and issue mixer control */
47 ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
48 if (!ctl) {
49 ALOGE("%s: Could not get ctl for mixer cmd - %s",
50 __func__, mixer_ctl_name);
51 return -EINVAL;
52 }
53
54 ALOGD("%s: Final Instance ID support:%d\n", __func__, acdb_support);
55 if (mixer_ctl_set_value(ctl, 0, acdb_support) < 0) {
56 ALOGE("%s: Could not set Instance ID support %d", __func__,
57 acdb_support);
58 return -EINVAL;
59 }
60 return 0;
61}
62#else
63#define check_and_set_instance_id_support(x, y) -ENOSYS
64#endif
65
Arun Mirpuria13495c2019-04-11 16:08:12 -070066void get_platform_file_for_device(struct mixer *mixer, char* platform_info_file)
67{
68 const char *snd_card_name = NULL;
69
70 if (mixer != NULL) {
71 /* Get Sound card name */
72 snd_card_name = mixer_get_name(mixer);
73 if (!snd_card_name) {
74 ALOGE("failed to allocate memory for snd_card_name");
75 return;
76 }
77 /* Get platform info file for target */
78 audio_extn_utils_get_platform_info(snd_card_name, platform_info_file);
79 }
80}
81
Vignesh Kulothungan55396882017-04-20 14:37:02 -070082int acdb_init(int snd_card_num)
83{
84
85 int result = -1;
Vignesh Kulothungan55396882017-04-20 14:37:02 -070086 struct mixer *mixer = NULL;
Vignesh Kulothungan55396882017-04-20 14:37:02 -070087
88 if(snd_card_num < 0) {
89 ALOGE("invalid sound card number");
90 return result;
91 }
92
93 mixer = mixer_open(snd_card_num);
94 if (!mixer) {
95 ALOGE("%s: Unable to open the mixer card: %d", __func__,
96 snd_card_num);
Soumya Managoli9fee7c62018-04-06 16:21:50 +053097 return result;
98 }
99 result = acdb_init_v2(mixer);
100 mixer_close(mixer);
101 return result;
102}
103
104int acdb_init_v2(struct mixer *mixer)
105{
106
107 int result = -1;
108 char *cvd_version = NULL;
Saurav Kumardba3caf2020-05-29 20:53:55 +0530109 char vendor_config_path[VENDOR_CONFIG_PATH_MAX_LENGTH];
110 char platform_info_file[VENDOR_CONFIG_FILE_MAX_LENGTH];
Soumya Managoli9fee7c62018-04-06 16:21:50 +0530111 const char *snd_card_name = NULL;
112 struct acdb_platform_data *my_data = NULL;
113
114 if (!mixer) {
115 ALOGE("Invalid mixer handle");
116 return result;
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700117 }
118
119 my_data = calloc(1, sizeof(struct acdb_platform_data));
120 if (!my_data) {
121 ALOGE("failed to allocate acdb platform data");
122 goto cleanup;
123 }
124
125 list_init(&my_data->acdb_meta_key_list);
Saurav Kumardba3caf2020-05-29 20:53:55 +0530126 audio_get_vendor_config_path(vendor_config_path, sizeof(vendor_config_path));
127 /* Get path for platorm_info_xml_path_name in vendor */
128 snprintf(platform_info_file, sizeof(platform_info_file),
129 "%s/%s", vendor_config_path, PLATFORM_INFO_XML_PATH_NAME);
Arun Mirpuria13495c2019-04-11 16:08:12 -0700130 get_platform_file_for_device(mixer, platform_info_file);
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700131 /* Extract META KEY LIST INFO */
Arun Mirpuria13495c2019-04-11 16:08:12 -0700132 platform_info_init(platform_info_file, my_data, ACDB_EXTN);
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700133
134 my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
135 if (my_data->acdb_handle == NULL) {
136 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
137 goto cleanup;
138 }
139
140 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
141
Aditya Bavanari29bcea22017-10-03 20:10:35 +0530142 my_data->acdb_init_v4 = (acdb_init_v4_t)dlsym(my_data->acdb_handle,
143 "acdb_loader_init_v4");
144 if (my_data->acdb_init_v4 == NULL)
145 ALOGE("%s: dlsym error %s for acdb_loader_init_v4", __func__, dlerror());
146
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700147 my_data->acdb_init_v3 = (acdb_init_v3_t)dlsym(my_data->acdb_handle,
148 "acdb_loader_init_v3");
149 if (my_data->acdb_init_v3 == NULL)
150 ALOGE("%s: dlsym error %s for acdb_loader_init_v3", __func__, dlerror());
151
152 my_data->acdb_init_v2 = (acdb_init_v2_t)dlsym(my_data->acdb_handle,
153 "acdb_loader_init_v2");
154 if (my_data->acdb_init_v2 == NULL)
155 ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
156
157 my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
158 "acdb_loader_init_ACDB");
159 if (my_data->acdb_init == NULL && my_data->acdb_init_v2 == NULL
Aditya Bavanari29bcea22017-10-03 20:10:35 +0530160 && my_data->acdb_init_v3 == NULL && my_data->acdb_init_v4 == NULL) {
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700161 ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror());
162 goto cleanup;
163 }
164
165 /* Get CVD version */
166 cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
167 if (!cvd_version) {
168 ALOGE("%s: Failed to allocate cvd version", __func__);
169 goto cleanup;
170 } else {
171 struct mixer_ctl *ctl = NULL;
172 int count = 0;
173
174 ctl = mixer_get_ctl_by_name(mixer, CVD_VERSION_MIXER_CTL);
175 if (!ctl) {
176 ALOGE("%s: Could not get ctl for mixer cmd - %s", __func__, CVD_VERSION_MIXER_CTL);
Abhinav Gaurbea85842021-12-27 16:00:58 +0530177#ifdef PLATFORM_AUTO
178 ALOGE("%s: Ctl check bypassed in automotive platform for mixer cmd - %s",
179 __func__, CVD_VERSION_MIXER_CTL);
180 goto get_sound_card_name;
181#else
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700182 goto cleanup;
Abhinav Gaurbea85842021-12-27 16:00:58 +0530183#endif
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700184 }
185 mixer_ctl_update(ctl);
186
187 count = mixer_ctl_get_num_values(ctl);
188 if (count > MAX_CVD_VERSION_STRING_SIZE)
189 count = MAX_CVD_VERSION_STRING_SIZE;
190
191 result = mixer_ctl_get_array(ctl, cvd_version, count);
192 if (result != 0) {
193 ALOGE("%s: ERROR! mixer_ctl_get_array() failed to get CVD Version", __func__);
194 goto cleanup;
195 }
196 }
197
Abhinav Gaurbea85842021-12-27 16:00:58 +0530198#ifdef PLATFORM_AUTO
199get_sound_card_name:
200#endif
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700201 /* Get Sound card name */
Aditya Bavanari71b6d532018-01-16 17:48:08 +0530202 snd_card_name = mixer_get_name(mixer);
Weiyin Jiang301dac62019-05-08 13:58:00 +0800203 snd_card_name = platform_get_snd_card_name_for_acdb_loader(snd_card_name);
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700204 if (!snd_card_name) {
Weiyin Jiang301dac62019-05-08 13:58:00 +0800205 ALOGE("failed to get snd_card_name");
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700206 result = -1;
207 goto cleanup;
208 }
209
210 int key = 0;
211 struct listnode *node = NULL;
212 struct meta_key_list *key_info = NULL;
Aditya Bavanari29bcea22017-10-03 20:10:35 +0530213 static bool acdb_instance_id_support = false;
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700214
Aditya Bavanari29bcea22017-10-03 20:10:35 +0530215 my_data->acdb_init_data.cvd_version = cvd_version;
216 my_data->acdb_init_data.snd_card_name = strdup(snd_card_name);
217 my_data->acdb_init_data.meta_key_list = &my_data->acdb_meta_key_list;
218 my_data->acdb_init_data.is_instance_id_supported = &acdb_instance_id_support;
219
220 if (my_data->acdb_init_v4) {
221 result = my_data->acdb_init_v4(&my_data->acdb_init_data, ACDB_LOADER_INIT_V4);
222 } else if (my_data->acdb_init_v3) {
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700223 result = my_data->acdb_init_v3(snd_card_name, cvd_version,
224 &my_data->acdb_meta_key_list);
225 } else if (my_data->acdb_init_v2) {
226 node = list_head(&my_data->acdb_meta_key_list);
227 key_info = node_to_item(node, struct meta_key_list, list);
228 key = key_info->cal_info.nKey;
229 result = my_data->acdb_init_v2(snd_card_name, cvd_version, key);
230 } else {
231 result = my_data->acdb_init();
232 }
Aditya Bavanari29bcea22017-10-03 20:10:35 +0530233 ALOGD("%s: ACDB Instance ID support after ACDB init:%d\n",
234 __func__, acdb_instance_id_support);
235 check_and_set_instance_id_support(mixer, acdb_instance_id_support);
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700236
237cleanup:
238 if (NULL != my_data) {
239 if (my_data->acdb_handle)
240 dlclose(my_data->acdb_handle);
241
Dhanalakshmi Siddani96eb5762017-12-11 11:56:46 +0530242 struct listnode *node = NULL;
243 struct meta_key_list *key_info = NULL;
244 struct listnode *tempnode = NULL;
245 list_for_each_safe(node, tempnode, &my_data->acdb_meta_key_list) {
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700246 key_info = node_to_item(node, struct meta_key_list, list);
Dhanalakshmi Siddani96eb5762017-12-11 11:56:46 +0530247 list_remove(node);
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700248 free(key_info);
249 }
Sandhya Mutha Naga Venkata4c6fc9f2022-10-14 19:38:02 +0530250
251 if (result < 0) {
252
253 if (snd_card_name)
254 free((void *)snd_card_name);
255
256 if (my_data->acdb_init_data.snd_card_name)
257 free(my_data->acdb_init_data.snd_card_name);
258
259 if (my_data)
260 platform_info_deinit();
261 }
262
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700263 free(my_data);
264 }
265
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700266 if (cvd_version)
267 free(cvd_version);
268
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700269 return result;
270}
271
272int acdb_set_metainfo_key(void *platform, char *name, int key) {
273
274 struct meta_key_list *key_info = (struct meta_key_list *)
275 calloc(1, sizeof(struct meta_key_list));
276 struct acdb_platform_data *pdata = (struct acdb_platform_data *)platform;
277 if (!key_info) {
278 ALOGE("%s: Could not allocate memory for key %d", __func__, key);
279 return -ENOMEM;
280 }
281
282 key_info->cal_info.nKey = key;
283 strlcpy(key_info->name, name, sizeof(key_info->name));
284 list_add_tail(&pdata->acdb_meta_key_list, &key_info->list);
285
286 ALOGD("%s: successfully added module %s and key %d to the list", __func__,
287 key_info->name, key_info->cal_info.nKey);
288
289 return 0;
290}