ASoC: q6dspv2: Support for pan-scale and downmix set param
Add support for set params on ASM/ADM for MFC and Volume modules. Make PSPD mitrix set param api generic. Change-Id: I75a5b9e3fd2316b75be41439848f89190944bc36 Signed-off-by: Varun Balaraj <varunb@codeaurora.org>
This commit is contained in:
parent
d9fbe4b921
commit
701ac49eb7
6 changed files with 368 additions and 12 deletions
|
@ -625,6 +625,10 @@ struct audproc_softvolume_params {
|
|||
*/
|
||||
#define AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT 0x00010913
|
||||
|
||||
/* ID of the Coefficient parameter used by AUDPROC_MODULE_ID_CHMIXER to
|
||||
*configure the channel mixer weighting coefficients.
|
||||
*/
|
||||
#define AUDPROC_CHMIXER_PARAM_ID_COEFF 0x00010342
|
||||
|
||||
struct audproc_mfc_output_media_fmt {
|
||||
struct adm_cmd_set_pp_params_v5 params;
|
||||
|
@ -3902,6 +3906,14 @@ struct asm_softvolume_params {
|
|||
u32 rampingcurve;
|
||||
} __packed;
|
||||
|
||||
struct asm_stream_pan_ctrl_params {
|
||||
uint16_t num_output_channels;
|
||||
uint16_t num_input_channels;
|
||||
uint16_t output_channel_map[8];
|
||||
uint16_t input_channel_map[8];
|
||||
uint16_t gain[64];
|
||||
} __packed;
|
||||
|
||||
#define ASM_END_POINT_DEVICE_MATRIX 0
|
||||
|
||||
#define PCM_CHANNEL_NULL 0
|
||||
|
@ -7802,6 +7814,48 @@ struct asm_volume_ctrl_lr_chan_gain {
|
|||
/*< Linear gain in Q13 format for the right channel.*/
|
||||
} __packed;
|
||||
|
||||
struct audproc_chmixer_param_coeff {
|
||||
uint32_t index;
|
||||
uint16_t num_output_channels;
|
||||
uint16_t num_input_channels;
|
||||
} __packed;
|
||||
|
||||
|
||||
/* ID of the Multichannel Volume Control parameters used by
|
||||
* AUDPROC_MODULE_ID_VOL_CTRL.
|
||||
*/
|
||||
#define AUDPROC_PARAM_ID_MULTICHANNEL_GAIN 0x00010713
|
||||
|
||||
/* Payload of the AUDPROC_PARAM_ID_MULTICHANNEL_GAIN channel type/gain
|
||||
* pairs used by the Volume Control module.
|
||||
* This structure immediately follows the
|
||||
* audproc_volume_ctrl_multichannel_gain_t structure.
|
||||
*/
|
||||
struct audproc_volume_ctrl_channel_type_gain_pair {
|
||||
uint8_t channel_type;
|
||||
/* Channel type for which the gain setting is to be applied. */
|
||||
|
||||
uint8_t reserved1;
|
||||
uint8_t reserved2;
|
||||
uint8_t reserved3;
|
||||
|
||||
uint32_t gain;
|
||||
/* Gain value for this channel in Q28 format. */
|
||||
} __packed;
|
||||
|
||||
/* Payload of the AUDPROC_PARAM_ID_MULTICHANNEL_MUTE parameters used by
|
||||
* the Volume Control module.
|
||||
*/
|
||||
struct audproc_volume_ctrl_multichannel_gain {
|
||||
uint32_t num_channels;
|
||||
/* Number of channels for which mute configuration is provided. Any
|
||||
* channels present in the data for which mute configuration is not
|
||||
* provided are set to unmute.
|
||||
*/
|
||||
|
||||
struct audproc_volume_ctrl_channel_type_gain_pair *gain_data;
|
||||
/* Array of channel type/mute setting pairs. */
|
||||
} __packed;
|
||||
|
||||
/* Structure for the mute configuration parameter for a
|
||||
volume control module. */
|
||||
|
|
|
@ -138,9 +138,13 @@ int adm_get_topology_for_port_copp_idx(int port_id, int copp_idx);
|
|||
|
||||
int adm_get_indexes_from_copp_id(int copp_id, int *port_idx, int *copp_idx);
|
||||
|
||||
int adm_set_stereo_to_custom_stereo(int port_id, int copp_idx,
|
||||
unsigned int session_id,
|
||||
char *params, uint32_t params_length);
|
||||
int adm_set_pspd_matrix_params(int port_id, int copp_idx,
|
||||
unsigned int session_id,
|
||||
char *params, uint32_t params_length);
|
||||
|
||||
int adm_set_downmix_params(int port_id, int copp_idx,
|
||||
unsigned int session_id, char *params,
|
||||
uint32_t params_length);
|
||||
|
||||
int adm_get_pp_topo_module_list(int port_id, int copp_idx, int32_t param_length,
|
||||
char *params);
|
||||
|
|
|
@ -611,6 +611,14 @@ int q6asm_set_softvolume(struct audio_client *ac,
|
|||
int q6asm_set_softvolume_v2(struct audio_client *ac,
|
||||
struct asm_softvolume_params *param, int instance);
|
||||
|
||||
/* Set panning and MFC params */
|
||||
int q6asm_set_mfc_panning_params(struct audio_client *ac,
|
||||
struct asm_stream_pan_ctrl_params *pan_param);
|
||||
|
||||
/* Set vol gain pair */
|
||||
int q6asm_set_vol_ctrl_gain_pair(struct audio_client *ac,
|
||||
struct asm_stream_pan_ctrl_params *pan_param);
|
||||
|
||||
/* Send left-right channel gain */
|
||||
int q6asm_set_lrgain(struct audio_client *ac, int left_gain, int right_gain);
|
||||
|
||||
|
|
|
@ -298,11 +298,11 @@ int msm_qti_pp_send_stereo_to_custom_stereo_cmd(int port_id, int copp_idx,
|
|||
*update_params_value16++ = op_FR_ip_FR_weight;
|
||||
avail_length = avail_length - (4 * sizeof(uint16_t));
|
||||
if (params_length) {
|
||||
rc = adm_set_stereo_to_custom_stereo(port_id,
|
||||
copp_idx,
|
||||
session_id,
|
||||
params_value,
|
||||
params_length);
|
||||
rc = adm_set_pspd_matrix_params(port_id,
|
||||
copp_idx,
|
||||
session_id,
|
||||
params_value,
|
||||
params_length);
|
||||
if (rc) {
|
||||
pr_err("%s: send params failed rc=%d\n", __func__, rc);
|
||||
kfree(params_value);
|
||||
|
|
|
@ -781,9 +781,9 @@ fail_cmd:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int adm_set_stereo_to_custom_stereo(int port_id, int copp_idx,
|
||||
unsigned int session_id, char *params,
|
||||
uint32_t params_length)
|
||||
int adm_set_pspd_matrix_params(int port_id, int copp_idx,
|
||||
unsigned int session_id, char *params,
|
||||
uint32_t params_length)
|
||||
{
|
||||
struct adm_cmd_set_pspd_mtmx_strtr_params_v5 *adm_params = NULL;
|
||||
int sz, rc = 0, port_idx;
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#define TRUE 0x01
|
||||
#define FALSE 0x00
|
||||
#define SESSION_MAX 8
|
||||
|
||||
#define ASM_MAX_CHANNELS 8
|
||||
enum {
|
||||
ASM_TOPOLOGY_CAL = 0,
|
||||
ASM_CUSTOM_TOP_CAL,
|
||||
|
@ -7419,6 +7419,296 @@ int q6asm_set_softvolume_v2(struct audio_client *ac,
|
|||
return __q6asm_set_softvolume(ac, softvol_param, instance);
|
||||
}
|
||||
|
||||
int q6asm_set_vol_ctrl_gain_pair(struct audio_client *ac,
|
||||
struct asm_stream_pan_ctrl_params *pan_param)
|
||||
{
|
||||
int sz = 0;
|
||||
int rc = 0;
|
||||
int i = 0;
|
||||
int32_t ch = 0;
|
||||
struct apr_hdr hdr;
|
||||
struct audproc_volume_ctrl_channel_type_gain_pair
|
||||
gain_data[ASM_MAX_CHANNELS];
|
||||
struct asm_stream_cmd_set_pp_params_v2 payload_params;
|
||||
struct asm_stream_param_data_v2 data;
|
||||
uint16_t *asm_params = NULL;
|
||||
|
||||
if (ac == NULL) {
|
||||
pr_err("%s: ac is NULL\n", __func__);
|
||||
rc = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
if (ac->apr == NULL) {
|
||||
dev_err(ac->dev, "%s: ac apr handle NULL\n", __func__);
|
||||
rc = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sz = sizeof(struct apr_hdr) +
|
||||
sizeof(struct asm_stream_cmd_set_pp_params_v2) +
|
||||
sizeof(struct asm_stream_param_data_v2) +
|
||||
sizeof(uint32_t) +
|
||||
(sizeof(struct audproc_volume_ctrl_channel_type_gain_pair) *
|
||||
ASM_MAX_CHANNELS);
|
||||
asm_params = kzalloc(sz, GFP_KERNEL);
|
||||
if (!asm_params) {
|
||||
rc = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
q6asm_add_hdr_async(ac, &hdr, sz, TRUE);
|
||||
atomic_set(&ac->cmd_state_pp, -1);
|
||||
|
||||
hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2;
|
||||
memcpy(((u8 *)asm_params), &hdr, sizeof(struct apr_hdr));
|
||||
|
||||
payload_params.data_payload_addr_lsw = 0;
|
||||
payload_params.data_payload_addr_msw = 0;
|
||||
payload_params.mem_map_handle = 0;
|
||||
payload_params.data_payload_size =
|
||||
sizeof(struct asm_stream_param_data_v2) +
|
||||
sizeof(uint32_t) +
|
||||
(sizeof(struct audproc_volume_ctrl_channel_type_gain_pair) *
|
||||
ASM_MAX_CHANNELS);
|
||||
memcpy(((u8 *)asm_params + sizeof(struct apr_hdr)),
|
||||
&payload_params,
|
||||
sizeof(struct asm_stream_cmd_set_pp_params_v2));
|
||||
|
||||
data.module_id = AUDPROC_MODULE_ID_VOL_CTRL;
|
||||
data.param_id = AUDPROC_PARAM_ID_MULTICHANNEL_GAIN;
|
||||
data.param_size = sizeof(uint32_t) +
|
||||
(sizeof(struct audproc_volume_ctrl_channel_type_gain_pair) *
|
||||
ASM_MAX_CHANNELS);
|
||||
data.reserved = 0;
|
||||
memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) +
|
||||
sizeof(struct asm_stream_cmd_set_pp_params_v2)),
|
||||
&data, sizeof(struct asm_stream_param_data_v2));
|
||||
|
||||
ch = pan_param->num_output_channels;
|
||||
memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) +
|
||||
sizeof(struct asm_stream_cmd_set_pp_params_v2) +
|
||||
sizeof(struct asm_stream_param_data_v2)),
|
||||
&ch,
|
||||
sizeof(uint32_t));
|
||||
|
||||
memset(gain_data, 0,
|
||||
ASM_MAX_CHANNELS *
|
||||
sizeof(struct audproc_volume_ctrl_channel_type_gain_pair));
|
||||
for (i = 0; i < pan_param->num_output_channels; i++) {
|
||||
gain_data[i].channel_type =
|
||||
pan_param->output_channel_map[i];
|
||||
gain_data[i].gain = pan_param->gain[i];
|
||||
}
|
||||
memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) +
|
||||
sizeof(struct asm_stream_cmd_set_pp_params_v2) +
|
||||
sizeof(struct asm_stream_param_data_v2) +
|
||||
sizeof(uint32_t)),
|
||||
gain_data,
|
||||
ASM_MAX_CHANNELS *
|
||||
sizeof(struct audproc_volume_ctrl_channel_type_gain_pair));
|
||||
|
||||
rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
|
||||
__func__, data.param_id, rc);
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = wait_event_timeout(ac->cmd_wait,
|
||||
(atomic_read(&ac->cmd_state_pp) >= 0), 5 * HZ);
|
||||
if (!rc) {
|
||||
pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__,
|
||||
data.param_id);
|
||||
rc = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
if (atomic_read(&ac->cmd_state_pp) > 0) {
|
||||
pr_err("%s: DSP returned error[%d], set-params paramid[0x%x]\n",
|
||||
__func__, atomic_read(&ac->cmd_state_pp),
|
||||
data.param_id);
|
||||
rc = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
rc = 0;
|
||||
done:
|
||||
kfree(asm_params);
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int q6asm_set_mfc_panning_params(struct audio_client *ac,
|
||||
struct asm_stream_pan_ctrl_params *pan_param)
|
||||
{
|
||||
int sz, rc, i;
|
||||
struct audproc_mfc_output_media_fmt mfc_cfg;
|
||||
struct apr_hdr hdr;
|
||||
struct asm_stream_cmd_set_pp_params_v2 payload_params;
|
||||
struct asm_stream_param_data_v2 data;
|
||||
struct audproc_chmixer_param_coeff pan_cfg;
|
||||
uint16_t variable_payload = 0;
|
||||
uint16_t *asm_params = NULL;
|
||||
|
||||
sz = rc = i = 0;
|
||||
if (ac == NULL) {
|
||||
pr_err("%s: ac handle NULL\n", __func__);
|
||||
rc = -EINVAL;
|
||||
goto fail_cmd1;
|
||||
}
|
||||
if (ac->apr == NULL) {
|
||||
pr_err("%s: ac apr handle NULL\n", __func__);
|
||||
rc = -EINVAL;
|
||||
goto fail_cmd1;
|
||||
}
|
||||
|
||||
sz = sizeof(struct audproc_mfc_output_media_fmt);
|
||||
q6asm_add_hdr_async(ac, &mfc_cfg.params.hdr, sz, TRUE);
|
||||
atomic_set(&ac->cmd_state_pp, -1);
|
||||
mfc_cfg.params.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2;
|
||||
mfc_cfg.params.payload_addr_lsw = 0;
|
||||
mfc_cfg.params.payload_addr_msw = 0;
|
||||
mfc_cfg.params.mem_map_handle = 0;
|
||||
mfc_cfg.params.payload_size = sizeof(mfc_cfg) - sizeof(mfc_cfg.params);
|
||||
mfc_cfg.data.module_id = AUDPROC_MODULE_ID_MFC;
|
||||
mfc_cfg.data.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT;
|
||||
mfc_cfg.data.param_size = mfc_cfg.params.payload_size -
|
||||
sizeof(mfc_cfg.data);
|
||||
mfc_cfg.data.reserved = 0;
|
||||
mfc_cfg.sampling_rate = 0;
|
||||
mfc_cfg.bits_per_sample = 0;
|
||||
mfc_cfg.num_channels = pan_param->num_output_channels;
|
||||
for (i = 0; i < mfc_cfg.num_channels; i++)
|
||||
mfc_cfg.channel_type[i] = pan_param->output_channel_map[i];
|
||||
|
||||
rc = apr_send_pkt(ac->apr, (uint32_t *) &mfc_cfg);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
|
||||
__func__, mfc_cfg.data.param_id, rc);
|
||||
rc = -EINVAL;
|
||||
goto fail_cmd1;
|
||||
}
|
||||
|
||||
rc = wait_event_timeout(ac->cmd_wait,
|
||||
(atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ);
|
||||
if (!rc) {
|
||||
pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__,
|
||||
mfc_cfg.data.param_id);
|
||||
rc = -ETIMEDOUT;
|
||||
goto fail_cmd1;
|
||||
}
|
||||
if (atomic_read(&ac->cmd_state_pp) > 0) {
|
||||
pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n",
|
||||
__func__, adsp_err_get_err_str(
|
||||
atomic_read(&ac->cmd_state_pp)),
|
||||
mfc_cfg.data.param_id);
|
||||
rc = adsp_err_get_lnx_err_code(
|
||||
atomic_read(&ac->cmd_state_pp));
|
||||
goto fail_cmd1;
|
||||
}
|
||||
|
||||
variable_payload = pan_param->num_output_channels * sizeof(uint16_t)+
|
||||
pan_param->num_input_channels * sizeof(uint16_t) +
|
||||
pan_param->num_output_channels * sizeof(uint16_t) *
|
||||
pan_param->num_input_channels * sizeof(uint16_t);
|
||||
i = (variable_payload % sizeof(uint32_t));
|
||||
variable_payload += (i == 0) ? 0 : sizeof(uint32_t) - i;
|
||||
sz = sizeof(struct apr_hdr) +
|
||||
sizeof(struct asm_stream_cmd_set_pp_params_v2) +
|
||||
sizeof(struct asm_stream_param_data_v2) +
|
||||
sizeof(struct audproc_chmixer_param_coeff) +
|
||||
variable_payload;
|
||||
|
||||
asm_params = kzalloc(sz, GFP_KERNEL);
|
||||
if (!asm_params) {
|
||||
rc = -ENOMEM;
|
||||
goto fail_cmd1;
|
||||
}
|
||||
|
||||
q6asm_add_hdr_async(ac, &hdr, sz, TRUE);
|
||||
atomic_set(&ac->cmd_state_pp, -1);
|
||||
hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2;
|
||||
memcpy(((u8 *)asm_params), &hdr, sizeof(struct apr_hdr));
|
||||
|
||||
payload_params.data_payload_addr_lsw = 0;
|
||||
payload_params.data_payload_addr_msw = 0;
|
||||
payload_params.mem_map_handle = 0;
|
||||
payload_params.data_payload_size =
|
||||
sizeof(struct audproc_chmixer_param_coeff) +
|
||||
variable_payload + sizeof(struct asm_stream_param_data_v2);
|
||||
memcpy(((u8 *)asm_params + sizeof(struct apr_hdr)),
|
||||
&payload_params,
|
||||
sizeof(struct asm_stream_cmd_set_pp_params_v2));
|
||||
|
||||
data.module_id = AUDPROC_MODULE_ID_MFC;
|
||||
data.param_id = AUDPROC_CHMIXER_PARAM_ID_COEFF;
|
||||
data.param_size = sizeof(struct audproc_chmixer_param_coeff) +
|
||||
variable_payload;
|
||||
data.reserved = 0;
|
||||
memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) +
|
||||
sizeof(struct asm_stream_cmd_set_pp_params_v2)),
|
||||
&data, sizeof(struct asm_stream_param_data_v2));
|
||||
|
||||
pan_cfg.index = 0;
|
||||
pan_cfg.num_output_channels = pan_param->num_output_channels;
|
||||
pan_cfg.num_input_channels = pan_param->num_input_channels;
|
||||
memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) +
|
||||
sizeof(struct asm_stream_cmd_set_pp_params_v2) +
|
||||
sizeof(struct asm_stream_param_data_v2)),
|
||||
&pan_cfg, sizeof(struct audproc_chmixer_param_coeff));
|
||||
memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) +
|
||||
sizeof(struct asm_stream_cmd_set_pp_params_v2) +
|
||||
sizeof(struct asm_stream_param_data_v2) +
|
||||
sizeof(struct audproc_chmixer_param_coeff)),
|
||||
pan_param->output_channel_map,
|
||||
pan_param->num_output_channels * sizeof(uint16_t));
|
||||
memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) +
|
||||
sizeof(struct asm_stream_cmd_set_pp_params_v2) +
|
||||
sizeof(struct asm_stream_param_data_v2) +
|
||||
sizeof(struct audproc_chmixer_param_coeff) +
|
||||
pan_param->num_output_channels * sizeof(uint16_t)),
|
||||
pan_param->input_channel_map,
|
||||
pan_param->num_input_channels * sizeof(uint16_t));
|
||||
memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) +
|
||||
sizeof(struct asm_stream_cmd_set_pp_params_v2) +
|
||||
sizeof(struct asm_stream_param_data_v2) +
|
||||
sizeof(struct audproc_chmixer_param_coeff) +
|
||||
(pan_param->num_output_channels * sizeof(uint16_t)) +
|
||||
(pan_param->num_input_channels * sizeof(uint16_t))),
|
||||
pan_param->gain,
|
||||
(pan_param->num_output_channels * sizeof(uint16_t)) *
|
||||
(pan_param->num_input_channels * sizeof(uint16_t)));
|
||||
|
||||
rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
|
||||
__func__, data.param_id, rc);
|
||||
rc = -EINVAL;
|
||||
goto fail_cmd2;
|
||||
}
|
||||
|
||||
rc = wait_event_timeout(ac->cmd_wait,
|
||||
(atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ);
|
||||
if (!rc) {
|
||||
pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__,
|
||||
data.param_id);
|
||||
rc = -ETIMEDOUT;
|
||||
goto fail_cmd2;
|
||||
}
|
||||
if (atomic_read(&ac->cmd_state_pp) > 0) {
|
||||
pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n",
|
||||
__func__, adsp_err_get_err_str(
|
||||
atomic_read(&ac->cmd_state_pp)),
|
||||
data.param_id);
|
||||
rc = adsp_err_get_lnx_err_code(
|
||||
atomic_read(&ac->cmd_state_pp));
|
||||
goto fail_cmd2;
|
||||
}
|
||||
rc = 0;
|
||||
fail_cmd2:
|
||||
kfree(asm_params);
|
||||
fail_cmd1:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int q6asm_equalizer(struct audio_client *ac, void *eq_p)
|
||||
{
|
||||
struct asm_eq_params eq;
|
||||
|
|
Loading…
Add table
Reference in a new issue