hal: add support to set custom channel configs
Add generic implementation to set custom channel configs
as per usecase config present in platform info xml.
Each usecase identified by usecase id, input channels,
output channels, snd_device and feature id can have
a separate channel config.
Change-Id: I957b5b06adbcd17f65ed49b839327bf8e9e8b318
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index e03230a..20d760c 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -373,6 +373,157 @@
}
#endif /* CUSTOM_STEREO_ENABLED */
+static int update_custom_mtmx_coefficients(struct audio_device *adev,
+ struct audio_custom_mtmx_params *params,
+ int pcm_device_id)
+{
+ struct mixer_ctl *ctl = NULL;
+ char *mixer_name_prefix = "AudStr";
+ char *mixer_name_suffix = "ChMixer Weight Ch";
+ char mixer_ctl_name[128] = {0};
+ struct audio_custom_mtmx_params_info *pinfo = ¶ms->info;
+ int i = 0, err = 0;
+
+ ALOGI("%s: ip_channels %d, op_channels %d, pcm_device_id %d",
+ __func__, pinfo->ip_channels, pinfo->op_channels, pcm_device_id);
+
+ for (i = 0; i < (int)pinfo->op_channels; i++) {
+ snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "%s %d %s %d",
+ mixer_name_prefix, pcm_device_id, mixer_name_suffix, i+1);
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
+ __func__, mixer_ctl_name);
+ return -EINVAL;
+ }
+
+ err = mixer_ctl_set_array(ctl,
+ ¶ms->coeffs[pinfo->ip_channels * i],
+ pinfo->ip_channels);
+ if (err) {
+ ALOGE("%s: ERROR. Mixer ctl set failed", __func__);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static void set_custom_mtmx_params(struct audio_device *adev,
+ struct audio_custom_mtmx_params_info *pinfo,
+ int pcm_device_id, bool enable)
+{
+ struct mixer_ctl *ctl = NULL;
+ char *mixer_name_prefix = "AudStr";
+ char *mixer_name_suffix = "ChMixer Cfg";
+ char mixer_ctl_name[128] = {0};
+ int chmixer_cfg[5] = {0}, len = 0;
+ int be_id = -1, err = 0;
+
+ be_id = platform_get_snd_device_backend_index(pinfo->snd_device);
+
+ ALOGI("%s: ip_channels %d,op_channels %d,pcm_device_id %d,be_id %d",
+ __func__, pinfo->ip_channels, pinfo->op_channels, pcm_device_id, be_id);
+
+ snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+ "%s %d %s", mixer_name_prefix, pcm_device_id, mixer_name_suffix);
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
+ __func__, mixer_ctl_name);
+ return;
+ }
+ chmixer_cfg[len++] = enable ? 1 : 0;
+ chmixer_cfg[len++] = 0; /* rule index */
+ chmixer_cfg[len++] = pinfo->ip_channels;
+ chmixer_cfg[len++] = pinfo->op_channels;
+ chmixer_cfg[len++] = be_id + 1;
+
+ err = mixer_ctl_set_array(ctl, chmixer_cfg, len);
+ if (err)
+ ALOGE("%s: ERROR. Mixer ctl set failed", __func__);
+}
+
+void audio_extn_set_custom_mtmx_params(struct audio_device *adev,
+ struct audio_usecase *usecase,
+ bool enable)
+{
+ struct audio_custom_mtmx_params_info info = {0};
+ struct audio_custom_mtmx_params *params = NULL;
+ int num_devices = 0, pcm_device_id = -1, i = 0, ret = 0;
+ snd_device_t new_snd_devices[SND_DEVICE_OUT_END] = {0};
+ struct audio_backend_cfg backend_cfg = {0};
+ uint32_t feature_id = 0;
+
+ switch(usecase->type) {
+ case PCM_PLAYBACK:
+ if (usecase->stream.out) {
+ pcm_device_id =
+ platform_get_pcm_device_id(usecase->id, PCM_PLAYBACK);
+ if (platform_split_snd_device(adev->platform,
+ usecase->out_snd_device,
+ &num_devices, new_snd_devices)) {
+ new_snd_devices[0] = usecase->out_snd_device;
+ num_devices = 1;
+ }
+ } else {
+ ALOGE("%s: invalid output stream for playback usecase id:%d",
+ __func__, usecase->id);
+ return;
+ }
+ break;
+ case PCM_CAPTURE:
+ if (usecase->stream.in) {
+ pcm_device_id =
+ platform_get_pcm_device_id(usecase->id, PCM_CAPTURE);
+ if (platform_split_snd_device(adev->platform,
+ usecase->in_snd_device,
+ &num_devices, new_snd_devices)) {
+ new_snd_devices[0] = usecase->in_snd_device;
+ num_devices = 1;
+ }
+ } else {
+ ALOGE("%s: invalid input stream for capture usecase id:%d",
+ __func__, usecase->id);
+ return;
+ }
+ break;
+ default:
+ ALOGV("%s: unsupported usecase id:%d", __func__, usecase->id);
+ return;
+ }
+
+ /*
+ * check and update feature_id before this assignment,
+ * if features like dual_mono is enabled and overrides the default(i.e. 0).
+ */
+ info.id = feature_id;
+ info.usecase_id = usecase->id;
+ for (i = 0, ret = 0; i < num_devices; i++) {
+ info.snd_device = new_snd_devices[i];
+ platform_get_codec_backend_cfg(adev, info.snd_device, &backend_cfg);
+ if (usecase->type == PCM_PLAYBACK) {
+ info.ip_channels = audio_channel_count_from_out_mask(
+ usecase->stream.out->channel_mask);
+ info.op_channels = backend_cfg.channels;
+ } else {
+ info.ip_channels = backend_cfg.channels;
+ info.op_channels = audio_channel_count_from_in_mask(
+ usecase->stream.in->channel_mask);
+ }
+
+ params = platform_get_custom_mtmx_params(adev->platform, &info);
+ if (params) {
+ if (enable)
+ ret = update_custom_mtmx_coefficients(adev, params,
+ pcm_device_id);
+ if (ret < 0)
+ ALOGE("%s: error updating mtmx coeffs err:%d", __func__, ret);
+ else
+ set_custom_mtmx_params(adev, &info, pcm_device_id, enable);
+ }
+ }
+}
+
#ifndef DTS_EAGLE
#define audio_extn_hpx_set_parameters(adev, parms) (0)
#define audio_extn_hpx_get_parameters(query, reply) (0)
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 6fa6b78..6b08671 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -1141,4 +1141,7 @@
#else
void audio_extn_send_dual_mono_mixing_coefficients(struct stream_out *out);
#endif
+void audio_extn_set_custom_mtmx_params(struct audio_device *adev,
+ struct audio_usecase *usecase,
+ bool enable);
#endif /* AUDIO_EXTN_H */
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 91f2a74..13dd4a0 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -992,6 +992,7 @@
if (out && out->compr)
audio_extn_utils_compress_set_clk_rec_mode(usecase);
}
+ audio_extn_set_custom_mtmx_params(adev, usecase, true);
strlcpy(mixer_path, use_case_table[usecase->id], MIXER_PATH_MAX_LENGTH);
platform_add_backend_name(mixer_path, snd_device, usecase);
@@ -1028,6 +1029,7 @@
audio_route_reset_and_update_path(adev->audio_route, mixer_path);
audio_extn_sound_trigger_update_stream_status(usecase, ST_EVENT_STREAM_FREE);
audio_extn_listen_update_stream_status(usecase, LISTEN_EVENT_STREAM_FREE);
+ audio_extn_set_custom_mtmx_params(adev, usecase, false);
ALOGV("%s: exit", __func__);
return 0;
}
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index a900ecd..263fe9f 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -306,6 +306,7 @@
uint32_t declared_mic_count;
struct audio_microphone_characteristic_t microphones[AUDIO_MICROPHONE_MAX_COUNT];
struct snd_device_to_mic_map mic_map[SND_DEVICE_MAX];
+ struct listnode custom_mtmx_params_list;
};
static bool is_external_codec = false;
@@ -2413,6 +2414,7 @@
my_data->hifi_audio = true;
list_init(&my_data->acdb_meta_key_list);
+ list_init(&my_data->custom_mtmx_params_list);
set_platform_defaults(my_data);
@@ -2783,6 +2785,86 @@
return my_data;
}
+struct audio_custom_mtmx_params *
+ platform_get_custom_mtmx_params(void *platform,
+ struct audio_custom_mtmx_params_info *info)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ struct listnode *node = NULL;
+ struct audio_custom_mtmx_params *params = NULL;
+
+ list_for_each(node, &my_data->custom_mtmx_params_list) {
+ params = node_to_item(node, struct audio_custom_mtmx_params, list);
+ if (params &&
+ params->info.id == info->id &&
+ params->info.ip_channels == info->ip_channels &&
+ params->info.op_channels == info->op_channels &&
+ params->info.usecase_id == info->usecase_id &&
+ params->info.snd_device == info->snd_device) {
+ ALOGV("%s: found params with ip_ch %d op_ch %d uc_id %d snd_dev %d",
+ __func__, info->ip_channels, info->op_channels,
+ info->usecase_id, info->snd_device);
+ return params;
+ }
+ }
+ ALOGI("%s: no matching param with id %d ip_ch %d op_ch %d uc_id %d snd_dev %d",
+ __func__, info->id, info->ip_channels, info->op_channels,
+ info->usecase_id, info->snd_device);
+ return NULL;
+}
+
+int platform_add_custom_mtmx_params(void *platform,
+ struct audio_custom_mtmx_params_info *info)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ struct audio_custom_mtmx_params *params = NULL;
+ uint32_t size = sizeof(*params);
+
+ if (info->ip_channels > AUDIO_CHANNEL_COUNT_MAX ||
+ info->op_channels > AUDIO_CHANNEL_COUNT_MAX) {
+ ALOGE("%s: unusupported channels in %d, out %d",
+ __func__, info->ip_channels, info->op_channels);
+ return -EINVAL;
+ }
+
+ size += sizeof(params->coeffs[0]) * info->ip_channels * info->op_channels;
+ params = (struct audio_custom_mtmx_params *) calloc(1, size);
+ if (!params) {
+ ALOGE("%s: failed to add custom mtmx params", __func__);
+ return -ENOMEM;
+ }
+
+ ALOGI("%s: adding mtmx params with id %d ip_ch %d op_ch %d uc_id %d snd_dev %d",
+ __func__, info->id, info->ip_channels, info->op_channels,
+ info->usecase_id, info->snd_device);
+
+ params->info = *info;
+ list_add_tail(&my_data->custom_mtmx_params_list, ¶ms->list);
+ return 0;
+}
+
+static void platform_release_custom_mtmx_params(void *platform)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ struct listnode *node = NULL, *tempnode = NULL;
+
+ list_for_each_safe(node, tempnode, &my_data->custom_mtmx_params_list) {
+ list_remove(node);
+ free(node_to_item(node, struct audio_custom_mtmx_params, list));
+ }
+}
+
+void platform_release_acdb_metainfo_key(void *platform)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ struct listnode *node, *tempnode;
+
+ list_for_each_safe(node, tempnode, &my_data->acdb_meta_key_list) {
+ list_remove(node);
+ free(node_to_item(node, struct meta_key_list, list));
+ }
+}
+
void platform_deinit(void *platform)
{
struct platform_data *my_data = (struct platform_data *)platform;
@@ -2831,6 +2913,27 @@
my_data->adev->mixer = NULL;
}
+ int32_t idx;
+
+ for (idx = 0; idx < MAX_CODEC_BACKENDS; idx++) {
+ if (my_data->current_backend_cfg[idx].bitwidth_mixer_ctl) {
+ free(my_data->current_backend_cfg[idx].bitwidth_mixer_ctl);
+ my_data->current_backend_cfg[idx].bitwidth_mixer_ctl = NULL;
+ }
+
+ if (my_data->current_backend_cfg[idx].samplerate_mixer_ctl) {
+ free(my_data->current_backend_cfg[idx].samplerate_mixer_ctl);
+ my_data->current_backend_cfg[idx].samplerate_mixer_ctl = NULL;
+ }
+
+ if (my_data->current_backend_cfg[idx].channels_mixer_ctl) {
+ free(my_data->current_backend_cfg[idx].channels_mixer_ctl);
+ my_data->current_backend_cfg[idx].channels_mixer_ctl = NULL;
+ }
+ }
+
+ platform_release_custom_mtmx_params(platform);
+
if (my_data->acdb_deallocate)
my_data->acdb_deallocate();
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index 480ef13..f7a7ebf 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -353,6 +353,27 @@
return my_data;
}
+struct audio_custom_mtmx_params *
+ platform_get_custom_mtmx_params
+ (
+ void *platform __unused,
+ struct audio_custom_mtmx_params_info *info __unused
+ )
+{
+ ALOGW("%s: not implemented!", __func__);
+ return NULL;
+}
+
+int platform_add_custom_mtmx_params
+ (
+ void *platform __unused,
+ struct audio_custom_mtmx_params_info *info __unused
+ )
+{
+ ALOGW("%s: not implemented!", __func__);
+ return -ENOSYS;
+}
+
void platform_deinit(void *platform)
{
struct platform_data *my_data = (struct platform_data *)platform;
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 229b385..c26f62e 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -289,6 +289,7 @@
uint32_t declared_mic_count;
struct audio_microphone_characteristic_t microphones[AUDIO_MICROPHONE_MAX_COUNT];
struct snd_device_to_mic_map mic_map[SND_DEVICE_MAX];
+ struct listnode custom_mtmx_params_list;
};
@@ -2275,6 +2276,7 @@
my_data->is_bcl_speaker = true;
list_init(&my_data->acdb_meta_key_list);
+ list_init(&my_data->custom_mtmx_params_list);
set_platform_defaults(my_data);
@@ -2688,6 +2690,86 @@
return my_data;
}
+struct audio_custom_mtmx_params *
+ platform_get_custom_mtmx_params(void *platform,
+ struct audio_custom_mtmx_params_info *info)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ struct listnode *node = NULL;
+ struct audio_custom_mtmx_params *params = NULL;
+
+ list_for_each(node, &my_data->custom_mtmx_params_list) {
+ params = node_to_item(node, struct audio_custom_mtmx_params, list);
+ if (params &&
+ params->info.id == info->id &&
+ params->info.ip_channels == info->ip_channels &&
+ params->info.op_channels == info->op_channels &&
+ params->info.usecase_id == info->usecase_id &&
+ params->info.snd_device == info->snd_device) {
+ ALOGV("%s: found params with ip_ch %d op_ch %d uc_id %d snd_dev %d",
+ __func__, info->ip_channels, info->op_channels,
+ info->usecase_id, info->snd_device);
+ return params;
+ }
+ }
+ ALOGI("%s: no matching param with id %d ip_ch %d op_ch %d uc_id %d snd_dev %d",
+ __func__, info->id, info->ip_channels, info->op_channels,
+ info->usecase_id, info->snd_device);
+ return NULL;
+}
+
+int platform_add_custom_mtmx_params(void *platform,
+ struct audio_custom_mtmx_params_info *info)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ struct audio_custom_mtmx_params *params = NULL;
+ uint32_t size = sizeof(*params);
+
+ if (info->ip_channels > AUDIO_CHANNEL_COUNT_MAX ||
+ info->op_channels > AUDIO_CHANNEL_COUNT_MAX) {
+ ALOGE("%s: unusupported channels in %d, out %d",
+ __func__, info->ip_channels, info->op_channels);
+ return -EINVAL;
+ }
+
+ size += sizeof(params->coeffs[0]) * info->ip_channels * info->op_channels;
+ params = (struct audio_custom_mtmx_params *) calloc(1, size);
+ if (!params) {
+ ALOGE("%s: failed to add custom mtmx params", __func__);
+ return -ENOMEM;
+ }
+
+ ALOGI("%s: adding mtmx params with id %d ip_ch %d op_ch %d uc_id %d snd_dev %d",
+ __func__, info->id, info->ip_channels, info->op_channels,
+ info->usecase_id, info->snd_device);
+
+ params->info = *info;
+ list_add_tail(&my_data->custom_mtmx_params_list, ¶ms->list);
+ return 0;
+}
+
+static void platform_release_custom_mtmx_params(void *platform)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ struct listnode *node = NULL, *tempnode = NULL;
+
+ list_for_each_safe(node, tempnode, &my_data->custom_mtmx_params_list) {
+ list_remove(node);
+ free(node_to_item(node, struct audio_custom_mtmx_params, list));
+ }
+}
+
+void platform_release_acdb_metainfo_key(void *platform)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ struct listnode *node, *tempnode;
+
+ list_for_each_safe(node, tempnode, &my_data->acdb_meta_key_list) {
+ list_remove(node);
+ free(node_to_item(node, struct meta_key_list, list));
+ }
+}
+
void platform_deinit(void *platform)
{
struct platform_data *my_data = (struct platform_data *)platform;
@@ -2735,6 +2817,27 @@
my_data->adev->mixer = NULL;
}
+ int32_t idx;
+
+ for (idx = 0; idx < MAX_CODEC_BACKENDS; idx++) {
+ if (my_data->current_backend_cfg[idx].bitwidth_mixer_ctl) {
+ free(my_data->current_backend_cfg[idx].bitwidth_mixer_ctl);
+ my_data->current_backend_cfg[idx].bitwidth_mixer_ctl = NULL;
+ }
+
+ if (my_data->current_backend_cfg[idx].samplerate_mixer_ctl) {
+ free(my_data->current_backend_cfg[idx].samplerate_mixer_ctl);
+ my_data->current_backend_cfg[idx].samplerate_mixer_ctl = NULL;
+ }
+
+ if (my_data->current_backend_cfg[idx].channels_mixer_ctl) {
+ free(my_data->current_backend_cfg[idx].channels_mixer_ctl);
+ my_data->current_backend_cfg[idx].channels_mixer_ctl = NULL;
+ }
+ }
+
+ platform_release_custom_mtmx_params(platform);
+
if (my_data->acdb_deallocate)
my_data->acdb_deallocate();
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 6ba962d..80138c8 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -93,6 +93,21 @@
uint32_t param_id;
} acdb_audio_cal_cfg_t;
+
+struct audio_custom_mtmx_params_info {
+ uint32_t id;
+ uint32_t ip_channels;
+ uint32_t op_channels;
+ uint32_t usecase_id;
+ uint32_t snd_device;
+};
+
+struct audio_custom_mtmx_params {
+ struct listnode list;
+ struct audio_custom_mtmx_params_info info;
+ uint32_t coeffs[0];
+};
+
enum card_status_t;
void *platform_init(struct audio_device *adev);
@@ -304,4 +319,9 @@
audio_usecase_t usecase,
struct audio_microphone_characteristic_t *mic_array,
size_t *mic_count);
+struct audio_custom_mtmx_params *
+ platform_get_custom_mtmx_params(void *platform,
+ struct audio_custom_mtmx_params_info *info);
+int platform_add_custom_mtmx_params(void *platform,
+ struct audio_custom_mtmx_params_info *info);
#endif // AUDIO_PLATFORM_API_H
diff --git a/hal/platform_info.c b/hal/platform_info.c
index 3341f20..70c2b70 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -68,6 +68,8 @@
INPUT_SND_DEVICE_TO_MIC_MAPPING,
SND_DEV,
MIC_INFO,
+ CUSTOM_MTMX_PARAMS,
+ CUSTOM_MTMX_PARAM_COEFFS,
} section_t;
typedef void (* section_process_fn)(const XML_Char **attr);
@@ -87,6 +89,8 @@
static void process_microphone_characteristic(const XML_Char **attr);
static void process_snd_dev(const XML_Char **attr);
static void process_mic_info(const XML_Char **attr);
+static void process_custom_mtmx_params(const XML_Char **attr);
+static void process_custom_mtmx_param_coeffs(const XML_Char **attr);
static section_process_fn section_table[] = {
[ROOT] = process_root,
@@ -103,6 +107,8 @@
[MICROPHONE_CHARACTERISTIC] = process_microphone_characteristic,
[SND_DEV] = process_snd_dev,
[MIC_INFO] = process_mic_info,
+ [CUSTOM_MTMX_PARAMS] = process_custom_mtmx_params,
+ [CUSTOM_MTMX_PARAM_COEFFS] = process_custom_mtmx_param_coeffs,
};
static section_t section;
@@ -207,6 +213,9 @@
}
return false;
}
+
+static struct audio_custom_mtmx_params_info mtmx_params_info;
+
/*
* <audio_platform_info>
* <acdb_ids>
@@ -871,6 +880,84 @@
return;
}
+static void process_custom_mtmx_param_coeffs(const XML_Char **attr)
+{
+ uint32_t attr_idx = 0, out_ch_idx = -1, ch_coeff_count = 0;
+ uint32_t ip_channels = 0, op_channels = 0;
+ char *context = NULL, *ch_coeff_value = NULL;
+ struct audio_custom_mtmx_params *mtmx_params = NULL;
+
+ if (strcmp(attr[attr_idx++], "out_channel_index") != 0) {
+ ALOGE("%s: 'out_channel_index' not found", __func__);
+ return;
+ }
+ out_ch_idx = atoi((char *)attr[attr_idx++]);
+
+ if (out_ch_idx < 0 || out_ch_idx >= mtmx_params_info.op_channels) {
+ ALOGE("%s: invalid out channel index(%d)", __func__, out_ch_idx);
+ return;
+ }
+
+ if (strcmp(attr[attr_idx++], "values") != 0) {
+ ALOGE("%s: 'values' not found", __func__);
+ return;
+ }
+ mtmx_params = platform_get_custom_mtmx_params((void *)my_data.platform,
+ &mtmx_params_info);
+ if (mtmx_params == NULL) {
+ ALOGE("%s: mtmx params with given param info, not found", __func__);
+ return;
+ }
+ ch_coeff_value = strtok_r((char *)attr[attr_idx++], " ", &context);
+ ip_channels = mtmx_params->info.ip_channels;
+ op_channels = mtmx_params->info.op_channels;
+ while(ch_coeff_value && ch_coeff_count < op_channels) {
+ mtmx_params->coeffs[ip_channels * out_ch_idx + ch_coeff_count++]
+ = atoi(ch_coeff_value);
+ ch_coeff_value = strtok_r(NULL, " ", &context);
+ }
+ if (ch_coeff_count != mtmx_params->info.ip_channels ||
+ ch_coeff_value != NULL)
+ ALOGE("%s: invalid/malformed coefficient values", __func__);
+}
+
+static void process_custom_mtmx_params(const XML_Char **attr)
+{
+ int attr_idx = 0;
+
+ if (strcmp(attr[attr_idx++], "param_id") != 0) {
+ ALOGE("%s: 'param_id' not found", __func__);
+ return;
+ }
+ mtmx_params_info.id = atoi((char *)attr[attr_idx++]);
+
+ if (strcmp(attr[attr_idx++], "in_channel_count") != 0) {
+ ALOGE("%s: 'in_channel_count' not found", __func__);
+ return;
+ }
+ mtmx_params_info.ip_channels = atoi((char *)attr[attr_idx++]);
+
+ if (strcmp(attr[attr_idx++], "out_channel_count") != 0) {
+ ALOGE("%s: 'out_channel_count' not found", __func__);
+ return;
+ }
+ mtmx_params_info.op_channels = atoi((char *)attr[attr_idx++]);
+
+ if (strcmp(attr[attr_idx++], "usecase") != 0) {
+ ALOGE("%s: 'usecase' not found", __func__);
+ return;
+ }
+ mtmx_params_info.usecase_id = platform_get_usecase_index((char *)attr[attr_idx++]);
+
+ if (strcmp(attr[attr_idx++], "snd_device") != 0) {
+ ALOGE("%s: 'snd_device' not found", __func__);
+ return;
+ }
+ mtmx_params_info.snd_device = platform_get_snd_device_index((char *)attr[attr_idx++]);
+ platform_add_custom_mtmx_params((void *)my_data.platform, &mtmx_params_info);
+
+}
+
static void start_tag(void *userdata __unused, const XML_Char *tag_name,
const XML_Char **attr)
{
@@ -993,7 +1080,23 @@
}
section_process_fn fn = section_table[MIC_INFO];
fn(attr);
- }
+ } else if (strcmp(tag_name, "custom_mtmx_params") == 0) {
+ if (section != ROOT) {
+ ALOGE("custom_mtmx_params tag supported only in ROOT section");
+ return;
+ }
+ section = CUSTOM_MTMX_PARAMS;
+ section_process_fn fn = section_table[section];
+ fn(attr);
+ } else if (strcmp(tag_name, "custom_mtmx_param_coeffs") == 0) {
+ if (section != CUSTOM_MTMX_PARAMS) {
+ ALOGE("custom_mtmx_param_coeffs tag supported only with CUSTOM_MTMX_PARAMS section");
+ return;
+ }
+ section = CUSTOM_MTMX_PARAM_COEFFS;
+ section_process_fn fn = section_table[section];
+ fn(attr);
+ }
} else {
ALOGE("%s: unknown caller!", __func__);
}
@@ -1035,6 +1138,10 @@
section = SND_DEVICES;
} else if (strcmp(tag_name, "input_snd_device_mic_mapping") == 0) {
section = INPUT_SND_DEVICE;
+ } else if (strcmp(tag_name, "custom_mtmx_params") == 0) {
+ section = ROOT;
+ } else if (strcmp(tag_name, "custom_mtmx_param_coeffs") == 0) {
+ section = CUSTOM_MTMX_PARAMS;
}
}