dsp: adm: Add support for port specific channel map
Add multi channel map support per afe port.
Change-Id: Ib032d1c81d918417f516131f11c500e4f6668b39
Signed-off-by: Rohit kumar <rohitkr@codeaurora.org>
Signed-off-by: Meng Wang <mengw@codeaurora.org>
diff --git a/dsp/q6adm.c b/dsp/q6adm.c
index 8848b22..8c8b614 100644
--- a/dsp/q6adm.c
+++ b/dsp/q6adm.c
@@ -128,6 +128,8 @@
}
};
+static struct adm_multi_ch_map port_channel_map[AFE_MAX_PORTS];
+
static int adm_get_parameters[MAX_COPPS_PER_PORT * ADM_GET_PARAMETER_LENGTH];
static int adm_module_topo_list[MAX_COPPS_PER_PORT *
ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH];
@@ -146,7 +148,8 @@
static int adm_arrange_mch_map_v8(
struct adm_device_endpoint_payload *ep_payload,
int path,
- int channel_mode);
+ int channel_mode,
+ int port_idx);
/**
* adm_validate_and_get_port_index -
@@ -578,7 +581,8 @@
index += ch_mixer->output_channel;
} else {
ep_params.dev_num_channel = ch_mixer->output_channel;
- adm_arrange_mch_map_v8(&ep_params, path_type, ep_params.dev_num_channel);
+ adm_arrange_mch_map_v8(&ep_params, path_type,
+ ep_params.dev_num_channel, port_idx);
for (i = 0; i < ch_mixer->output_channel; i++)
adm_pspd_params[index++] = ep_params.dev_channel_mapping[i];
}
@@ -589,7 +593,8 @@
index += ch_mixer->input_channel;
} else {
ep_params.dev_num_channel = ch_mixer->input_channels[channel_index];
- adm_arrange_mch_map_v8(&ep_params, path_type, ep_params.dev_num_channel);
+ adm_arrange_mch_map_v8(&ep_params, path_type,
+ ep_params.dev_num_channel, port_idx);
for (i = 0; i < ch_mixer->input_channels[channel_index]; i++)
adm_pspd_params[index++] = ep_params.dev_channel_mapping[i];
}
@@ -1302,6 +1307,31 @@
}
EXPORT_SYMBOL(adm_get_multi_ch_map);
+/**
+ * adm_set_port_multi_ch_map -
+ * Update port specific channel map info
+ *
+ * @channel_map: pointer with channel map info
+ * @port_id: port for which chmap is set
+ */
+void adm_set_port_multi_ch_map(char *channel_map, int port_id)
+{
+ int port_idx;
+
+ port_id = q6audio_convert_virtual_to_portid(port_id);
+ port_idx = adm_validate_and_get_port_index(port_id);
+
+ if (port_idx < 0) {
+ pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id);
+ return;
+ }
+
+ memcpy(port_channel_map[port_idx].channel_mapping, channel_map,
+ PCM_FORMAT_MAX_NUM_CHANNEL_V8);
+ port_channel_map[port_idx].set_channel_map = true;
+}
+EXPORT_SYMBOL(adm_set_port_multi_ch_map);
+
static int adm_process_get_param_response(u32 opcode, u32 idx, u32 *payload,
u32 payload_size)
{
@@ -2380,7 +2410,7 @@
EXPORT_SYMBOL(adm_connect_afe_port);
int adm_arrange_mch_map(struct adm_cmd_device_open_v5 *open, int path,
- int channel_mode)
+ int channel_mode, int port_idx)
{
int rc = 0, idx;
@@ -2398,10 +2428,18 @@
default:
goto non_mch_path;
};
- if ((open->dev_num_channel > 2) && multi_ch_maps[idx].set_channel_map) {
- memcpy(open->dev_channel_mapping,
- multi_ch_maps[idx].channel_mapping,
- PCM_FORMAT_MAX_NUM_CHANNEL);
+
+ if ((open->dev_num_channel > 2) &&
+ (port_channel_map[port_idx].set_channel_map ||
+ multi_ch_maps[idx].set_channel_map)) {
+ if (port_channel_map[port_idx].set_channel_map)
+ memcpy(open->dev_channel_mapping,
+ port_channel_map[port_idx].channel_mapping,
+ PCM_FORMAT_MAX_NUM_CHANNEL);
+ else
+ memcpy(open->dev_channel_mapping,
+ multi_ch_maps[idx].channel_mapping,
+ PCM_FORMAT_MAX_NUM_CHANNEL);
} else {
if (channel_mode == 1) {
open->dev_channel_mapping[0] = PCM_CHANNEL_FC;
@@ -2515,8 +2553,7 @@
static int adm_arrange_mch_map_v8(
struct adm_device_endpoint_payload *ep_payload,
- int path,
- int channel_mode)
+ int path, int channel_mode, int port_idx)
{
int rc = 0, idx;
@@ -2535,10 +2572,16 @@
};
if ((ep_payload->dev_num_channel > 2) &&
- multi_ch_maps[idx].set_channel_map) {
- memcpy(ep_payload->dev_channel_mapping,
- multi_ch_maps[idx].channel_mapping,
- PCM_FORMAT_MAX_NUM_CHANNEL_V8);
+ (port_channel_map[port_idx].set_channel_map ||
+ multi_ch_maps[idx].set_channel_map)) {
+ if (port_channel_map[port_idx].set_channel_map)
+ memcpy(ep_payload->dev_channel_mapping,
+ port_channel_map[port_idx].channel_mapping,
+ PCM_FORMAT_MAX_NUM_CHANNEL_V8);
+ else
+ memcpy(ep_payload->dev_channel_mapping,
+ multi_ch_maps[idx].channel_mapping,
+ PCM_FORMAT_MAX_NUM_CHANNEL_V8);
} else {
if (channel_mode == 1) {
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FC;
@@ -3052,7 +3095,7 @@
ep1_payload.bit_width = bit_width;
ep1_payload.sample_rate = rate;
ret = adm_arrange_mch_map_v8(&ep1_payload, path,
- channel_mode);
+ channel_mode, port_idx);
if (ret)
return ret;
@@ -3165,8 +3208,8 @@
(rate != ULL_SUPPORTED_SAMPLE_RATE));
open.sample_rate = rate;
- ret = adm_arrange_mch_map(&open, path, channel_mode);
-
+ ret = adm_arrange_mch_map(&open, path, channel_mode,
+ port_idx);
if (ret)
return ret;
@@ -3314,7 +3357,7 @@
atomic_read(&this_adm.copp.channels[port_idx][copp_idx]);
rc = adm_arrange_mch_map(&open, ADM_PATH_PLAYBACK,
- mfc_cfg.num_channels);
+ mfc_cfg.num_channels, port_idx);
if (rc < 0) {
pr_err("%s: unable to get channal map\n", __func__);
goto fail_cmd;
@@ -3671,6 +3714,7 @@
return -EINVAL;
}
+ port_channel_map[port_idx].set_channel_map = false;
if (this_adm.copp.adm_delay[port_idx][copp_idx] && perf_mode
== LEGACY_PCM_MODE) {
atomic_set(&this_adm.copp.adm_delay_stat[port_idx][copp_idx],