Loading dsp/q6adm.c +206 −76 Original line number Diff line number Diff line Loading @@ -3006,15 +3006,21 @@ 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, static int adm_copp_set_ec_ref_mfc_cfg_v2(int port_id, int copp_idx, int sample_rate, int bps, int in_channels, int out_channels) struct msm_pcm_channel_mixer *cfg) { 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} }; int in_channels, out_channels; if (!cfg) return -EINVAL; in_channels = cfg->input_channel; out_channels = cfg->output_channel; memset(&mfc_cfg, 0, sizeof(mfc_cfg)); memset(&ep_payload, 0, sizeof(ep_payload)); Loading @@ -3028,7 +3034,8 @@ static int adm_copp_set_ec_ref_mfc_cfg(int port_id, int copp_idx, bps, in_channels, out_channels); if (out_channels <= 0 || out_channels > AUDPROC_MFC_OUT_CHANNELS_MAX) { pr_err("%s: unsupported out channels=%d\n", __func__, out_channels); pr_err("%s: unsupported out channels=%d\n", __func__, out_channels); return -EINVAL; } Loading @@ -3041,67 +3048,121 @@ static int adm_copp_set_ec_ref_mfc_cfg(int port_id, int copp_idx, mfc_cfg.num_channels = out_channels; ep_payload.dev_num_channel = out_channels; if (cfg && cfg->override_out_ch_map) { for (i = 0; i < out_channels; i++) { ep_payload.dev_channel_mapping[i] = cfg->out_ch_map[i]; pr_debug("%s: out_ch_map[%d] = %d", __func__, i, ep_payload.dev_channel_mapping[i]); } } else { 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]; 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); 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 = 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) { if (!chmixer_params) return -ENOMEM; } param_index = 2; /* param[0] and [1] represents chmixer rule(always 0) */ /* param[0] and [1] represents chmixer rule(always 0) */ param_index = 2; 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]; chmixer_params[param_index++] = ep_payload.dev_channel_mapping[i]; /* input channel map should be same as one set for ep2 during copp open */ /* input chmap should be same as one set for ep2 during copp open */ ep_payload.dev_num_channel = in_channels; if (cfg && cfg->override_in_ch_map) { for (i = 0; i < in_channels; i++) { ep_payload.dev_channel_mapping[i] = cfg->in_ch_map[i]; pr_debug("%s: in_ch_map[%d] = %d", __func__, i, ep_payload.dev_channel_mapping[i]); } } else { 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]; 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]; for (j = 0; j < in_channels; j++) { chmixer_params[param_index++] = cfg->channel_weight[i][j]; pr_debug("%s: ch_weight[%d][%d] = %d\n", __func__, i, j, cfg->channel_weight[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); pr_err("%s: Failed to set chmixer params, err %d\n", __func__, rc); exit: kfree(chmixer_params); 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 msm_pcm_channel_mixer *cfg = NULL; int rc =0, i, j; cfg =kzalloc(sizeof(struct msm_pcm_channel_mixer), GFP_KERNEL); if (!cfg) { pr_err("%s: fail to allocate memory\n", __func__); return -ENOMEM; } cfg->input_channel = in_channels; cfg->output_channel = out_channels; for (i = 0; i < out_channels; i++) for (j = 0; j < in_channels; j++) cfg->channel_weight[i][j] = this_adm.ec_ref_chmixer_weights[i][j]; rc = adm_copp_set_ec_ref_mfc_cfg_v2(port_id, copp_idx, sample_rate, bps, cfg); kfree(cfg); return rc; } /** * adm_open - * command to send ADM open Loading @@ -3122,6 +3183,38 @@ static int adm_copp_set_ec_ref_mfc_cfg(int port_id, int copp_idx, int adm_open(int port_id, int path, int rate, int channel_mode, int topology, int perf_mode, uint16_t bit_width, int app_type, int acdb_id, int session_type, uint32_t passthr_mode, uint32_t copp_token) { return adm_open_v2(port_id, path, rate, channel_mode, topology, perf_mode, bit_width, app_type, acdb_id, session_type, passthr_mode, copp_token, NULL, NULL); } EXPORT_SYMBOL(adm_open); /** * adm_open_v2 - * command to send ADM open with ec_ref config * * @port_id: port id number * @path: direction or ADM path type * @rate: sample rate of session * @channel_mode: number of channels set * @topology: topology active for this session * @perf_mode: performance mode like LL/ULL/.. * @bit_width: bit width to set for copp * @app_type: App type used for this session * @acdb_id: ACDB ID of this device * @session_type: type of session * @ec_ref_port_cfg: ec_ref port configuration * @ec_ref_chmix_cfg: ec_ref channel mixer configuration * * Returns 0 on success or error on failure */ int adm_open_v2(int port_id, int path, int rate, int channel_mode, int topology, int perf_mode, uint16_t bit_width, int app_type, int acdb_id, int session_type, uint32_t passthr_mode, uint32_t copp_token, struct msm_ec_ref_port_cfg *ec_ref_port_cfg, struct msm_pcm_channel_mixer *ec_ref_chmix_cfg) { struct adm_cmd_device_open_v5 open; struct adm_cmd_device_open_v6 open_v6; Loading @@ -3136,7 +3229,23 @@ 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; int i; int ec_ref_port_id = ec_ref_port_cfg ? ec_ref_port_cfg->port_id : this_adm.ec_ref_rx; int ec_ref_ch = ec_ref_port_cfg ? ec_ref_port_cfg->ch : this_adm.num_ec_ref_rx_chans; int ec_ref_bit = ec_ref_port_cfg ? ec_ref_port_cfg->bit_width : this_adm.ec_ref_rx_bit_width; int ec_ref_sampling_rate = ec_ref_port_cfg ? ec_ref_port_cfg->sampling_rate : this_adm.ec_ref_rx_sampling_rate; 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 @@ -3227,7 +3336,8 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, copp_idx = adm_get_idx_if_copp_exists(port_idx, topology, perf_mode, rate, bit_width, app_type, session_type, copp_token); app_type, session_type, copp_token); if (copp_idx < 0) { copp_idx = adm_get_next_available_copp(port_idx); Loading Loading @@ -3324,17 +3434,16 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, open_v8.endpoint_id_2 = 0xFFFF; open_v8.endpoint_id_3 = 0xFFFF; if (((this_adm.ec_ref_rx & AFE_PORT_INVALID) != if (((ec_ref_port_id & AFE_PORT_INVALID) != AFE_PORT_INVALID) && (path != ADM_PATH_PLAYBACK)) { if (this_adm.num_ec_ref_rx_chans != 0) { if (ec_ref_ch != 0) { open_v8.endpoint_id_2 = this_adm.ec_ref_rx; this_adm.ec_ref_rx = AFE_PORT_INVALID; ec_ref_port_id; ec_ref_port_id = AFE_PORT_INVALID; } else { pr_err("%s: EC channels not set %d\n", __func__, this_adm.num_ec_ref_rx_chans); __func__, ec_ref_ch); return -EINVAL; } } Loading Loading @@ -3367,25 +3476,22 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, + ep1_payload_size; atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); if ((this_adm.num_ec_ref_rx_chans != 0) if ((ec_ref_ch != 0) && (path != ADM_PATH_PLAYBACK) && (open_v8.endpoint_id_2 != 0xFFFF)) { ep2_payload.dev_num_channel = this_adm.num_ec_ref_rx_chans; ec_ref_ch; if (this_adm.ec_ref_rx_bit_width != 0) { ep2_payload.bit_width = this_adm.ec_ref_rx_bit_width; } else { if (ec_ref_bit != 0) ep2_payload.bit_width = ec_ref_bit; else ep2_payload.bit_width = bit_width; } if (this_adm.ec_ref_rx_sampling_rate != 0) { if (ec_ref_sampling_rate != 0) ep2_payload.sample_rate = this_adm.ec_ref_rx_sampling_rate; } else { ec_ref_sampling_rate; else ep2_payload.sample_rate = rate; } pr_debug("%s: adm open_v8 eid2_channels=%d eid2_bit_width=%d eid2_rate=%d\n", __func__, Loading @@ -3393,11 +3499,22 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, ep2_payload.bit_width, ep2_payload.sample_rate); ret = adm_arrange_mch_ep2_map_v8(&ep2_payload, if (ec_ref_chmix_cfg && ec_ref_chmix_cfg->override_in_ch_map) { for (i = 0; i < ec_ref_ch; i++) { ep2_payload.dev_channel_mapping[i] = ec_ref_chmix_cfg->in_ch_map[i]; pr_debug("%s: in_ch_map[%d] = %d", __func__, i, ep2_payload.dev_channel_mapping[i]); } } else { ret = adm_arrange_mch_ep2_map_v8( &ep2_payload, ep2_payload.dev_num_channel); if (ret) return ret; } ep2_payload_size = 8 + roundup(ep2_payload.dev_num_channel, 4); param_size += ep2_payload_size; Loading @@ -3412,7 +3529,7 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, (void *)&ep1_payload, ep1_payload_size); if ((this_adm.num_ec_ref_rx_chans != 0) if ((ec_ref_ch != 0) && (path != ADM_PATH_PLAYBACK) && (open_v8.endpoint_id_2 != 0xFFFF)) { memcpy(adm_params + sizeof(open_v8) Loading Loading @@ -3473,7 +3590,7 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); if ((this_adm.num_ec_ref_rx_chans != 0) && if ((ec_ref_ch != 0) && (path != 1) && (open.endpoint_id_2 != 0xFFFF)) { memset(&open_v6, 0, sizeof(struct adm_cmd_device_open_v6)); Loading @@ -3482,21 +3599,18 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, open_v6.hdr.opcode = ADM_CMD_DEVICE_OPEN_V6; open_v6.hdr.pkt_size = sizeof(open_v6); open_v6.dev_num_channel_eid2 = this_adm.num_ec_ref_rx_chans; ec_ref_ch; if (this_adm.ec_ref_rx_bit_width != 0) { open_v6.bit_width_eid2 = this_adm.ec_ref_rx_bit_width; } else { if (ec_ref_bit != 0) open_v6.bit_width_eid2 = ec_ref_bit; else open_v6.bit_width_eid2 = bit_width; } if (this_adm.ec_ref_rx_sampling_rate != 0) { if (ec_ref_sampling_rate != 0) open_v6.sample_rate_eid2 = this_adm.ec_ref_rx_sampling_rate; } else { ec_ref_sampling_rate; else open_v6.sample_rate_eid2 = rate; } pr_debug("%s: eid2_channels=%d eid2_bit_width=%d eid2_rate=%d\n", __func__, open_v6.dev_num_channel_eid2, Loading Loading @@ -3527,24 +3641,40 @@ 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. * Configure MFC(in ec_ref path) if chmix 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 (ec_ref_chmix_cfg) { if (path != ADM_PATH_PLAYBACK && ec_ref_chmix_cfg->output_channel != 0 && ec_ref_chmix_cfg->input_channel != ec_ref_chmix_cfg->output_channel) { ret = adm_copp_set_ec_ref_mfc_cfg_v2(port_id, copp_idx, rate, bit_width, ec_ref_chmix_cfg); ec_ref_chmix_cfg->output_channel = 0; if (ret) pr_err("%s: set EC REF MFC cfg v2 failed, err %d\n", __func__, ret); } } else { 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) { this_adm.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, rate, bit_width, this_adm.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); pr_err("%s: set EC REF MFC cfg failed, err %d\n", __func__, ret); } } return copp_idx; } EXPORT_SYMBOL(adm_open); EXPORT_SYMBOL(adm_open_v2); /** * adm_copp_mfc_cfg - Loading include/dsp/q6adm-v2.h +15 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,14 @@ enum { #define ADSP_ADM_API_VERSION_V3 3 struct msm_ec_ref_port_cfg { int rx; int port_id; int ch; int bit_width; int sampling_rate; }; /* multiple copp per stream. */ struct route_payload { unsigned int copp_idx[MAX_COPPS_PER_PORT]; Loading Loading @@ -122,6 +130,13 @@ int adm_open(int port, int path, int rate, int mode, int topology, int app_type, int acdbdev_id, int session_type, uint32_t pass_thr, uint32_t copp_token); int adm_open_v2(int port, int path, int rate, int mode, int topology, int perf_mode, uint16_t bits_per_sample, int app_type, int acdbdev_id, int session_type, uint32_t pass_thr, uint32_t copp_token, struct msm_ec_ref_port_cfg *ec_ref_port_cfg, struct msm_pcm_channel_mixer *ec_ref_chmix_cfg); int adm_map_rtac_block(struct rtac_cal_block_data *cal_block); int adm_unmap_rtac_block(uint32_t *mem_map_handle); Loading Loading
dsp/q6adm.c +206 −76 Original line number Diff line number Diff line Loading @@ -3006,15 +3006,21 @@ 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, static int adm_copp_set_ec_ref_mfc_cfg_v2(int port_id, int copp_idx, int sample_rate, int bps, int in_channels, int out_channels) struct msm_pcm_channel_mixer *cfg) { 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} }; int in_channels, out_channels; if (!cfg) return -EINVAL; in_channels = cfg->input_channel; out_channels = cfg->output_channel; memset(&mfc_cfg, 0, sizeof(mfc_cfg)); memset(&ep_payload, 0, sizeof(ep_payload)); Loading @@ -3028,7 +3034,8 @@ static int adm_copp_set_ec_ref_mfc_cfg(int port_id, int copp_idx, bps, in_channels, out_channels); if (out_channels <= 0 || out_channels > AUDPROC_MFC_OUT_CHANNELS_MAX) { pr_err("%s: unsupported out channels=%d\n", __func__, out_channels); pr_err("%s: unsupported out channels=%d\n", __func__, out_channels); return -EINVAL; } Loading @@ -3041,67 +3048,121 @@ static int adm_copp_set_ec_ref_mfc_cfg(int port_id, int copp_idx, mfc_cfg.num_channels = out_channels; ep_payload.dev_num_channel = out_channels; if (cfg && cfg->override_out_ch_map) { for (i = 0; i < out_channels; i++) { ep_payload.dev_channel_mapping[i] = cfg->out_ch_map[i]; pr_debug("%s: out_ch_map[%d] = %d", __func__, i, ep_payload.dev_channel_mapping[i]); } } else { 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]; 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); 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 = 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) { if (!chmixer_params) return -ENOMEM; } param_index = 2; /* param[0] and [1] represents chmixer rule(always 0) */ /* param[0] and [1] represents chmixer rule(always 0) */ param_index = 2; 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]; chmixer_params[param_index++] = ep_payload.dev_channel_mapping[i]; /* input channel map should be same as one set for ep2 during copp open */ /* input chmap should be same as one set for ep2 during copp open */ ep_payload.dev_num_channel = in_channels; if (cfg && cfg->override_in_ch_map) { for (i = 0; i < in_channels; i++) { ep_payload.dev_channel_mapping[i] = cfg->in_ch_map[i]; pr_debug("%s: in_ch_map[%d] = %d", __func__, i, ep_payload.dev_channel_mapping[i]); } } else { 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]; 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]; for (j = 0; j < in_channels; j++) { chmixer_params[param_index++] = cfg->channel_weight[i][j]; pr_debug("%s: ch_weight[%d][%d] = %d\n", __func__, i, j, cfg->channel_weight[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); pr_err("%s: Failed to set chmixer params, err %d\n", __func__, rc); exit: kfree(chmixer_params); 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 msm_pcm_channel_mixer *cfg = NULL; int rc =0, i, j; cfg =kzalloc(sizeof(struct msm_pcm_channel_mixer), GFP_KERNEL); if (!cfg) { pr_err("%s: fail to allocate memory\n", __func__); return -ENOMEM; } cfg->input_channel = in_channels; cfg->output_channel = out_channels; for (i = 0; i < out_channels; i++) for (j = 0; j < in_channels; j++) cfg->channel_weight[i][j] = this_adm.ec_ref_chmixer_weights[i][j]; rc = adm_copp_set_ec_ref_mfc_cfg_v2(port_id, copp_idx, sample_rate, bps, cfg); kfree(cfg); return rc; } /** * adm_open - * command to send ADM open Loading @@ -3122,6 +3183,38 @@ static int adm_copp_set_ec_ref_mfc_cfg(int port_id, int copp_idx, int adm_open(int port_id, int path, int rate, int channel_mode, int topology, int perf_mode, uint16_t bit_width, int app_type, int acdb_id, int session_type, uint32_t passthr_mode, uint32_t copp_token) { return adm_open_v2(port_id, path, rate, channel_mode, topology, perf_mode, bit_width, app_type, acdb_id, session_type, passthr_mode, copp_token, NULL, NULL); } EXPORT_SYMBOL(adm_open); /** * adm_open_v2 - * command to send ADM open with ec_ref config * * @port_id: port id number * @path: direction or ADM path type * @rate: sample rate of session * @channel_mode: number of channels set * @topology: topology active for this session * @perf_mode: performance mode like LL/ULL/.. * @bit_width: bit width to set for copp * @app_type: App type used for this session * @acdb_id: ACDB ID of this device * @session_type: type of session * @ec_ref_port_cfg: ec_ref port configuration * @ec_ref_chmix_cfg: ec_ref channel mixer configuration * * Returns 0 on success or error on failure */ int adm_open_v2(int port_id, int path, int rate, int channel_mode, int topology, int perf_mode, uint16_t bit_width, int app_type, int acdb_id, int session_type, uint32_t passthr_mode, uint32_t copp_token, struct msm_ec_ref_port_cfg *ec_ref_port_cfg, struct msm_pcm_channel_mixer *ec_ref_chmix_cfg) { struct adm_cmd_device_open_v5 open; struct adm_cmd_device_open_v6 open_v6; Loading @@ -3136,7 +3229,23 @@ 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; int i; int ec_ref_port_id = ec_ref_port_cfg ? ec_ref_port_cfg->port_id : this_adm.ec_ref_rx; int ec_ref_ch = ec_ref_port_cfg ? ec_ref_port_cfg->ch : this_adm.num_ec_ref_rx_chans; int ec_ref_bit = ec_ref_port_cfg ? ec_ref_port_cfg->bit_width : this_adm.ec_ref_rx_bit_width; int ec_ref_sampling_rate = ec_ref_port_cfg ? ec_ref_port_cfg->sampling_rate : this_adm.ec_ref_rx_sampling_rate; 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 @@ -3227,7 +3336,8 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, copp_idx = adm_get_idx_if_copp_exists(port_idx, topology, perf_mode, rate, bit_width, app_type, session_type, copp_token); app_type, session_type, copp_token); if (copp_idx < 0) { copp_idx = adm_get_next_available_copp(port_idx); Loading Loading @@ -3324,17 +3434,16 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, open_v8.endpoint_id_2 = 0xFFFF; open_v8.endpoint_id_3 = 0xFFFF; if (((this_adm.ec_ref_rx & AFE_PORT_INVALID) != if (((ec_ref_port_id & AFE_PORT_INVALID) != AFE_PORT_INVALID) && (path != ADM_PATH_PLAYBACK)) { if (this_adm.num_ec_ref_rx_chans != 0) { if (ec_ref_ch != 0) { open_v8.endpoint_id_2 = this_adm.ec_ref_rx; this_adm.ec_ref_rx = AFE_PORT_INVALID; ec_ref_port_id; ec_ref_port_id = AFE_PORT_INVALID; } else { pr_err("%s: EC channels not set %d\n", __func__, this_adm.num_ec_ref_rx_chans); __func__, ec_ref_ch); return -EINVAL; } } Loading Loading @@ -3367,25 +3476,22 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, + ep1_payload_size; atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); if ((this_adm.num_ec_ref_rx_chans != 0) if ((ec_ref_ch != 0) && (path != ADM_PATH_PLAYBACK) && (open_v8.endpoint_id_2 != 0xFFFF)) { ep2_payload.dev_num_channel = this_adm.num_ec_ref_rx_chans; ec_ref_ch; if (this_adm.ec_ref_rx_bit_width != 0) { ep2_payload.bit_width = this_adm.ec_ref_rx_bit_width; } else { if (ec_ref_bit != 0) ep2_payload.bit_width = ec_ref_bit; else ep2_payload.bit_width = bit_width; } if (this_adm.ec_ref_rx_sampling_rate != 0) { if (ec_ref_sampling_rate != 0) ep2_payload.sample_rate = this_adm.ec_ref_rx_sampling_rate; } else { ec_ref_sampling_rate; else ep2_payload.sample_rate = rate; } pr_debug("%s: adm open_v8 eid2_channels=%d eid2_bit_width=%d eid2_rate=%d\n", __func__, Loading @@ -3393,11 +3499,22 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, ep2_payload.bit_width, ep2_payload.sample_rate); ret = adm_arrange_mch_ep2_map_v8(&ep2_payload, if (ec_ref_chmix_cfg && ec_ref_chmix_cfg->override_in_ch_map) { for (i = 0; i < ec_ref_ch; i++) { ep2_payload.dev_channel_mapping[i] = ec_ref_chmix_cfg->in_ch_map[i]; pr_debug("%s: in_ch_map[%d] = %d", __func__, i, ep2_payload.dev_channel_mapping[i]); } } else { ret = adm_arrange_mch_ep2_map_v8( &ep2_payload, ep2_payload.dev_num_channel); if (ret) return ret; } ep2_payload_size = 8 + roundup(ep2_payload.dev_num_channel, 4); param_size += ep2_payload_size; Loading @@ -3412,7 +3529,7 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, (void *)&ep1_payload, ep1_payload_size); if ((this_adm.num_ec_ref_rx_chans != 0) if ((ec_ref_ch != 0) && (path != ADM_PATH_PLAYBACK) && (open_v8.endpoint_id_2 != 0xFFFF)) { memcpy(adm_params + sizeof(open_v8) Loading Loading @@ -3473,7 +3590,7 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); if ((this_adm.num_ec_ref_rx_chans != 0) && if ((ec_ref_ch != 0) && (path != 1) && (open.endpoint_id_2 != 0xFFFF)) { memset(&open_v6, 0, sizeof(struct adm_cmd_device_open_v6)); Loading @@ -3482,21 +3599,18 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, open_v6.hdr.opcode = ADM_CMD_DEVICE_OPEN_V6; open_v6.hdr.pkt_size = sizeof(open_v6); open_v6.dev_num_channel_eid2 = this_adm.num_ec_ref_rx_chans; ec_ref_ch; if (this_adm.ec_ref_rx_bit_width != 0) { open_v6.bit_width_eid2 = this_adm.ec_ref_rx_bit_width; } else { if (ec_ref_bit != 0) open_v6.bit_width_eid2 = ec_ref_bit; else open_v6.bit_width_eid2 = bit_width; } if (this_adm.ec_ref_rx_sampling_rate != 0) { if (ec_ref_sampling_rate != 0) open_v6.sample_rate_eid2 = this_adm.ec_ref_rx_sampling_rate; } else { ec_ref_sampling_rate; else open_v6.sample_rate_eid2 = rate; } pr_debug("%s: eid2_channels=%d eid2_bit_width=%d eid2_rate=%d\n", __func__, open_v6.dev_num_channel_eid2, Loading Loading @@ -3527,24 +3641,40 @@ 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. * Configure MFC(in ec_ref path) if chmix 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 (ec_ref_chmix_cfg) { if (path != ADM_PATH_PLAYBACK && ec_ref_chmix_cfg->output_channel != 0 && ec_ref_chmix_cfg->input_channel != ec_ref_chmix_cfg->output_channel) { ret = adm_copp_set_ec_ref_mfc_cfg_v2(port_id, copp_idx, rate, bit_width, ec_ref_chmix_cfg); ec_ref_chmix_cfg->output_channel = 0; if (ret) pr_err("%s: set EC REF MFC cfg v2 failed, err %d\n", __func__, ret); } } else { 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) { this_adm.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, rate, bit_width, this_adm.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); pr_err("%s: set EC REF MFC cfg failed, err %d\n", __func__, ret); } } return copp_idx; } EXPORT_SYMBOL(adm_open); EXPORT_SYMBOL(adm_open_v2); /** * adm_copp_mfc_cfg - Loading
include/dsp/q6adm-v2.h +15 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,14 @@ enum { #define ADSP_ADM_API_VERSION_V3 3 struct msm_ec_ref_port_cfg { int rx; int port_id; int ch; int bit_width; int sampling_rate; }; /* multiple copp per stream. */ struct route_payload { unsigned int copp_idx[MAX_COPPS_PER_PORT]; Loading Loading @@ -122,6 +130,13 @@ int adm_open(int port, int path, int rate, int mode, int topology, int app_type, int acdbdev_id, int session_type, uint32_t pass_thr, uint32_t copp_token); int adm_open_v2(int port, int path, int rate, int mode, int topology, int perf_mode, uint16_t bits_per_sample, int app_type, int acdbdev_id, int session_type, uint32_t pass_thr, uint32_t copp_token, struct msm_ec_ref_port_cfg *ec_ref_port_cfg, struct msm_pcm_channel_mixer *ec_ref_chmix_cfg); int adm_map_rtac_block(struct rtac_cal_block_data *cal_block); int adm_unmap_rtac_block(uint32_t *mem_map_handle); Loading