Loading dsp/q6adm.c +159 −1 Original line number Diff line number Diff line Loading @@ -98,7 +98,9 @@ struct adm_ctl { int num_ec_ref_rx_chans; int ec_ref_rx_bit_width; int ec_ref_rx_sampling_rate; int num_ec_ref_rx_chans_downmixed; uint16_t ec_ref_chmixer_weights[PCM_FORMAT_MAX_NUM_CHANNEL_V8] [PCM_FORMAT_MAX_NUM_CHANNEL_V8]; int native_mode; }; Loading Loading @@ -2716,6 +2718,98 @@ static int adm_arrange_mch_ep2_map_v8( return rc; } static int adm_copp_set_ec_ref_mfc_cfg(int port_id, int copp_idx, int sample_rate, int bps, int in_channels, int out_channels) { struct audproc_mfc_param_media_fmt mfc_cfg; struct param_hdr_v3 param_hdr; u16 *chmixer_params = NULL; int rc = 0, i = 0, j = 0, param_index = 0, param_size = 0; struct adm_device_endpoint_payload ep_payload = {0, 0, 0, {0}}; memset(&mfc_cfg, 0, sizeof(mfc_cfg)); memset(&ep_payload, 0, sizeof(ep_payload)); memset(¶m_hdr, 0, sizeof(param_hdr)); param_hdr.module_id = AUDPROC_MODULE_ID_MFC_EC_REF; param_hdr.instance_id = INSTANCE_ID_0; pr_debug("%s: port_id %d copp_idx %d SR %d, BW %d in_ch %d out_ch %d\n", __func__, port_id, copp_idx, sample_rate, bps, in_channels, out_channels); /* 1. Update Media Format */ param_hdr.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT; param_hdr.param_size = sizeof(mfc_cfg); mfc_cfg.sampling_rate = sample_rate; mfc_cfg.bits_per_sample = bps; mfc_cfg.num_channels = out_channels; ep_payload.dev_num_channel = out_channels; rc = adm_arrange_mch_ep2_map_v8(&ep_payload, out_channels); if (rc < 0) { pr_err("%s: unable to get map for out channels=%d\n", __func__, out_channels); return -EINVAL; } for (i = 0; i < out_channels; i++) mfc_cfg.channel_type[i] = (uint16_t) ep_payload.dev_channel_mapping[i]; rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, (uint8_t *) &mfc_cfg); if (rc) { pr_err("%s: Failed to set media format, err %d\n", __func__, rc); return rc; } /* 2. Send Channel Mixer params */ param_size = 2 * (4 + out_channels + in_channels + (out_channels * in_channels)); param_size = round_up(param_size, 4); param_hdr.param_id = DEFAULT_CHMIXER_PARAM_ID_COEFF; param_hdr.param_size = param_size; pr_debug("%s: chmixer param sz = %d\n", __func__, param_size); chmixer_params = kzalloc(param_size, GFP_KERNEL); if (!chmixer_params) { return -ENOMEM; } param_index = 2; /* param[0] and [1] represents chmixer rule(always 0) */ chmixer_params[param_index++] = out_channels; chmixer_params[param_index++] = in_channels; /* output channel map is same as one set in media format */ for (i = 0; i < out_channels; i++) chmixer_params[param_index++] = ep_payload.dev_channel_mapping[i]; /* input channel map should be same as one set for ep2 during copp open */ ep_payload.dev_num_channel = in_channels; rc = adm_arrange_mch_ep2_map_v8(&ep_payload, in_channels); if (rc < 0) { pr_err("%s: unable to get in channal map\n", __func__); goto exit; } for (i = 0; i < in_channels; i++) chmixer_params[param_index++] = ep_payload.dev_channel_mapping[i]; for (i = 0; i < out_channels; i++) for (j = 0; j < in_channels; j++) chmixer_params[param_index++] = this_adm.ec_ref_chmixer_weights[i][j]; rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, (uint8_t *) chmixer_params); if (rc) pr_err("%s: Failed to set chmixer params, err %d\n", __func__, rc); exit: kfree(chmixer_params); return rc; } /** * adm_open - * command to send ADM open Loading Loading @@ -2750,6 +2844,7 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, int tmp_port = q6audio_get_port_id(port_id); void *adm_params = NULL; int param_size; int num_ec_ref_rx_chans = this_adm.num_ec_ref_rx_chans; pr_debug("%s:port %#x path:%d rate:%d mode:%d perf_mode:%d,topo_id %d\n", __func__, port_id, path, rate, channel_mode, perf_mode, Loading Loading @@ -3137,6 +3232,23 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, } } atomic_inc(&this_adm.copp.cnt[port_idx][copp_idx]); /* * Configure MFC(in ec_ref path) if chmixing param is applicable and set. * Except channels and channel maps the media format config for this module * should match with the COPP(EP1) config values. */ if (path != ADM_PATH_PLAYBACK && this_adm.num_ec_ref_rx_chans_downmixed != 0 && num_ec_ref_rx_chans != this_adm.num_ec_ref_rx_chans_downmixed) { ret = adm_copp_set_ec_ref_mfc_cfg(port_id, copp_idx, rate, bit_width, num_ec_ref_rx_chans, this_adm.num_ec_ref_rx_chans_downmixed); this_adm.num_ec_ref_rx_chans_downmixed = 0; if (ret) pr_err("%s: set EC REF MFC cfg failed, err %d\n", __func__, ret); } return copp_idx; } EXPORT_SYMBOL(adm_open); Loading Loading @@ -3424,6 +3536,52 @@ void adm_num_ec_ref_rx_chans(int num_chans) } EXPORT_SYMBOL(adm_num_ec_ref_rx_chans); /** * adm_num_ec_rx_ref_chans_downmixed - * Update EC ref num of channels(downmixed) to be fed to EC algo * */ void adm_num_ec_ref_rx_chans_downmixed(int num_chans) { this_adm.num_ec_ref_rx_chans_downmixed = num_chans; pr_debug("%s: num_ec_ref_rx_chans_downmixed:%d\n", __func__, this_adm.num_ec_ref_rx_chans_downmixed); } EXPORT_SYMBOL(adm_num_ec_ref_rx_chans_downmixed); /** * adm_ec_ref_chmixer_weights - * Update MFC(in ec ref) Channel Mixer Weights to be used * for downmixing rx channels before feeding them to EC algo * @out_channel_idx: index of output channel to which weightages are applicable * @weights: pointer to array having input weightages * @count: array sizeof pointer weights, max supported value is * PCM_FORMAT_MAX_NUM_CHANNEL_V8 * Returns 0 on success or error on failure */ int adm_ec_ref_chmixer_weights(int out_channel_idx, uint16_t *weights, int count) { int i = 0; if (weights == NULL || count <= 0 || out_channel_idx < 0 || count > PCM_FORMAT_MAX_NUM_CHANNEL_V8 || out_channel_idx >= PCM_FORMAT_MAX_NUM_CHANNEL_V8) { pr_err("%s: invalid weightages count(%d) ch_idx(%d)", __func__, count, out_channel_idx); return -EINVAL; } for (i = 0; i < count; i++) { this_adm.ec_ref_chmixer_weights[out_channel_idx][i] = weights[i]; pr_debug("%s: out ch idx :%d, weight[%d] = %d\n", __func__, out_channel_idx, i, weights[i]); } return 0; } EXPORT_SYMBOL(adm_ec_ref_chmixer_weights); /** * adm_ec_ref_rx_bit_width - * Update EC ref bit_width Loading include/dsp/apr_audio-v2.h +6 −0 Original line number Diff line number Diff line Loading @@ -843,6 +843,12 @@ struct audproc_softvolume_params { /* Param ID of Channel Mixer used by AUDPROC_MODULE_ID_MFC */ #define AUDPROC_CHMIXER_PARAM_ID_COEFF 0x00010342 /* * ID of the Media Format Converter (MFC) module present in EC REF COPP. * This module supports the all param IDs supported by AUDPROC_MODULE_ID_MFC. */ #define AUDPROC_MODULE_ID_MFC_EC_REF 0x0001092C struct adm_cmd_set_pp_params_v5 { struct apr_hdr hdr; Loading include/dsp/q6adm-v2.h +5 −0 Original line number Diff line number Diff line Loading @@ -130,6 +130,11 @@ void adm_ec_ref_rx_id(int port_id); void adm_num_ec_ref_rx_chans(int num_chans); void adm_num_ec_ref_rx_chans_downmixed(int num_chans); int adm_ec_ref_chmixer_weights(int out_channel_idx, uint16_t *weights, int count); void adm_ec_ref_rx_bit_width(int bit_width); void adm_ec_ref_rx_sampling_rate(int sampling_rate); Loading Loading
dsp/q6adm.c +159 −1 Original line number Diff line number Diff line Loading @@ -98,7 +98,9 @@ struct adm_ctl { int num_ec_ref_rx_chans; int ec_ref_rx_bit_width; int ec_ref_rx_sampling_rate; int num_ec_ref_rx_chans_downmixed; uint16_t ec_ref_chmixer_weights[PCM_FORMAT_MAX_NUM_CHANNEL_V8] [PCM_FORMAT_MAX_NUM_CHANNEL_V8]; int native_mode; }; Loading Loading @@ -2716,6 +2718,98 @@ static int adm_arrange_mch_ep2_map_v8( return rc; } static int adm_copp_set_ec_ref_mfc_cfg(int port_id, int copp_idx, int sample_rate, int bps, int in_channels, int out_channels) { struct audproc_mfc_param_media_fmt mfc_cfg; struct param_hdr_v3 param_hdr; u16 *chmixer_params = NULL; int rc = 0, i = 0, j = 0, param_index = 0, param_size = 0; struct adm_device_endpoint_payload ep_payload = {0, 0, 0, {0}}; memset(&mfc_cfg, 0, sizeof(mfc_cfg)); memset(&ep_payload, 0, sizeof(ep_payload)); memset(¶m_hdr, 0, sizeof(param_hdr)); param_hdr.module_id = AUDPROC_MODULE_ID_MFC_EC_REF; param_hdr.instance_id = INSTANCE_ID_0; pr_debug("%s: port_id %d copp_idx %d SR %d, BW %d in_ch %d out_ch %d\n", __func__, port_id, copp_idx, sample_rate, bps, in_channels, out_channels); /* 1. Update Media Format */ param_hdr.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT; param_hdr.param_size = sizeof(mfc_cfg); mfc_cfg.sampling_rate = sample_rate; mfc_cfg.bits_per_sample = bps; mfc_cfg.num_channels = out_channels; ep_payload.dev_num_channel = out_channels; rc = adm_arrange_mch_ep2_map_v8(&ep_payload, out_channels); if (rc < 0) { pr_err("%s: unable to get map for out channels=%d\n", __func__, out_channels); return -EINVAL; } for (i = 0; i < out_channels; i++) mfc_cfg.channel_type[i] = (uint16_t) ep_payload.dev_channel_mapping[i]; rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, (uint8_t *) &mfc_cfg); if (rc) { pr_err("%s: Failed to set media format, err %d\n", __func__, rc); return rc; } /* 2. Send Channel Mixer params */ param_size = 2 * (4 + out_channels + in_channels + (out_channels * in_channels)); param_size = round_up(param_size, 4); param_hdr.param_id = DEFAULT_CHMIXER_PARAM_ID_COEFF; param_hdr.param_size = param_size; pr_debug("%s: chmixer param sz = %d\n", __func__, param_size); chmixer_params = kzalloc(param_size, GFP_KERNEL); if (!chmixer_params) { return -ENOMEM; } param_index = 2; /* param[0] and [1] represents chmixer rule(always 0) */ chmixer_params[param_index++] = out_channels; chmixer_params[param_index++] = in_channels; /* output channel map is same as one set in media format */ for (i = 0; i < out_channels; i++) chmixer_params[param_index++] = ep_payload.dev_channel_mapping[i]; /* input channel map should be same as one set for ep2 during copp open */ ep_payload.dev_num_channel = in_channels; rc = adm_arrange_mch_ep2_map_v8(&ep_payload, in_channels); if (rc < 0) { pr_err("%s: unable to get in channal map\n", __func__); goto exit; } for (i = 0; i < in_channels; i++) chmixer_params[param_index++] = ep_payload.dev_channel_mapping[i]; for (i = 0; i < out_channels; i++) for (j = 0; j < in_channels; j++) chmixer_params[param_index++] = this_adm.ec_ref_chmixer_weights[i][j]; rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, (uint8_t *) chmixer_params); if (rc) pr_err("%s: Failed to set chmixer params, err %d\n", __func__, rc); exit: kfree(chmixer_params); return rc; } /** * adm_open - * command to send ADM open Loading Loading @@ -2750,6 +2844,7 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, int tmp_port = q6audio_get_port_id(port_id); void *adm_params = NULL; int param_size; int num_ec_ref_rx_chans = this_adm.num_ec_ref_rx_chans; pr_debug("%s:port %#x path:%d rate:%d mode:%d perf_mode:%d,topo_id %d\n", __func__, port_id, path, rate, channel_mode, perf_mode, Loading Loading @@ -3137,6 +3232,23 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, } } atomic_inc(&this_adm.copp.cnt[port_idx][copp_idx]); /* * Configure MFC(in ec_ref path) if chmixing param is applicable and set. * Except channels and channel maps the media format config for this module * should match with the COPP(EP1) config values. */ if (path != ADM_PATH_PLAYBACK && this_adm.num_ec_ref_rx_chans_downmixed != 0 && num_ec_ref_rx_chans != this_adm.num_ec_ref_rx_chans_downmixed) { ret = adm_copp_set_ec_ref_mfc_cfg(port_id, copp_idx, rate, bit_width, num_ec_ref_rx_chans, this_adm.num_ec_ref_rx_chans_downmixed); this_adm.num_ec_ref_rx_chans_downmixed = 0; if (ret) pr_err("%s: set EC REF MFC cfg failed, err %d\n", __func__, ret); } return copp_idx; } EXPORT_SYMBOL(adm_open); Loading Loading @@ -3424,6 +3536,52 @@ void adm_num_ec_ref_rx_chans(int num_chans) } EXPORT_SYMBOL(adm_num_ec_ref_rx_chans); /** * adm_num_ec_rx_ref_chans_downmixed - * Update EC ref num of channels(downmixed) to be fed to EC algo * */ void adm_num_ec_ref_rx_chans_downmixed(int num_chans) { this_adm.num_ec_ref_rx_chans_downmixed = num_chans; pr_debug("%s: num_ec_ref_rx_chans_downmixed:%d\n", __func__, this_adm.num_ec_ref_rx_chans_downmixed); } EXPORT_SYMBOL(adm_num_ec_ref_rx_chans_downmixed); /** * adm_ec_ref_chmixer_weights - * Update MFC(in ec ref) Channel Mixer Weights to be used * for downmixing rx channels before feeding them to EC algo * @out_channel_idx: index of output channel to which weightages are applicable * @weights: pointer to array having input weightages * @count: array sizeof pointer weights, max supported value is * PCM_FORMAT_MAX_NUM_CHANNEL_V8 * Returns 0 on success or error on failure */ int adm_ec_ref_chmixer_weights(int out_channel_idx, uint16_t *weights, int count) { int i = 0; if (weights == NULL || count <= 0 || out_channel_idx < 0 || count > PCM_FORMAT_MAX_NUM_CHANNEL_V8 || out_channel_idx >= PCM_FORMAT_MAX_NUM_CHANNEL_V8) { pr_err("%s: invalid weightages count(%d) ch_idx(%d)", __func__, count, out_channel_idx); return -EINVAL; } for (i = 0; i < count; i++) { this_adm.ec_ref_chmixer_weights[out_channel_idx][i] = weights[i]; pr_debug("%s: out ch idx :%d, weight[%d] = %d\n", __func__, out_channel_idx, i, weights[i]); } return 0; } EXPORT_SYMBOL(adm_ec_ref_chmixer_weights); /** * adm_ec_ref_rx_bit_width - * Update EC ref bit_width Loading
include/dsp/apr_audio-v2.h +6 −0 Original line number Diff line number Diff line Loading @@ -843,6 +843,12 @@ struct audproc_softvolume_params { /* Param ID of Channel Mixer used by AUDPROC_MODULE_ID_MFC */ #define AUDPROC_CHMIXER_PARAM_ID_COEFF 0x00010342 /* * ID of the Media Format Converter (MFC) module present in EC REF COPP. * This module supports the all param IDs supported by AUDPROC_MODULE_ID_MFC. */ #define AUDPROC_MODULE_ID_MFC_EC_REF 0x0001092C struct adm_cmd_set_pp_params_v5 { struct apr_hdr hdr; Loading
include/dsp/q6adm-v2.h +5 −0 Original line number Diff line number Diff line Loading @@ -130,6 +130,11 @@ void adm_ec_ref_rx_id(int port_id); void adm_num_ec_ref_rx_chans(int num_chans); void adm_num_ec_ref_rx_chans_downmixed(int num_chans); int adm_ec_ref_chmixer_weights(int out_channel_idx, uint16_t *weights, int count); void adm_ec_ref_rx_bit_width(int bit_width); void adm_ec_ref_rx_sampling_rate(int sampling_rate); Loading