blob: 1614cc951ade2d610a93678cad63ba0ea337c284 [file] [log] [blame]
vivek mehta0fb11312017-05-15 19:35:32 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "audio_hw_acdb"
18//#define LOG_NDEBUG 0
19#define LOG_NDDEBUG 0
20
21#include <stdlib.h>
22#include <stdbool.h>
23#include <dlfcn.h>
24#include <cutils/log.h>
25#include <cutils/str_parms.h>
26#include <system/audio.h>
27#include <tinyalsa/asoundlib.h>
28#include "acdb.h"
29#include <platform_api.h>
30
31#define PLATFORM_CONFIG_KEY_SOUNDCARD_NAME "snd_card_name"
32#define PLATFORM_INFO_XML_PATH "audio_platform_info.xml"
33
34int acdb_init(int snd_card_num)
35{
36
37 int result = -1;
38 char *cvd_version = NULL;
39
40 char *snd_card_name = NULL;
41 struct mixer *mixer = NULL;
42 struct acdb_platform_data *my_data = NULL;
43
44 if(snd_card_num < 0) {
45 ALOGE("invalid sound card number");
46 return result;
47 }
48
49 mixer = mixer_open(snd_card_num);
50 if (!mixer) {
51 ALOGE("%s: Unable to open the mixer card: %d", __func__,
52 snd_card_num);
53 goto cleanup;
54 }
55
56 my_data = calloc(1, sizeof(struct acdb_platform_data));
57 if (!my_data) {
58 ALOGE("failed to allocate acdb platform data");
59 goto cleanup;
60 }
61
62 list_init(&my_data->acdb_meta_key_list);
63
64 /* Extract META KEY LIST INFO */
65 //platform_info_init(PLATFORM_INFO_XML_PATH, my_data);
66
67 my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
68 if (my_data->acdb_handle == NULL) {
69 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
70 goto cleanup;
71 }
72
73 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
74
75 my_data->acdb_init_v3 = (acdb_init_v3_t)dlsym(my_data->acdb_handle,
76 "acdb_loader_init_v3");
77 if (my_data->acdb_init_v3 == NULL)
78 ALOGE("%s: dlsym error %s for acdb_loader_init_v3", __func__, dlerror());
79
80 my_data->acdb_init_v2 = (acdb_init_v2_cvd_t)dlsym(my_data->acdb_handle,
81 "acdb_loader_init_v2");
82 if (my_data->acdb_init_v2 == NULL)
83 ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
84
85 my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
86 "acdb_loader_init_ACDB");
87 if (my_data->acdb_init == NULL && my_data->acdb_init_v2 == NULL
88 && my_data->acdb_init_v3 == NULL) {
89 ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror());
90 goto cleanup;
91 }
92
93 /* Get CVD version */
94 cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
95 if (!cvd_version) {
96 ALOGE("%s: Failed to allocate cvd version", __func__);
97 goto cleanup;
98 } else {
99 struct mixer_ctl *ctl = NULL;
100 int count = 0;
101
102 ctl = mixer_get_ctl_by_name(mixer, CVD_VERSION_MIXER_CTL);
103 if (!ctl) {
104 ALOGE("%s: Could not get ctl for mixer cmd - %s", __func__, CVD_VERSION_MIXER_CTL);
105 goto cleanup;
106 }
107 mixer_ctl_update(ctl);
108
109 count = mixer_ctl_get_num_values(ctl);
110 if (count > MAX_CVD_VERSION_STRING_SIZE)
111 count = MAX_CVD_VERSION_STRING_SIZE;
112
113 result = mixer_ctl_get_array(ctl, cvd_version, count);
114 if (result != 0) {
115 ALOGE("%s: ERROR! mixer_ctl_get_array() failed to get CVD Version", __func__);
116 goto cleanup;
117 }
118 }
119
120 /* Get Sound card name */
121 snd_card_name = strdup(mixer_get_name(mixer));
122 if (!snd_card_name) {
123 ALOGE("failed to allocate memory for snd_card_name");
124 result = -1;
125 goto cleanup;
126 }
127
128 int key = 0;
129 struct listnode *node = NULL;
130 struct meta_key_list *key_info = NULL;
131
132 if (my_data->acdb_init_v3) {
133 result = my_data->acdb_init_v3(snd_card_name, cvd_version,
134 &my_data->acdb_meta_key_list);
135 } else if (my_data->acdb_init_v2) {
136 node = list_head(&my_data->acdb_meta_key_list);
137 key_info = node_to_item(node, struct meta_key_list, list);
138 key = key_info->cal_info.nKey;
139 result = my_data->acdb_init_v2(snd_card_name, cvd_version, key);
140 } else {
141 result = my_data->acdb_init();
142 }
143
144cleanup:
145 if (NULL != my_data) {
146 if (my_data->acdb_handle)
147 dlclose(my_data->acdb_handle);
148
149 struct listnode *node;
150 struct meta_key_list *key_info;
151 list_for_each(node, &my_data->acdb_meta_key_list) {
152 key_info = node_to_item(node, struct meta_key_list, list);
153 free(key_info);
154 }
155 free(my_data);
156 }
157
158 mixer_close(mixer);
159 free(cvd_version);
160 free(snd_card_name);
161
162 return result;
163}
164
165int acdb_set_metainfo_key(void *platform, char *name, int key) {
166
167 struct meta_key_list *key_info = (struct meta_key_list *)
168 calloc(1, sizeof(struct meta_key_list));
169 struct acdb_platform_data *pdata = (struct acdb_platform_data *)platform;
170 if (!key_info) {
171 ALOGE("%s: Could not allocate memory for key %d", __func__, key);
172 return -ENOMEM;
173 }
174
175 key_info->cal_info.nKey = key;
176 strlcpy(key_info->name, name, sizeof(key_info->name));
177 list_add_tail(&pdata->acdb_meta_key_list, &key_info->list);
178
179 ALOGD("%s: successfully added module %s and key %d to the list", __func__,
180 key_info->name, key_info->cal_info.nKey);
181
182 return 0;
183}
184
185int acdb_set_parameters(void *platform, struct str_parms *parms)
186{
187 struct acdb_platform_data *my_data = (struct acdb_platform_data *)platform;
188 char value[128];
189 char *kv_pairs = str_parms_to_str(parms);
190 int ret = 0;
191
192 if (kv_pairs == NULL) {
193 ret = -EINVAL;
194 ALOGE("%s: key-value pair is NULL",__func__);
195 goto done;
196 }
197
198 ret = str_parms_get_str(parms, PLATFORM_CONFIG_KEY_SOUNDCARD_NAME,
199 value, sizeof(value));
200 if (ret >= 0) {
201 str_parms_del(parms, PLATFORM_CONFIG_KEY_SOUNDCARD_NAME);
202 my_data->snd_card_name = strdup(value);
203 ALOGV("%s: sound card name %s", __func__, my_data->snd_card_name);
204 }
205
206done:
207 free(kv_pairs);
208
209 return ret;
210}