summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkeunhui.park <keunhui.park@lge.com>2015-08-05 17:20:00 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2015-08-05 17:20:00 +0000
commit278ae2b58d5f365f426012cde24e4bc979eb89e5 (patch)
tree7f9032697b5315f6d3850cce9fca1946d73a5f15
parent075842f2ff6967b34b3c146c3393ce01d6de6db1 (diff)
parent2f7306a9dae56a1204e8ec090198ce76b167bfa9 (diff)
downloadhardware_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.c7
-rw-r--r--hal/msm8974/platform.c182
-rw-r--r--hal/platform_api.h4
-rw-r--r--hal/platform_info.c57
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;
}
}