From 2054b690a909d01dec8f054210cacd88fe665ffe Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Fri, 1 Feb 2019 18:01:12 +0530 Subject: [PATCH] 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 Signed-off-by: Meng Wang --- dsp/q6adm.c | 80 ++++++++++++++++++++++++++++++++---------- include/dsp/q6adm-v2.h | 2 ++ 2 files changed, 64 insertions(+), 18 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 8848b2290c4d..8c8b61497d51 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -128,6 +128,8 @@ static struct adm_multi_ch_map multi_ch_maps[2] = { } }; +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 @@ void msm_dts_srs_release_lock(void) 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 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, 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 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, 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 @@ int adm_get_multi_ch_map(char *channel_map, int path) } 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 @@ fail_cmd: 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 @@ int adm_arrange_mch_map(struct adm_cmd_device_open_v5 *open, int path, 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 @@ int adm_arrange_mch_ep2_map(struct adm_cmd_device_open_v6 *open_v6, 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 @@ static int adm_arrange_mch_map_v8( }; 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 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, 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 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, (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 @@ void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate) 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 @@ int adm_close(int port_id, int perf_mode, int copp_idx) 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], diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 70dc2d094833..a48082b75cce 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -145,6 +145,8 @@ int adm_set_multi_ch_map(char *channel_map, int path); int adm_get_multi_ch_map(char *channel_map, int path); +void adm_set_port_multi_ch_map(char *channel_map, int port_id); + int adm_validate_and_get_port_index(int port_id); int adm_get_default_copp_idx(int port_id);