diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2014-10-10 06:28:15 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2014-10-10 06:28:15 -0700 |
commit | 07ce65e52f96c4a1989017d5f61ca75ec316f2b8 (patch) | |
tree | 35364ef2912a920c1cfc4d2b5b4c7903be54c47d | |
parent | d5a03f06d21ce9b009a29405d381d426b67cb463 (diff) | |
parent | 2275675f25e31ffb8f135a1634974e6a3c2cd931 (diff) | |
download | android_hardware_qcom_audio-07ce65e52f96c4a1989017d5f61ca75ec316f2b8.tar.gz android_hardware_qcom_audio-07ce65e52f96c4a1989017d5f61ca75ec316f2b8.tar.bz2 android_hardware_qcom_audio-07ce65e52f96c4a1989017d5f61ca75ec316f2b8.zip |
Merge "audio: extend platform parser"
-rw-r--r-- | hal/audio_extn/spkr_protection.c | 9 | ||||
-rw-r--r-- | hal/msm8960/platform.c | 17 | ||||
-rw-r--r-- | hal/msm8974/platform.c | 177 | ||||
-rw-r--r-- | hal/platform_api.h | 5 | ||||
-rw-r--r-- | hal/platform_info.c | 172 |
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); |