hal: Add XML parser for platform info
Add XML parser which parses the platform_info.xml
on the device. That xml contains ACDB ID information
and is populated from the device project folder to
the /etc folder on the device. It is used to overwrite
hardcoded ACDB ID's in platform.c.
Change-Id: I86419bf0f48bcf7f0125da58626adab1d23fa50a
diff --git a/hal/Android.mk b/hal/Android.mk
index 037be56..b6e9cad 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -116,6 +116,12 @@
$(LOCAL_PATH)/audio_extn \
$(LOCAL_PATH)/voice_extn
+ifneq ($(filter msm8974,$(AUDIO_PLATFORM)),)
+ LOCAL_C_INCLUDES += external/expat/lib
+ LOCAL_SHARED_LIBRARIES += libexpat
+ LOCAL_SRC_FILES += $(AUDIO_PLATFORM)/platform_parser.c
+endif
+
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_LISTEN)),true)
LOCAL_CFLAGS += -DAUDIO_LISTEN_ENABLED
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/audio-listen
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index 298c60d..54bda5a 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -391,6 +391,11 @@
return device_id;
}
+int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
+{
+ return -ENODEV;
+}
+
int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
{
struct platform_data *my_data = (struct platform_data *)platform;
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index c7896ae..34ff8cc 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -31,6 +31,7 @@
#include "platform.h"
#include "audio_extn.h"
#include "voice_extn.h"
+#include "platform_parser.h"
#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
@@ -222,7 +223,7 @@
};
/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
-static const int acdb_device_table[SND_DEVICE_MAX] = {
+static int acdb_device_table[SND_DEVICE_MAX] = {
[SND_DEVICE_NONE] = -1,
[SND_DEVICE_OUT_HANDSET] = 7,
[SND_DEVICE_OUT_SPEAKER] = 14,
@@ -572,6 +573,9 @@
my_data->acdb_init();
}
+ /* Initialize ACDB ID's */
+ platform_info_init();
+
/* If platform is apq8084 and baseband is MDM, load CSD Client specific
* symbols. Voice call is handled by MDM and apps processor talks to
* MDM through CSD Client
@@ -669,6 +673,22 @@
return device_id;
}
+int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
+{
+ int ret = 0;
+
+ if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
+ ALOGE("%s: Invalid snd_device = %d",
+ __func__, snd_device);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ acdb_device_table[snd_device] = acdb_id;
+done:
+ return ret;
+}
+
int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
{
struct platform_data *my_data = (struct platform_data *)platform;
diff --git a/hal/msm8974/platform_parser.c b/hal/msm8974/platform_parser.c
new file mode 100644
index 0000000..8f86d97
--- /dev/null
+++ b/hal/msm8974/platform_parser.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "platform_parser"
+#define LOG_NDDEBUG 0
+
+#include <errno.h>
+#include <stdio.h>
+#include <expat.h>
+#include <cutils/log.h>
+#include <audio_hw.h>
+#include <platform_api.h>
+#include "platform.h"
+#include "platform_parser.h"
+
+#define PLATFORM_XML_PATH "/system/etc/platform_info.xml"
+#define BUF_SIZE 1024
+
+static void process_device(void *userdata, const XML_Char **attr)
+{
+ unsigned int *snd_device_index = userdata;
+
+ if (strcmp(attr[0], "name") != 0)
+ goto done;
+
+ if (platform_get_snd_device_name(*snd_device_index) == NULL)
+ goto next;
+ if (strcmp(attr[1], platform_get_snd_device_name(*snd_device_index)) != 0) {
+ ALOGE("%s: %s in platform.h at index %d does not match %s, from %s no ACDB ID set!",
+ __func__, platform_get_snd_device_name(*snd_device_index),
+ *snd_device_index, attr[1], PLATFORM_XML_PATH);
+ goto done;
+ }
+
+ if (strcmp(attr[2], "acdb_id") != 0) {
+ ALOGE("%s: Device %s at index %d in %s has no acdb_id, no ACDB ID set!",
+ __func__, attr[1], *snd_device_index, PLATFORM_XML_PATH);
+ goto done;
+ }
+
+ if(platform_set_snd_device_acdb_id(*snd_device_index,
+ atoi((char *)attr[3])) != 0)
+ goto done;
+
+next:
+ (*snd_device_index)++;
+done:
+ return;
+}
+
+static void start_tag(void *userdata, const XML_Char *tag_name,
+ const XML_Char **attr)
+{
+ const XML_Char *attr_name = NULL;
+ const XML_Char *attr_value = NULL;
+ unsigned int i;
+
+ if (strcmp(tag_name, "device") == 0)
+ process_device(userdata, attr);
+
+ return;
+}
+
+static void end_tag(void *userdata, const XML_Char *tag_name)
+{
+
+}
+
+int platform_info_init(void)
+{
+ XML_Parser parser;
+ FILE *file;
+ int ret = 0;
+ int bytes_read;
+ unsigned int snd_device_index = SND_DEVICE_MIN;
+ void *buf;
+
+ file = fopen(PLATFORM_XML_PATH, "r");
+ if (!file) {
+ ALOGD("%s: Failed to open %s, using defaults.",
+ __func__, PLATFORM_XML_PATH);
+ ret = -ENODEV;
+ goto done;
+ }
+
+ parser = XML_ParserCreate(NULL);
+ if (!parser) {
+ ALOGE("%s: Failed to create XML parser!", __func__);
+ ret = -ENODEV;
+ goto err_close_file;
+ }
+
+ XML_SetUserData(parser, &snd_device_index);
+ XML_SetElementHandler(parser, start_tag, end_tag);
+
+ while (1) {
+ buf = XML_GetBuffer(parser, BUF_SIZE);
+ if (buf == NULL) {
+ ALOGE("%s: XML_GetBuffer failed", __func__);
+ ret = -ENOMEM;
+ goto err_free_parser;
+ }
+
+ bytes_read = fread(buf, 1, BUF_SIZE, file);
+ if (bytes_read < 0) {
+ ALOGE("%s: fread failed, bytes read = %d", __func__, bytes_read);
+ ret = bytes_read;
+ goto err_free_parser;
+ }
+
+ if (XML_ParseBuffer(parser, bytes_read,
+ bytes_read == 0) == XML_STATUS_ERROR) {
+ ALOGE("%s: XML_ParseBuffer failed, for %s",
+ __func__, PLATFORM_XML_PATH);
+ ret = -EINVAL;
+ goto err_free_parser;
+ }
+
+ if (bytes_read == 0)
+ break;
+ }
+
+ if (snd_device_index != SND_DEVICE_MAX) {
+ ALOGE("%s: Only %d/%d ACDB ID's set! Fix %s!",
+ __func__, snd_device_index, SND_DEVICE_MAX, PLATFORM_XML_PATH);
+ ret = -EINVAL;
+ }
+
+err_free_parser:
+ XML_ParserFree(parser);
+err_close_file:
+ fclose(file);
+done:
+ return ret;
+}
diff --git a/hal/msm8974/platform_parser.h b/hal/msm8974/platform_parser.h
new file mode 100644
index 0000000..3e91934
--- /dev/null
+++ b/hal/msm8974/platform_parser.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AUDIO_PLATFORM_PARSER_H
+#define AUDIO_PLATFORM_PARSER_H
+
+int platform_info_init(void);
+
+#endif // AUDIO_PLATFORM_PARSER_H
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 4096ef0..0b2c435 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -17,8 +17,8 @@
* limitations under the License.
*/
-#ifndef QCOM_AUDIO_PLATFORM_API_H
-#define QCOM_AUDIO_PLATFORM_API_H
+#ifndef AUDIO_PLATFORM_API_H
+#define AUDIO_PLATFORM_API_H
void *platform_init(struct audio_device *adev);
void platform_deinit(void *platform);
@@ -27,6 +27,7 @@
char *device_name);
void platform_add_backend_name(char *mixer_path, snd_device_t snd_device);
int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type);
+int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id);
int platform_send_audio_calibration(void *platform, snd_device_t snd_device);
int platform_switch_voice_call_device_pre(void *platform);
int platform_switch_voice_call_device_post(void *platform,
@@ -57,4 +58,4 @@
bool platform_listen_update_status(snd_device_t snd_device);
-#endif // QCOM_AUDIO_PLATFORM_API_H
+#endif // AUDIO_PLATFORM_API_H