blob: 79ef4ae2b46768fcc918db1f87948090963c450c [file] [log] [blame]
Vignesh Kulothungan55396882017-04-20 14:37:02 -07001/*
Soumya Managolid4a9c962018-04-06 16:21:50 +05302 * Copyright (c) 2013-2018, 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 *
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.
18 */
19
20#define LOG_TAG "audio_hw_acdb"
21//#define LOG_NDEBUG 0
22#define LOG_NDDEBUG 0
23
24#include <stdlib.h>
25#include <dlfcn.h>
26#include <cutils/log.h>
27#include <cutils/list.h>
28#include "acdb.h"
29#include "platform_api.h"
30
Aditya Bavanari20fd7812017-10-03 20:10:35 +053031#ifdef INSTANCE_ID_ENABLED
32int check_and_set_instance_id_support(struct mixer* mixer, bool acdb_support)
33{
34 const char *mixer_ctl_name = "Instance ID Support";
35 struct mixer_ctl* ctl;
36
37 ALOGV("%s", __func__);
38
39 /* Check for ACDB and property instance ID support and issue mixer control */
40 ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
41 if (!ctl) {
42 ALOGE("%s: Could not get ctl for mixer cmd - %s",
43 __func__, mixer_ctl_name);
44 return -EINVAL;
45 }
46
47 ALOGD("%s: Final Instance ID support:%d\n", __func__, acdb_support);
48 if (mixer_ctl_set_value(ctl, 0, acdb_support) < 0) {
49 ALOGE("%s: Could not set Instance ID support %d", __func__,
50 acdb_support);
51 return -EINVAL;
52 }
53 return 0;
54}
55#else
56#define check_and_set_instance_id_support(x, y) -ENOSYS
57#endif
58
Vignesh Kulothungan55396882017-04-20 14:37:02 -070059int acdb_init(int snd_card_num)
60{
61
62 int result = -1;
Vignesh Kulothungan55396882017-04-20 14:37:02 -070063 struct mixer *mixer = NULL;
Vignesh Kulothungan55396882017-04-20 14:37:02 -070064
65 if(snd_card_num < 0) {
66 ALOGE("invalid sound card number");
67 return result;
68 }
69
70 mixer = mixer_open(snd_card_num);
71 if (!mixer) {
72 ALOGE("%s: Unable to open the mixer card: %d", __func__,
73 snd_card_num);
Soumya Managolid4a9c962018-04-06 16:21:50 +053074 return result;
75 }
76 result = acdb_init_v2(mixer);
77 mixer_close(mixer);
78 return result;
79}
80
81int acdb_init_v2(struct mixer *mixer)
82{
83
84 int result = -1;
85 char *cvd_version = NULL;
86
87 const char *snd_card_name = NULL;
88 struct acdb_platform_data *my_data = NULL;
89
90 if (!mixer) {
91 ALOGE("Invalid mixer handle");
92 return result;
Vignesh Kulothungan55396882017-04-20 14:37:02 -070093 }
94
95 my_data = calloc(1, sizeof(struct acdb_platform_data));
96 if (!my_data) {
97 ALOGE("failed to allocate acdb platform data");
98 goto cleanup;
99 }
100
101 list_init(&my_data->acdb_meta_key_list);
102
103 /* Extract META KEY LIST INFO */
104 platform_info_init(PLATFORM_INFO_XML_PATH, my_data, ACDB_EXTN);
105
106 my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
107 if (my_data->acdb_handle == NULL) {
108 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
109 goto cleanup;
110 }
111
112 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
113
Aditya Bavanari20fd7812017-10-03 20:10:35 +0530114 my_data->acdb_init_v4 = (acdb_init_v4_t)dlsym(my_data->acdb_handle,
115 "acdb_loader_init_v4");
116 if (my_data->acdb_init_v4 == NULL)
117 ALOGE("%s: dlsym error %s for acdb_loader_init_v4", __func__, dlerror());
118
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700119 my_data->acdb_init_v3 = (acdb_init_v3_t)dlsym(my_data->acdb_handle,
120 "acdb_loader_init_v3");
121 if (my_data->acdb_init_v3 == NULL)
122 ALOGE("%s: dlsym error %s for acdb_loader_init_v3", __func__, dlerror());
123
124 my_data->acdb_init_v2 = (acdb_init_v2_t)dlsym(my_data->acdb_handle,
125 "acdb_loader_init_v2");
126 if (my_data->acdb_init_v2 == NULL)
127 ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
128
129 my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
130 "acdb_loader_init_ACDB");
131 if (my_data->acdb_init == NULL && my_data->acdb_init_v2 == NULL
Aditya Bavanari20fd7812017-10-03 20:10:35 +0530132 && my_data->acdb_init_v3 == NULL && my_data->acdb_init_v4 == NULL) {
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700133 ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror());
134 goto cleanup;
135 }
136
137 /* Get CVD version */
138 cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
139 if (!cvd_version) {
140 ALOGE("%s: Failed to allocate cvd version", __func__);
141 goto cleanup;
142 } else {
143 struct mixer_ctl *ctl = NULL;
144 int count = 0;
145
146 ctl = mixer_get_ctl_by_name(mixer, CVD_VERSION_MIXER_CTL);
147 if (!ctl) {
148 ALOGE("%s: Could not get ctl for mixer cmd - %s", __func__, CVD_VERSION_MIXER_CTL);
149 goto cleanup;
150 }
151 mixer_ctl_update(ctl);
152
153 count = mixer_ctl_get_num_values(ctl);
154 if (count > MAX_CVD_VERSION_STRING_SIZE)
155 count = MAX_CVD_VERSION_STRING_SIZE;
156
157 result = mixer_ctl_get_array(ctl, cvd_version, count);
158 if (result != 0) {
159 ALOGE("%s: ERROR! mixer_ctl_get_array() failed to get CVD Version", __func__);
160 goto cleanup;
161 }
162 }
163
164 /* Get Sound card name */
Aditya Bavanari71b6d532018-01-16 17:48:08 +0530165 snd_card_name = mixer_get_name(mixer);
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700166 if (!snd_card_name) {
167 ALOGE("failed to allocate memory for snd_card_name");
168 result = -1;
169 goto cleanup;
170 }
171
Aditya Bavanari71b6d532018-01-16 17:48:08 +0530172 snd_card_name = platform_get_snd_card_name_for_acdb_loader(snd_card_name);
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700173 int key = 0;
174 struct listnode *node = NULL;
175 struct meta_key_list *key_info = NULL;
Aditya Bavanari20fd7812017-10-03 20:10:35 +0530176 static bool acdb_instance_id_support = false;
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700177
Aditya Bavanari20fd7812017-10-03 20:10:35 +0530178 my_data->acdb_init_data.cvd_version = cvd_version;
179 my_data->acdb_init_data.snd_card_name = strdup(snd_card_name);
180 my_data->acdb_init_data.meta_key_list = &my_data->acdb_meta_key_list;
181 my_data->acdb_init_data.is_instance_id_supported = &acdb_instance_id_support;
182
183 if (my_data->acdb_init_v4) {
184 result = my_data->acdb_init_v4(&my_data->acdb_init_data, ACDB_LOADER_INIT_V4);
185 } else if (my_data->acdb_init_v3) {
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700186 result = my_data->acdb_init_v3(snd_card_name, cvd_version,
187 &my_data->acdb_meta_key_list);
188 } else if (my_data->acdb_init_v2) {
189 node = list_head(&my_data->acdb_meta_key_list);
190 key_info = node_to_item(node, struct meta_key_list, list);
191 key = key_info->cal_info.nKey;
192 result = my_data->acdb_init_v2(snd_card_name, cvd_version, key);
193 } else {
194 result = my_data->acdb_init();
195 }
Aditya Bavanari20fd7812017-10-03 20:10:35 +0530196 ALOGD("%s: ACDB Instance ID support after ACDB init:%d\n",
197 __func__, acdb_instance_id_support);
198 check_and_set_instance_id_support(mixer, acdb_instance_id_support);
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700199
200cleanup:
201 if (NULL != my_data) {
202 if (my_data->acdb_handle)
203 dlclose(my_data->acdb_handle);
204
Dhanalakshmi Siddani96eb5762017-12-11 11:56:46 +0530205 struct listnode *node = NULL;
206 struct meta_key_list *key_info = NULL;
207 struct listnode *tempnode = NULL;
208 list_for_each_safe(node, tempnode, &my_data->acdb_meta_key_list) {
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700209 key_info = node_to_item(node, struct meta_key_list, list);
Dhanalakshmi Siddani96eb5762017-12-11 11:56:46 +0530210 list_remove(node);
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700211 free(key_info);
212 }
213 free(my_data);
214 }
215
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700216 if (cvd_version)
217 free(cvd_version);
218
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700219 return result;
220}
221
222int acdb_set_metainfo_key(void *platform, char *name, int key) {
223
224 struct meta_key_list *key_info = (struct meta_key_list *)
225 calloc(1, sizeof(struct meta_key_list));
226 struct acdb_platform_data *pdata = (struct acdb_platform_data *)platform;
227 if (!key_info) {
228 ALOGE("%s: Could not allocate memory for key %d", __func__, key);
229 return -ENOMEM;
230 }
231
232 key_info->cal_info.nKey = key;
233 strlcpy(key_info->name, name, sizeof(key_info->name));
234 list_add_tail(&pdata->acdb_meta_key_list, &key_info->list);
235
236 ALOGD("%s: successfully added module %s and key %d to the list", __func__,
237 key_info->name, key_info->cal_info.nKey);
238
239 return 0;
240}