diff options
author | keunhui.park <keunhui.park@lge.com> | 2015-08-05 17:20:00 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-08-05 17:20:00 +0000 |
commit | 278ae2b58d5f365f426012cde24e4bc979eb89e5 (patch) | |
tree | 7f9032697b5315f6d3850cce9fca1946d73a5f15 | |
parent | 075842f2ff6967b34b3c146c3393ce01d6de6db1 (diff) | |
parent | 2f7306a9dae56a1204e8ec090198ce76b167bfa9 (diff) | |
download | hardware_qcom_audio-278ae2b58d5f365f426012cde24e4bc979eb89e5.tar.gz hardware_qcom_audio-278ae2b58d5f365f426012cde24e4bc979eb89e5.tar.bz2 hardware_qcom_audio-278ae2b58d5f365f426012cde24e4bc979eb89e5.zip |
am 2f7306a9: audio: add operator specific device change
* commit '2f7306a9dae56a1204e8ec090198ce76b167bfa9':
audio: add operator specific device change
-rw-r--r-- | hal/msm8960/platform.c | 7 | ||||
-rw-r--r-- | hal/msm8974/platform.c | 182 | ||||
-rw-r--r-- | hal/platform_api.h | 4 | ||||
-rw-r--r-- | hal/platform_info.c | 57 |
4 files changed, 236 insertions, 14 deletions
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c index 2f596bac..06663a4a 100644 --- a/hal/msm8960/platform.c +++ b/hal/msm8960/platform.c @@ -423,6 +423,13 @@ int platform_get_snd_device_acdb_id(snd_device_t snd_device __unused) return -ENOSYS; } +void platform_add_operator_specific_device(snd_device_t snd_device, + const char *operator, + const char *mixer_path, + unsigned int acdb_id) +{ +} + 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 c697ed88..7b1fa75c 100644 --- a/hal/msm8974/platform.c +++ b/hal/msm8974/platform.c @@ -78,6 +78,24 @@ enum { CAL_MODE_RTAC = 0x4 }; +#define PLATFORM_CONFIG_KEY_OPERATOR_INFO "operator_info" + +struct operator_info { + struct listnode list; + char *name; + char *mccmnc; +}; + +struct operator_specific_device { + struct listnode list; + char *operator; + char *mixer_path; + int acdb_id; +}; + +static struct listnode operator_info_list; +static struct listnode *operator_specific_device_table[SND_DEVICE_MAX]; + /* Audio calibration related functions */ typedef void (*acdb_deallocate_t)(); typedef int (*acdb_init_v2_cvd_t)(char *, char *); @@ -458,6 +476,71 @@ bool is_operator_tmus() return is_tmus; } +static char *get_current_operator() +{ + struct listnode *node; + struct operator_info *info_item; + char mccmnc[PROPERTY_VALUE_MAX]; + char *ret = NULL; + + property_get("gsm.sim.operator.numeric",mccmnc,"0"); + + list_for_each(node, &operator_info_list) { + info_item = node_to_item(node, struct operator_info, list); + if (strstr(info_item->mccmnc, mccmnc) != NULL) { + ret = info_item->name; + } + } + + return ret; +} + +static struct operator_specific_device *get_operator_specific_device(snd_device_t snd_device) +{ + struct listnode *node; + struct operator_specific_device *ret = NULL; + struct operator_specific_device *device_item; + char *operator_name; + + operator_name = get_current_operator(); + if (operator_name == NULL) + return ret; + + list_for_each(node, operator_specific_device_table[snd_device]) { + device_item = node_to_item(node, struct operator_specific_device, list); + if (strcmp(operator_name, device_item->operator) == 0) { + ret = device_item; + } + } + + return ret; +} + + +static int get_operator_specific_device_acdb_id(snd_device_t snd_device) +{ + struct operator_specific_device *device; + int ret = acdb_device_table[snd_device]; + + device = get_operator_specific_device(snd_device); + if (device != NULL) + ret = device->acdb_id; + + return ret; +} + +static const char *get_operator_specific_device_mixer_path(snd_device_t snd_device) +{ + struct operator_specific_device *device; + const char *ret = device_table[snd_device]; + + device = get_operator_specific_device(snd_device); + if (device != NULL) + ret = device->mixer_path; + + return ret; +} + bool platform_send_gain_dep_cal(void *platform, int level) { bool ret_val = false; @@ -723,6 +806,7 @@ static void set_platform_defaults(struct platform_data * my_data __unused) for (dev = 0; dev < SND_DEVICE_MAX; dev++) { backend_tag_table[dev] = NULL; hw_interface_table[dev] = NULL; + operator_specific_device_table[dev] = NULL; } // To overwrite these go to the audio_platform_info.xml file. @@ -804,6 +888,8 @@ void *platform_init(struct audio_device *adev) my_data->adev = adev; + list_init(&operator_info_list); + set_platform_defaults(my_data); /* Initialize platform specific ids and/or backends*/ @@ -993,6 +1079,9 @@ init_failed: void platform_deinit(void *platform) { int32_t dev; + struct operator_info *info_item; + struct operator_specific_device *device_item; + struct listnode *node; struct platform_data *my_data = (struct platform_data *)platform; close_csd_client(my_data->csd); @@ -1002,19 +1091,42 @@ void platform_deinit(void *platform) free(backend_tag_table[dev]); if (hw_interface_table[dev]) free(hw_interface_table[dev]); + if (operator_specific_device_table[dev]) { + while (!list_empty(operator_specific_device_table[dev])) { + node = list_head(operator_specific_device_table[dev]); + list_remove(node); + device_item = node_to_item(node, struct operator_specific_device, list); + free(device_item->operator); + free(device_item->mixer_path); + free(device_item); + } + free(operator_specific_device_table[dev]); + } } if (my_data->snd_card_name) free(my_data->snd_card_name); + while (!list_empty(&operator_info_list)) { + node = list_head(&operator_info_list); + list_remove(node); + info_item = node_to_item(node, struct operator_info, list); + free(info_item->name); + free(info_item->mccmnc); + free(info_item); + } + free(platform); } const char *platform_get_snd_device_name(snd_device_t snd_device) { - if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) + if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) { + if (operator_specific_device_table[snd_device] != NULL) { + return get_operator_specific_device_mixer_path(snd_device); + } return device_table[snd_device]; - else + } else return "none"; } @@ -1117,6 +1229,32 @@ int platform_get_usecase_index(const char *usecase_name) return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name); } +void platform_add_operator_specific_device(snd_device_t snd_device, + const char *operator, + const char *mixer_path, + unsigned int acdb_id) +{ + struct operator_specific_device *device; + + if (operator_specific_device_table[snd_device] == NULL) { + operator_specific_device_table[snd_device] = + (struct listnode *)calloc(1, sizeof(struct listnode)); + list_init(operator_specific_device_table[snd_device]); + } + + device = (struct operator_specific_device *)calloc(1, sizeof(struct operator_specific_device)); + + device->operator = strdup(operator); + device->mixer_path = strdup(mixer_path); + device->acdb_id = acdb_id; + + list_add_tail(operator_specific_device_table[snd_device], &device->list); + + ALOGD("%s : deivce[%s] -> operator[%s] mixer_path[%s] acdb_id [%d]", __func__, + platform_get_snd_device_name(snd_device), operator, mixer_path, acdb_id); + +} + int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id) { int ret = 0; @@ -1141,7 +1279,11 @@ int platform_get_snd_device_acdb_id(snd_device_t snd_device) ALOGE("%s: Invalid snd_device = %d", __func__, snd_device); return -EINVAL; } - return acdb_device_table[snd_device]; + + if (operator_specific_device_table[snd_device] != NULL) + return get_operator_specific_device_acdb_id(snd_device); + else + return acdb_device_table[snd_device]; } int platform_send_audio_calibration(void *platform, snd_device_t snd_device) @@ -1198,11 +1340,11 @@ int platform_switch_voice_call_enable_device_config(void *platform, if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER && audio_extn_spkr_prot_is_enabled()) - acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED]; + acdb_rx_id = platform_get_snd_device_acdb_id(SND_DEVICE_OUT_SPEAKER_PROTECTED); else - acdb_rx_id = acdb_device_table[out_snd_device]; + acdb_rx_id = platform_get_snd_device_acdb_id(out_snd_device); - acdb_tx_id = acdb_device_table[in_snd_device]; + acdb_tx_id = platform_get_snd_device_acdb_id(in_snd_device); if (acdb_rx_id > 0 && acdb_tx_id > 0) { ret = my_data->csd->enable_device_config(acdb_rx_id, acdb_tx_id); @@ -1232,8 +1374,8 @@ int platform_switch_voice_call_device_post(void *platform, audio_extn_spkr_prot_is_enabled()) out_snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED; - acdb_rx_id = acdb_device_table[out_snd_device]; - acdb_tx_id = acdb_device_table[in_snd_device]; + acdb_rx_id = platform_get_snd_device_acdb_id(out_snd_device); + acdb_tx_id = platform_get_snd_device_acdb_id(in_snd_device); if (acdb_rx_id > 0 && acdb_tx_id > 0) my_data->acdb_send_voice_cal(acdb_rx_id, acdb_tx_id); @@ -1258,11 +1400,11 @@ int platform_switch_voice_call_usecase_route_post(void *platform, if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER && audio_extn_spkr_prot_is_enabled()) - acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED]; + acdb_rx_id = platform_get_snd_device_acdb_id(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED); else - acdb_rx_id = acdb_device_table[out_snd_device]; + acdb_rx_id = platform_get_snd_device_acdb_id(out_snd_device); - acdb_tx_id = acdb_device_table[in_snd_device]; + acdb_tx_id = platform_get_snd_device_acdb_id(in_snd_device); if (acdb_rx_id > 0 && acdb_tx_id > 0) { ret = my_data->csd->enable_device(acdb_rx_id, acdb_tx_id, @@ -2010,7 +2152,7 @@ int platform_stop_incall_music_usecase(void *platform) int platform_set_parameters(void *platform, struct str_parms *parms) { struct platform_data *my_data = (struct platform_data *)platform; - char value[64]; + char value[128]; char *kv_pairs = str_parms_to_str(parms); int ret = 0, err; @@ -2030,6 +2172,22 @@ int platform_set_parameters(void *platform, struct str_parms *parms) ALOGV("%s: sound card name %s", __func__, my_data->snd_card_name); } + err = str_parms_get_str(parms, PLATFORM_CONFIG_KEY_OPERATOR_INFO, + value, sizeof(value)); + if (err >= 0) { + struct operator_info *info; + char *str = value; + char *name; + + str_parms_del(parms, PLATFORM_CONFIG_KEY_OPERATOR_INFO); + info = (struct operator_info *)calloc(1, sizeof(struct operator_info)); + name = strtok(str, ";"); + info->name = strdup(name); + info->mccmnc = strdup(str + strlen(name) + 1); + + list_add_tail(&operator_info_list, &info->list); + ALOGD("%s: add operator[%s] mccmnc[%s]", __func__, info->name, info->mccmnc); + } done: ALOGV("%s: exit with code(%d)", __func__, ret); if (kv_pairs != NULL) diff --git a/hal/platform_api.h b/hal/platform_api.h index 61bb92f6..569577e4 100644 --- a/hal/platform_api.h +++ b/hal/platform_api.h @@ -48,6 +48,10 @@ snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devi snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device); int platform_set_hdmi_channels(void *platform, int channel_count); int platform_edid_get_max_channels(void *platform); +void platform_add_operator_specific_device(snd_device_t snd_device, + const char *operator, + const char *mixer_path, + unsigned int acdb_id); /* returns the latency for a usecase in Us */ int64_t platform_render_latency(audio_usecase_t usecase); diff --git a/hal/platform_info.c b/hal/platform_info.c index c0527b4b..45562947 100644 --- a/hal/platform_info.c +++ b/hal/platform_info.c @@ -33,6 +33,7 @@ typedef enum { PCM_ID, BACKEND_NAME, CONFIG_PARAMS, + OPERATOR_SPECIFIC, } section_t; typedef void (* section_process_fn)(const XML_Char **attr); @@ -42,6 +43,7 @@ static void process_pcm_id(const XML_Char **attr); static void process_backend_name(const XML_Char **attr); static void process_config_params(const XML_Char **attr); static void process_root(const XML_Char **attr); +static void process_operator_specific(const XML_Char **attr); static section_process_fn section_table[] = { [ROOT] = process_root, @@ -49,6 +51,7 @@ static section_process_fn section_table[] = { [PCM_ID] = process_pcm_id, [BACKEND_NAME] = process_backend_name, [CONFIG_PARAMS] = process_config_params, + [OPERATOR_SPECIFIC] = process_operator_specific, }; static section_t section; @@ -79,10 +82,18 @@ static struct platform_info my_data; * </pcm_ids> * <config_params> * <param key="snd_card_name" value="msm8994-tomtom-mtp-snd-card"/> + * <param key="operator_info" value="tmus;aa;bb;cc"/> + * <param key="operator_info" value="sprint;xx;yy;zz"/> * ... * ... * </config_params> * + * <operator_specific> + * <device name="???" operator="???" mixer_path="???" acdb_id="???"/> + * ... + * ... + * </operator_specific> + * * </audio_platform_info> */ @@ -214,6 +225,44 @@ done: return; } + +static void process_operator_specific(const XML_Char **attr) +{ + snd_device_t snd_device = SND_DEVICE_NONE; + + if (strcmp(attr[0], "name") != 0) { + ALOGE("%s: 'name' not found", __func__); + goto done; + } + + snd_device = platform_get_snd_device_index((char *)attr[1]); + if (snd_device < 0) { + ALOGE("%s: Device %s in %s not found, no ACDB ID set!", + __func__, (char *)attr[3], PLATFORM_INFO_XML_PATH); + goto done; + } + + if (strcmp(attr[2], "operator") != 0) { + ALOGE("%s: 'operator' not found", __func__); + goto done; + } + + if (strcmp(attr[4], "mixer_path") != 0) { + ALOGE("%s: 'mixer_path' not found", __func__); + goto done; + } + + if (strcmp(attr[6], "acdb_id") != 0) { + ALOGE("%s: 'acdb_id' not found", __func__); + goto done; + } + + platform_add_operator_specific_device(snd_device, (char *)attr[3], (char *)attr[5], atoi((char *)attr[7])); + +done: + return; +} + /* platform specific configuration key-value pairs */ static void process_config_params(const XML_Char **attr) { @@ -228,6 +277,7 @@ static void process_config_params(const XML_Char **attr) } str_parms_add_str(my_data.kvpairs, (char*)attr[1], (char*)attr[3]); + platform_set_parameters(my_data.platform, my_data.kvpairs); done: return; } @@ -247,8 +297,10 @@ static void start_tag(void *userdata __unused, const XML_Char *tag_name, section = BACKEND_NAME; } else if (strcmp(tag_name, "config_params") == 0) { section = CONFIG_PARAMS; + } else if (strcmp(tag_name, "operator_specific") == 0) { + section = OPERATOR_SPECIFIC; } else if (strcmp(tag_name, "device") == 0) { - if ((section != ACDB) && (section != BACKEND_NAME)) { + if ((section != ACDB) && (section != BACKEND_NAME) && (section != OPERATOR_SPECIFIC)) { ALOGE("device tag only supported for acdb/backend names"); return; } @@ -287,7 +339,8 @@ static void end_tag(void *userdata __unused, const XML_Char *tag_name) section = ROOT; } else if (strcmp(tag_name, "config_params") == 0) { section = ROOT; - platform_set_parameters(my_data.platform, my_data.kvpairs); + } else if (strcmp(tag_name, "operator_specific") == 0) { + section = ROOT; } } |