diff --git a/dsp/q6adm.c b/dsp/q6adm.c index f905ef1ae6..1851b98773 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -141,6 +141,11 @@ void msm_dts_srs_release_lock(void) mutex_unlock(&dts_srs_lock); } +static int adm_arrange_mch_map_v8( + struct adm_device_endpoint_payload *ep_payload, + int path, + int channel_mode); + /** * adm_validate_and_get_port_index - * validate given port id @@ -488,9 +493,10 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, struct adm_cmd_set_pspd_mtmx_strtr_params_v5 *adm_params = NULL; struct param_hdr_v1 data_v5; int ret = 0, port_idx, sz = 0, param_size = 0; + struct adm_device_endpoint_payload ep_params = {0, 0, 0, {0}}; u16 *adm_pspd_params; u16 *ptr; - int index = 0; + int index = 0, i = 0, path_type = ADM_PATH_PLAYBACK; pr_debug("%s: port_id = %d\n", __func__, port_id); port_id = afe_convert_virtual_to_portid(port_id); @@ -515,7 +521,7 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, ch_mixer->input_channels[channel_index] + ch_mixer->input_channels[channel_index] * ch_mixer->output_channel); - roundup(param_size, 4); + param_size = roundup(param_size, 4); sz = sizeof(struct adm_cmd_set_pspd_mtmx_strtr_params_v5) + sizeof(struct default_chmixer_param_id_coeff) + @@ -561,84 +567,31 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, adm_pspd_params[3] = ch_mixer->input_channels[channel_index]; index = 4; - if (ch_mixer->output_channel == 1) { - adm_pspd_params[index] = PCM_CHANNEL_FC; - } else if (ch_mixer->output_channel == 2) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - } else if (ch_mixer->output_channel == 3) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_FC; - } else if (ch_mixer->output_channel == 4) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_LS; - adm_pspd_params[index + 3] = PCM_CHANNEL_RS; - } else if (ch_mixer->output_channel == 5) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_FC; - adm_pspd_params[index + 3] = PCM_CHANNEL_LS; - adm_pspd_params[index + 4] = PCM_CHANNEL_RS; - } else if (ch_mixer->output_channel == 6) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_LFE; - adm_pspd_params[index + 3] = PCM_CHANNEL_FC; - adm_pspd_params[index + 4] = PCM_CHANNEL_LS; - adm_pspd_params[index + 5] = PCM_CHANNEL_RS; - } else if (ch_mixer->output_channel == 8) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_LFE; - adm_pspd_params[index + 3] = PCM_CHANNEL_FC; - adm_pspd_params[index + 4] = PCM_CHANNEL_LS; - adm_pspd_params[index + 5] = PCM_CHANNEL_RS; - adm_pspd_params[index + 6] = PCM_CHANNEL_LB; - adm_pspd_params[index + 7] = PCM_CHANNEL_RB; + path_type = (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) ? + ADM_PATH_PLAYBACK : ADM_PATH_LIVE_REC; + + if (ch_mixer->override_out_ch_map) { + memcpy(&adm_pspd_params[index], &ch_mixer->out_ch_map, + ch_mixer->output_channel * sizeof(uint16_t)); + 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); + for (i = 0; i < ch_mixer->output_channel; i++) + adm_pspd_params[index++] = ep_params.dev_channel_mapping[i]; } - index = index + ch_mixer->output_channel; - if (ch_mixer->input_channels[channel_index] == 1) { - adm_pspd_params[index] = PCM_CHANNEL_FC; - } else if (ch_mixer->input_channels[channel_index] == 2) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - } else if (ch_mixer->input_channels[channel_index] == 3) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_FC; - } else if (ch_mixer->input_channels[channel_index] == 4) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_LS; - adm_pspd_params[index + 3] = PCM_CHANNEL_RS; - } else if (ch_mixer->input_channels[channel_index] == 5) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_FC; - adm_pspd_params[index + 3] = PCM_CHANNEL_LS; - adm_pspd_params[index + 4] = PCM_CHANNEL_RS; - } else if (ch_mixer->input_channels[channel_index] == 6) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_LFE; - adm_pspd_params[index + 3] = PCM_CHANNEL_FC; - adm_pspd_params[index + 4] = PCM_CHANNEL_LS; - adm_pspd_params[index + 5] = PCM_CHANNEL_RS; - } else if (ch_mixer->input_channels[channel_index] == 8) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_LFE; - adm_pspd_params[index + 3] = PCM_CHANNEL_FC; - adm_pspd_params[index + 4] = PCM_CHANNEL_LS; - adm_pspd_params[index + 5] = PCM_CHANNEL_RS; - adm_pspd_params[index + 6] = PCM_CHANNEL_LB; - adm_pspd_params[index + 7] = PCM_CHANNEL_RB; + if (ch_mixer->override_in_ch_map) { + memcpy(&adm_pspd_params[index], &ch_mixer->in_ch_map, + ch_mixer->input_channel * sizeof(uint16_t)); + 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); + for (i = 0; i < ch_mixer->input_channels[channel_index]; i++) + adm_pspd_params[index++] = ep_params.dev_channel_mapping[i]; } - index = index + ch_mixer->input_channels[channel_index]; ret = adm_populate_channel_weight(&adm_pspd_params[index], ch_mixer, channel_index); if (ret) { diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 5c9de064fe..1b10d62b4a 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -114,8 +114,6 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir, static int q6asm_memory_unmap_regions(struct audio_client *ac, int dir); static void q6asm_reset_buf_state(struct audio_client *ac); -static int q6asm_map_channels(u8 *channel_mapping, uint32_t channels, - bool use_back_flavor); void *q6asm_mmap_apr_reg(void); static int q6asm_is_valid_session(struct apr_client_data *data, void *priv); @@ -5420,7 +5418,16 @@ fail_cmd: } EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_native); -static int q6asm_map_channels(u8 *channel_mapping, uint32_t channels, +/* + * q6asm_map_channels: + * Provide default asm channel mapping for given channel count. + * + * @channel_mapping: buffer pointer to write back channel maps. + * @channels: channel count for which channel map is required. + * @use_back_flavor: use back channels instead of surround channels. + * Returns 0 for success, -EINVAL for unsupported channel count. + */ +int q6asm_map_channels(u8 *channel_mapping, uint32_t channels, bool use_back_flavor) { u8 *lchannel_mapping; @@ -5528,6 +5535,7 @@ static int q6asm_map_channels(u8 *channel_mapping, uint32_t channels, } return 0; } +EXPORT_SYMBOL(q6asm_map_channels); /** * q6asm_enable_sbrps - diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 3d60963a84..b86175a002 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #ifndef __Q6_ADM_V2_H__ #define __Q6_ADM_V2_H__ @@ -77,6 +77,12 @@ struct msm_pcm_channel_mixer { bool enable; int rule; int channel_weight[ADM_MAX_CHANNELS][ADM_MAX_CHANNELS]; + int port_idx; + int input_channel; + uint16_t in_ch_map[ADM_MAX_CHANNELS]; + uint16_t out_ch_map[ADM_MAX_CHANNELS]; + bool override_in_ch_map; + bool override_out_ch_map; }; int srs_trumedia_open(int port_id, int copp_idx, __s32 srs_tech_id, diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h index 4851a81ff0..1bb44b4a31 100644 --- a/include/dsp/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #ifndef __Q6_ASM_V2_H__ #define __Q6_ASM_V2_H__ @@ -741,4 +741,8 @@ uint8_t q6asm_get_stream_id_from_token(uint32_t token); int q6asm_adjust_session_clock(struct audio_client *ac, uint32_t adjust_time_lsw, uint32_t adjust_time_msw); + +/* Provide default asm channel mapping for given channel count */ +int q6asm_map_channels(u8 *channel_mapping, uint32_t channels, + bool use_back_flavor); #endif /* __Q6_ASM_H__ */