summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHaynes Mathew George <hgeorge@codeaurora.org>2014-06-20 19:14:25 -0700
committerVidyakumar Athota <vathota@codeaurora.org>2014-10-08 16:01:37 -0700
commit2275675f25e31ffb8f135a1634974e6a3c2cd931 (patch)
tree35364ef2912a920c1cfc4d2b5b4c7903be54c47d
parent88c2f797ca950a292aa495418b2ab5ade815aac1 (diff)
downloadandroid_hardware_qcom_audio-2275675f25e31ffb8f135a1634974e6a3c2cd931.tar.gz
android_hardware_qcom_audio-2275675f25e31ffb8f135a1634974e6a3c2cd931.tar.bz2
android_hardware_qcom_audio-2275675f25e31ffb8f135a1634974e6a3c2cd931.zip
audio: extend platform parser
Extend platform parser with support for additional sections. Supported sections now include acdb ids, pcm device ids and backend names. Change-Id: Idfbc8a8bb490606686436c107db5b0c7d636ccbe
-rw-r--r--hal/audio_extn/spkr_protection.c9
-rw-r--r--hal/msm8960/platform.c17
-rw-r--r--hal/msm8974/platform.c177
-rw-r--r--hal/platform_api.h5
-rw-r--r--hal/platform_info.c172
5 files changed, 331 insertions, 49 deletions
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index f2db4d0c..438f22ff 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -575,6 +575,15 @@ void audio_extn_spkr_prot_init(void *adev)
handle.thermal_handle = NULL;
handle.spkr_prot_enable = false;
}
+
+ if (handle.spkr_prot_enable) {
+ char platform[PROPERTY_VALUE_MAX];
+ property_get("ro.board.platform", platform, "");
+ if (!strncmp("apq8084", platform, sizeof("apq8084"))) {
+ platform_set_snd_device_backend(SND_DEVICE_OUT_VOICE_SPEAKER,
+ "speaker-protected");
+ }
+ }
}
int audio_extn_spkr_prot_start_processing(snd_device_t snd_device)
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index 997b6535..01d5fd80 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1071,3 +1071,20 @@ int platform_set_device_params(struct stream_out *out __unused,
{
return 0;
}
+
+int platform_get_usecase_index(const char * usecase __unused)
+{
+ return -ENOSYS;
+}
+
+int platform_set_usecase_pcm_id(audio_usecase_t usecase __unused, int32_t type __unused,
+ int32_t pcm_id __unused)
+{
+ return -ENOSYS;
+}
+
+int platform_set_snd_device_backend(snd_device_t snd_device __unused,
+ const char * backend __unused)
+{
+ return -ENOSYS;
+}
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 9aaeec42..702e7aa2 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -146,7 +146,7 @@ struct platform_data {
void *edid_info;
};
-static const int pcm_device_table[AUDIO_USECASE_MAX][2] = {
+static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
[USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {DEEP_BUFFER_PCM_DEVICE,
DEEP_BUFFER_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
@@ -350,7 +350,7 @@ static int acdb_device_table[SND_DEVICE_MAX] = {
[SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE] = 120,
};
-struct snd_device_index {
+struct name_to_index {
char name[100];
unsigned int index;
};
@@ -358,7 +358,7 @@ struct snd_device_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] = {
+static struct name_to_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)},
@@ -433,6 +433,26 @@ struct snd_device_index snd_device_name_index[SND_DEVICE_MAX] = {
{TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE)},
};
+static char * backend_table[SND_DEVICE_MAX] = {0};
+
+static struct name_to_index usecase_name_index[AUDIO_USECASE_MAX] = {
+ {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_DEEP_BUFFER)},
+ {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
+ {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MULTI_CH)},
+ {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
+ {TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
+ {TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
+ {TO_NAME_INDEX(USECASE_VOICE_CALL)},
+ {TO_NAME_INDEX(USECASE_VOICE2_CALL)},
+ {TO_NAME_INDEX(USECASE_VOLTE_CALL)},
+ {TO_NAME_INDEX(USECASE_QCHAT_CALL)},
+ {TO_NAME_INDEX(USECASE_VOWLAN_CALL)},
+ {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK)},
+ {TO_NAME_INDEX(USECASE_INCALL_REC_DOWNLINK)},
+ {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK_AND_DOWNLINK)},
+ {TO_NAME_INDEX(USECASE_AUDIO_HFP_SCO)},
+};
+
#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
@@ -630,6 +650,30 @@ static bool platform_is_i2s_ext_modem(const char *snd_card_name,
return plat_data->is_i2s_ext_modem;
}
+static void set_platform_defaults()
+{
+ int32_t dev;
+ for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
+ backend_table[dev] = NULL;
+ }
+
+ // TBD - do these go to the platform-info.xml file.
+ // will help in avoiding strdups here
+ backend_table[SND_DEVICE_IN_BT_SCO_MIC] = strdup("bt-sco");
+ backend_table[SND_DEVICE_IN_BT_SCO_MIC_WB] = strdup("bt-sco-wb");
+ backend_table[SND_DEVICE_OUT_BT_SCO] = strdup("bt-sco");
+ backend_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("bt-sco-wb");
+ backend_table[SND_DEVICE_OUT_HDMI] = strdup("hdmi");
+ backend_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("speaker-and-hdmi");
+ backend_table[SND_DEVICE_OUT_AFE_PROXY] = strdup("afe-proxy");
+ backend_table[SND_DEVICE_OUT_USB_HEADSET] = strdup("usb-headphones");
+ backend_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] =
+ strdup("speaker-and-usb-headphones");
+ backend_table[SND_DEVICE_IN_USB_HEADSET_MIC] = strdup("usb-headset-mic");
+ backend_table[SND_DEVICE_IN_CAPTURE_FM] = strdup("capture-fm");
+ backend_table[SND_DEVICE_OUT_TRANSMISSION_FM] = strdup("transmission-fm");
+}
+
void *platform_init(struct audio_device *adev)
{
char value[PROPERTY_VALUE_MAX];
@@ -776,6 +820,8 @@ void *platform_init(struct audio_device *adev)
my_data->acdb_init(snd_card_name);
}
+ set_platform_defaults();
+
/* Initialize ACDB ID's */
if (my_data->is_i2s_ext_modem)
platform_info_init(PLATFORM_INFO_XML_PATH_I2S);
@@ -812,6 +858,14 @@ void platform_deinit(void *platform)
hw_info_deinit(my_data->hw_info);
close_csd_client(my_data->csd);
+ int32_t dev;
+ for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
+ if (backend_table[dev]) {
+ free(backend_table[dev]);
+ backend_table[dev]= NULL;
+ }
+ }
+
free(platform);
/* deinit usb */
audio_extn_usb_deinit();
@@ -844,37 +898,16 @@ int platform_get_snd_device_name_extn(void *platform, snd_device_t snd_device,
void platform_add_backend_name(char *mixer_path, snd_device_t snd_device)
{
- if (snd_device == SND_DEVICE_IN_BT_SCO_MIC)
- strlcat(mixer_path, " bt-sco", MIXER_PATH_MAX_LENGTH);
- else if (snd_device == SND_DEVICE_IN_BT_SCO_MIC_WB)
- strlcat(mixer_path, " bt-sco-wb", MIXER_PATH_MAX_LENGTH);
- else if(snd_device == SND_DEVICE_OUT_BT_SCO)
- strlcat(mixer_path, " bt-sco", MIXER_PATH_MAX_LENGTH);
- else if(snd_device == SND_DEVICE_OUT_BT_SCO_WB)
- strlcat(mixer_path, " bt-sco-wb", MIXER_PATH_MAX_LENGTH);
- else if (snd_device == SND_DEVICE_OUT_HDMI)
- strlcat(mixer_path, " hdmi", MIXER_PATH_MAX_LENGTH);
- else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HDMI)
- strcat(mixer_path, " speaker-and-hdmi");
- else if (snd_device == SND_DEVICE_OUT_AFE_PROXY)
- strlcat(mixer_path, " afe-proxy", MIXER_PATH_MAX_LENGTH);
- else if (snd_device == SND_DEVICE_OUT_USB_HEADSET)
- strlcat(mixer_path, " usb-headphones", MIXER_PATH_MAX_LENGTH);
- else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET)
- strlcat(mixer_path, " speaker-and-usb-headphones",
- MIXER_PATH_MAX_LENGTH);
- else if (snd_device == SND_DEVICE_IN_USB_HEADSET_MIC)
- strlcat(mixer_path, " usb-headset-mic", MIXER_PATH_MAX_LENGTH);
- else if (snd_device == SND_DEVICE_IN_CAPTURE_FM)
- strlcat(mixer_path, " capture-fm", MIXER_PATH_MAX_LENGTH);
- else if (snd_device == SND_DEVICE_OUT_TRANSMISSION_FM)
- strlcat(mixer_path, " transmission-fm", MIXER_PATH_MAX_LENGTH);
- else if (snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
- audio_extn_spkr_prot_is_enabled() ) {
- char platform[PROPERTY_VALUE_MAX];
- property_get("ro.board.platform", platform, "");
- if (!strncmp("apq8084", platform, sizeof("apq8084")))
- strlcat(mixer_path, " speaker-protected", MIXER_PATH_MAX_LENGTH);
+ if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
+ ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
+ return;
+ }
+
+ const char * suffix = backend_table[snd_device];
+
+ if (suffix != NULL) {
+ strlcat(mixer_path, " ", MIXER_PATH_MAX_LENGTH);
+ strlcat(mixer_path, suffix, MIXER_PATH_MAX_LENGTH);
}
}
@@ -888,25 +921,36 @@ 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)
+static int find_index(struct name_to_index * table, int32_t len, const char * name)
{
int ret = 0;
- int i;
+ int32_t i;
+
+ if (table == NULL) {
+ ALOGE("%s: table is NULL", __func__);
+ ret = -ENODEV;
+ goto done;
+ }
- if (snd_device_index_name == NULL) {
- ALOGE("%s: snd_device_index_name is NULL", __func__);
+ if (name == NULL) {
+ ALOGE("null key");
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;
+ for (i=0; i < len; i++) {
+ const char* tn = table[i].name;
+ size_t len = strlen(tn);
+ if (strncmp(tn, name, len) == 0) {
+ if (strlen(name) != len) {
+ continue; // substring
+ }
+ ret = table[i].index;
goto done;
}
}
- ALOGE("%s: Could not find index for snd_device_index_name = %s",
- __func__, snd_device_index_name);
+ ALOGE("%s: Could not find index for name = %s",
+ __func__, name);
ret = -ENODEV;
done:
return ret;
@@ -969,6 +1013,16 @@ int platform_get_fluence_type(void *platform, char *value, uint32_t len)
return ret;
}
+int platform_get_snd_device_index(char *device_name)
+{
+ return find_index(snd_device_name_index, SND_DEVICE_MAX, device_name);
+}
+
+int platform_get_usecase_index(const char *usecase_name)
+{
+ return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
+}
+
int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
{
int ret = 0;
@@ -2485,3 +2539,40 @@ int platform_set_device_params(struct stream_out *out, int param, int value)
end:
return ret;
}
+
+int platform_set_snd_device_backend(snd_device_t device, const char *backend)
+{
+ int ret = 0;
+
+ if ((device < SND_DEVICE_MIN) || (device >= SND_DEVICE_MAX)) {
+ ALOGE("%s: Invalid snd_device = %d",
+ __func__, device);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (backend_table[device]) {
+ free(backend_table[device]);
+ }
+ backend_table[device] = strdup(backend);
+done:
+ return ret;
+}
+
+int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id)
+{
+ int ret = 0;
+ if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) {
+ ALOGE("%s: invalid usecase case idx %d", __func__, usecase);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if ((type != 0) && (type != 1)) {
+ ALOGE("%s: invalid usecase type", __func__);
+ ret = -EINVAL;
+ }
+ pcm_device_table[usecase][type] = pcm_id;
+done:
+ return ret;
+}
diff --git a/hal/platform_api.h b/hal/platform_api.h
index bedfb750..f91c1d85 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -69,6 +69,8 @@ int platform_update_usecase_from_source(int source, audio_usecase_t usecase);
bool platform_listen_update_status(snd_device_t snd_device);
+int platform_set_snd_device_backend(snd_device_t snd_device, const char * backend);
+
/* From platform_info_parser.c */
int platform_info_init(const char *filename);
@@ -88,4 +90,7 @@ unsigned char platform_map_to_edid_format(int format);
bool platform_is_edid_supported_format(void *platform, int format);
int platform_set_hdmi_format_and_samplerate(struct stream_out *out);
int platform_set_device_params(struct stream_out *out, int param, int value);
+int platform_get_usecase_index(const char * usecase);
+int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id);
+
#endif // AUDIO_PLATFORM_API_H
diff --git a/hal/platform_info.c b/hal/platform_info.c
index 047ac4c6..3188c867 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -40,7 +40,137 @@
#define BUF_SIZE 1024
-static void process_device(const XML_Char **attr)
+typedef enum {
+ ROOT,
+ ACDB,
+ PCM_ID,
+ BACKEND_NAME,
+} section_t;
+
+typedef void (* section_process_fn)(const XML_Char **attr);
+
+static void process_acdb_id(const XML_Char **attr);
+static void process_pcm_id(const XML_Char **attr);
+static void process_backend_name(const XML_Char **attr);
+static void process_root(const XML_Char **attr);
+
+static section_process_fn section_table[] = {
+ [ROOT] = process_root,
+ [ACDB] = process_acdb_id,
+ [PCM_ID] = process_pcm_id,
+ [BACKEND_NAME] = process_backend_name,
+};
+
+static section_t section;
+
+/*
+ * <audio_platform_info>
+ * <acdb_ids>
+ * <device name="???" acdb_id="???"/>
+ * ...
+ * ...
+ * </acdb_ids>
+ * <backend_names>
+ * <device name="???" backend="???"/>
+ * ...
+ * ...
+ * </backend_names>
+ * <pcm_ids>
+ * <usecase name="???" type="in/out" id="???"/>
+ * ...
+ * ...
+ * </pcm_ids>
+ * </audio_platform_info>
+ */
+
+static void process_root(const XML_Char **attr __unused)
+{
+}
+
+/* mapping from usecase to pcm dev id */
+static void process_pcm_id(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_usecase_index((char *)attr[1]);
+ if (index < 0) {
+ ALOGE("%s: usecase %s not found!",
+ __func__, attr[1]);
+ goto done;
+ }
+
+ if (strcmp(attr[2], "type") != 0) {
+ ALOGE("%s: usecase type not mentioned", __func__);
+ goto done;
+ }
+
+ int type = -1;
+
+ if (!strcasecmp((char *)attr[3], "in")) {
+ type = 1;
+ } else if (!strcasecmp((char *)attr[3], "out")) {
+ type = 0;
+ } else {
+ ALOGE("%s: type must be IN or OUT", __func__);
+ goto done;
+ }
+
+ if (strcmp(attr[4], "id") != 0) {
+ ALOGE("%s: usecase id not mentioned", __func__);
+ goto done;
+ }
+
+ int id = atoi((char *)attr[5]);
+
+ if (platform_set_usecase_pcm_id(index, type, id) < 0) {
+ ALOGE("%s: usecase %s type %d id %d was not set!",
+ __func__, attr[1], type, id);
+ goto done;
+ }
+
+done:
+ return;
+}
+
+/* backend to be used for a device */
+static void process_backend_name(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 not found, no ACDB ID set!",
+ __func__, attr[1]);
+ goto done;
+ }
+
+ if (strcmp(attr[2], "backend") != 0) {
+ ALOGE("%s: Device %s has no backend set!",
+ __func__, attr[1]);
+ goto done;
+ }
+
+ if (platform_set_snd_device_backend(index, attr[3]) < 0) {
+ ALOGE("%s: Device %s backend %s was not set!",
+ __func__, attr[1], attr[3]);
+ goto done;
+ }
+
+done:
+ return;
+}
+
+static void process_acdb_id(const XML_Char **attr)
{
int index;
@@ -62,8 +192,8 @@ static void process_device(const XML_Char **attr)
goto done;
}
- if(platform_set_snd_device_acdb_id(index, atoi((char *)attr[3])) < 0) {
- ALOGE("%s: Device %s in platform info xml ACDB ID %d was not set!",
+ if (platform_set_snd_device_acdb_id(index, atoi((char *)attr[3])) < 0) {
+ ALOGE("%s: Device %s, ACDB ID %d was not set!",
__func__, attr[1], atoi((char *)attr[3]));
goto done;
}
@@ -79,15 +209,43 @@ static void start_tag(void *userdata __unused, const XML_Char *tag_name,
const XML_Char *attr_value = NULL;
unsigned int i;
- if (strcmp(tag_name, "device") == 0)
- process_device(attr);
+ if (strcmp(tag_name, "acdb_ids") == 0) {
+ section = ACDB;
+ } else if (strcmp(tag_name, "pcm_ids") == 0) {
+ section = PCM_ID;
+ } else if (strcmp(tag_name, "backend_names") == 0) {
+ section = BACKEND_NAME;
+ } else if (strcmp(tag_name, "device") == 0) {
+ if ((section != ACDB) && (section != BACKEND_NAME)) {
+ ALOGE("device tag only supported for acdb/backend names");
+ return;
+ }
+
+ /* call into process function for the current section */
+ section_process_fn fn = section_table[section];
+ fn(attr);
+ } else if (strcmp(tag_name, "usecase") == 0) {
+ if (section != PCM_ID) {
+ ALOGE("usecase tag only supported with PCM_ID section");
+ return;
+ }
+
+ section_process_fn fn = section_table[PCM_ID];
+ fn(attr);
+ }
return;
}
static void end_tag(void *userdata __unused, const XML_Char *tag_name __unused)
{
-
+ if (strcmp(tag_name, "acdb_ids") == 0) {
+ section = ROOT;
+ } else if (strcmp(tag_name, "pcm_ids") == 0) {
+ section = ROOT;
+ } else if (strcmp(tag_name, "backend_names") == 0) {
+ section = ROOT;
+ }
}
int platform_info_init(const char *filename)
@@ -99,6 +257,8 @@ int platform_info_init(const char *filename)
void *buf;
file = fopen(filename, "r");
+ section = ROOT;
+
if (!file) {
ALOGD("%s: Failed to open %s, using defaults.",
__func__, filename);