blob: 4ae03e9243c80417ef64d5df415e4a6186418b43 [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
31int acdb_init(int snd_card_num)
32{
33
34 int result = -1;
Vignesh Kulothungan55396882017-04-20 14:37:02 -070035 struct mixer *mixer = NULL;
Vignesh Kulothungan55396882017-04-20 14:37:02 -070036
37 if(snd_card_num < 0) {
38 ALOGE("invalid sound card number");
39 return result;
40 }
41
42 mixer = mixer_open(snd_card_num);
43 if (!mixer) {
44 ALOGE("%s: Unable to open the mixer card: %d", __func__,
45 snd_card_num);
Soumya Managolid4a9c962018-04-06 16:21:50 +053046 return result;
47 }
48 result = acdb_init_v2(mixer);
49 mixer_close(mixer);
50 return result;
51}
52
53int acdb_init_v2(struct mixer *mixer)
54{
55
56 int result = -1;
57 char *cvd_version = NULL;
58
59 const char *snd_card_name = NULL;
60 struct acdb_platform_data *my_data = NULL;
61
62 if (!mixer) {
63 ALOGE("Invalid mixer handle");
64 return result;
Vignesh Kulothungan55396882017-04-20 14:37:02 -070065 }
66
67 my_data = calloc(1, sizeof(struct acdb_platform_data));
68 if (!my_data) {
69 ALOGE("failed to allocate acdb platform data");
70 goto cleanup;
71 }
72
73 list_init(&my_data->acdb_meta_key_list);
74
75 /* Extract META KEY LIST INFO */
76 platform_info_init(PLATFORM_INFO_XML_PATH, my_data, ACDB_EXTN);
77
78 my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
79 if (my_data->acdb_handle == NULL) {
80 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
81 goto cleanup;
82 }
83
84 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
85
86 my_data->acdb_init_v3 = (acdb_init_v3_t)dlsym(my_data->acdb_handle,
87 "acdb_loader_init_v3");
88 if (my_data->acdb_init_v3 == NULL)
89 ALOGE("%s: dlsym error %s for acdb_loader_init_v3", __func__, dlerror());
90
91 my_data->acdb_init_v2 = (acdb_init_v2_t)dlsym(my_data->acdb_handle,
92 "acdb_loader_init_v2");
93 if (my_data->acdb_init_v2 == NULL)
94 ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
95
96 my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
97 "acdb_loader_init_ACDB");
98 if (my_data->acdb_init == NULL && my_data->acdb_init_v2 == NULL
99 && my_data->acdb_init_v3 == NULL) {
100 ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror());
101 goto cleanup;
102 }
103
104 /* Get CVD version */
105 cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
106 if (!cvd_version) {
107 ALOGE("%s: Failed to allocate cvd version", __func__);
108 goto cleanup;
109 } else {
110 struct mixer_ctl *ctl = NULL;
111 int count = 0;
112
113 ctl = mixer_get_ctl_by_name(mixer, CVD_VERSION_MIXER_CTL);
114 if (!ctl) {
115 ALOGE("%s: Could not get ctl for mixer cmd - %s", __func__, CVD_VERSION_MIXER_CTL);
116 goto cleanup;
117 }
118 mixer_ctl_update(ctl);
119
120 count = mixer_ctl_get_num_values(ctl);
121 if (count > MAX_CVD_VERSION_STRING_SIZE)
122 count = MAX_CVD_VERSION_STRING_SIZE;
123
124 result = mixer_ctl_get_array(ctl, cvd_version, count);
125 if (result != 0) {
126 ALOGE("%s: ERROR! mixer_ctl_get_array() failed to get CVD Version", __func__);
127 goto cleanup;
128 }
129 }
130
131 /* Get Sound card name */
Aditya Bavanari71b6d532018-01-16 17:48:08 +0530132 snd_card_name = mixer_get_name(mixer);
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700133 if (!snd_card_name) {
134 ALOGE("failed to allocate memory for snd_card_name");
135 result = -1;
136 goto cleanup;
137 }
138
Aditya Bavanari71b6d532018-01-16 17:48:08 +0530139 snd_card_name = platform_get_snd_card_name_for_acdb_loader(snd_card_name);
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700140 int key = 0;
141 struct listnode *node = NULL;
142 struct meta_key_list *key_info = NULL;
143
144 if (my_data->acdb_init_v3) {
145 result = my_data->acdb_init_v3(snd_card_name, cvd_version,
146 &my_data->acdb_meta_key_list);
147 } else if (my_data->acdb_init_v2) {
148 node = list_head(&my_data->acdb_meta_key_list);
149 key_info = node_to_item(node, struct meta_key_list, list);
150 key = key_info->cal_info.nKey;
151 result = my_data->acdb_init_v2(snd_card_name, cvd_version, key);
152 } else {
153 result = my_data->acdb_init();
154 }
155
156cleanup:
157 if (NULL != my_data) {
158 if (my_data->acdb_handle)
159 dlclose(my_data->acdb_handle);
160
Dhanalakshmi Siddani96eb5762017-12-11 11:56:46 +0530161 struct listnode *node = NULL;
162 struct meta_key_list *key_info = NULL;
163 struct listnode *tempnode = NULL;
164 list_for_each_safe(node, tempnode, &my_data->acdb_meta_key_list) {
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700165 key_info = node_to_item(node, struct meta_key_list, list);
Dhanalakshmi Siddani96eb5762017-12-11 11:56:46 +0530166 list_remove(node);
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700167 free(key_info);
168 }
169 free(my_data);
170 }
171
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700172 if (cvd_version)
173 free(cvd_version);
174
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700175 return result;
176}
177
178int acdb_set_metainfo_key(void *platform, char *name, int key) {
179
180 struct meta_key_list *key_info = (struct meta_key_list *)
181 calloc(1, sizeof(struct meta_key_list));
182 struct acdb_platform_data *pdata = (struct acdb_platform_data *)platform;
183 if (!key_info) {
184 ALOGE("%s: Could not allocate memory for key %d", __func__, key);
185 return -ENOMEM;
186 }
187
188 key_info->cal_info.nKey = key;
189 strlcpy(key_info->name, name, sizeof(key_info->name));
190 list_add_tail(&pdata->acdb_meta_key_list, &key_info->list);
191
192 ALOGD("%s: successfully added module %s and key %d to the list", __func__,
193 key_info->name, key_info->cal_info.nKey);
194
195 return 0;
196}