diff options
| author | Haynes Mathew George <hgeorge@codeaurora.org> | 2014-06-16 16:36:20 -0700 |
|---|---|---|
| committer | Eric Laurent <elaurent@google.com> | 2014-07-11 14:15:25 -0700 |
| commit | 5bc188456348ebdfc5d3c86414952503ec41bd44 (patch) | |
| tree | 3390c9541177c859af2d9c9b4a03085921cd0f1e /hal | |
| parent | fdf296a35ba3deb8490522c834037e5e977b05cf (diff) | |
| download | android_hardware_qcom_audio-5bc188456348ebdfc5d3c86414952503ec41bd44.tar.gz android_hardware_qcom_audio-5bc188456348ebdfc5d3c86414952503ec41bd44.tar.bz2 android_hardware_qcom_audio-5bc188456348ebdfc5d3c86414952503ec41bd44.zip | |
hal: Add XML parser for platform info
change 1
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 2
Move platform_parser to root hal directory. Rename
platform_parser to platform_info. Change name of
XML file read from platform_info.xml to
audio_platform_info.xml. The xml now only needs
information for ACDB ID's that you want overwritten.
Names in the XML now match sound device enums in
platform.c.
(cherry-picked from CAF commits
61764e3b8069b819c3da19a6bb38b37ad173bf50, 5588688cbdd065a3572afb032e48a265790dfea2)
Change-Id: Ie5978f609bbe9d60a64e20a0906d6bd7a8c48e1b
Diffstat (limited to 'hal')
| -rw-r--r-- | hal/Android.mk | 7 | ||||
| -rw-r--r-- | hal/msm8960/platform.c | 10 | ||||
| -rw-r--r-- | hal/msm8974/platform.c | 87 | ||||
| -rw-r--r-- | hal/platform_api.h | 11 | ||||
| -rw-r--r-- | hal/platform_info.c | 139 |
5 files changed, 248 insertions, 6 deletions
diff --git a/hal/Android.mk b/hal/Android.mk index 30abdf31..c7cb167c 100644 --- a/hal/Android.mk +++ b/hal/Android.mk @@ -21,6 +21,7 @@ endif LOCAL_SRC_FILES := \ audio_hw.c \ voice.c \ + platform_info.c \ $(AUDIO_PLATFORM)/platform.c LOCAL_SHARED_LIBRARIES := \ @@ -29,7 +30,8 @@ LOCAL_SHARED_LIBRARIES := \ libtinyalsa \ libtinycompress \ libaudioroute \ - libdl + libdl \ + libexpat LOCAL_C_INCLUDES += \ external/tinyalsa/include \ @@ -38,7 +40,8 @@ LOCAL_C_INCLUDES += \ $(call include-path-for, audio-effects) \ $(LOCAL_PATH)/$(AUDIO_PLATFORM) \ $(LOCAL_PATH)/audio_extn \ - $(LOCAL_PATH)/voice_extn + $(LOCAL_PATH)/voice_extn \ + external/expat/lib ifneq ($(filter msm8084,$(TARGET_BOARD_PLATFORM)),) LOCAL_SHARED_LIBRARIES += libmdmdetect diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c index 9efcf268..02935bd9 100644 --- a/hal/msm8960/platform.c +++ b/hal/msm8960/platform.c @@ -405,6 +405,16 @@ int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type) return device_id; } +int platform_get_snd_device_index(char *snd_device_index_name) +{ + return -ENODEV; +} + +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 3fba99b5..8d5ed1a4 100644 --- a/hal/msm8974/platform.c +++ b/hal/msm8974/platform.c @@ -169,7 +169,7 @@ static const char * const device_table[SND_DEVICE_MAX] = { }; /* 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] = 15, @@ -221,6 +221,47 @@ static const int acdb_device_table[SND_DEVICE_MAX] = { [SND_DEVICE_IN_VOICE_REC_DMIC_BS_FLUENCE] = 5, }; +struct snd_device_index { + char name[100]; + unsigned int index; +}; + +#define TO_NAME_INDEX(X) #X, X + +/* Used to get index from parsed sting */ +struct snd_device_index snd_device_name_index[SND_DEVICE_MAX] = { + {TO_NAME_INDEX(SND_DEVICE_OUT_HANDSET)}, + {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER)}, + {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)}, + {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)}, + {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)}, + {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)}, + {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)}, + {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)}, + {TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)}, + {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)}, + {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)}, + {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)}, + {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)}, + {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)}, + {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)}, + {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)}, + {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC)}, + {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC)}, + {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC)}, + {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC)}, + {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC)}, + {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)}, + {TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)}, + {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC)}, + {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)}, + {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)}, + {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC)}, + {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC)}, + {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC)}, + {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC)}, +}; + #define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL) #define LOW_LATENCY_PLATFORM_DELAY (13*1000LL) @@ -576,6 +617,10 @@ void *platform_init(struct audio_device *adev) else my_data->acdb_init(); #endif + + /* Initialize ACDB ID's */ + /* Comment - does it make sense to init if acdb handle is NULL */ + platform_info_init(); } /* load csd client */ @@ -642,6 +687,46 @@ int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type) return device_id; } +int platform_get_snd_device_index(char *snd_device_index_name) +{ + int ret = 0; + int i; + + if (snd_device_index_name == NULL) { + ALOGE("%s: snd_device_index_name is NULL", __func__); + ret = -ENODEV; + goto done; + } + + for (i=0; i < SND_DEVICE_MAX; i++) { + if(strcmp(snd_device_name_index[i].name, snd_device_index_name) == 0) { + ret = snd_device_name_index[i].index; + goto done; + } + } + ALOGE("%s: Could not find index for snd_device_index_name = %s", + __func__, snd_device_index_name); + ret = -ENODEV; +done: + return ret; +} + +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/platform_api.h b/hal/platform_api.h index 81fbc08e..7d543818 100644 --- a/hal/platform_api.h +++ b/hal/platform_api.h @@ -14,8 +14,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); @@ -23,6 +23,8 @@ const char *platform_get_snd_device_name(snd_device_t snd_device); void platform_add_backend_name(void *platform, char *mixer_path, snd_device_t snd_device); int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type); +int platform_get_snd_device_index(char *snd_device_index_name); +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_enable_device_config(void *platform, @@ -54,4 +56,7 @@ int platform_stop_incall_recording_usecase(void *platform); int platform_start_incall_music_usecase(void *platform); int platform_stop_incall_music_usecase(void *platform); -#endif // QCOM_AUDIO_PLATFORM_API_H +/* From platform_info_parser.c */ +int platform_info_init(void); + +#endif // AUDIO_PLATFORM_API_H diff --git a/hal/platform_info.c b/hal/platform_info.c new file mode 100644 index 00000000..409c3969 --- /dev/null +++ b/hal/platform_info.c @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#define LOG_TAG "platform_info" +#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> + +#define PLATFORM_INFO_XML_PATH "/system/etc/audio_platform_info.xml" + +static void process_device(const XML_Char **attr) +{ + int index; + + if (strcmp(attr[0], "name") != 0) { + ALOGE("%s: 'name' not found, no ACDB ID set!", __func__); + goto done; + } + + index = platform_get_snd_device_index((char *)attr[1]); + if (index < 0) { + ALOGE("%s: Device %s in %s not found, no ACDB ID set!", + __func__, attr[1], PLATFORM_INFO_XML_PATH); + goto done; + } + + if (strcmp(attr[2], "acdb_id") != 0) { + ALOGE("%s: Device %s in %s has no acdb_id, no ACDB ID set!", + __func__, attr[1], PLATFORM_INFO_XML_PATH); + goto done; + } + + if(platform_set_snd_device_acdb_id(index, atoi((char *)attr[3])) < 0) { + ALOGE("%s: Device %s in %s, ACDB ID %d was not set!", + __func__, attr[1], PLATFORM_INFO_XML_PATH, atoi((char *)attr[3])); + goto done; + } + +done: + return; +} + +static void start_tag(void *userdata __unused, 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(attr); + + return; +} + +static void end_tag(void *userdata __unused, const XML_Char *tag_name __unused) +{ + +} + +int platform_info_init(void) +{ + XML_Parser parser; + FILE *file; + int ret = 0; + int bytes_read; + void *buf; + static const uint32_t kBufSize = 1024; + + file = fopen(PLATFORM_INFO_XML_PATH, "r"); + if (!file) { + ALOGD("%s: Failed to open %s, using defaults.", + __func__, PLATFORM_INFO_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_SetElementHandler(parser, start_tag, end_tag); + + while (1) { + buf = XML_GetBuffer(parser, kBufSize); + if (buf == NULL) { + ALOGE("%s: XML_GetBuffer failed", __func__); + ret = -ENOMEM; + goto err_free_parser; + } + + bytes_read = fread(buf, 1, kBufSize, 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_INFO_XML_PATH); + ret = -EINVAL; + goto err_free_parser; + } + + if (bytes_read == 0) + break; + } + +err_free_parser: + XML_ParserFree(parser); +err_close_file: + fclose(file); +done: + return ret; +} |
