blob: f8a78d8b921259d62e6c826c44b287ac4f64020a [file] [log] [blame]
Ben Romberger55886882014-01-10 13:49:02 -08001/*
Aalique Grahame22e49102018-12-18 14:23:57 -08002 * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
Ben Romberger55886882014-01-10 13:49:02 -08003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
Ben Romberger61764e32014-01-10 13:49:02 -080030#define LOG_TAG "platform_info"
Ben Romberger55886882014-01-10 13:49:02 -080031#define LOG_NDDEBUG 0
32
33#include <errno.h>
34#include <stdio.h>
35#include <expat.h>
Aalique Grahame22e49102018-12-18 14:23:57 -080036#include <log/log.h>
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -070037#include <cutils/str_parms.h>
Ben Romberger55886882014-01-10 13:49:02 -080038#include <audio_hw.h>
Vignesh Kulothungan55396882017-04-20 14:37:02 -070039#include "acdb.h"
Ben Romberger61764e32014-01-10 13:49:02 -080040#include "platform_api.h"
41#include <platform.h>
Aniket Kumar Lataf56b6402016-10-27 12:03:18 -070042#include <math.h>
Ben Romberger55886882014-01-10 13:49:02 -080043
Revathi Uddaraju1eac8b02017-05-18 17:13:33 +053044#ifdef DYNAMIC_LOG_ENABLED
45#include <log_xml_parser.h>
46#define LOG_MASK HAL_MOD_FILE_PLATFORM_INFO
47#include <log_utils.h>
48#endif
49
Ben Romberger55886882014-01-10 13:49:02 -080050#define BUF_SIZE 1024
51
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -070052typedef enum {
53 ROOT,
54 ACDB,
Vikram Pandurangadf59cae2017-08-03 18:04:55 -070055 MODULE,
56 AEC,
57 NS,
Amit Shekhar5a39c912014-10-14 15:39:30 -070058 BITWIDTH,
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -070059 PCM_ID,
60 BACKEND_NAME,
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -080061 INTERFACE_NAME,
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -070062 CONFIG_PARAMS,
Aalique Grahame22e49102018-12-18 14:23:57 -080063 OPERATOR_SPECIFIC,
Aniket Kumar Lataf56b6402016-10-27 12:03:18 -070064 GAIN_LEVEL_MAPPING,
Aalique Grahame22e49102018-12-18 14:23:57 -080065 APP_TYPE,
Dhanalakshmi Siddani21be3ac2016-12-29 14:31:08 +053066 ACDB_METAINFO_KEY,
Naresh Tannirudcb47c52018-06-25 16:23:32 +053067 MICROPHONE_CHARACTERISTIC,
68 SND_DEVICES,
69 INPUT_SND_DEVICE,
70 INPUT_SND_DEVICE_TO_MIC_MAPPING,
71 SND_DEV,
72 MIC_INFO,
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -070073} section_t;
74
75typedef void (* section_process_fn)(const XML_Char **attr);
76
77static void process_acdb_id(const XML_Char **attr);
Vikram Pandurangadf59cae2017-08-03 18:04:55 -070078static void process_audio_effect(const XML_Char **attr, effect_type_t effect_type);
79static void process_effect_aec(const XML_Char **attr);
80static void process_effect_ns(const XML_Char **attr);
Amit Shekhar5a39c912014-10-14 15:39:30 -070081static void process_bit_width(const XML_Char **attr);
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -070082static void process_pcm_id(const XML_Char **attr);
83static void process_backend_name(const XML_Char **attr);
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -080084static void process_interface_name(const XML_Char **attr);
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -070085static void process_config_params(const XML_Char **attr);
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -070086static void process_root(const XML_Char **attr);
Aalique Grahame22e49102018-12-18 14:23:57 -080087static void process_operator_specific(const XML_Char **attr);
Aniket Kumar Lataf56b6402016-10-27 12:03:18 -070088static void process_gain_db_to_level_map(const XML_Char **attr);
Aalique Grahame22e49102018-12-18 14:23:57 -080089static void process_app_type(const XML_Char **attr);
Dhanalakshmi Siddani21be3ac2016-12-29 14:31:08 +053090static void process_acdb_metainfo_key(const XML_Char **attr);
Naresh Tannirudcb47c52018-06-25 16:23:32 +053091static void process_microphone_characteristic(const XML_Char **attr);
92static void process_snd_dev(const XML_Char **attr);
93static void process_mic_info(const XML_Char **attr);
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -070094
95static section_process_fn section_table[] = {
96 [ROOT] = process_root,
97 [ACDB] = process_acdb_id,
Vikram Pandurangadf59cae2017-08-03 18:04:55 -070098 [AEC] = process_effect_aec,
99 [NS] = process_effect_ns,
Amit Shekhar5a39c912014-10-14 15:39:30 -0700100 [BITWIDTH] = process_bit_width,
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700101 [PCM_ID] = process_pcm_id,
102 [BACKEND_NAME] = process_backend_name,
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -0800103 [INTERFACE_NAME] = process_interface_name,
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -0700104 [CONFIG_PARAMS] = process_config_params,
Aalique Grahame22e49102018-12-18 14:23:57 -0800105 [OPERATOR_SPECIFIC] = process_operator_specific,
106 [APP_TYPE] = process_app_type,
Aniket Kumar Lataf56b6402016-10-27 12:03:18 -0700107 [GAIN_LEVEL_MAPPING] = process_gain_db_to_level_map,
Dhanalakshmi Siddani21be3ac2016-12-29 14:31:08 +0530108 [ACDB_METAINFO_KEY] = process_acdb_metainfo_key,
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530109 [MICROPHONE_CHARACTERISTIC] = process_microphone_characteristic,
110 [SND_DEV] = process_snd_dev,
111 [MIC_INFO] = process_mic_info,
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700112};
113
114static section_t section;
115
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -0700116struct platform_info {
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700117 caller_t caller;
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -0700118 void *platform;
119 struct str_parms *kvpairs;
120};
121
122static struct platform_info my_data;
123
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530124
125struct audio_string_to_enum {
126 const char* name;
127 unsigned int value;
128};
129
130static snd_device_t in_snd_device;
131
132static const struct audio_string_to_enum mic_locations[AUDIO_MICROPHONE_LOCATION_CNT] = {
133 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_LOCATION_UNKNOWN),
134 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_LOCATION_MAINBODY),
135 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_LOCATION_MAINBODY_MOVABLE),
136 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_LOCATION_PERIPHERAL),
137};
138
139static const struct audio_string_to_enum mic_directionalities[AUDIO_MICROPHONE_DIRECTIONALITY_CNT] = {
140 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_OMNI),
141 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_BI_DIRECTIONAL),
142 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_UNKNOWN),
143 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_CARDIOID),
144 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_HYPER_CARDIOID),
145 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_SUPER_CARDIOID),
146};
147
148static const struct audio_string_to_enum mic_channel_mapping[AUDIO_MICROPHONE_CHANNEL_MAPPING_CNT] = {
149 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED),
150 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT),
151 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED),
152};
153
154static const struct audio_string_to_enum device_in_types[] = {
155 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_AMBIENT),
156 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_COMMUNICATION),
157 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC),
158 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
159 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET),
160 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL),
161 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_HDMI),
162 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_VOICE_CALL),
163 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_TELEPHONY_RX),
164 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BACK_MIC),
165 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX),
166 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET),
167 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET),
168 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY),
169 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_DEVICE),
170 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_FM_TUNER),
171 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_TV_TUNER),
172 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_LINE),
173 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_SPDIF),
174 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_A2DP),
175 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_LOOPBACK),
176 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_IP),
177 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BUS),
178 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_PROXY),
179 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_HEADSET),
180 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_BLE),
181 AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_DEFAULT),
182};
183
184enum {
185 AUDIO_MICROPHONE_CHARACTERISTIC_NONE = 0u, // 0x0
186 AUDIO_MICROPHONE_CHARACTERISTIC_SENSITIVITY = 1u, // 0x1
187 AUDIO_MICROPHONE_CHARACTERISTIC_MAX_SPL = 2u, // 0x2
188 AUDIO_MICROPHONE_CHARACTERISTIC_MIN_SPL = 4u, // 0x4
189 AUDIO_MICROPHONE_CHARACTERISTIC_ORIENTATION = 8u, // 0x8
190 AUDIO_MICROPHONE_CHARACTERISTIC_GEOMETRIC_LOCATION = 16u, // 0x10
191 AUDIO_MICROPHONE_CHARACTERISTIC_ALL = 31u, /* ((((SENSITIVITY | MAX_SPL) | MIN_SPL)
192 | ORIENTATION) | GEOMETRIC_LOCATION) */
193};
194
195static bool find_enum_by_string(const struct audio_string_to_enum * table, const char * name,
196 int32_t len, unsigned int *value)
197{
198 if (table == NULL) {
199 ALOGE("%s: table is NULL", __func__);
200 return false;
201 }
202
203 if (name == NULL) {
204 ALOGE("null key");
205 return false;
206 }
207
208 for (int i = 0; i < len; i++) {
209 if (!strcmp(table[i].name, name)) {
210 *value = table[i].value;
211 return true;
212 }
213 }
214 return false;
215}
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700216/*
217 * <audio_platform_info>
218 * <acdb_ids>
219 * <device name="???" acdb_id="???"/>
220 * ...
221 * ...
222 * </acdb_ids>
Vikram Pandurangadf59cae2017-08-03 18:04:55 -0700223 * <module_ids>
224 * <device name="???" module_id="???"/>
225 * ...
226 * ...
227 * </module_ids>
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700228 * <backend_names>
229 * <device name="???" backend="???"/>
230 * ...
231 * ...
232 * </backend_names>
233 * <pcm_ids>
234 * <usecase name="???" type="in/out" id="???"/>
235 * ...
236 * ...
237 * </pcm_ids>
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -0800238 * <interface_names>
Karthik Reddy Katta508eca42015-05-11 13:43:18 +0530239 * <device name="Use audio device name here, not sound device name" interface="PRIMARY_I2S" codec_type="external/internal"/>
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -0800240 * ...
241 * ...
242 * </interface_names>
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -0700243 * <config_params>
244 * <param key="snd_card_name" value="msm8994-tomtom-mtp-snd-card"/>
Aalique Grahame22e49102018-12-18 14:23:57 -0800245 * <param key="operator_info" value="tmus;aa;bb;cc"/>
246 * <param key="operator_info" value="sprint;xx;yy;zz"/>
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -0700247 * ...
248 * ...
249 * </config_params>
Aalique Grahame22e49102018-12-18 14:23:57 -0800250 *
251 * <operator_specific>
252 * <device name="???" operator="???" mixer_path="???" acdb_id="???"/>
253 * ...
254 * ...
255 * </operator_specific>
256 *
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700257 * </audio_platform_info>
258 */
259
260static void process_root(const XML_Char **attr __unused)
261{
262}
263
264/* mapping from usecase to pcm dev id */
265static void process_pcm_id(const XML_Char **attr)
266{
267 int index;
268
269 if (strcmp(attr[0], "name") != 0) {
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -0700270 ALOGE("%s: 'name' not found, no pcm_id set!", __func__);
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700271 goto done;
272 }
273
274 index = platform_get_usecase_index((char *)attr[1]);
275 if (index < 0) {
276 ALOGE("%s: usecase %s not found!",
277 __func__, attr[1]);
278 goto done;
279 }
280
281 if (strcmp(attr[2], "type") != 0) {
282 ALOGE("%s: usecase type not mentioned", __func__);
283 goto done;
284 }
285
286 int type = -1;
287
288 if (!strcasecmp((char *)attr[3], "in")) {
289 type = 1;
290 } else if (!strcasecmp((char *)attr[3], "out")) {
291 type = 0;
292 } else {
293 ALOGE("%s: type must be IN or OUT", __func__);
294 goto done;
295 }
296
297 if (strcmp(attr[4], "id") != 0) {
298 ALOGE("%s: usecase id not mentioned", __func__);
299 goto done;
300 }
301
302 int id = atoi((char *)attr[5]);
303
304 if (platform_set_usecase_pcm_id(index, type, id) < 0) {
305 ALOGE("%s: usecase %s type %d id %d was not set!",
306 __func__, attr[1], type, id);
307 goto done;
308 }
309
310done:
311 return;
312}
313
314/* backend to be used for a device */
315static void process_backend_name(const XML_Char **attr)
316{
317 int index;
Sidipotu Ashok9f0b16e2016-04-28 13:48:28 +0530318 char *hw_interface = NULL;
Ashish Jaind150d4c2017-02-03 18:44:34 +0530319 char *backend = NULL;
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700320
321 if (strcmp(attr[0], "name") != 0) {
322 ALOGE("%s: 'name' not found, no ACDB ID set!", __func__);
323 goto done;
324 }
325
326 index = platform_get_snd_device_index((char *)attr[1]);
327 if (index < 0) {
328 ALOGE("%s: Device %s not found, no ACDB ID set!",
329 __func__, attr[1]);
330 goto done;
331 }
332
333 if (strcmp(attr[2], "backend") != 0) {
Ashish Jaind150d4c2017-02-03 18:44:34 +0530334 if (strcmp(attr[2], "interface") == 0)
335 hw_interface = (char *)attr[3];
336 } else {
337 backend = (char *)attr[3];
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700338 }
339
Sidipotu Ashok9f0b16e2016-04-28 13:48:28 +0530340 if (attr[4] != NULL) {
341 if (strcmp(attr[4], "interface") != 0) {
342 hw_interface = NULL;
343 } else {
344 hw_interface = (char *)attr[5];
345 }
346 }
347
Ashish Jaind150d4c2017-02-03 18:44:34 +0530348 if (platform_set_snd_device_backend(index, backend, hw_interface) < 0) {
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700349 ALOGE("%s: Device %s backend %s was not set!",
350 __func__, attr[1], attr[3]);
351 goto done;
352 }
353
354done:
355 return;
356}
357
Aniket Kumar Lataf56b6402016-10-27 12:03:18 -0700358static void process_gain_db_to_level_map(const XML_Char **attr)
359{
360 struct amp_db_and_gain_table tbl_entry;
361
362 if ((strcmp(attr[0], "db") != 0) ||
363 (strcmp(attr[2], "level") != 0)) {
364 ALOGE("%s: invalid attribute passed %s %sexpected amp db level",
365 __func__, attr[0], attr[2]);
366 goto done;
367 }
368
369 tbl_entry.db = atof(attr[1]);
370 tbl_entry.amp = exp(tbl_entry.db * 0.115129f);
371 tbl_entry.level = atoi(attr[3]);
372
Aalique Grahame22e49102018-12-18 14:23:57 -0800373 //custome level should be > 0. Level 0 is fixed for default
374 CHECK(tbl_entry.level > 0);
375
Aniket Kumar Lataf56b6402016-10-27 12:03:18 -0700376 ALOGV("%s: amp [%f] db [%f] level [%d]", __func__,
377 tbl_entry.amp, tbl_entry.db, tbl_entry.level);
378 platform_add_gain_level_mapping(&tbl_entry);
379
380done:
381 return;
382}
383
384
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700385static void process_acdb_id(const XML_Char **attr)
Ben Romberger55886882014-01-10 13:49:02 -0800386{
Ben Romberger61764e32014-01-10 13:49:02 -0800387 int index;
Ben Romberger55886882014-01-10 13:49:02 -0800388
Ben Romberger61764e32014-01-10 13:49:02 -0800389 if (strcmp(attr[0], "name") != 0) {
390 ALOGE("%s: 'name' not found, no ACDB ID set!", __func__);
Ben Romberger55886882014-01-10 13:49:02 -0800391 goto done;
Ben Romberger61764e32014-01-10 13:49:02 -0800392 }
Ben Romberger55886882014-01-10 13:49:02 -0800393
Ben Romberger61764e32014-01-10 13:49:02 -0800394 index = platform_get_snd_device_index((char *)attr[1]);
395 if (index < 0) {
Helen Zeng6a16ad72014-02-23 22:04:44 -0800396 ALOGE("%s: Device %s in platform info xml not found, no ACDB ID set!",
397 __func__, attr[1]);
Ben Romberger55886882014-01-10 13:49:02 -0800398 goto done;
399 }
400
401 if (strcmp(attr[2], "acdb_id") != 0) {
Helen Zeng6a16ad72014-02-23 22:04:44 -0800402 ALOGE("%s: Device %s in platform info xml has no acdb_id, no ACDB ID set!",
403 __func__, attr[1]);
Ben Romberger55886882014-01-10 13:49:02 -0800404 goto done;
405 }
406
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700407 if (platform_set_snd_device_acdb_id(index, atoi((char *)attr[3])) < 0) {
408 ALOGE("%s: Device %s, ACDB ID %d was not set!",
Helen Zeng6a16ad72014-02-23 22:04:44 -0800409 __func__, attr[1], atoi((char *)attr[3]));
Ben Romberger55886882014-01-10 13:49:02 -0800410 goto done;
Ben Romberger61764e32014-01-10 13:49:02 -0800411 }
Ben Romberger55886882014-01-10 13:49:02 -0800412
Ben Romberger55886882014-01-10 13:49:02 -0800413done:
414 return;
415}
416
Aalique Grahame22e49102018-12-18 14:23:57 -0800417static void process_operator_specific(const XML_Char **attr)
418{
419 snd_device_t snd_device = SND_DEVICE_NONE;
420
421 if (strcmp(attr[0], "name") != 0) {
422 ALOGE("%s: 'name' not found", __func__);
423 goto done;
424 }
425
426 snd_device = platform_get_snd_device_index((char *)attr[1]);
427 if (snd_device < 0) {
428 ALOGE("%s: Device %s in %s not found, no ACDB ID set!",
429 __func__, (char *)attr[3], PLATFORM_INFO_XML_PATH);
430 goto done;
431 }
432
433 if (strcmp(attr[2], "operator") != 0) {
434 ALOGE("%s: 'operator' not found", __func__);
435 goto done;
436 }
437
438 if (strcmp(attr[4], "mixer_path") != 0) {
439 ALOGE("%s: 'mixer_path' not found", __func__);
440 goto done;
441 }
442
443 if (strcmp(attr[6], "acdb_id") != 0) {
444 ALOGE("%s: 'acdb_id' not found", __func__);
445 goto done;
446 }
447
448 platform_add_operator_specific_device(snd_device, (char *)attr[3], (char *)attr[5], atoi((char *)attr[7]));
449
450done:
451 return;
452}
453
Vikram Pandurangadf59cae2017-08-03 18:04:55 -0700454static void process_audio_effect(const XML_Char **attr, effect_type_t effect_type)
455{
456 int index;
457 struct audio_effect_config effect_config;
458
459 if (strcmp(attr[0], "name") != 0) {
460 ALOGE("%s: 'name' not found, no MODULE ID set!", __func__);
461 goto done;
462 }
463
464 index = platform_get_snd_device_index((char *)attr[1]);
465 if (index < 0) {
466 ALOGE("%s: Device %s in platform info xml not found, no MODULE ID set!",
467 __func__, attr[1]);
468 goto done;
469 }
470
471 if (strcmp(attr[2], "module_id") != 0) {
472 ALOGE("%s: Device %s in platform info xml has no module_id, no MODULE ID set!",
473 __func__, attr[2]);
474 goto done;
475 }
476
477 if (strcmp(attr[4], "instance_id") != 0) {
478 ALOGE("%s: Device %s in platform info xml has no instance_id, no INSTANCE ID set!",
479 __func__, attr[4]);
480 goto done;
481 }
482
483 if (strcmp(attr[6], "param_id") != 0) {
484 ALOGE("%s: Device %s in platform info xml has no param_id, no PARAM ID set!",
485 __func__, attr[6]);
486 goto done;
487 }
488
489 if (strcmp(attr[8], "param_value") != 0) {
490 ALOGE("%s: Device %s in platform info xml has no param_value, no PARAM VALUE set!",
491 __func__, attr[8]);
492 goto done;
493 }
494
495 effect_config = (struct audio_effect_config){strtol((char *)attr[3], NULL, 0),
496 strtol((char *)attr[5], NULL, 0),
497 strtol((char *)attr[7], NULL, 0),
498 strtol((char *)attr[9], NULL, 0)};
499
500
501 if (platform_set_effect_config_data(index, effect_config, effect_type) < 0) {
502 ALOGE("%s: Effect = %d Device %s, MODULE/INSTANCE/PARAM ID %lu %lu %lu %lu was not set!",
503 __func__, effect_type, attr[1], strtol((char *)attr[3], NULL, 0),
504 strtol((char *)attr[5], NULL, 0), strtol((char *)attr[7], NULL, 0),
505 strtol((char *)attr[9], NULL, 0));
506 goto done;
507 }
508
509done:
510 return;
511}
512
513static void process_effect_aec(const XML_Char **attr)
514{
515 process_audio_effect(attr, EFFECT_AEC);
516 return;
517}
518
519static void process_effect_ns(const XML_Char **attr)
520{
521 process_audio_effect(attr, EFFECT_NS);
522 return;
523}
524
Amit Shekhar5a39c912014-10-14 15:39:30 -0700525static void process_bit_width(const XML_Char **attr)
526{
527 int index;
528
529 if (strcmp(attr[0], "name") != 0) {
530 ALOGE("%s: 'name' not found, no ACDB ID set!", __func__);
531 goto done;
532 }
533
534 index = platform_get_snd_device_index((char *)attr[1]);
535 if (index < 0) {
536 ALOGE("%s: Device %s in platform info xml not found, no ACDB ID set!",
537 __func__, attr[1]);
538 goto done;
539 }
540
541 if (strcmp(attr[2], "bit_width") != 0) {
542 ALOGE("%s: Device %s in platform info xml has no bit_width, no ACDB ID set!",
543 __func__, attr[1]);
544 goto done;
545 }
546
547 if (platform_set_snd_device_bit_width(index, atoi((char *)attr[3])) < 0) {
548 ALOGE("%s: Device %s, ACDB ID %d was not set!",
549 __func__, attr[1], atoi((char *)attr[3]));
550 goto done;
551 }
552
553done:
554 return;
555}
556
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -0800557static void process_interface_name(const XML_Char **attr)
558{
559 int ret;
560
561 if (strcmp(attr[0], "name") != 0) {
562 ALOGE("%s: 'name' not found, no Audio Interface set!", __func__);
563
564 goto done;
565 }
566
567 if (strcmp(attr[2], "interface") != 0) {
568 ALOGE("%s: Device %s has no Audio Interface set!",
569 __func__, attr[1]);
570
571 goto done;
572 }
573
Karthik Reddy Katta508eca42015-05-11 13:43:18 +0530574 if (strcmp(attr[4], "codec_type") != 0) {
575 ALOGE("%s: Device %s has no codec type set!",
576 __func__, attr[1]);
577
578 goto done;
579 }
580
581 ret = platform_set_audio_device_interface((char *)attr[1], (char *)attr[3],
582 (char *)attr[5]);
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -0800583 if (ret < 0) {
584 ALOGE("%s: Audio Interface not set!", __func__);
Apoorv Raghuvanshi21492162015-02-19 18:19:36 -0800585 goto done;
586 }
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -0800587
Apoorv Raghuvanshi21492162015-02-19 18:19:36 -0800588done:
589 return;
590}
Laxminath Kasam44f49402015-05-29 18:37:11 +0530591
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -0700592static void process_config_params(const XML_Char **attr)
593{
594 if (strcmp(attr[0], "key") != 0) {
595 ALOGE("%s: 'key' not found", __func__);
596 goto done;
597 }
598
599 if (strcmp(attr[2], "value") != 0) {
600 ALOGE("%s: 'value' not found", __func__);
601 goto done;
602 }
603
604 str_parms_add_str(my_data.kvpairs, (char*)attr[1], (char*)attr[3]);
605done:
606 return;
607}
608
Aalique Grahame22e49102018-12-18 14:23:57 -0800609static void process_app_type(const XML_Char **attr)
610{
611 if (strcmp(attr[0], "uc_type")) {
612 ALOGE("%s: uc_type not found", __func__);
613 goto done;
614 }
615
616 if (strcmp(attr[2], "mode")) {
617 ALOGE("%s: mode not found", __func__);
618 goto done;
619 }
620
621 if (strcmp(attr[4], "bit_width")) {
622 ALOGE("%s: bit_width not found", __func__);
623 goto done;
624 }
625
626 if (strcmp(attr[6], "id")) {
627 ALOGE("%s: id not found", __func__);
628 goto done;
629 }
630
631 if (strcmp(attr[8], "max_rate")) {
632 ALOGE("%s: max rate not found", __func__);
633 goto done;
634 }
635
636 platform_add_app_type(attr[1], attr[3], atoi(attr[5]), atoi(attr[7]),
637 atoi(attr[9]));
638done:
639 return;
640}
641
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530642static void process_microphone_characteristic(const XML_Char **attr) {
643 struct audio_microphone_characteristic_t microphone;
644 uint32_t curIdx = 0;
645
646 if (strcmp(attr[curIdx++], "valid_mask")) {
647 ALOGE("%s: valid_mask not found", __func__);
648 goto done;
649 }
650 uint32_t valid_mask = atoi(attr[curIdx++]);
651
652 if (strcmp(attr[curIdx++], "device_id")) {
653 ALOGE("%s: device_id not found", __func__);
654 goto done;
655 }
656 if (strlen(attr[curIdx]) > AUDIO_MICROPHONE_ID_MAX_LEN) {
657 ALOGE("%s: device_id %s is too long", __func__, attr[curIdx]);
658 goto done;
659 }
Ramjee Singh83e1eb12018-07-11 16:22:46 +0530660 strlcpy(microphone.device_id, attr[curIdx++], sizeof(microphone.device_id));
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530661
662 if (strcmp(attr[curIdx++], "type")) {
663 ALOGE("%s: device not found", __func__);
664 goto done;
665 }
666 if (!find_enum_by_string(device_in_types, (char*)attr[curIdx++],
667 ARRAY_SIZE(device_in_types), &microphone.device)) {
668 ALOGE("%s: type %s in %s not found!",
669 __func__, attr[--curIdx], PLATFORM_INFO_XML_PATH);
670 goto done;
671 }
672
673 if (strcmp(attr[curIdx++], "address")) {
674 ALOGE("%s: address not found", __func__);
675 goto done;
676 }
677 if (strlen(attr[curIdx]) > AUDIO_DEVICE_MAX_ADDRESS_LEN) {
678 ALOGE("%s, address %s is too long", __func__, attr[curIdx]);
679 goto done;
680 }
Ramjee Singh83e1eb12018-07-11 16:22:46 +0530681 strlcpy(microphone.address, attr[curIdx++], sizeof(microphone.address));
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530682 if (strlen(microphone.address) == 0) {
683 // If the address is empty, populate the address according to device type.
684 if (microphone.device == AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ramjee Singh83e1eb12018-07-11 16:22:46 +0530685 strlcpy(microphone.address, AUDIO_BOTTOM_MICROPHONE_ADDRESS, sizeof(microphone.address));
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530686 } else if (microphone.device == AUDIO_DEVICE_IN_BACK_MIC) {
Ramjee Singh83e1eb12018-07-11 16:22:46 +0530687 strlcpy(microphone.address, AUDIO_BACK_MICROPHONE_ADDRESS, sizeof(microphone.address));
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530688 }
689 }
690
691 if (strcmp(attr[curIdx++], "location")) {
692 ALOGE("%s: location not found", __func__);
693 goto done;
694 }
695 if (!find_enum_by_string(mic_locations, (char*)attr[curIdx++],
696 AUDIO_MICROPHONE_LOCATION_CNT, &microphone.location)) {
697 ALOGE("%s: location %s in %s not found!",
698 __func__, attr[--curIdx], PLATFORM_INFO_XML_PATH);
699 goto done;
700 }
701
702 if (strcmp(attr[curIdx++], "group")) {
703 ALOGE("%s: group not found", __func__);
704 goto done;
705 }
706 microphone.group = atoi(attr[curIdx++]);
707
708 if (strcmp(attr[curIdx++], "index_in_the_group")) {
709 ALOGE("%s: index_in_the_group not found", __func__);
710 goto done;
711 }
712 microphone.index_in_the_group = atoi(attr[curIdx++]);
713
714 if (strcmp(attr[curIdx++], "directionality")) {
715 ALOGE("%s: directionality not found", __func__);
716 goto done;
717 }
718 if (!find_enum_by_string(mic_directionalities, (char*)attr[curIdx++],
719 AUDIO_MICROPHONE_DIRECTIONALITY_CNT, &microphone.directionality)) {
720 ALOGE("%s: directionality %s in %s not found!",
721 __func__, attr[--curIdx], PLATFORM_INFO_XML_PATH);
722 goto done;
723 }
724
725 if (strcmp(attr[curIdx++], "num_frequency_responses")) {
726 ALOGE("%s: num_frequency_responses not found", __func__);
727 goto done;
728 }
729 microphone.num_frequency_responses = atoi(attr[curIdx++]);
Ramjee Singhf57ff2a2018-08-27 16:22:16 +0530730 if (microphone.num_frequency_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530731 ALOGE("%s: num_frequency_responses is too large", __func__);
732 goto done;
733 }
734 if (microphone.num_frequency_responses > 0) {
735 if (strcmp(attr[curIdx++], "frequencies")) {
736 ALOGE("%s: frequencies not found", __func__);
737 goto done;
738 }
Ramjee Singh83e1eb12018-07-11 16:22:46 +0530739 char *context = NULL;
740 char *token = strtok_r((char *)attr[curIdx++], " ", &context);
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530741 uint32_t num_frequencies = 0;
742 while (token) {
743 microphone.frequency_responses[0][num_frequencies++] = atof(token);
Weiyin Jiang20d3fa62018-08-01 18:06:27 +0800744 if (num_frequencies >= AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
Ramjee Singhf57ff2a2018-08-27 16:22:16 +0530745 break;
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530746 }
Ramjee Singh83e1eb12018-07-11 16:22:46 +0530747 token = strtok_r(NULL, " ", &context);
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530748 }
749
750 if (strcmp(attr[curIdx++], "responses")) {
751 ALOGE("%s: responses not found", __func__);
752 goto done;
753 }
Ramjee Singh83e1eb12018-07-11 16:22:46 +0530754 token = strtok_r((char *)attr[curIdx++], " ", &context);
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530755 uint32_t num_responses = 0;
756 while (token) {
757 microphone.frequency_responses[1][num_responses++] = atof(token);
Weiyin Jiang20d3fa62018-08-01 18:06:27 +0800758 if (num_responses >= AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
Ramjee Singhf57ff2a2018-08-27 16:22:16 +0530759 break;
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530760 }
Ramjee Singh83e1eb12018-07-11 16:22:46 +0530761 token = strtok_r(NULL, " ", &context);
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530762 }
763
764 if (num_frequencies != num_responses
765 || num_frequencies != microphone.num_frequency_responses) {
766 ALOGE("%s: num of frequency and response not match: %u, %u, %u",
767 __func__, num_frequencies, num_responses, microphone.num_frequency_responses);
768 goto done;
769 }
770 }
771
772 if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_SENSITIVITY) {
773 if (strcmp(attr[curIdx++], "sensitivity")) {
774 ALOGE("%s: sensitivity not found", __func__);
775 goto done;
776 }
777 microphone.sensitivity = atof(attr[curIdx++]);
778 } else {
779 microphone.sensitivity = AUDIO_MICROPHONE_SENSITIVITY_UNKNOWN;
780 }
781
782 if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_MAX_SPL) {
783 if (strcmp(attr[curIdx++], "max_spl")) {
784 ALOGE("%s: max_spl not found", __func__);
785 goto done;
786 }
787 microphone.max_spl = atof(attr[curIdx++]);
788 } else {
789 microphone.max_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
790 }
791
792 if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_MIN_SPL) {
793 if (strcmp(attr[curIdx++], "min_spl")) {
794 ALOGE("%s: min_spl not found", __func__);
795 goto done;
796 }
797 microphone.min_spl = atof(attr[curIdx++]);
798 } else {
799 microphone.min_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
800 }
801
802 if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_ORIENTATION) {
803 if (strcmp(attr[curIdx++], "orientation")) {
804 ALOGE("%s: orientation not found", __func__);
805 goto done;
806 }
Ramjee Singh83e1eb12018-07-11 16:22:46 +0530807 char *context = NULL;
808 char *token = strtok_r((char *)attr[curIdx++], " ", &context);
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530809 float orientation[3];
810 uint32_t idx = 0;
811 while (token) {
812 orientation[idx++] = atof(token);
Weiyin Jiang20d3fa62018-08-01 18:06:27 +0800813 if (idx >= 3) {
Ramjee Singhf57ff2a2018-08-27 16:22:16 +0530814 break;
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530815 }
Ramjee Singh83e1eb12018-07-11 16:22:46 +0530816 token = strtok_r(NULL, " ", &context);
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530817 }
Ramjee Singhf57ff2a2018-08-27 16:22:16 +0530818 if (idx != 3) {
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530819 ALOGE("%s: orientation invalid", __func__);
820 goto done;
821 }
822 microphone.orientation.x = orientation[0];
823 microphone.orientation.y = orientation[1];
824 microphone.orientation.z = orientation[2];
825 } else {
826 microphone.orientation.x = 0.0f;
827 microphone.orientation.y = 0.0f;
828 microphone.orientation.z = 0.0f;
829 }
830
831 if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_GEOMETRIC_LOCATION) {
832 if (strcmp(attr[curIdx++], "geometric_location")) {
833 ALOGE("%s: geometric_location not found", __func__);
834 goto done;
835 }
Ramjee Singh83e1eb12018-07-11 16:22:46 +0530836 char *context = NULL;
837 char *token = strtok_r((char *)attr[curIdx++], " ", &context);
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530838 float geometric_location[3];
839 uint32_t idx = 0;
840 while (token) {
841 geometric_location[idx++] = atof(token);
Weiyin Jiang20d3fa62018-08-01 18:06:27 +0800842 if (idx >= 3) {
Ramjee Singhf57ff2a2018-08-27 16:22:16 +0530843 break;
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530844 }
Ramjee Singh83e1eb12018-07-11 16:22:46 +0530845 token = strtok_r(NULL, " ", &context);
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530846 }
Ramjee Singhf57ff2a2018-08-27 16:22:16 +0530847 if (idx != 3) {
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530848 ALOGE("%s: geometric_location invalid", __func__);
849 goto done;
850 }
851 microphone.geometric_location.x = geometric_location[0];
852 microphone.geometric_location.y = geometric_location[1];
853 microphone.geometric_location.z = geometric_location[2];
854 } else {
855 microphone.geometric_location.x = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
856 microphone.geometric_location.y = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
857 microphone.geometric_location.z = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
858 }
859
860 platform_set_microphone_characteristic(my_data.platform, microphone);
861done:
862 return;
863}
864
865static void process_snd_dev(const XML_Char **attr)
866{
867 uint32_t curIdx = 0;
868 in_snd_device = SND_DEVICE_NONE;
869
870 if (strcmp(attr[curIdx++], "in_snd_device")) {
871 ALOGE("%s: snd_device not found", __func__);
872 return;
873 }
874 in_snd_device = platform_get_snd_device_index((char *)attr[curIdx++]);
875 if (in_snd_device < SND_DEVICE_IN_BEGIN ||
876 in_snd_device >= SND_DEVICE_IN_END) {
877 ALOGE("%s: Sound device not valid", __func__);
878 in_snd_device = SND_DEVICE_NONE;
879 }
880
881 return;
882}
883
884static void process_mic_info(const XML_Char **attr)
885{
886 uint32_t curIdx = 0;
887 struct mic_info microphone;
888
889 memset(&microphone.channel_mapping, AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED,
890 sizeof(microphone.channel_mapping));
891
892 if (strcmp(attr[curIdx++], "mic_device_id")) {
893 ALOGE("%s: mic_device_id not found", __func__);
894 goto on_error;
895 }
896 strlcpy(microphone.device_id,
897 (char *)attr[curIdx++], AUDIO_MICROPHONE_ID_MAX_LEN);
898
899 if (strcmp(attr[curIdx++], "channel_mapping")) {
900 ALOGE("%s: channel_mapping not found", __func__);
901 goto on_error;
902 }
Ramjee Singh83e1eb12018-07-11 16:22:46 +0530903 char *context = NULL;
904 const char *token = strtok_r((char *)attr[curIdx++], " ", &context);
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530905 uint32_t idx = 0;
906 while (token) {
907 if (!find_enum_by_string(mic_channel_mapping, token,
908 AUDIO_MICROPHONE_CHANNEL_MAPPING_CNT,
909 &microphone.channel_mapping[idx++])) {
910 ALOGE("%s: channel_mapping %s in %s not found!",
911 __func__, attr[--curIdx], PLATFORM_INFO_XML_PATH);
912 goto on_error;
913 }
Ramjee Singh83e1eb12018-07-11 16:22:46 +0530914 token = strtok_r(NULL, " ", &context);
Naresh Tannirudcb47c52018-06-25 16:23:32 +0530915 }
916 microphone.channel_count = idx;
917
918 platform_set_microphone_map(my_data.platform, in_snd_device,
919 &microphone);
920 return;
921on_error:
922 in_snd_device = SND_DEVICE_NONE;
923 return;
924}
925
926
Dhanalakshmi Siddani21be3ac2016-12-29 14:31:08 +0530927/* process acdb meta info key value */
928static void process_acdb_metainfo_key(const XML_Char **attr)
929{
930 if (strcmp(attr[0], "name") != 0) {
931 ALOGE("%s: 'name' not found", __func__);
932 goto done;
933 }
934
935 if (strcmp(attr[2], "value") != 0) {
936 ALOGE("%s: 'value' not found", __func__);
937 goto done;
938 }
939
940 int key = atoi((char *)attr[3]);
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700941 switch(my_data.caller) {
942 case ACDB_EXTN:
943 if(acdb_set_metainfo_key(my_data.platform, (char*)attr[1], key) < 0) {
944 ALOGE("%s: key %d was not set!", __func__, key);
945 goto done;
946 }
947 break;
948 case PLATFORM:
949 if(platform_set_acdb_metainfo_key(my_data.platform, (char*)attr[1], key) < 0) {
950 ALOGE("%s: key %d was not set!", __func__, key);
951 goto done;
952 }
953 break;
954 default:
955 ALOGE("%s: unknown caller!", __func__);
Dhanalakshmi Siddani21be3ac2016-12-29 14:31:08 +0530956 }
957
958done:
959 return;
960}
961
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700962static void start_tag(void *userdata __unused, const XML_Char *tag_name,
Ben Romberger55886882014-01-10 13:49:02 -0800963 const XML_Char **attr)
964{
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700965 if (my_data.caller == ACDB_EXTN) {
966 if(strcmp(tag_name, "acdb_metainfo_key") == 0) {
967 section = ACDB_METAINFO_KEY;
968 } else if (strcmp(tag_name, "param") == 0) {
969 if ((section != CONFIG_PARAMS) && (section != ACDB_METAINFO_KEY)) {
970 ALOGE("param tag only supported with CONFIG_PARAMS section");
971 return;
972 }
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700973
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700974 section_process_fn fn = section_table[section];
975 fn(attr);
Aniket Kumar Lataf56b6402016-10-27 12:03:18 -0700976 }
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700977 } else if(my_data.caller == PLATFORM) {
978 if (strcmp(tag_name, "bit_width_configs") == 0) {
979 section = BITWIDTH;
980 } else if (strcmp(tag_name, "acdb_ids") == 0) {
981 section = ACDB;
Vikram Pandurangadf59cae2017-08-03 18:04:55 -0700982 } else if (strcmp(tag_name, "module_ids") == 0) {
983 section = MODULE;
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700984 } else if (strcmp(tag_name, "pcm_ids") == 0) {
985 section = PCM_ID;
986 } else if (strcmp(tag_name, "backend_names") == 0) {
987 section = BACKEND_NAME;
988 } else if (strcmp(tag_name, "config_params") == 0) {
989 section = CONFIG_PARAMS;
Aalique Grahame22e49102018-12-18 14:23:57 -0800990 } else if (strcmp(tag_name, "operator_specific") == 0) {
991 section = OPERATOR_SPECIFIC;
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700992 } else if (strcmp(tag_name, "interface_names") == 0) {
993 section = INTERFACE_NAME;
994 } else if (strcmp(tag_name, "gain_db_to_level_mapping") == 0) {
995 section = GAIN_LEVEL_MAPPING;
Aalique Grahame22e49102018-12-18 14:23:57 -0800996 } else if (strcmp(tag_name, "app_types") == 0) {
997 section = APP_TYPE;
Vignesh Kulothungan55396882017-04-20 14:37:02 -0700998 } else if(strcmp(tag_name, "acdb_metainfo_key") == 0) {
999 section = ACDB_METAINFO_KEY;
Naresh Tannirudcb47c52018-06-25 16:23:32 +05301000 } else if (strcmp(tag_name, "microphone_characteristics") == 0) {
1001 section = MICROPHONE_CHARACTERISTIC;
1002 } else if (strcmp(tag_name, "snd_devices") == 0) {
1003 section = SND_DEVICES;
Vignesh Kulothungan55396882017-04-20 14:37:02 -07001004 } else if (strcmp(tag_name, "device") == 0) {
Vikram Pandurangadf59cae2017-08-03 18:04:55 -07001005 if ((section != ACDB) && (section != AEC) && (section != NS) &&
1006 (section != BACKEND_NAME) && (section != BITWIDTH) &&
Aalique Grahame22e49102018-12-18 14:23:57 -08001007 (section != INTERFACE_NAME) && (section != OPERATOR_SPECIFIC)) {
Vignesh Kulothungan55396882017-04-20 14:37:02 -07001008 ALOGE("device tag only supported for acdb/backend names/bitwitdh/interface names");
1009 return;
1010 }
Aniket Kumar Lataf56b6402016-10-27 12:03:18 -07001011
Vignesh Kulothungan55396882017-04-20 14:37:02 -07001012 /* call into process function for the current section */
1013 section_process_fn fn = section_table[section];
1014 fn(attr);
1015 } else if (strcmp(tag_name, "gain_level_map") == 0) {
1016 if (section != GAIN_LEVEL_MAPPING) {
1017 ALOGE("usecase tag only supported with GAIN_LEVEL_MAPPING section");
1018 return;
1019 }
1020
1021 section_process_fn fn = section_table[GAIN_LEVEL_MAPPING];
1022 fn(attr);
1023 } else if (strcmp(tag_name, "usecase") == 0) {
1024 if (section != PCM_ID) {
1025 ALOGE("usecase tag only supported with PCM_ID section");
1026 return;
1027 }
1028
1029 section_process_fn fn = section_table[PCM_ID];
1030 fn(attr);
1031 } else if (strcmp(tag_name, "param") == 0) {
1032 if ((section != CONFIG_PARAMS) && (section != ACDB_METAINFO_KEY)) {
1033 ALOGE("param tag only supported with CONFIG_PARAMS section");
1034 return;
1035 }
1036
1037 section_process_fn fn = section_table[section];
1038 fn(attr);
Naresh Tannirudcb47c52018-06-25 16:23:32 +05301039 } else if (strcmp(tag_name, "aec") == 0) {
Vikram Pandurangadf59cae2017-08-03 18:04:55 -07001040 if (section != MODULE) {
1041 ALOGE("aec tag only supported with MODULE section");
1042 return;
1043 }
1044 section = AEC;
Naresh Tannirudcb47c52018-06-25 16:23:32 +05301045 } else if (strcmp(tag_name, "ns") == 0) {
Vikram Pandurangadf59cae2017-08-03 18:04:55 -07001046 if (section != MODULE) {
1047 ALOGE("ns tag only supported with MODULE section");
1048 return;
1049 }
1050 section = NS;
Aalique Grahame22e49102018-12-18 14:23:57 -08001051 } else if (strcmp(tag_name, "gain_level_map") == 0) {
1052 if (section != GAIN_LEVEL_MAPPING) {
1053 ALOGE("gain_level_map tag only supported with GAIN_LEVEL_MAPPING section");
1054 return;
1055 }
1056
1057 section_process_fn fn = section_table[GAIN_LEVEL_MAPPING];
1058 fn(attr);
1059 } else if (!strcmp(tag_name, "app")) {
1060 if (section != APP_TYPE) {
1061 ALOGE("app tag only valid in section APP_TYPE");
1062 return;
1063 }
1064
1065 section_process_fn fn = section_table[APP_TYPE];
1066 fn(attr);
Naresh Tannirudcb47c52018-06-25 16:23:32 +05301067 } else if (strcmp(tag_name, "microphone") == 0) {
1068 if (section != MICROPHONE_CHARACTERISTIC) {
1069 ALOGE("microphone tag only supported with MICROPHONE_CHARACTERISTIC section");
1070 return;
1071 }
1072 section_process_fn fn = section_table[MICROPHONE_CHARACTERISTIC];
1073 fn(attr);
1074 } else if (strcmp(tag_name, "input_snd_device") == 0) {
1075 if (section != SND_DEVICES) {
1076 ALOGE("input_snd_device tag only supported with SND_DEVICES section");
1077 return;
1078 }
1079 section = INPUT_SND_DEVICE;
1080 } else if (strcmp(tag_name, "input_snd_device_mic_mapping") == 0) {
1081 if (section != INPUT_SND_DEVICE) {
1082 ALOGE("input_snd_device_mic_mapping tag only supported with INPUT_SND_DEVICE section");
1083 return;
1084 }
1085 section = INPUT_SND_DEVICE_TO_MIC_MAPPING;
1086 } else if (strcmp(tag_name, "snd_dev") == 0) {
1087 if (section != INPUT_SND_DEVICE_TO_MIC_MAPPING) {
1088 ALOGE("snd_dev tag only supported with INPUT_SND_DEVICE_TO_MIC_MAPPING section");
1089 return;
1090 }
1091 section_process_fn fn = section_table[SND_DEV];
1092 fn(attr);
1093 } else if (strcmp(tag_name, "mic_info") == 0) {
1094 if (section != INPUT_SND_DEVICE_TO_MIC_MAPPING) {
1095 ALOGE("mic_info tag only supported with INPUT_SND_DEVICE_TO_MIC_MAPPING section");
1096 return;
1097 }
1098 if (in_snd_device == SND_DEVICE_NONE) {
1099 ALOGE("%s: Error in previous tags, do not process mic info", __func__);
1100 return;
1101 }
1102 section_process_fn fn = section_table[MIC_INFO];
1103 fn(attr);
1104 }
Vignesh Kulothungan55396882017-04-20 14:37:02 -07001105 } else {
Aalique Grahame22e49102018-12-18 14:23:57 -08001106 if(strcmp(tag_name, "config_params") == 0) {
1107 section = CONFIG_PARAMS;
1108 } else if (strcmp(tag_name, "param") == 0) {
1109 if (section != CONFIG_PARAMS) {
1110 ALOGE("param tag only supported with CONFIG_PARAMS section");
1111 return;
1112 }
1113
1114 section_process_fn fn = section_table[section];
1115 fn(attr);
1116 }
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001117 }
Ben Romberger55886882014-01-10 13:49:02 -08001118 return;
1119}
1120
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001121static void end_tag(void *userdata __unused, const XML_Char *tag_name)
Ben Romberger55886882014-01-10 13:49:02 -08001122{
Amit Shekhar5a39c912014-10-14 15:39:30 -07001123 if (strcmp(tag_name, "bit_width_configs") == 0) {
1124 section = ROOT;
1125 } else if (strcmp(tag_name, "acdb_ids") == 0) {
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001126 section = ROOT;
Vikram Pandurangadf59cae2017-08-03 18:04:55 -07001127 } else if (strcmp(tag_name, "module_ids") == 0) {
1128 section = ROOT;
1129 } else if (strcmp(tag_name, "aec") == 0) {
1130 section = MODULE;
1131 } else if (strcmp(tag_name, "ns") == 0) {
1132 section = MODULE;
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001133 } else if (strcmp(tag_name, "pcm_ids") == 0) {
1134 section = ROOT;
1135 } else if (strcmp(tag_name, "backend_names") == 0) {
1136 section = ROOT;
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -07001137 } else if (strcmp(tag_name, "config_params") == 0) {
1138 section = ROOT;
Vignesh Kulothungan55396882017-04-20 14:37:02 -07001139 if (my_data.caller == PLATFORM) {
1140 platform_set_parameters(my_data.platform, my_data.kvpairs);
1141 }
Aalique Grahame22e49102018-12-18 14:23:57 -08001142 } else if (strcmp(tag_name, "operator_specific") == 0) {
1143 section = ROOT;
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -08001144 } else if (strcmp(tag_name, "interface_names") == 0) {
1145 section = ROOT;
Aniket Kumar Lataf56b6402016-10-27 12:03:18 -07001146 } else if (strcmp(tag_name, "gain_db_to_level_mapping") == 0) {
1147 section = ROOT;
Aalique Grahame22e49102018-12-18 14:23:57 -08001148 } else if (strcmp(tag_name, "app_types") == 0) {
1149 section = ROOT;
Dhanalakshmi Siddani21be3ac2016-12-29 14:31:08 +05301150 } else if (strcmp(tag_name, "acdb_metainfo_key") == 0) {
1151 section = ROOT;
Naresh Tannirudcb47c52018-06-25 16:23:32 +05301152 } else if (strcmp(tag_name, "microphone_characteristics") == 0) {
1153 section = ROOT;
1154 } else if (strcmp(tag_name, "snd_devices") == 0) {
1155 section = ROOT;
1156 } else if (strcmp(tag_name, "input_snd_device") == 0) {
1157 section = SND_DEVICES;
1158 } else if (strcmp(tag_name, "input_snd_device_mic_mapping") == 0) {
1159 section = INPUT_SND_DEVICE;
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001160 }
Ben Romberger55886882014-01-10 13:49:02 -08001161}
1162
Vignesh Kulothungan55396882017-04-20 14:37:02 -07001163int platform_info_init(const char *filename, void *platform, caller_t caller_type)
Ben Romberger55886882014-01-10 13:49:02 -08001164{
1165 XML_Parser parser;
1166 FILE *file;
1167 int ret = 0;
1168 int bytes_read;
Ben Romberger55886882014-01-10 13:49:02 -08001169 void *buf;
Aalique Grahame22e49102018-12-18 14:23:57 -08001170 char platform_info_file_name[MIXER_PATH_MAX_LENGTH]= {0};
Ben Romberger55886882014-01-10 13:49:02 -08001171
Aalique Grahame22e49102018-12-18 14:23:57 -08001172 if (filename == NULL)
1173 strlcpy(platform_info_file_name, PLATFORM_INFO_XML_PATH,
1174 MIXER_PATH_MAX_LENGTH);
1175 else
1176 strlcpy(platform_info_file_name, filename, MIXER_PATH_MAX_LENGTH);
1177
1178 ALOGV("%s: platform info file name is %s", __func__,
1179 platform_info_file_name);
1180
1181 file = fopen(platform_info_file_name, "r");
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001182 section = ROOT;
1183
Ben Romberger55886882014-01-10 13:49:02 -08001184 if (!file) {
1185 ALOGD("%s: Failed to open %s, using defaults.",
Aalique Grahame22e49102018-12-18 14:23:57 -08001186 __func__, platform_info_file_name);
Ben Romberger55886882014-01-10 13:49:02 -08001187 ret = -ENODEV;
1188 goto done;
1189 }
1190
1191 parser = XML_ParserCreate(NULL);
1192 if (!parser) {
1193 ALOGE("%s: Failed to create XML parser!", __func__);
1194 ret = -ENODEV;
1195 goto err_close_file;
1196 }
1197
Vignesh Kulothungan55396882017-04-20 14:37:02 -07001198 my_data.caller = caller_type;
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -07001199 my_data.platform = platform;
1200 my_data.kvpairs = str_parms_create();
1201
Ben Romberger55886882014-01-10 13:49:02 -08001202 XML_SetElementHandler(parser, start_tag, end_tag);
1203
1204 while (1) {
1205 buf = XML_GetBuffer(parser, BUF_SIZE);
1206 if (buf == NULL) {
1207 ALOGE("%s: XML_GetBuffer failed", __func__);
1208 ret = -ENOMEM;
1209 goto err_free_parser;
1210 }
1211
1212 bytes_read = fread(buf, 1, BUF_SIZE, file);
1213 if (bytes_read < 0) {
1214 ALOGE("%s: fread failed, bytes read = %d", __func__, bytes_read);
1215 ret = bytes_read;
1216 goto err_free_parser;
1217 }
1218
1219 if (XML_ParseBuffer(parser, bytes_read,
1220 bytes_read == 0) == XML_STATUS_ERROR) {
1221 ALOGE("%s: XML_ParseBuffer failed, for %s",
Aalique Grahame22e49102018-12-18 14:23:57 -08001222 __func__, platform_info_file_name);
Ben Romberger55886882014-01-10 13:49:02 -08001223 ret = -EINVAL;
1224 goto err_free_parser;
1225 }
1226
1227 if (bytes_read == 0)
1228 break;
1229 }
1230
Ben Romberger55886882014-01-10 13:49:02 -08001231err_free_parser:
1232 XML_ParserFree(parser);
1233err_close_file:
1234 fclose(file);
1235done:
1236 return ret;
1237}