blob: cbb96bdf6d8f80a96c1c592088adbc6352fc1eee [file] [log] [blame]
Vignesh Kulothungan55396882017-04-20 14:37:02 -07001/*
2 * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
3 * 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;
35 char *cvd_version = NULL;
36
37 char *snd_card_name = NULL;
38 struct mixer *mixer = NULL;
39 struct acdb_platform_data *my_data = NULL;
40
41 if(snd_card_num < 0) {
42 ALOGE("invalid sound card number");
43 return result;
44 }
45
46 mixer = mixer_open(snd_card_num);
47 if (!mixer) {
48 ALOGE("%s: Unable to open the mixer card: %d", __func__,
49 snd_card_num);
50 goto cleanup;
51 }
52
53 my_data = calloc(1, sizeof(struct acdb_platform_data));
54 if (!my_data) {
55 ALOGE("failed to allocate acdb platform data");
56 goto cleanup;
57 }
58
59 list_init(&my_data->acdb_meta_key_list);
60
61 /* Extract META KEY LIST INFO */
62 platform_info_init(PLATFORM_INFO_XML_PATH, my_data, ACDB_EXTN);
63
64 my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
65 if (my_data->acdb_handle == NULL) {
66 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
67 goto cleanup;
68 }
69
70 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
71
72 my_data->acdb_init_v3 = (acdb_init_v3_t)dlsym(my_data->acdb_handle,
73 "acdb_loader_init_v3");
74 if (my_data->acdb_init_v3 == NULL)
75 ALOGE("%s: dlsym error %s for acdb_loader_init_v3", __func__, dlerror());
76
77 my_data->acdb_init_v2 = (acdb_init_v2_t)dlsym(my_data->acdb_handle,
78 "acdb_loader_init_v2");
79 if (my_data->acdb_init_v2 == NULL)
80 ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
81
82 my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
83 "acdb_loader_init_ACDB");
84 if (my_data->acdb_init == NULL && my_data->acdb_init_v2 == NULL
85 && my_data->acdb_init_v3 == NULL) {
86 ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror());
87 goto cleanup;
88 }
89
90 /* Get CVD version */
91 cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
92 if (!cvd_version) {
93 ALOGE("%s: Failed to allocate cvd version", __func__);
94 goto cleanup;
95 } else {
96 struct mixer_ctl *ctl = NULL;
97 int count = 0;
98
99 ctl = mixer_get_ctl_by_name(mixer, CVD_VERSION_MIXER_CTL);
100 if (!ctl) {
101 ALOGE("%s: Could not get ctl for mixer cmd - %s", __func__, CVD_VERSION_MIXER_CTL);
102 goto cleanup;
103 }
104 mixer_ctl_update(ctl);
105
106 count = mixer_ctl_get_num_values(ctl);
107 if (count > MAX_CVD_VERSION_STRING_SIZE)
108 count = MAX_CVD_VERSION_STRING_SIZE;
109
110 result = mixer_ctl_get_array(ctl, cvd_version, count);
111 if (result != 0) {
112 ALOGE("%s: ERROR! mixer_ctl_get_array() failed to get CVD Version", __func__);
113 goto cleanup;
114 }
115 }
116
117 /* Get Sound card name */
118 snd_card_name = strdup(mixer_get_name(mixer));
119 if (!snd_card_name) {
120 ALOGE("failed to allocate memory for snd_card_name");
121 result = -1;
122 goto cleanup;
123 }
124
125 int key = 0;
126 struct listnode *node = NULL;
127 struct meta_key_list *key_info = NULL;
128
129 if (my_data->acdb_init_v3) {
130 result = my_data->acdb_init_v3(snd_card_name, cvd_version,
131 &my_data->acdb_meta_key_list);
132 } else if (my_data->acdb_init_v2) {
133 node = list_head(&my_data->acdb_meta_key_list);
134 key_info = node_to_item(node, struct meta_key_list, list);
135 key = key_info->cal_info.nKey;
136 result = my_data->acdb_init_v2(snd_card_name, cvd_version, key);
137 } else {
138 result = my_data->acdb_init();
139 }
140
141cleanup:
142 if (NULL != my_data) {
143 if (my_data->acdb_handle)
144 dlclose(my_data->acdb_handle);
145
146 struct listnode *node;
147 struct meta_key_list *key_info;
148 list_for_each(node, &my_data->acdb_meta_key_list) {
149 key_info = node_to_item(node, struct meta_key_list, list);
150 free(key_info);
151 }
152 free(my_data);
153 }
154
155 if (mixer)
156 mixer_close(mixer);
157
158 if (cvd_version)
159 free(cvd_version);
160
161 if (snd_card_name)
162 free(snd_card_name);
163
164 return result;
165}
166
167int acdb_set_metainfo_key(void *platform, char *name, int key) {
168
169 struct meta_key_list *key_info = (struct meta_key_list *)
170 calloc(1, sizeof(struct meta_key_list));
171 struct acdb_platform_data *pdata = (struct acdb_platform_data *)platform;
172 if (!key_info) {
173 ALOGE("%s: Could not allocate memory for key %d", __func__, key);
174 return -ENOMEM;
175 }
176
177 key_info->cal_info.nKey = key;
178 strlcpy(key_info->name, name, sizeof(key_info->name));
179 list_add_tail(&pdata->acdb_meta_key_list, &key_info->list);
180
181 ALOGD("%s: successfully added module %s and key %d to the list", __func__,
182 key_info->name, key_info->cal_info.nKey);
183
184 return 0;
185}