From 916967ba228a9c141907b983fa49f36a0e999b46 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Mon, 29 Jan 2018 16:52:52 -0800 Subject: [PATCH 1/3] ASoC: dsp: Update dap driver to support Instance ID Add support to set and get dap modules params with Instance ID support for both Dolby and DS2. Maintain support for non Instance ID set and get param structures as well. Use common pack and set param functions to set and get parameters to DSP instead of handling them at an individual module level. CRs-Fixed: 2151551 Change-Id: I1633b63a1a598c0e4ea874d00655b09a240a47e3 Signed-off-by: Vignesh Kulothungan --- asoc/msm-ds2-dap-config.c | 538 ++++++++++++++++++++------------------ asoc/msm-ds2-dap-config.h | 31 ++- dsp/q6adm.c | 51 ---- include/dsp/q6adm-v2.h | 6 - 4 files changed, 313 insertions(+), 313 deletions(-) diff --git a/asoc/msm-ds2-dap-config.c b/asoc/msm-ds2-dap-config.c index 645ecf5cfd2d..ad7a3c6a406f 100644 --- a/asoc/msm-ds2-dap-config.c +++ b/asoc/msm-ds2-dap-config.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -17,6 +17,7 @@ #include #include #include +#include #include "msm-ds2-dap-config.h" #include "msm-pcm-routing-v2.h" @@ -196,18 +197,23 @@ static void msm_ds2_dap_check_and_update_ramp_wait(int port_id, int copp_idx, int32_t *update_params_value = NULL; uint32_t params_length = SOFT_VOLUME_PARAM_SIZE * sizeof(uint32_t); uint32_t param_payload_len = PARAM_PAYLOAD_SIZE * sizeof(uint32_t); + struct param_hdr_v3 param_hdr; int rc = 0; update_params_value = kzalloc(params_length + param_payload_len, GFP_KERNEL); - if (!update_params_value) + if (!update_params_value) { + pr_err("%s: params memory alloc failed\n", __func__); goto end; + } - rc = adm_get_params(port_id, copp_idx, - AUDPROC_MODULE_ID_VOL_CTRL, - AUDPROC_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS, - params_length + param_payload_len, - (char *) update_params_value); + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AUDPROC_MODULE_ID_VOL_CTRL; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS; + param_hdr.param_size = params_length + param_payload_len; + rc = adm_get_pp_params(port_id, copp_idx, ADM_CLIENT_ID_DEFAULT, NULL, + ¶m_hdr, (char *) update_params_value); if (rc == 0) { pr_debug("%s: params_value [0x%x, 0x%x, 0x%x]\n", __func__, update_params_value[0], @@ -227,12 +233,13 @@ end: static int msm_ds2_dap_set_vspe_vdhe(int dev_map_idx, bool is_custom_stereo_enabled) { - int32_t *update_params_value = NULL; - int32_t *param_val = NULL; - int idx, i, j, rc = 0, cdev; - uint32_t params_length = (TOTAL_LENGTH_DOLBY_PARAM + - 2 * DOLBY_PARAM_PAYLOAD_SIZE) * - sizeof(uint32_t); + u8 *packed_param_data = NULL; + u8 *param_data = NULL; + struct param_hdr_v3 param_hdr; + u32 packed_param_size = 0; + u32 param_size = 0; + int cdev; + int rc = 0; if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) { pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx); @@ -260,74 +267,95 @@ static int msm_ds2_dap_set_vspe_vdhe(int dev_map_idx, goto end; } - update_params_value = kzalloc(params_length, GFP_KERNEL); - if (!update_params_value) { - rc = -ENOMEM; + /* Allocate the max space needed */ + packed_param_size = (TOTAL_LENGTH_DOLBY_PARAM * sizeof(uint32_t)) + + (2 * sizeof(union param_hdrs)); + packed_param_data = kzalloc(packed_param_size, GFP_KERNEL); + if (!packed_param_data) + return -ENOMEM; + + packed_param_size = 0; + memset(¶m_hdr, 0, sizeof(param_hdr)); + + /* Set common values */ + cdev = dev_map[dev_map_idx].cache_dev; + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + + /* Pack VDHE header + data */ + param_hdr.param_id = DOLBY_PARAM_ID_VDHE; + param_size = DOLBY_PARAM_VDHE_LENGTH * sizeof(uint32_t); + param_hdr.param_size = param_size; + + if (is_custom_stereo_enabled) + param_data = NULL; + else + param_data = (u8 *) &ds2_dap_params[cdev] + .params_val[DOLBY_PARAM_VDHE_OFFSET]; + + rc = q6common_pack_pp_params(packed_param_data, ¶m_hdr, param_data, + ¶m_size); + if (rc) { + pr_err("%s: Failed to pack params for dolby vdhe, error %d\n", + __func__, rc); goto end; } - params_length = 0; - param_val = update_params_value; - cdev = dev_map[dev_map_idx].cache_dev; - /* for VDHE and VSPE DAP params at index 0 and 1 in table */ - for (i = 0; i < 2; i++) { - *update_params_value++ = DOLBY_BUNDLE_MODULE_ID; - *update_params_value++ = ds2_dap_params_id[i]; - *update_params_value++ = ds2_dap_params_length[i] * - sizeof(uint32_t); - idx = ds2_dap_params_offset[i]; - for (j = 0; j < ds2_dap_params_length[i]; j++) { - if (is_custom_stereo_enabled) - *update_params_value++ = 0; - else - *update_params_value++ = - ds2_dap_params[cdev].params_val[idx+j]; - } - params_length += (DOLBY_PARAM_PAYLOAD_SIZE + - ds2_dap_params_length[i]) * - sizeof(uint32_t); - } + packed_param_size += param_size; - pr_debug("%s: valid param length: %d\n", __func__, params_length); - if (params_length) { - rc = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id, - dev_map[dev_map_idx].copp_idx, - (char *)param_val, - params_length); - if (rc) { - pr_err("%s: send vdhe/vspe params failed with rc=%d\n", - __func__, rc); - rc = -EINVAL; - goto end; - } + /* Pack VSPE header + data */ + param_hdr.param_id = DOLBY_PARAM_ID_VSPE; + param_size = DOLBY_PARAM_VSPE_LENGTH * sizeof(uint32_t); + param_hdr.param_size = param_size; + + if (is_custom_stereo_enabled) + param_data = NULL; + else + param_data = (u8 *) &ds2_dap_params[cdev] + .params_val[DOLBY_PARAM_VSPE_OFFSET]; + + rc = q6common_pack_pp_params(packed_param_data + packed_param_size, + ¶m_hdr, param_data, ¶m_size); + if (rc) { + pr_err("%s: Failed to pack params for dolby vspe, error %d\n", + __func__, rc); + goto end; + } + packed_param_size += param_size; + + rc = adm_set_pp_params(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, NULL, + packed_param_data, packed_param_size); + if (rc) { + pr_err("%s: send vdhe/vspe params failed with rc=%d\n", + __func__, rc); + rc = -EINVAL; + goto end; } end: - kfree(param_val); + kfree(packed_param_data); return rc; } int qti_set_custom_stereo_on(int port_id, int copp_idx, bool is_custom_stereo_on) { - + struct custom_stereo_param custom_stereo; + struct param_hdr_v3 param_hdr; uint16_t op_FL_ip_FL_weight; uint16_t op_FL_ip_FR_weight; uint16_t op_FR_ip_FL_weight; uint16_t op_FR_ip_FR_weight; - - int32_t *update_params_value32 = NULL, rc = 0; - int32_t *param_val = NULL; - int16_t *update_params_value16 = 0; - uint32_t params_length_bytes = CUSTOM_STEREO_PAYLOAD_SIZE * - sizeof(uint32_t); - uint32_t avail_length = params_length_bytes; + int rc = 0; if ((port_id != SLIMBUS_0_RX) && (port_id != RT_PROXY_PORT_001_RX)) { pr_debug("%s:No Custom stereo for port:0x%x\n", __func__, port_id); - goto skip_send_cmd; + return 0; } + memset(&custom_stereo, 0, sizeof(custom_stereo)); + memset(¶m_hdr, 0, sizeof(param_hdr)); pr_debug("%s: port 0x%x, copp_idx %d, is_custom_stereo_on %d\n", __func__, port_id, copp_idx, is_custom_stereo_on); if (is_custom_stereo_on) { @@ -346,76 +374,50 @@ int qti_set_custom_stereo_on(int port_id, int copp_idx, op_FR_ip_FR_weight = Q14_GAIN_UNITY; } - update_params_value32 = kzalloc(params_length_bytes, GFP_KERNEL); - if (!update_params_value32) { - rc = -ENOMEM; - goto skip_send_cmd; - } - param_val = update_params_value32; - if (avail_length < 2 * sizeof(uint32_t)) - goto skip_send_cmd; - *update_params_value32++ = MTMX_MODULE_ID_DEFAULT_CHMIXER; - *update_params_value32++ = DEFAULT_CHMIXER_PARAM_ID_COEFF; - avail_length = avail_length - (2 * sizeof(uint32_t)); + param_hdr.module_id = MTMX_MODULE_ID_DEFAULT_CHMIXER; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = DEFAULT_CHMIXER_PARAM_ID_COEFF; + param_hdr.param_size = sizeof(struct custom_stereo_param); - update_params_value16 = (int16_t *)update_params_value32; - if (avail_length < 10 * sizeof(uint16_t)) - goto skip_send_cmd; - *update_params_value16++ = CUSTOM_STEREO_CMD_PARAM_SIZE; - /* for alignment only*/ - *update_params_value16++ = 0; /* index is 32-bit param in little endian*/ - *update_params_value16++ = CUSTOM_STEREO_INDEX_PARAM; - *update_params_value16++ = 0; + custom_stereo.index = CUSTOM_STEREO_INDEX_PARAM; + custom_stereo.reserved = 0; /* for stereo mixing num out ch*/ - *update_params_value16++ = CUSTOM_STEREO_NUM_OUT_CH; + custom_stereo.num_out_ch = CUSTOM_STEREO_NUM_OUT_CH; /* for stereo mixing num in ch*/ - *update_params_value16++ = CUSTOM_STEREO_NUM_IN_CH; + custom_stereo.num_in_ch = CUSTOM_STEREO_NUM_IN_CH; /* Out ch map FL/FR*/ - *update_params_value16++ = PCM_CHANNEL_FL; - *update_params_value16++ = PCM_CHANNEL_FR; + custom_stereo.out_fl = PCM_CHANNEL_FL; + custom_stereo.out_fr = PCM_CHANNEL_FR; /* In ch map FL/FR*/ - *update_params_value16++ = PCM_CHANNEL_FL; - *update_params_value16++ = PCM_CHANNEL_FR; - avail_length = avail_length - (10 * sizeof(uint16_t)); + custom_stereo.in_fl = PCM_CHANNEL_FL; + custom_stereo.in_fr = PCM_CHANNEL_FR; + /* weighting coefficients as name suggests, * mixing will be done according to these coefficients */ - if (avail_length < 4 * sizeof(uint16_t)) - goto skip_send_cmd; - *update_params_value16++ = op_FL_ip_FL_weight; - *update_params_value16++ = op_FL_ip_FR_weight; - *update_params_value16++ = op_FR_ip_FL_weight; - *update_params_value16++ = op_FR_ip_FR_weight; - avail_length = avail_length - (4 * sizeof(uint16_t)); - if (params_length_bytes != 0) { - rc = adm_dolby_dap_send_params(port_id, copp_idx, - (char *)param_val, - params_length_bytes); - if (rc) { - pr_err("%s: send params failed rc=%d\n", __func__, rc); - rc = -EINVAL; - goto skip_send_cmd; - } + custom_stereo.op_FL_ip_FL_weight = op_FL_ip_FL_weight; + custom_stereo.op_FL_ip_FR_weight = op_FL_ip_FR_weight; + custom_stereo.op_FR_ip_FL_weight = op_FR_ip_FL_weight; + custom_stereo.op_FR_ip_FR_weight = op_FR_ip_FR_weight; + rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (u8 *) &custom_stereo); + if (rc) { + pr_err("%s: send params failed rc=%d\n", __func__, rc); + return -EINVAL; } - kfree(param_val); + return 0; -skip_send_cmd: - pr_err("%s: insufficient memory, send cmd failed\n", - __func__); - kfree(param_val); - return rc; } static int dap_set_custom_stereo_onoff(int dev_map_idx, bool is_custom_stereo_enabled) { + uint32_t enable = is_custom_stereo_enabled ? 1 : 0; + struct param_hdr_v3 param_hdr; + int rc = 0; - int32_t *update_params_value = NULL, rc = 0; - int32_t *param_val = NULL; - uint32_t params_length_bytes = (TOTAL_LENGTH_DOLBY_PARAM + - DOLBY_PARAM_PAYLOAD_SIZE) * sizeof(uint32_t); if ((dev_map[dev_map_idx].port_id != SLIMBUS_0_RX) && (dev_map[dev_map_idx].port_id != RT_PROXY_PORT_001_RX)) { pr_debug("%s:No Custom stereo for port:0x%x\n", @@ -429,41 +431,25 @@ static int dap_set_custom_stereo_onoff(int dev_map_idx, goto end; } + memset(¶m_hdr, 0, sizeof(param_hdr)); + /* DAP custom stereo */ msm_ds2_dap_set_vspe_vdhe(dev_map_idx, is_custom_stereo_enabled); - update_params_value = kzalloc(params_length_bytes, GFP_KERNEL); - if (!update_params_value) { - pr_err("%s: params memory alloc failed\n", __func__); - rc = -ENOMEM; - goto end; - } - params_length_bytes = 0; - param_val = update_params_value; - *update_params_value++ = DOLBY_BUNDLE_MODULE_ID; - *update_params_value++ = DOLBY_ENABLE_CUSTOM_STEREO; - *update_params_value++ = sizeof(uint32_t); - if (is_custom_stereo_enabled) - *update_params_value++ = 1; - else - *update_params_value++ = 0; - params_length_bytes += (DOLBY_PARAM_PAYLOAD_SIZE + 1) * - sizeof(uint32_t); - pr_debug("%s: valid param length: %d\n", __func__, params_length_bytes); - if (params_length_bytes) { - rc = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id, - dev_map[dev_map_idx].copp_idx, - (char *)param_val, - params_length_bytes); - if (rc) { - pr_err("%s: custom stereo param failed with rc=%d\n", - __func__, rc); - rc = -EINVAL; - goto end; - } + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = DOLBY_ENABLE_CUSTOM_STEREO; + param_hdr.param_size = sizeof(enable); + + rc = adm_pack_and_set_one_pp_param(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, + param_hdr, (u8 *) &enable); + if (rc) { + pr_err("%s: set custom stereo enable failed with rc=%d\n", + __func__, rc); + rc = -EINVAL; } end: - kfree(param_val); return rc; } @@ -652,8 +638,11 @@ static int msm_ds2_dap_init_modules_in_topology(int dev_map_idx) { int rc = 0, i = 0, port_id, copp_idx; /* Account for 32 bit integer allocation */ - int32_t param_sz = (ADM_GET_TOPO_MODULE_LIST_LENGTH / sizeof(uint32_t)); + int32_t param_sz = + (ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH / sizeof(uint32_t)); int32_t *update_param_val = NULL; + struct module_instance_info mod_inst_info; + int mod_inst_info_sz = 0; if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) { pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx); @@ -661,10 +650,12 @@ static int msm_ds2_dap_init_modules_in_topology(int dev_map_idx) goto end; } + memset(&mod_inst_info, 0, sizeof(mod_inst_info)); port_id = dev_map[dev_map_idx].port_id; copp_idx = dev_map[dev_map_idx].copp_idx; pr_debug("%s: port_id 0x%x copp_idx %d\n", __func__, port_id, copp_idx); - update_param_val = kzalloc(ADM_GET_TOPO_MODULE_LIST_LENGTH, GFP_KERNEL); + update_param_val = + kzalloc(ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH, GFP_KERNEL); if (!update_param_val) { pr_err("%s, param memory alloc failed\n", __func__); rc = -ENOMEM; @@ -673,9 +664,10 @@ static int msm_ds2_dap_init_modules_in_topology(int dev_map_idx) if (!ds2_dap_params_states.dap_bypass) { /* get modules from dsp */ - rc = adm_get_pp_topo_module_list(port_id, copp_idx, - ADM_GET_TOPO_MODULE_LIST_LENGTH, - (char *)update_param_val); + rc = adm_get_pp_topo_module_list_v2( + port_id, copp_idx, + ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH, + update_param_val); if (rc < 0) { pr_err("%s:topo list port %d, err %d,copp_idx %d\n", __func__, port_id, copp_idx, rc); @@ -689,11 +681,15 @@ static int msm_ds2_dap_init_modules_in_topology(int dev_map_idx) rc = -EINVAL; goto end; } + + mod_inst_info_sz = sizeof(struct module_instance_info) / + sizeof(uint32_t); /* Turn off modules */ - for (i = 1; i < update_param_val[0]; i++) { + for (i = 1; i < update_param_val[0] * mod_inst_info_sz; + i += mod_inst_info_sz) { if (!msm_ds2_dap_can_enable_module( - update_param_val[i]) || - (update_param_val[i] == DS2_MODULE_ID)) { + update_param_val[i]) || + (update_param_val[i] == DS2_MODULE_ID)) { pr_debug("%s: Do not enable/disable %d\n", __func__, update_param_val[i]); continue; @@ -701,15 +697,21 @@ static int msm_ds2_dap_init_modules_in_topology(int dev_map_idx) pr_debug("%s: param disable %d\n", __func__, update_param_val[i]); - adm_param_enable(port_id, copp_idx, update_param_val[i], - MODULE_DISABLE); + memcpy(&mod_inst_info, &update_param_val[i], + sizeof(mod_inst_info)); + adm_param_enable_v2(port_id, copp_idx, + mod_inst_info, + MODULE_DISABLE); } } else { msm_ds2_dap_send_cal_data(dev_map_idx); } - adm_param_enable(port_id, copp_idx, DS2_MODULE_ID, - !ds2_dap_params_states.dap_bypass); + + mod_inst_info.module_id = DS2_MODULE_ID; + mod_inst_info.instance_id = INSTANCE_ID_0; + adm_param_enable_v2(port_id, copp_idx, mod_inst_info, + !ds2_dap_params_states.dap_bypass); end: kfree(update_param_val); return rc; @@ -885,17 +887,22 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) { int rc = 0, i = 0, j = 0; /*Account for 32 bit integer allocation */ - int32_t param_sz = (ADM_GET_TOPO_MODULE_LIST_LENGTH / sizeof(uint32_t)); + int32_t param_sz = + (ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH / sizeof(uint32_t)); int32_t *mod_list = NULL; int port_id = 0, copp_idx = -1; bool cs_onoff = ds2_dap_params_states.custom_stereo_onoff; int ramp_wait = DOLBY_SOFT_VOLUME_PERIOD; + struct module_instance_info mod_inst_info; + int mod_inst_info_sz = 0; pr_debug("%s: bypass type %d bypass %d custom stereo %d\n", __func__, ds2_dap_params_states.dap_bypass_type, ds2_dap_params_states.dap_bypass, ds2_dap_params_states.custom_stereo_onoff); - mod_list = kzalloc(ADM_GET_TOPO_MODULE_LIST_LENGTH, GFP_KERNEL); + memset(&mod_inst_info, 0, sizeof(mod_inst_info)); + mod_list = + kzalloc(ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH, GFP_KERNEL); if (!mod_list) { pr_err("%s: param memory alloc failed\n", __func__); rc = -ENOMEM; @@ -922,9 +929,10 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) } /* getmodules from dsp */ - rc = adm_get_pp_topo_module_list(port_id, copp_idx, - ADM_GET_TOPO_MODULE_LIST_LENGTH, - (char *)mod_list); + rc = adm_get_pp_topo_module_list_v2( + port_id, copp_idx, + ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH, + mod_list); if (rc < 0) { pr_err("%s:adm get topo list port %d", __func__, port_id); @@ -976,8 +984,11 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) /* if dap bypass is set */ if (ds2_dap_params_states.dap_bypass) { /* Turn off dap module */ - adm_param_enable(port_id, copp_idx, - DS2_MODULE_ID, MODULE_DISABLE); + mod_inst_info.module_id = DS2_MODULE_ID; + mod_inst_info.instance_id = INSTANCE_ID_0; + adm_param_enable_v2(port_id, copp_idx, + mod_inst_info, + MODULE_DISABLE); /* * If custom stereo is on at the time of bypass, * switch off custom stereo on dap and turn on @@ -1000,8 +1011,13 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) copp_idx, rc); } } + + mod_inst_info_sz = + sizeof(struct module_instance_info) / + sizeof(uint32_t); /* Turn on qti modules */ - for (j = 1; j < mod_list[0]; j++) { + for (j = 1; j < mod_list[0] * mod_inst_info_sz; + j += mod_inst_info_sz) { if (!msm_ds2_dap_can_enable_module( mod_list[j]) || mod_list[j] == @@ -1009,9 +1025,11 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) continue; pr_debug("%s: param enable %d\n", __func__, mod_list[j]); - adm_param_enable(port_id, copp_idx, - mod_list[j], - MODULE_ENABLE); + memcpy(&mod_inst_info, &mod_list[j], + sizeof(mod_inst_info)); + adm_param_enable_v2(port_id, copp_idx, + mod_inst_info, + MODULE_ENABLE); } /* Add adm api to resend calibration on port */ @@ -1026,7 +1044,8 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) } } else { /* Turn off qti modules */ - for (j = 1; j < mod_list[0]; j++) { + for (j = 1; j < mod_list[0] * mod_inst_info_sz; + j += mod_inst_info_sz) { if (!msm_ds2_dap_can_enable_module( mod_list[j]) || mod_list[j] == @@ -1034,15 +1053,20 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) continue; pr_debug("%s: param disable %d\n", __func__, mod_list[j]); - adm_param_enable(port_id, copp_idx, - mod_list[j], - MODULE_DISABLE); + memcpy(&mod_inst_info, &mod_list[j], + sizeof(mod_inst_info)); + adm_param_enable_v2(port_id, copp_idx, + mod_inst_info, + MODULE_DISABLE); } /* Enable DAP modules */ pr_debug("%s:DS2 param enable\n", __func__); - adm_param_enable(port_id, copp_idx, - DS2_MODULE_ID, MODULE_ENABLE); + mod_inst_info.module_id = DS2_MODULE_ID; + mod_inst_info.instance_id = INSTANCE_ID_0; + adm_param_enable_v2(port_id, copp_idx, + mod_inst_info, + MODULE_ENABLE); /* * If custom stereo is on at the time of dap on, * switch off custom stereo on qti channel mixer @@ -1101,19 +1125,19 @@ end: static int msm_ds2_dap_send_end_point(int dev_map_idx, int endp_idx) { - int rc = 0; - int32_t *update_params_value = NULL, *params_value = NULL; - uint32_t params_length = (DOLBY_PARAM_INT_ENDP_LENGTH + - DOLBY_PARAM_PAYLOAD_SIZE) * sizeof(uint32_t); + uint32_t offset = 0; + struct param_hdr_v3 param_hdr; int cache_device = 0; struct ds2_dap_params_s *ds2_ap_params_obj = NULL; int32_t *modified_param = NULL; + int rc = 0; if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) { pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx); rc = -EINVAL; goto end; } + memset(¶m_hdr, 0, sizeof(param_hdr)); cache_device = dev_map[dev_map_idx].cache_dev; ds2_ap_params_obj = &ds2_dap_params[cache_device]; @@ -1122,12 +1146,6 @@ static int msm_ds2_dap_send_end_point(int dev_map_idx, int endp_idx) pr_debug("%s: endp - %pK %pK\n", __func__, &ds2_dap_params[cache_device], ds2_ap_params_obj); - params_value = kzalloc(params_length, GFP_KERNEL); - if (!params_value) { - rc = -ENOMEM; - goto end; - } - if (dev_map[dev_map_idx].port_id == DOLBY_INVALID_PORT_ID) { pr_err("%s: invalid port\n", __func__); rc = -EINVAL; @@ -1141,21 +1159,20 @@ static int msm_ds2_dap_send_end_point(int dev_map_idx, int endp_idx) goto end; } - update_params_value = params_value; - *update_params_value++ = DOLBY_BUNDLE_MODULE_ID; - *update_params_value++ = DOLBY_PARAM_ID_INIT_ENDP; - *update_params_value++ = DOLBY_PARAM_INT_ENDP_LENGTH * sizeof(uint32_t); - *update_params_value++ = ds2_ap_params_obj->params_val[ - ds2_dap_params_offset[endp_idx]]; + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = DOLBY_PARAM_ID_INIT_ENDP; + param_hdr.param_size = sizeof(offset); + offset = ds2_ap_params_obj->params_val[ds2_dap_params_offset[endp_idx]]; pr_debug("%s: off %d, length %d\n", __func__, ds2_dap_params_offset[endp_idx], ds2_dap_params_length[endp_idx]); pr_debug("%s: param 0x%x, param val %d\n", __func__, ds2_dap_params_id[endp_idx], ds2_ap_params_obj-> params_val[ds2_dap_params_offset[endp_idx]]); - rc = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id, - dev_map[dev_map_idx].copp_idx, - (char *)params_value, params_length); + rc = adm_pack_and_set_one_pp_param(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, + param_hdr, (u8 *) &offset); if (rc) { pr_err("%s: send dolby params failed rc %d\n", __func__, rc); rc = -EINVAL; @@ -1172,19 +1189,17 @@ static int msm_ds2_dap_send_end_point(int dev_map_idx, int endp_idx) ds2_ap_params_obj->dap_params_modified[endp_idx] = 0x00010001; end: - kfree(params_value); return rc; } static int msm_ds2_dap_send_cached_params(int dev_map_idx, int commit) { - int32_t *update_params_value = NULL, *params_value = NULL; - uint32_t idx, i, j, ret = 0; - uint32_t params_length = (TOTAL_LENGTH_DOLBY_PARAM + - (MAX_DS2_PARAMS - 1) * - DOLBY_PARAM_PAYLOAD_SIZE) * - sizeof(uint32_t); + uint8_t *packed_params = NULL; + uint32_t packed_params_size = 0; + uint32_t param_size = 0; + struct param_hdr_v3 param_hdr; + uint32_t idx, i, ret = 0; int cache_device = 0; struct ds2_dap_params_s *ds2_ap_params_obj = NULL; int32_t *modified_param = NULL; @@ -1194,6 +1209,7 @@ static int msm_ds2_dap_send_cached_params(int dev_map_idx, ret = -EINVAL; goto end; } + memset(¶m_hdr, 0, sizeof(param_hdr)); cache_device = dev_map[dev_map_idx].cache_dev; /* Use off profile cache in only for soft bypass */ @@ -1207,12 +1223,16 @@ static int msm_ds2_dap_send_cached_params(int dev_map_idx, pr_debug("%s: cached param - %pK %pK, cache_device %d\n", __func__, &ds2_dap_params[cache_device], ds2_ap_params_obj, cache_device); - params_value = kzalloc(params_length, GFP_KERNEL); - if (!params_value) { - pr_err("%s: params memory alloc failed\n", __func__); - ret = -ENOMEM; - goto end; - } + + /* + * Allocate the max space needed. This is enough space to hold the + * header for each param plus the total size of all the params. + */ + packed_params_size = (sizeof(param_hdr) * (MAX_DS2_PARAMS - 1)) + + (TOTAL_LENGTH_DOLBY_PARAM * sizeof(uint32_t)); + packed_params = kzalloc(packed_params_size, GFP_KERNEL); + if (!packed_params) + return -ENOMEM; if (dev_map[dev_map_idx].port_id == DOLBY_INVALID_PORT_ID) { pr_err("%s: invalid port id\n", __func__); @@ -1227,8 +1247,7 @@ static int msm_ds2_dap_send_cached_params(int dev_map_idx, goto end; } - update_params_value = params_value; - params_length = 0; + packed_params_size = 0; for (i = 0; i < (MAX_DS2_PARAMS-1); i++) { /*get the pointer to the param modified array in the cache*/ modified_param = ds2_ap_params_obj->dap_params_modified; @@ -1241,28 +1260,33 @@ static int msm_ds2_dap_send_cached_params(int dev_map_idx, if (!msm_ds2_dap_check_is_param_modified(modified_param, i, commit)) continue; - *update_params_value++ = DOLBY_BUNDLE_MODULE_ID; - *update_params_value++ = ds2_dap_params_id[i]; - *update_params_value++ = ds2_dap_params_length[i] * - sizeof(uint32_t); + + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = ds2_dap_params_id[i]; + param_hdr.param_size = + ds2_dap_params_length[i] * sizeof(uint32_t); + idx = ds2_dap_params_offset[i]; - for (j = 0; j < ds2_dap_params_length[i]; j++) { - *update_params_value++ = - ds2_ap_params_obj->params_val[idx+j]; - pr_debug("%s: id 0x%x,val %d\n", __func__, - ds2_dap_params_id[i], - ds2_ap_params_obj->params_val[idx+j]); + ret = q6common_pack_pp_params( + packed_params + packed_params_size, ¶m_hdr, + (u8 *) &ds2_ap_params_obj->params_val[idx], + ¶m_size); + if (ret) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, ret); + goto end; } - params_length += (DOLBY_PARAM_PAYLOAD_SIZE + - ds2_dap_params_length[i]) * sizeof(uint32_t); + + packed_params_size += param_size; } - pr_debug("%s: valid param length: %d\n", __func__, params_length); - if (params_length) { - ret = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id, - dev_map[dev_map_idx].copp_idx, - (char *)params_value, - params_length); + pr_debug("%s: total packed param length: %d\n", __func__, + packed_params_size); + if (packed_params_size) { + ret = adm_set_pp_params(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, NULL, + packed_params, packed_params_size); if (ret) { pr_err("%s: send dolby params failed ret %d\n", __func__, ret); @@ -1285,7 +1309,7 @@ static int msm_ds2_dap_send_cached_params(int dev_map_idx, } } end: - kfree(params_value); + kfree(packed_params); return ret; } @@ -1523,11 +1547,12 @@ static int msm_ds2_dap_get_param(u32 cmd, void *arg) { int rc = 0, i, port_id = 0, copp_idx = -1; struct dolby_param_data *dolby_data = (struct dolby_param_data *)arg; - int32_t *update_params_value = NULL, *params_value = NULL; + int32_t *params_value = NULL; uint32_t params_length = DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM * sizeof(uint32_t); uint32_t param_payload_len = DOLBY_PARAM_PAYLOAD_SIZE * sizeof(uint32_t); + struct param_hdr_v3 param_hdr; /* Return error on get param in soft or hard bypass */ if (ds2_dap_params_states.dap_bypass == true) { @@ -1573,17 +1598,15 @@ static int msm_ds2_dap_get_param(u32 cmd, void *arg) params_value = kzalloc(params_length + param_payload_len, GFP_KERNEL); - if (!params_value) { - rc = -ENOMEM; - goto end; - } + if (!params_value) + return -ENOMEM; + memset(¶m_hdr, 0, sizeof(param_hdr)); if (dolby_data->param_id == DOLBY_PARAM_ID_VER) { - rc = adm_get_params(port_id, copp_idx, - DOLBY_BUNDLE_MODULE_ID, - DOLBY_PARAM_ID_VER, - params_length + param_payload_len, - (char *)params_value); + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = DOLBY_PARAM_ID_VER; + param_hdr.param_size = params_length + param_payload_len; } else { for (i = 0; i < MAX_DS2_PARAMS; i++) if (ds2_dap_params_id[i] == @@ -1596,25 +1619,25 @@ static int msm_ds2_dap_get_param(u32 cmd, void *arg) goto end; } else { params_length = - ds2_dap_params_length[i] * sizeof(uint32_t); + ds2_dap_params_length[i] * sizeof(uint32_t); - rc = adm_get_params(port_id, copp_idx, - DOLBY_BUNDLE_MODULE_ID, - ds2_dap_params_id[i], - params_length + - param_payload_len, - (char *)params_value); + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = ds2_dap_params_id[i]; + param_hdr.param_size = + params_length + param_payload_len; } } + rc = adm_get_pp_params(port_id, copp_idx, ADM_CLIENT_ID_DEFAULT, NULL, + ¶m_hdr, (u8 *) params_value); if (rc) { pr_err("%s: get parameters failed rc %d\n", __func__, rc); rc = -EINVAL; goto end; } - update_params_value = params_value; - if (copy_to_user((void *)dolby_data->data, - &update_params_value[DOLBY_PARAM_PAYLOAD_SIZE], - (dolby_data->length * sizeof(uint32_t)))) { + if (copy_to_user((void __user *) dolby_data->data, + ¶ms_value[DOLBY_PARAM_PAYLOAD_SIZE], + (dolby_data->length * sizeof(uint32_t)))) { pr_err("%s: error getting param\n", __func__); rc = -EFAULT; goto end; @@ -1633,6 +1656,7 @@ static int msm_ds2_dap_param_visualizer_control_get(u32 cmd, void *arg) uint32_t offset, length, params_length; uint32_t param_payload_len = DOLBY_PARAM_PAYLOAD_SIZE * sizeof(uint32_t); + struct param_hdr_v3 param_hdr; for (i = 0; i < DS2_DEVICES_ALL; i++) { if ((dev_map[i].active)) { @@ -1651,6 +1675,7 @@ static int msm_ds2_dap_param_visualizer_control_get(u32 cmd, void *arg) goto end; } + memset(¶m_hdr, 0, sizeof(param_hdr)); length = ds2_dap_params[cache_dev].params_val[DOLBY_PARAM_VCNB_OFFSET]; if (length > DOLBY_PARAM_VCNB_MAX_LENGTH || length <= 0) { @@ -1665,6 +1690,7 @@ static int msm_ds2_dap_param_visualizer_control_get(u32 cmd, void *arg) visualizer_data = kzalloc(params_length, GFP_KERNEL); if (!visualizer_data) { + pr_err("%s: params memory alloc failed\n", __func__); ret = -ENOMEM; dolby_data->length = 0; goto end; @@ -1682,11 +1708,13 @@ static int msm_ds2_dap_param_visualizer_control_get(u32 cmd, void *arg) offset = 0; params_length = length * sizeof(uint32_t); - ret = adm_get_params(port_id, copp_idx, - DOLBY_BUNDLE_MODULE_ID, - DOLBY_PARAM_ID_VCBG, - params_length + param_payload_len, - (((char *)(visualizer_data)) + offset)); + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = DOLBY_PARAM_ID_VCBG; + param_hdr.param_size = length * sizeof(uint32_t) + param_payload_len; + ret = adm_get_pp_params(port_id, copp_idx, ADM_CLIENT_ID_DEFAULT, NULL, + ¶m_hdr, + (((char *) (visualizer_data)) + offset)); if (ret) { pr_err("%s: get parameters failed ret %d\n", __func__, ret); ret = -EINVAL; @@ -1694,11 +1722,13 @@ static int msm_ds2_dap_param_visualizer_control_get(u32 cmd, void *arg) goto end; } offset = length * sizeof(uint32_t); - ret = adm_get_params(port_id, copp_idx, - DOLBY_BUNDLE_MODULE_ID, - DOLBY_PARAM_ID_VCBE, - params_length + param_payload_len, - (((char *)(visualizer_data)) + offset)); + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = DOLBY_PARAM_ID_VCBE; + param_hdr.param_size = length * sizeof(uint32_t) + param_payload_len; + ret = adm_get_pp_params(port_id, copp_idx, ADM_CLIENT_ID_DEFAULT, NULL, + ¶m_hdr, + (((char *) (visualizer_data)) + offset)); if (ret) { pr_err("%s: get parameters failed ret %d\n", __func__, ret); ret = -EINVAL; diff --git a/asoc/msm-ds2-dap-config.h b/asoc/msm-ds2-dap-config.h index c90bd8fb83a4..4d6b5eb3d210 100644 --- a/asoc/msm-ds2-dap-config.h +++ b/asoc/msm-ds2-dap-config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014, 2017-2018 The Linux Foundation. All rights reserved. * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. @@ -33,7 +33,6 @@ struct dolby_param_license32 { compat_uptr_t license_key; }; - #define SNDRV_DEVDEP_DAP_IOCTL_SET_PARAM32\ _IOWR('U', 0x10, struct dolby_param_data32) #define SNDRV_DEVDEP_DAP_IOCTL_GET_PARAM32\ @@ -63,6 +62,34 @@ enum { DAP_CMD_SET_BYPASS_TYPE = 5, }; +struct custom_stereo_param { + /* Index is 32-bit param in little endian */ + u16 index; + u16 reserved; + + /* For stereo mixing, the number of out channels */ + u16 num_out_ch; + /* For stereo mixing, the number of in channels */ + u16 num_in_ch; + + /* Out channel map FL/FR*/ + u16 out_fl; + u16 out_fr; + + /* In channel map FL/FR*/ + u16 in_fl; + u16 in_fr; + + /* + * Weighting coefficients. Mixing will be done according to + * these coefficients. + */ + u16 op_FL_ip_FL_weight; + u16 op_FL_ip_FR_weight; + u16 op_FR_ip_FL_weight; + u16 op_FR_ip_FR_weight; +}; + #define DOLBY_PARAM_INT_ENDP_LENGTH 1 #define DOLBY_PARAM_INT_ENDP_OFFSET (DOLBY_PARAM_PSTG_OFFSET + \ DOLBY_PARAM_PSTG_LENGTH) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 8ebab78ac1e4..f0b7121977fb 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -789,26 +789,6 @@ set_stereo_to_custom_stereo_return: } EXPORT_SYMBOL(adm_set_stereo_to_custom_stereo); -/** - * adm_dolby_dap_send_params - - * command to send dolby dap params - * - * @port_id: Port ID number - * @copp_idx: copp index of ADM copp - * @params: params pointer - * @param_length: length of params - * - * Returns 0 on success or error on failure - */ -int adm_dolby_dap_send_params(int port_id, int copp_idx, char *params, - uint32_t params_length) -{ - /* Use as wrapper for adm_set_pp_params until no longer used */ - return adm_set_pp_params(port_id, copp_idx, NULL, params, - params_length); -} -EXPORT_SYMBOL(adm_dolby_dap_send_params); - /* * With pre-packed data, only the opcode differes from V5 and V6. * Use q6common_pack_pp_params to pack the data correctly. @@ -941,29 +921,6 @@ done: } EXPORT_SYMBOL(adm_pack_and_set_one_pp_param); -int adm_get_params_v2(int port_id, int copp_idx, uint32_t module_id, - uint32_t param_id, uint32_t params_length, char *params, - uint32_t client_id) -{ - struct param_hdr_v3 param_hdr; - - memset(¶m_hdr, 0, sizeof(param_hdr)); - param_hdr.module_id = module_id; - param_hdr.instance_id = INSTANCE_ID_0; - param_hdr.param_id = param_id; - param_hdr.param_size = params_length; - - return adm_get_pp_params(port_id, copp_idx, client_id, NULL, ¶m_hdr, - params); -} - -int adm_get_params(int port_id, int copp_idx, uint32_t module_id, - uint32_t param_id, uint32_t params_length, char *params) -{ - return adm_get_params_v2(port_id, copp_idx, module_id, param_id, - params_length, params, 0); -} - /* * Only one parameter can be requested at a time. Therefore, packing and sending * the request can be handled locally. @@ -1082,14 +1039,6 @@ done: } EXPORT_SYMBOL(adm_get_pp_params); -int adm_get_pp_topo_module_list(int port_id, int copp_idx, int32_t param_length, - char *params) -{ - return adm_get_pp_topo_module_list_v2(port_id, copp_idx, param_length, - (int32_t *) params); -} -EXPORT_SYMBOL(adm_get_pp_topo_module_list); - int adm_get_pp_topo_module_list_v2(int port_id, int copp_idx, int32_t param_length, int32_t *returned_params) diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 0f7e7b240428..bc3fdcfabfc5 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -93,9 +93,6 @@ int adm_dts_eagle_get(int port_id, int copp_idx, int param_id, void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate); -int adm_get_params(int port_id, int copp_idx, uint32_t module_id, - uint32_t param_id, uint32_t params_length, char *params); - int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id, struct mem_mapping_hdr *mem_hdr, struct param_hdr_v3 *param_hdr, u8 *returned_param_data); @@ -103,9 +100,6 @@ int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id, int adm_send_params_v5(int port_id, int copp_idx, char *params, uint32_t params_length); -int adm_dolby_dap_send_params(int port_id, int copp_idx, char *params, - uint32_t params_length); - int adm_set_pp_params(int port_id, int copp_idx, struct mem_mapping_hdr *mem_hdr, u8 *param_data, u32 params_size); From f20d5b7ea55335d696a2958bb6a5b877f6aa48d2 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Mon, 29 Jan 2018 17:02:58 -0800 Subject: [PATCH 2/3] ASoC: dsp: Update ASM driver to support Instance ID Add support to set and get ASM module params with Instance ID support. Maintain support for non Instance ID set and get param structures as well. Use common pack and set param functions to set and get parameters to DSP instead of handling them at an individual module level. CRs-Fixed: 2151551 Change-Id: I633ce10a83d9033d42fadb7bad0b26842459df84 Signed-off-by: Vignesh Kulothungan --- dsp/q6asm.c | 796 ++++++++++++++----------------------- include/dsp/apr_audio-v2.h | 115 +----- include/dsp/q6asm-v2.h | 11 + 3 files changed, 330 insertions(+), 592 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 3bcf4f1cd05b..fe1b39acb8fd 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "adsp_err.h" #define TRUE 0x01 @@ -1898,6 +1899,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) if (data->opcode == APR_BASIC_RSP_RESULT) { switch (payload[0]) { case ASM_STREAM_CMD_SET_PP_PARAMS_V2: + case ASM_STREAM_CMD_SET_PP_PARAMS_V3: if (rtac_make_asm_callback(ac->session, payload, data->payload_size)) break; @@ -1945,9 +1947,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) pr_err("%s: cmd = 0x%x returned error = 0x%x\n", __func__, payload[0], payload[1]); if (wakeup_flag) { - if ((is_adsp_reg_event(payload[0]) >= 0) - || (payload[0] == - ASM_STREAM_CMD_SET_PP_PARAMS_V2)) + if ((is_adsp_reg_event(payload[0]) >= + 0) || + (payload[0] == + ASM_STREAM_CMD_SET_PP_PARAMS_V2) || + (payload[0] == + ASM_STREAM_CMD_SET_PP_PARAMS_V3)) atomic_set(&ac->cmd_state_pp, payload[1]); else @@ -1960,7 +1965,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) return 0; } if ((is_adsp_reg_event(payload[0]) >= 0) || - (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V2)) { + (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V2) || + (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V3)) { if (atomic_read(&ac->cmd_state_pp) && wakeup_flag) { atomic_set(&ac->cmd_state_pp, 0); @@ -2619,6 +2625,174 @@ static void q6asm_add_mmaphdr(struct audio_client *ac, struct apr_hdr *hdr, hdr->pkt_size = pkt_size; } +/** + * q6asm_set_pp_params + * command to set ASM parameter data + * send memory mapping header for out of band case + * send pre-packed parameter data for in band case + * + * @ac: audio client handle + * @mem_hdr: memory mapping header + * @param_data: pre-packed parameter payload + * @param_size: size of pre-packed parameter data + * + * Returns 0 on success or error on failure + */ +int q6asm_set_pp_params(struct audio_client *ac, + struct mem_mapping_hdr *mem_hdr, u8 *param_data, + u32 param_size) +{ + struct asm_stream_cmd_set_pp_params *asm_set_param = NULL; + int pkt_size = 0; + int ret = 0; + + if (ac == NULL) { + pr_err("%s: Audio Client is NULL\n", __func__); + return -EINVAL; + } else if (ac->apr == NULL) { + pr_err("%s: APR pointer is NULL\n", __func__); + return -EINVAL; + } + + pkt_size = sizeof(struct asm_stream_cmd_set_pp_params); + /* Add param size to packet size when sending in-band only */ + if (param_data != NULL) + pkt_size += param_size; + asm_set_param = kzalloc(pkt_size, GFP_KERNEL); + if (!asm_set_param) + return -ENOMEM; + + q6asm_add_hdr_async(ac, &asm_set_param->apr_hdr, pkt_size, TRUE); + + /* With pre-packed data, only the opcode differs from V2 and V3. */ + if (q6common_is_instance_id_supported()) + asm_set_param->apr_hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V3; + else + asm_set_param->apr_hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; + + asm_set_param->payload_size = param_size; + + if (mem_hdr != NULL) { + /* Out of band case */ + asm_set_param->mem_hdr = *mem_hdr; + } else if (param_data != NULL) { + /* + * In band case. Parameter data must be pre-packed with its + * header before calling this function. Use + * q6common_pack_pp_params to pack parameter data and header + * correctly. + */ + memcpy(&asm_set_param->param_data, param_data, param_size); + } else { + pr_err("%s: Received NULL pointers for both mem header and param data\n", + __func__); + ret = -EINVAL; + goto done; + } + + atomic_set(&ac->cmd_state_pp, -1); + ret = apr_send_pkt(ac->apr, (uint32_t *)asm_set_param); + if (ret < 0) { + pr_err("%s: apr send failed rc %d\n", __func__, ret); + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(ac->cmd_wait, + atomic_read(&ac->cmd_state_pp) >= 0, 5 * HZ); + if (!ret) { + pr_err("%s: timeout sending apr pkt\n", __func__); + ret = -ETIMEDOUT; + goto done; + } + + if (atomic_read(&ac->cmd_state_pp) > 0) { + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(atomic_read(&ac->cmd_state_pp))); + ret = adsp_err_get_lnx_err_code(atomic_read(&ac->cmd_state_pp)); + goto done; + } + ret = 0; +done: + kfree(asm_set_param); + return ret; +} +EXPORT_SYMBOL(q6asm_set_pp_params); + +/** + * q6asm_pack_and_set_pp_param_in_band + * command to pack and set parameter data for in band case + * + * @ac: audio client handle + * @param_hdr: parameter header + * @param_data: parameter data + * + * Returns 0 on success or error on failure + */ +int q6asm_pack_and_set_pp_param_in_band(struct audio_client *ac, + struct param_hdr_v3 param_hdr, + u8 *param_data) +{ + u8 *packed_data = NULL; + u32 packed_size = sizeof(union param_hdrs) + param_hdr.param_size; + int ret = 0; + + if (ac == NULL) { + pr_err("%s: Audio Client is NULL\n", __func__); + return -EINVAL; + } + + packed_data = kzalloc(packed_size, GFP_KERNEL); + if (packed_data == NULL) + return -ENOMEM; + + ret = q6common_pack_pp_params(packed_data, ¶m_hdr, param_data, + &packed_size); + if (ret) { + pr_err("%s: Failed to pack params, error %d\n", __func__, ret); + goto done; + } + + ret = q6asm_set_pp_params(ac, NULL, packed_data, packed_size); +done: + kfree(packed_data); + return ret; +} +EXPORT_SYMBOL(q6asm_pack_and_set_pp_param_in_band); + +/** + * q6asm_set_soft_volume_module_instance_ids + * command to set module and instance ids for soft volume + * + * @instance: soft volume instance + * @param_hdr: parameter header + * + * Returns 0 on success or error on failure + */ +int q6asm_set_soft_volume_module_instance_ids(int instance, + struct param_hdr_v3 *param_hdr) +{ + if (param_hdr == NULL) { + pr_err("%s: Param header is NULL\n", __func__); + return -EINVAL; + } + + switch (instance) { + case SOFT_VOLUME_INSTANCE_2: + param_hdr->module_id = ASM_MODULE_ID_VOL_CTRL2; + param_hdr->instance_id = INSTANCE_ID_0; + return 0; + case SOFT_VOLUME_INSTANCE_1: + param_hdr->module_id = ASM_MODULE_ID_VOL_CTRL; + param_hdr->instance_id = INSTANCE_ID_0; + return 0; + default: + pr_err("%s: Invalid instance %d\n", __func__, instance); + return -EINVAL; + } +} +EXPORT_SYMBOL(q6asm_set_soft_volume_module_instance_ids); + static int __q6asm_open_read(struct audio_client *ac, uint32_t format, uint16_t bits_per_sample, uint32_t pcm_format_block_ver, @@ -7336,67 +7510,28 @@ EXPORT_SYMBOL(q6asm_memory_unmap_regions); int q6asm_set_lrgain(struct audio_client *ac, int left_gain, int right_gain) { struct asm_volume_ctrl_multichannel_gain multi_ch_gain; - int sz = 0; + struct param_hdr_v3 param_info; int rc = 0; - if (ac == NULL) { - pr_err("%s: APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - + memset(¶m_info, 0, sizeof(param_info)); memset(&multi_ch_gain, 0, sizeof(multi_ch_gain)); - sz = sizeof(struct asm_volume_ctrl_multichannel_gain); - q6asm_add_hdr_async(ac, &multi_ch_gain.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - multi_ch_gain.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - multi_ch_gain.param.data_payload_addr_lsw = 0; - multi_ch_gain.param.data_payload_addr_msw = 0; - multi_ch_gain.param.mem_map_handle = 0; - multi_ch_gain.param.data_payload_size = sizeof(multi_ch_gain) - - sizeof(multi_ch_gain.hdr) - sizeof(multi_ch_gain.param); - multi_ch_gain.data.module_id = ASM_MODULE_ID_VOL_CTRL; - multi_ch_gain.data.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN; - multi_ch_gain.data.param_size = multi_ch_gain.param.data_payload_size - - sizeof(multi_ch_gain.data); - multi_ch_gain.data.reserved = 0; + + param_info.module_id = ASM_MODULE_ID_VOL_CTRL; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN; + param_info.param_size = sizeof(multi_ch_gain); + multi_ch_gain.gain_data[0].channeltype = PCM_CHANNEL_FL; multi_ch_gain.gain_data[0].gain = left_gain << 15; multi_ch_gain.gain_data[1].channeltype = PCM_CHANNEL_FR; multi_ch_gain.gain_data[1].gain = right_gain << 15; multi_ch_gain.num_channels = 2; - rc = apr_send_pkt(ac->apr, (uint32_t *) &multi_ch_gain); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, + (u8 *) &multi_ch_gain); + if (rc < 0) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, multi_ch_gain.data.param_id, rc); - rc = -EINVAL; - goto fail_cmd; - } + __func__, param_info.param_id, rc); - 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__, - multi_ch_gain.data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd; - } - 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)), - multi_ch_gain.data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd; - } - rc = 0; -fail_cmd: return rc; } @@ -7412,20 +7547,14 @@ int q6asm_set_multich_gain(struct audio_client *ac, uint32_t channels, uint32_t *gains, uint8_t *ch_map, bool use_default) { struct asm_volume_ctrl_multichannel_gain multich_gain; - int sz = 0; + struct param_hdr_v3 param_info; int rc = 0; int i; u8 default_chmap[VOLUME_CONTROL_MAX_CHANNELS]; if (ac == NULL) { - pr_err("%s: ac is NULL\n", __func__); - rc = -EINVAL; - goto done; - } - if (ac->apr == NULL) { - dev_err(ac->dev, "%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto done; + pr_err("%s: Audio client is NULL\n", __func__); + return -EINVAL; } if (gains == NULL) { dev_err(ac->dev, "%s: gain_list is NULL\n", __func__); @@ -7444,21 +7573,12 @@ int q6asm_set_multich_gain(struct audio_client *ac, uint32_t channels, goto done; } + memset(¶m_info, 0, sizeof(param_info)); memset(&multich_gain, 0, sizeof(multich_gain)); - sz = sizeof(struct asm_volume_ctrl_multichannel_gain); - q6asm_add_hdr_async(ac, &multich_gain.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - multich_gain.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - multich_gain.param.data_payload_addr_lsw = 0; - multich_gain.param.data_payload_addr_msw = 0; - multich_gain.param.mem_map_handle = 0; - multich_gain.param.data_payload_size = sizeof(multich_gain) - - sizeof(multich_gain.hdr) - sizeof(multich_gain.param); - multich_gain.data.module_id = ASM_MODULE_ID_VOL_CTRL; - multich_gain.data.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN; - multich_gain.data.param_size = multich_gain.param.data_payload_size - - sizeof(multich_gain.data); - multich_gain.data.reserved = 0; + param_info.module_id = ASM_MODULE_ID_VOL_CTRL; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN; + param_info.param_size = sizeof(multich_gain); if (use_default) { rc = q6asm_map_channels(default_chmap, channels, false); @@ -7477,29 +7597,11 @@ int q6asm_set_multich_gain(struct audio_client *ac, uint32_t channels, } multich_gain.num_channels = channels; - rc = apr_send_pkt(ac->apr, (uint32_t *) &multich_gain); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, + (u8 *) &multich_gain); + if (rc) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, multich_gain.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__, - multich_gain.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), - multich_gain.data.param_id); - rc = -EINVAL; - goto done; - } - rc = 0; + __func__, param_info.param_id, rc); done: return rc; } @@ -7517,62 +7619,21 @@ EXPORT_SYMBOL(q6asm_set_multich_gain); int q6asm_set_mute(struct audio_client *ac, int muteflag) { struct asm_volume_ctrl_mute_config mute; - int sz = 0; + struct param_hdr_v3 param_info; int rc = 0; - if (ac == NULL) { - pr_err("%s: APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - - sz = sizeof(struct asm_volume_ctrl_mute_config); - q6asm_add_hdr_async(ac, &mute.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - mute.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - mute.param.data_payload_addr_lsw = 0; - mute.param.data_payload_addr_msw = 0; - mute.param.mem_map_handle = 0; - mute.param.data_payload_size = sizeof(mute) - - sizeof(mute.hdr) - sizeof(mute.param); - mute.data.module_id = ASM_MODULE_ID_VOL_CTRL; - mute.data.param_id = ASM_PARAM_ID_VOL_CTRL_MUTE_CONFIG; - mute.data.param_size = mute.param.data_payload_size - sizeof(mute.data); - mute.data.reserved = 0; + memset(&mute, 0, sizeof(mute)); + memset(¶m_info, 0, sizeof(param_info)); + param_info.module_id = ASM_MODULE_ID_VOL_CTRL; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = ASM_PARAM_ID_VOL_CTRL_MUTE_CONFIG; + param_info.param_size = sizeof(mute); mute.mute_flag = muteflag; - rc = apr_send_pkt(ac->apr, (uint32_t *) &mute); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, (u8 *) &mute); + if (rc) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, mute.data.param_id, rc); - rc = -EINVAL; - goto fail_cmd; - } - - 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__, - mute.data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd; - } - 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)), - mute.data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd; - } - rc = 0; -fail_cmd: + __func__, param_info.param_id, rc); return rc; } EXPORT_SYMBOL(q6asm_set_mute); @@ -7580,74 +7641,28 @@ EXPORT_SYMBOL(q6asm_set_mute); static int __q6asm_set_volume(struct audio_client *ac, int volume, int instance) { struct asm_volume_ctrl_master_gain vol; - int sz = 0; - int rc = 0; - int module_id; + struct param_hdr_v3 param_info; + int rc = 0; - if (ac == NULL) { - pr_err("%s: APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; + memset(&vol, 0, sizeof(vol)); + memset(¶m_info, 0, sizeof(param_info)); + + rc = q6asm_set_soft_volume_module_instance_ids(instance, ¶m_info); + if (rc) { + pr_err("%s: Failed to pack soft volume module and instance IDs, error %d\n", + __func__, rc); + return rc; } - switch (instance) { - case SOFT_VOLUME_INSTANCE_2: - module_id = ASM_MODULE_ID_VOL_CTRL2; - break; - case SOFT_VOLUME_INSTANCE_1: - default: - module_id = ASM_MODULE_ID_VOL_CTRL; - break; - } - - sz = sizeof(struct asm_volume_ctrl_master_gain); - q6asm_add_hdr_async(ac, &vol.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - vol.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - vol.param.data_payload_addr_lsw = 0; - vol.param.data_payload_addr_msw = 0; - vol.param.mem_map_handle = 0; - vol.param.data_payload_size = sizeof(vol) - - sizeof(vol.hdr) - sizeof(vol.param); - vol.data.module_id = module_id; - vol.data.param_id = ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN; - vol.data.param_size = vol.param.data_payload_size - sizeof(vol.data); - vol.data.reserved = 0; + param_info.param_id = ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN; + param_info.param_size = sizeof(vol); vol.master_gain = volume; - rc = apr_send_pkt(ac->apr, (uint32_t *) &vol); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, (u8 *) &vol); + if (rc) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, vol.data.param_id, rc); - rc = -EINVAL; - goto fail_cmd; - } + __func__, param_info.param_id, rc); - 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__, - vol.data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd; - } - 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)), - vol.data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd; - } - - rc = 0; -fail_cmd: return rc; } @@ -7925,67 +7940,27 @@ int q6asm_set_softpause(struct audio_client *ac, struct asm_softpause_params *pause_param) { struct asm_soft_pause_params softpause; - int sz = 0; + struct param_hdr_v3 param_info; int rc = 0; - if (ac == NULL) { - pr_err("%s: APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } + memset(&softpause, 0, sizeof(softpause)); + memset(¶m_info, 0, sizeof(param_info)); + param_info.module_id = ASM_MODULE_ID_VOL_CTRL; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = ASM_PARAM_ID_SOFT_PAUSE_PARAMETERS; + param_info.param_size = sizeof(softpause); - sz = sizeof(struct asm_soft_pause_params); - q6asm_add_hdr_async(ac, &softpause.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - softpause.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - - softpause.param.data_payload_addr_lsw = 0; - softpause.param.data_payload_addr_msw = 0; - softpause.param.mem_map_handle = 0; - softpause.param.data_payload_size = sizeof(softpause) - - sizeof(softpause.hdr) - sizeof(softpause.param); - softpause.data.module_id = ASM_MODULE_ID_VOL_CTRL; - softpause.data.param_id = ASM_PARAM_ID_SOFT_PAUSE_PARAMETERS; - softpause.data.param_size = softpause.param.data_payload_size - - sizeof(softpause.data); - softpause.data.reserved = 0; softpause.enable_flag = pause_param->enable; softpause.period = pause_param->period; softpause.step = pause_param->step; softpause.ramping_curve = pause_param->rampingcurve; - rc = apr_send_pkt(ac->apr, (uint32_t *) &softpause); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, + (u8 *) &softpause); + if (rc) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, softpause.data.param_id, rc); - rc = -EINVAL; - goto fail_cmd; - } + __func__, param_info.param_id, rc); - 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__, - softpause.data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd; - } - 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)), - softpause.data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd; - } - rc = 0; -fail_cmd: return rc; } EXPORT_SYMBOL(q6asm_set_softpause); @@ -7995,76 +7970,32 @@ static int __q6asm_set_softvolume(struct audio_client *ac, int instance) { struct asm_soft_step_volume_params softvol; - int sz = 0; - int rc = 0; - int module_id; + struct param_hdr_v3 param_info; + int rc = 0; - if (ac == NULL) { - pr_err("%s: APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; + memset(&softvol, 0, sizeof(softvol)); + memset(¶m_info, 0, sizeof(param_info)); + + rc = q6asm_set_soft_volume_module_instance_ids(instance, ¶m_info); + if (rc) { + pr_err("%s: Failed to pack soft volume module and instance IDs, error %d\n", + __func__, rc); + return rc; } - switch (instance) { - case SOFT_VOLUME_INSTANCE_2: - module_id = ASM_MODULE_ID_VOL_CTRL2; - break; - case SOFT_VOLUME_INSTANCE_1: - default: - module_id = ASM_MODULE_ID_VOL_CTRL; - break; - } + param_info.param_id = ASM_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS; + param_info.param_size = sizeof(softvol); - sz = sizeof(struct asm_soft_step_volume_params); - q6asm_add_hdr_async(ac, &softvol.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - softvol.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - softvol.param.data_payload_addr_lsw = 0; - softvol.param.data_payload_addr_msw = 0; - softvol.param.mem_map_handle = 0; - softvol.param.data_payload_size = sizeof(softvol) - - sizeof(softvol.hdr) - sizeof(softvol.param); - softvol.data.module_id = module_id; - softvol.data.param_id = ASM_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS; - softvol.data.param_size = softvol.param.data_payload_size - - sizeof(softvol.data); - softvol.data.reserved = 0; softvol.period = softvol_param->period; softvol.step = softvol_param->step; softvol.ramping_curve = softvol_param->rampingcurve; - rc = apr_send_pkt(ac->apr, (uint32_t *) &softvol); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, + (u8 *) &softvol); + if (rc) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, softvol.data.param_id, rc); - rc = -EINVAL; - goto fail_cmd; - } + __func__, param_info.param_id, rc); - 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__, - softvol.data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd; - } - 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)), - softvol.data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd; - } - rc = 0; -fail_cmd: return rc; } @@ -8116,40 +8047,27 @@ int q6asm_equalizer(struct audio_client *ac, void *eq_p) { struct asm_eq_params eq; struct msm_audio_eq_stream_config *eq_params = NULL; + struct param_hdr_v3 param_info; int i = 0; - int sz = 0; int rc = 0; if (ac == NULL) { - pr_err("%s: APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; + pr_err("%s: Audio client is NULL\n", __func__); + return -EINVAL; } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - if (eq_p == NULL) { pr_err("%s: [%d]: Invalid Eq param\n", __func__, ac->session); rc = -EINVAL; goto fail_cmd; } - sz = sizeof(struct asm_eq_params); - eq_params = (struct msm_audio_eq_stream_config *) eq_p; - q6asm_add_hdr(ac, &eq.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - eq.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - eq.param.data_payload_addr_lsw = 0; - eq.param.data_payload_addr_msw = 0; - eq.param.mem_map_handle = 0; - eq.param.data_payload_size = sizeof(eq) - - sizeof(eq.hdr) - sizeof(eq.param); - eq.data.module_id = ASM_MODULE_ID_EQUALIZER; - eq.data.param_id = ASM_PARAM_ID_EQUALIZER_PARAMETERS; - eq.data.param_size = eq.param.data_payload_size - sizeof(eq.data); + memset(&eq, 0, sizeof(eq)); + memset(¶m_info, 0, sizeof(param_info)); + eq_params = (struct msm_audio_eq_stream_config *) eq_p; + param_info.module_id = ASM_MODULE_ID_EQUALIZER; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = ASM_PARAM_ID_EQUALIZER_PARAMETERS; + param_info.param_size = sizeof(eq); eq.enable_flag = eq_params->enable; eq.num_bands = eq_params->num_bands; @@ -8175,32 +8093,11 @@ int q6asm_equalizer(struct audio_client *ac, void *eq_p) pr_debug("%s: q_factor:%d bandnum:%d\n", __func__, eq_params->eq_bands[i].q_factor, i); } - rc = apr_send_pkt(ac->apr, (uint32_t *)&eq); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, (u8 *) &eq); + if (rc) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, eq.data.param_id, rc); - rc = -EINVAL; - goto fail_cmd; - } + __func__, param_info.param_id, rc); - 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__, - eq.data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd; - } - 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)), - eq.data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd; - } - rc = 0; fail_cmd: return rc; } @@ -8797,7 +8694,7 @@ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) mtmx_params.param_info.param_id = ASM_SESSION_MTMX_STRTR_PARAM_SESSION_TIME_V3; mtmx_params.param_info.param_max_size = - sizeof(struct asm_stream_param_data_v2) + + sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_strtr_param_session_time_v3_t); atomic_set(&ac->time_flag, 1); @@ -8894,72 +8791,18 @@ EXPORT_SYMBOL(q6asm_get_session_time_legacy); int q6asm_send_audio_effects_params(struct audio_client *ac, char *params, uint32_t params_length) { - char *asm_params = NULL; - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 payload_params; - int sz, rc; + int rc; pr_debug("%s:\n", __func__); - if (!ac) { - pr_err("%s: APR handle NULL\n", __func__); - return -EINVAL; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - return -EINVAL; - } - if (params == NULL) { - pr_err("%s: params NULL\n", __func__); - return -EINVAL; - } - sz = sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2) + - params_length; - asm_params = kzalloc(sz, GFP_KERNEL); - if (!asm_params) { - pr_err("%s, asm params memory alloc failed", __func__); - return -ENOMEM; - } - q6asm_add_hdr_async(ac, &hdr, (sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2) + - params_length), TRUE); - atomic_set(&ac->cmd_state_pp, -1); - hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - 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 = params_length; - memcpy(((u8 *)asm_params), &hdr, sizeof(struct apr_hdr)); - memcpy(((u8 *)asm_params + sizeof(struct apr_hdr)), &payload_params, - sizeof(struct asm_stream_cmd_set_pp_params_v2)); - memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2)), - params, params_length); - rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params); - if (rc < 0) { - pr_err("%s: audio effects set-params send failed\n", __func__); - rc = -EINVAL; - goto fail_send_param; - } - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 1*HZ); - if (!rc) { - pr_err("%s: timeout, audio effects set-params\n", __func__); - rc = -ETIMEDOUT; - goto fail_send_param; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%s] set-params\n", - __func__, adsp_err_get_err_str( - atomic_read(&ac->cmd_state_pp))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_send_param; - } - rc = 0; -fail_send_param: - kfree(asm_params); + /* + * Leave function as wrapper for use by effects. Params must be properly + * packed. Use q6common_pack_pp_param to pack params correctly. + */ + rc = q6asm_set_pp_params(ac, NULL, params, params_length); + if (rc) + pr_err("%s: audio effects set-params send failed\n", __func__); + return rc; } EXPORT_SYMBOL(q6asm_send_audio_effects_params); @@ -9006,7 +8849,7 @@ int q6asm_send_mtmx_strtr_window(struct audio_client *ac, matrix.param.data_payload_addr_msw = 0; matrix.param.mem_map_handle = 0; matrix.param.data_payload_size = - sizeof(struct asm_stream_param_data_v2) + + sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_strtr_param_window_v2_t); matrix.param.direction = 0; /* RX */ matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; @@ -9101,7 +8944,7 @@ int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac, matrix.param.data_payload_addr_msw = 0; matrix.param.mem_map_handle = 0; matrix.param.data_payload_size = - sizeof(struct asm_stream_param_data_v2) + + sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_strtr_param_render_mode_t); matrix.param.direction = 0; /* RX */ matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; @@ -9196,7 +9039,7 @@ int q6asm_send_mtmx_strtr_clk_rec_mode(struct audio_client *ac, matrix.param.data_payload_addr_msw = 0; matrix.param.mem_map_handle = 0; matrix.param.data_payload_size = - sizeof(struct asm_stream_param_data_v2) + + sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_strtr_param_clk_rec_t); matrix.param.direction = 0; /* RX */ matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; @@ -9281,7 +9124,7 @@ int q6asm_send_mtmx_strtr_enable_adjust_session_clock(struct audio_client *ac, matrix.param.data_payload_addr_msw = 0; matrix.param.mem_map_handle = 0; matrix.param.data_payload_size = - sizeof(struct asm_stream_param_data_v2) + + sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_param_adjust_session_time_ctl_t); matrix.param.direction = 0; /* RX */ matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; @@ -10010,20 +9853,14 @@ done: int q6asm_send_cal(struct audio_client *ac) { struct cal_block_data *cal_block = NULL; - struct apr_hdr hdr; - char *asm_params = NULL; - struct asm_stream_cmd_set_pp_params_v2 payload_params; - int sz, rc = -EINVAL; - + struct mem_mapping_hdr mem_hdr; + u32 payload_size = 0; + int rc = -EINVAL; pr_debug("%s:\n", __func__); if (!ac) { - pr_err("%s: APR handle NULL\n", __func__); - goto done; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - goto done; + pr_err("%s: Audio client is NULL\n", __func__); + return -EINVAL; } if (ac->io_mode & NT_MODE) { pr_debug("%s: called for NT MODE, exiting\n", __func__); @@ -10038,6 +9875,7 @@ int q6asm_send_cal(struct audio_client *ac) goto done; } + memset(&mem_hdr, 0, sizeof(mem_hdr)); mutex_lock(&cal_data[ASM_AUDSTRM_CAL]->lock); cal_block = cal_utils_get_only_cal_block(cal_data[ASM_AUDSTRM_CAL]); if (cal_block == NULL) { @@ -10060,62 +9898,26 @@ int q6asm_send_cal(struct audio_client *ac) goto unlock; } - sz = sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2); - asm_params = kzalloc(sz, GFP_KERNEL); - if (!asm_params) { - pr_err("%s, asm params memory alloc failed", __func__); - rc = -ENOMEM; - goto unlock; - } - - /* asm_stream_cmd_set_pp_params_v2 has no APR header in it */ - q6asm_add_hdr_async(ac, &hdr, (sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2)), TRUE); - - atomic_set(&ac->cmd_state_pp, -1); - hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - payload_params.data_payload_addr_lsw = - lower_32_bits(cal_block->cal_data.paddr); - payload_params.data_payload_addr_msw = - msm_audio_populate_upper_32_bits( - cal_block->cal_data.paddr); - payload_params.mem_map_handle = cal_block->map_data.q6map_handle; - payload_params.data_payload_size = cal_block->cal_data.size; - memcpy(((u8 *)asm_params), &hdr, sizeof(struct apr_hdr)); - memcpy(((u8 *)asm_params + sizeof(struct apr_hdr)), &payload_params, - sizeof(struct asm_stream_cmd_set_pp_params_v2)); + mem_hdr.data_payload_addr_lsw = + lower_32_bits(cal_block->cal_data.paddr); + mem_hdr.data_payload_addr_msw = + msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr); + mem_hdr.mem_map_handle = cal_block->map_data.q6map_handle; + payload_size = cal_block->cal_data.size; pr_debug("%s: phyaddr lsw = %x msw = %x, maphdl = %x calsize = %d\n", - __func__, payload_params.data_payload_addr_lsw, - payload_params.data_payload_addr_msw, - payload_params.mem_map_handle, - payload_params.data_payload_size); + __func__, mem_hdr.data_payload_addr_lsw, + mem_hdr.data_payload_addr_msw, mem_hdr.mem_map_handle, + payload_size); - rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params); - if (rc < 0) { + rc = q6asm_set_pp_params(ac, &mem_hdr, NULL, payload_size); + if (rc) { pr_err("%s: audio audstrm cal send failed\n", __func__); - rc = -EINVAL; - goto free; - } - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5 * HZ); - if (!rc) { - pr_err("%s: timeout, audio audstrm cal send\n", __func__); - rc = -ETIMEDOUT; - goto free; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%d] audio audstrm cal send\n", - __func__, atomic_read(&ac->cmd_state_pp)); - rc = -EINVAL; - goto free; + goto unlock; } rc = 0; -free: - kfree(asm_params); unlock: mutex_unlock(&cal_data[ASM_AUDSTRM_CAL]->lock); done: diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 8438c37bea70..ae096e62606e 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -730,15 +730,6 @@ struct adm_cmd_set_pp_params_v5 { */ } __packed; -struct audproc_mfc_output_media_fmt { - struct adm_cmd_set_pp_params_v5 params; - struct param_hdr_v1 data; - uint32_t sampling_rate; - uint16_t bits_per_sample; - uint16_t num_channels; - uint16_t channel_type[8]; -} __packed; - struct audproc_mfc_param_media_fmt { uint32_t sampling_rate; uint16_t bits_per_sample; @@ -6610,55 +6601,27 @@ struct asm_stream_cmd_open_transcode_loopback_t { #define ASM_STREAM_CMD_SET_PP_PARAMS_V2 0x00010DA1 #define ASM_STREAM_CMD_SET_PP_PARAMS_V3 0x0001320D -struct asm_stream_cmd_set_pp_params_v2 { - u32 data_payload_addr_lsw; -/* LSW of parameter data payload address. Supported values: any. */ - u32 data_payload_addr_msw; -/* MSW of Parameter data payload address. Supported values: any. - * - Must be set to zero for in-band data. - * - In the case of 32 bit Shared memory address, msw field must be - * - set to zero. - * - In the case of 36 bit shared memory address, bit 31 to bit 4 of - * msw - * - * - must be set to zero. - */ - u32 mem_map_handle; -/* Supported Values: Any. - * memory map handle returned by DSP through - * ASM_CMD_SHARED_MEM_MAP_REGIONS - * command. - * if mmhandle is NULL, the ParamData payloads are within the - * message payload (in-band). - * If mmhandle is non-NULL, the ParamData payloads begin at the - * address specified in the address msw and lsw (out-of-band). +/* + * Structure for the ASM Stream Set PP Params command. Parameter data must be + * pre-packed with the correct header for either V2 or V3 when sent in-band. + * Use q6core_pack_pp_params to pack the header and data correctly depending on + * Instance ID support. */ +struct asm_stream_cmd_set_pp_params { + /* APR Header */ + struct apr_hdr apr_hdr; - u32 data_payload_size; -/* Size in bytes of the variable payload accompanying the - * message, or in shared memory. This field is used for parsing the - * parameter payload. - */ -} __packed; + /* The memory mapping header to be used when sending out of band */ + struct mem_mapping_hdr mem_hdr; + /* The total size of the payload, including the parameter header */ + u32 payload_size; -struct asm_stream_param_data_v2 { - u32 module_id; - /* Unique module ID. */ - - u32 param_id; - /* Unique parameter ID. */ - - u16 param_size; -/* Data size of the param_id/module_id combination. This is - * a multiple of 4 bytes. - */ - - u16 reserved; -/* Reserved for future enhancements. This field must be set to - * zero. - */ - + /* The parameter data to be filled when sent inband. Parameter data + * must be pre-packed with parameter header and then copied here. Use + * q6core_pack_pp_params to pack the header and param data correctly. + */ + u32 param_data[0]; } __packed; #define ASM_STREAM_CMD_GET_PP_PARAMS_V2 0x00010DA2 @@ -8082,9 +8045,6 @@ struct audproc_topology_module_id_info_t { struct asm_volume_ctrl_master_gain { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint16_t master_gain; /* Linear gain in Q13 format. */ @@ -8094,10 +8054,6 @@ struct asm_volume_ctrl_master_gain { struct asm_volume_ctrl_lr_chan_gain { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; - uint16_t l_chan_gain; /*< Linear gain in Q13 format for the left channel. */ @@ -8117,9 +8073,6 @@ struct asm_volume_ctrl_lr_chan_gain { struct asm_volume_ctrl_mute_config { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint32_t mute_flag; /*< Specifies whether mute is disabled (0) or enabled (nonzero).*/ @@ -8147,9 +8100,6 @@ struct asm_volume_ctrl_mute_config { * parameters used by the Volume Control module. */ struct asm_soft_step_volume_params { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint32_t period; /*< Period in milliseconds. * Supported values: 0 to 15000 @@ -8179,9 +8129,6 @@ struct asm_soft_step_volume_params { struct asm_soft_pause_params { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint32_t enable_flag; /*< Specifies whether soft pause is disabled (0) or enabled * (nonzero). @@ -8271,10 +8218,7 @@ struct asm_volume_ctrl_channeltype_gain_pair { struct asm_volume_ctrl_multichannel_gain { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; - uint32_t num_channels; + uint32_t num_channels; /* * Number of channels for which gain values are provided. Any * channels present in the data for which gain is not provided are @@ -8299,9 +8243,6 @@ struct asm_volume_ctrl_multichannel_gain { struct asm_volume_ctrl_channelype_mute_pair { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint8_t channelype; /*< Channel type for which the mute setting is to be applied. * Supported values: @@ -8350,9 +8291,6 @@ struct asm_volume_ctrl_channelype_mute_pair { struct asm_volume_ctrl_multichannel_mute { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint32_t num_channels; /*< Number of channels for which mute configuration is * provided. Any channels present in the data for which mute @@ -8797,9 +8735,6 @@ struct asm_eq_per_band_params { } __packed; struct asm_eq_params { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint32_t enable_flag; /*< Specifies whether the equalizer module is disabled (0) or enabled * (nonzero). @@ -9463,16 +9398,6 @@ struct srs_trumedia_params { #define ASM_STREAM_POSTPROC_TOPO_ID_DTS_HPX 0x00010DED #define ASM_STREAM_POSTPROC_TOPO_ID_HPX_PLUS 0x10015000 #define ASM_STREAM_POSTPROC_TOPO_ID_HPX_MASTER 0x10015001 -struct asm_dts_eagle_param { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; -} __packed; - -struct asm_dts_eagle_param_get { - struct apr_hdr hdr; - struct asm_stream_cmd_get_pp_params_v2 param; -} __packed; /* Opcode to set BT address and license for aptx decoder */ #define APTX_DECODER_BT_ADDRESS 0x00013201 @@ -10759,7 +10684,7 @@ union asm_session_mtmx_strtr_param_config { struct asm_mtmx_strtr_params { struct apr_hdr hdr; struct asm_session_cmd_set_mtmx_strstr_params_v2 param; - struct asm_stream_param_data_v2 data; + struct param_hdr_v1 data; union asm_session_mtmx_strtr_param_config config; } __packed; @@ -10869,7 +10794,7 @@ struct asm_mtmx_strtr_get_params { struct asm_mtmx_strtr_get_params_cmdrsp { uint32_t err_code; - struct asm_stream_param_data_v2 param_info; + struct param_hdr_v1 param_info; union asm_session_mtmx_strtr_data_type param_data; } __packed; diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h index 27b360f376c5..693397a73bf3 100644 --- a/include/dsp/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -264,6 +264,17 @@ int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir int q6asm_audio_client_buf_free_contiguous(unsigned int dir, struct audio_client *ac); +int q6asm_set_pp_params(struct audio_client *ac, + struct mem_mapping_hdr *mem_hdr, u8 *param_data, + u32 param_size); + +int q6asm_pack_and_set_pp_param_in_band(struct audio_client *ac, + struct param_hdr_v3 param_hdr, + u8 *param_data); + +int q6asm_set_soft_volume_module_instance_ids(int instance, + struct param_hdr_v3 *param_hdr); + int q6asm_open_read(struct audio_client *ac, uint32_t format /*, uint16_t bits_per_sample*/); From fa497d2051f93195b1e02376b8ebbd9bae7dca7b Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Mon, 29 Jan 2018 17:21:19 -0800 Subject: [PATCH 3/3] ASoC: dsp: Update audio effects driver to support Instance ID Add support to set and get audio effects module params with Instance ID support. Maintain support for non Instance ID set and get param structures as well. Use common pack and set param functions to set and get parameters to DSP instead of handling them at an individual module level. CRs-Fixed: 2151551 Change-Id: I0fdba2560950c931a2ec6f152499fd4bb9f59086 Signed-off-by: Vignesh Kulothungan --- asoc/msm-audio-effects-q6-v2.c | 1278 ++++++++++++++-------------- dsp/q6asm.c | 29 - include/dsp/q6asm-v2.h | 3 - include/uapi/sound/audio_effects.h | 4 + 4 files changed, 625 insertions(+), 689 deletions(-) diff --git a/asoc/msm-audio-effects-q6-v2.c b/asoc/msm-audio-effects-q6-v2.c index 5bab856d2290..8b2ca3168bcf 100644 --- a/asoc/msm-audio-effects-q6-v2.c +++ b/asoc/msm-audio-effects-q6-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -16,6 +16,7 @@ #include #include #include +#include #define MAX_ENABLE_CMD_SIZE 32 @@ -67,44 +68,36 @@ int msm_audio_effects_enable_extn(struct audio_client *ac, struct msm_nt_eff_all_config *effects, bool flag) { - uint32_t updt_params[MAX_ENABLE_CMD_SIZE] = {0}; - uint32_t params_length; + u32 flag_param = flag ? 1 : 0; + struct param_hdr_v3 param_hdr; int rc = 0; pr_debug("%s\n", __func__); - if (!ac) { - pr_err("%s: cannot set audio effects\n", __func__); - return -EINVAL; - } - params_length = 0; - updt_params[0] = AUDPROC_MODULE_ID_VIRTUALIZER; - updt_params[1] = AUDPROC_PARAM_ID_ENABLE; - updt_params[2] = VIRTUALIZER_ENABLE_PARAM_SZ; - updt_params[3] = flag; - params_length += COMMAND_PAYLOAD_SZ + VIRTUALIZER_ENABLE_PARAM_SZ; + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AUDPROC_MODULE_ID_VIRTUALIZER; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_ENABLE; + param_hdr.param_size = VIRTUALIZER_ENABLE_PARAM_SZ; if (effects->virtualizer.enable_flag) - q6asm_send_audio_effects_params(ac, (char *)&updt_params[0], - params_length); - memset(updt_params, 0, MAX_ENABLE_CMD_SIZE); - params_length = 0; - updt_params[0] = AUDPROC_MODULE_ID_BASS_BOOST; - updt_params[1] = AUDPROC_PARAM_ID_ENABLE; - updt_params[2] = BASS_BOOST_ENABLE_PARAM_SZ; - updt_params[3] = flag; - params_length += COMMAND_PAYLOAD_SZ + BASS_BOOST_ENABLE_PARAM_SZ; + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_hdr, + (u8 *) &flag_param); + + param_hdr.module_id = AUDPROC_MODULE_ID_BASS_BOOST; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_ENABLE; + param_hdr.param_size = BASS_BOOST_ENABLE_PARAM_SZ; if (effects->bass_boost.enable_flag) - q6asm_send_audio_effects_params(ac, (char *)&updt_params[0], - params_length); - memset(updt_params, 0, MAX_ENABLE_CMD_SIZE); - params_length = 0; - updt_params[0] = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; - updt_params[1] = AUDPROC_PARAM_ID_ENABLE; - updt_params[2] = EQ_ENABLE_PARAM_SZ; - updt_params[3] = flag; - params_length += COMMAND_PAYLOAD_SZ + EQ_ENABLE_PARAM_SZ; + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_hdr, + (u8 *) &flag_param); + + param_hdr.module_id = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_ENABLE; + param_hdr.param_size = EQ_ENABLE_PARAM_SZ; if (effects->equalizer.enable_flag) - q6asm_send_audio_effects_params(ac, (char *)&updt_params[0], - params_length); + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_hdr, + (u8 *) &flag_param); + return rc; } @@ -124,24 +117,32 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, { long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; char *params = NULL; + u8 *updt_params; int rc = 0; int devices = GET_NEXT(values, param_max_offset, rc); int num_commands = GET_NEXT(values, param_max_offset, rc); - int *updt_params, i, prev_enable_flag; - uint32_t params_length = (MAX_INBAND_PARAM_SZ); + int i, prev_enable_flag; + uint32_t max_params_length = 0; + uint32_t params_length = 0; + struct param_hdr_v3 param_hdr; + u8 *param_data = NULL; + u32 packed_data_size = 0; pr_debug("%s\n", __func__); if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { pr_err("%s: cannot set audio effects\n", __func__); return -EINVAL; } - params = kzalloc(params_length, GFP_KERNEL); - if (!params) + params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL); + if (!params) { + pr_err("%s, params memory alloc failed\n", __func__); return -ENOMEM; - + } pr_debug("%s: device: %d\n", __func__, devices); - updt_params = (int *)params; - params_length = 0; + updt_params = (u8 *) params; + /* Set MID and IID once at top and only update param specific fields*/ + param_hdr.module_id = AUDPROC_MODULE_ID_VIRTUALIZER; + param_hdr.instance_id = INSTANCE_ID_0; for (i = 0; i < num_commands; i++) { uint32_t command_id = GET_NEXT(values, param_max_offset, rc); @@ -163,23 +164,19 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s:VIRT ENABLE prev:%d, new:%d\n", __func__, prev_enable_flag, virtualizer->enable_flag); - if (prev_enable_flag != virtualizer->enable_flag) { - params_length += COMMAND_PAYLOAD_SZ + - VIRTUALIZER_ENABLE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "VIRT ENABLE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_VIRTUALIZER; - *updt_params++ = + if (prev_enable_flag == virtualizer->enable_flag) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + VIRTUALIZER_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "VIRT ENABLE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_VIRTUALIZER_ENABLE; - *updt_params++ = - VIRTUALIZER_ENABLE_PARAM_SZ; - *updt_params++ = - virtualizer->enable_flag; - } + param_hdr.param_size = VIRTUALIZER_ENABLE_PARAM_SZ; + param_data = (u8 *) &virtualizer->enable_flag; break; case VIRTUALIZER_STRENGTH: if (length != 1 || index_offset != 0) { @@ -191,23 +188,19 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: VIRT STRENGTH val: %d\n", __func__, virtualizer->strength); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - VIRTUALIZER_STRENGTH_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "VIRT STRENGTH", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_VIRTUALIZER; - *updt_params++ = - AUDPROC_PARAM_ID_VIRTUALIZER_STRENGTH; - *updt_params++ = - VIRTUALIZER_STRENGTH_PARAM_SZ; - *updt_params++ = - virtualizer->strength; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + VIRTUALIZER_STRENGTH_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "VIRT STRENGTH", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_VIRTUALIZER_STRENGTH; + param_hdr.param_size = VIRTUALIZER_STRENGTH_PARAM_SZ; + param_data = (u8 *) &virtualizer->strength; break; case VIRTUALIZER_OUT_TYPE: if (length != 1 || index_offset != 0) { @@ -219,23 +212,19 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: VIRT OUT_TYPE val:%d\n", __func__, virtualizer->out_type); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - VIRTUALIZER_OUT_TYPE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "VIRT OUT_TYPE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_VIRTUALIZER; - *updt_params++ = - AUDPROC_PARAM_ID_VIRTUALIZER_OUT_TYPE; - *updt_params++ = - VIRTUALIZER_OUT_TYPE_PARAM_SZ; - *updt_params++ = - virtualizer->out_type; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + VIRTUALIZER_OUT_TYPE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "VIRT OUT_TYPE", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_VIRTUALIZER_OUT_TYPE; + param_hdr.param_size = VIRTUALIZER_OUT_TYPE_PARAM_SZ; + param_data = (u8 *) &virtualizer->out_type; break; case VIRTUALIZER_GAIN_ADJUST: if (length != 1 || index_offset != 0) { @@ -247,32 +236,40 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: VIRT GAIN_ADJUST val:%d\n", __func__, virtualizer->gain_adjust); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - VIRTUALIZER_GAIN_ADJUST_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "VIRT GAIN_ADJUST", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_VIRTUALIZER; - *updt_params++ = + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + VIRTUALIZER_GAIN_ADJUST_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "VIRT GAIN_ADJUST", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_VIRTUALIZER_GAIN_ADJUST; - *updt_params++ = - VIRTUALIZER_GAIN_ADJUST_PARAM_SZ; - *updt_params++ = - virtualizer->gain_adjust; - } + param_hdr.param_size = VIRTUALIZER_GAIN_ADJUST_PARAM_SZ; + param_data = (u8 *) &virtualizer->gain_adjust; break; default: pr_err("%s: Invalid command to set config\n", __func__); - break; + continue; } + if (rc) + goto invalid_config; + + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + param_data, &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; + } + + updt_params += packed_data_size; + params_length += packed_data_size; } if (params_length && (rc == 0)) - q6asm_send_audio_effects_params(ac, params, - params_length); + q6asm_set_pp_params(ac, NULL, params, params_length); else pr_debug("%s: did not send pp params\n", __func__); invalid_config: @@ -297,24 +294,33 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, { long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; char *params = NULL; + u8 *updt_params; int rc = 0; int devices = GET_NEXT(values, param_max_offset, rc); int num_commands = GET_NEXT(values, param_max_offset, rc); - int *updt_params, i, prev_enable_flag; - uint32_t params_length = (MAX_INBAND_PARAM_SZ); + int i, prev_enable_flag; + uint32_t max_params_length = 0; + uint32_t params_length = 0; + struct param_hdr_v3 param_hdr; + u8 *param_data = NULL; + u32 packed_data_size = 0; pr_debug("%s\n", __func__); if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { pr_err("%s: cannot set audio effects\n", __func__); return -EINVAL; } - params = kzalloc(params_length, GFP_KERNEL); - if (!params) + params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL); + if (!params) { + pr_err("%s, params memory alloc failed\n", __func__); return -ENOMEM; - + } pr_debug("%s: device: %d\n", __func__, devices); - updt_params = (int *)params; - params_length = 0; + updt_params = (u8 *) params; + /* Set MID and IID once at top and only update param specific fields*/ + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AUDPROC_MODULE_ID_REVERB; + param_hdr.instance_id = INSTANCE_ID_0; for (i = 0; i < num_commands; i++) { uint32_t command_id = GET_NEXT(values, param_max_offset, rc); @@ -336,23 +342,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s:REVERB_ENABLE prev:%d,new:%d\n", __func__, prev_enable_flag, reverb->enable_flag); - if (prev_enable_flag != reverb->enable_flag) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_ENABLE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_ENABLE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_ENABLE; - *updt_params++ = - REVERB_ENABLE_PARAM_SZ; - *updt_params++ = - reverb->enable_flag; - } + if (prev_enable_flag == reverb->enable_flag) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_ENABLE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_ENABLE; + param_hdr.param_size = REVERB_ENABLE_PARAM_SZ; + param_data = (u8 *) &reverb->enable_flag; break; case REVERB_MODE: if (length != 1 || index_offset != 0) { @@ -364,23 +365,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_MODE val:%d\n", __func__, reverb->mode); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_MODE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_MODE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_MODE; - *updt_params++ = - REVERB_MODE_PARAM_SZ; - *updt_params++ = - reverb->mode; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_MODE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_MODE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_MODE; + param_hdr.param_size = REVERB_MODE_PARAM_SZ; + param_data = (u8 *) &reverb->mode; break; case REVERB_PRESET: if (length != 1 || index_offset != 0) { @@ -392,23 +388,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_PRESET val:%d\n", __func__, reverb->preset); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_PRESET_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_PRESET", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_PRESET; - *updt_params++ = - REVERB_PRESET_PARAM_SZ; - *updt_params++ = - reverb->preset; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_PRESET_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_PRESET", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_PRESET; + param_hdr.param_size = REVERB_PRESET_PARAM_SZ; + param_data = (u8 *) &reverb->preset; break; case REVERB_WET_MIX: if (length != 1 || index_offset != 0) { @@ -420,23 +411,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_WET_MIX val:%d\n", __func__, reverb->wet_mix); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_WET_MIX_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_WET_MIX", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_WET_MIX; - *updt_params++ = - REVERB_WET_MIX_PARAM_SZ; - *updt_params++ = - reverb->wet_mix; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_WET_MIX_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_WET_MIX", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_WET_MIX; + param_hdr.param_size = REVERB_WET_MIX_PARAM_SZ; + param_data = (u8 *) &reverb->wet_mix; break; case REVERB_GAIN_ADJUST: if (length != 1 || index_offset != 0) { @@ -448,23 +434,19 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_GAIN_ADJUST val:%d\n", __func__, reverb->gain_adjust); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_GAIN_ADJUST_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_GAIN_ADJUST", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_GAIN_ADJUST; - *updt_params++ = - REVERB_GAIN_ADJUST_PARAM_SZ; - *updt_params++ = - reverb->gain_adjust; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_GAIN_ADJUST_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_GAIN_ADJUST", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_REVERB_GAIN_ADJUST; + param_hdr.param_size = REVERB_GAIN_ADJUST_PARAM_SZ; + param_data = (u8 *) &reverb->gain_adjust; break; case REVERB_ROOM_LEVEL: if (length != 1 || index_offset != 0) { @@ -476,23 +458,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_ROOM_LEVEL val:%d\n", __func__, reverb->room_level); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_ROOM_LEVEL_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_ROOM_LEVEL", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_ROOM_LEVEL; - *updt_params++ = - REVERB_ROOM_LEVEL_PARAM_SZ; - *updt_params++ = - reverb->room_level; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_ROOM_LEVEL_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_ROOM_LEVEL", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_ROOM_LEVEL; + param_hdr.param_size = REVERB_ROOM_LEVEL_PARAM_SZ; + param_data = (u8 *) &reverb->room_level; break; case REVERB_ROOM_HF_LEVEL: if (length != 1 || index_offset != 0) { @@ -504,23 +481,19 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_ROOM_HF_LEVEL val%d\n", __func__, reverb->room_hf_level); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_ROOM_HF_LEVEL_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_ROOM_HF_LEVEL", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_ROOM_HF_LEVEL; - *updt_params++ = - REVERB_ROOM_HF_LEVEL_PARAM_SZ; - *updt_params++ = - reverb->room_hf_level; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_ROOM_HF_LEVEL_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_ROOM_HF_LEVEL", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_REVERB_ROOM_HF_LEVEL; + param_hdr.param_size = REVERB_ROOM_HF_LEVEL_PARAM_SZ; + param_data = (u8 *) &reverb->room_hf_level; break; case REVERB_DECAY_TIME: if (length != 1 || index_offset != 0) { @@ -532,23 +505,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_DECAY_TIME val:%d\n", __func__, reverb->decay_time); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_DECAY_TIME_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_DECAY_TIME", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_DECAY_TIME; - *updt_params++ = - REVERB_DECAY_TIME_PARAM_SZ; - *updt_params++ = - reverb->decay_time; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_DECAY_TIME_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_DECAY_TIME", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DECAY_TIME; + param_hdr.param_size = REVERB_DECAY_TIME_PARAM_SZ; + param_data = (u8 *) &reverb->decay_time; break; case REVERB_DECAY_HF_RATIO: if (length != 1 || index_offset != 0) { @@ -560,23 +528,19 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_DECAY_HF_RATIO val%d\n", __func__, reverb->decay_hf_ratio); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_DECAY_HF_RATIO_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_DECAY_HF_RATIO", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_DECAY_HF_RATIO; - *updt_params++ = - REVERB_DECAY_HF_RATIO_PARAM_SZ; - *updt_params++ = - reverb->decay_hf_ratio; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_DECAY_HF_RATIO_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_DECAY_HF_RATIO", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_REVERB_DECAY_HF_RATIO; + param_hdr.param_size = REVERB_DECAY_HF_RATIO_PARAM_SZ; + param_data = (u8 *) &reverb->decay_hf_ratio; break; case REVERB_REFLECTIONS_LEVEL: if (length != 1 || index_offset != 0) { @@ -588,23 +552,20 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_REFLECTIONS_LEVEL val:%d\n", __func__, reverb->reflections_level); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_REFLECTIONS_LEVEL_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_REFLECTIONS_LEVEL", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_REFLECTIONS_LEVEL_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_REFLECTIONS_LEVEL", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_REFLECTIONS_LEVEL; - *updt_params++ = + param_hdr.param_size = REVERB_REFLECTIONS_LEVEL_PARAM_SZ; - *updt_params++ = - reverb->reflections_level; - } + param_data = (u8 *) &reverb->reflections_level; break; case REVERB_REFLECTIONS_DELAY: if (length != 1 || index_offset != 0) { @@ -616,23 +577,20 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_REFLECTIONS_DELAY val:%d\n", __func__, reverb->reflections_delay); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_REFLECTIONS_DELAY_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_REFLECTIONS_DELAY", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_REFLECTIONS_DELAY_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_REFLECTIONS_DELAY", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_REFLECTIONS_DELAY; - *updt_params++ = + param_hdr.param_size = REVERB_REFLECTIONS_DELAY_PARAM_SZ; - *updt_params++ = - reverb->reflections_delay; - } + param_data = (u8 *) &reverb->reflections_delay; break; case REVERB_LEVEL: if (length != 1 || index_offset != 0) { @@ -644,23 +602,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_LEVEL val:%d\n", __func__, reverb->level); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_LEVEL_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_LEVEL", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_LEVEL; - *updt_params++ = - REVERB_LEVEL_PARAM_SZ; - *updt_params++ = - reverb->level; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_LEVEL_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_LEVEL", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_LEVEL; + param_hdr.param_size = REVERB_LEVEL_PARAM_SZ; + param_data = (u8 *) &reverb->level; break; case REVERB_DELAY: if (length != 1 || index_offset != 0) { @@ -672,23 +625,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s:REVERB_DELAY val:%d\n", __func__, reverb->delay); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_DELAY_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_DELAY", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_DELAY; - *updt_params++ = - REVERB_DELAY_PARAM_SZ; - *updt_params++ = - reverb->delay; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_DELAY_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_DELAY", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DELAY; + param_hdr.param_size = REVERB_DELAY_PARAM_SZ; + param_data = (u8 *) &reverb->delay; break; case REVERB_DIFFUSION: if (length != 1 || index_offset != 0) { @@ -700,23 +648,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_DIFFUSION val:%d\n", __func__, reverb->diffusion); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_DIFFUSION_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_DIFFUSION", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_DIFFUSION; - *updt_params++ = - REVERB_DIFFUSION_PARAM_SZ; - *updt_params++ = - reverb->diffusion; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_DIFFUSION_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_DIFFUSION", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DIFFUSION; + param_hdr.param_size = REVERB_DIFFUSION_PARAM_SZ; + param_data = (u8 *) &reverb->diffusion; break; case REVERB_DENSITY: if (length != 1 || index_offset != 0) { @@ -728,32 +671,39 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_DENSITY val:%d\n", __func__, reverb->density); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_DENSITY_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_DENSITY", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_DENSITY; - *updt_params++ = - REVERB_DENSITY_PARAM_SZ; - *updt_params++ = - reverb->density; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_DENSITY_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_DENSITY", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DENSITY; + param_hdr.param_size = REVERB_DENSITY_PARAM_SZ; + param_data = (u8 *) &reverb->density; break; default: pr_err("%s: Invalid command to set config\n", __func__); - break; + continue; } + if (rc) + goto invalid_config; + + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + param_data, &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; + } + + updt_params += packed_data_size; + params_length += packed_data_size; } if (params_length && (rc == 0)) - q6asm_send_audio_effects_params(ac, params, - params_length); + q6asm_set_pp_params(ac, NULL, params, params_length); else pr_debug("%s: did not send pp params\n", __func__); invalid_config: @@ -778,24 +728,33 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, { long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; char *params = NULL; + u8 *updt_params; int rc = 0; int devices = GET_NEXT(values, param_max_offset, rc); int num_commands = GET_NEXT(values, param_max_offset, rc); - int *updt_params, i, prev_enable_flag; - uint32_t params_length = (MAX_INBAND_PARAM_SZ); + int i, prev_enable_flag; + uint32_t max_params_length = 0; + uint32_t params_length = 0; + struct param_hdr_v3 param_hdr; + u8 *param_data = NULL; + u32 packed_data_size = 0; pr_debug("%s\n", __func__); if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { pr_err("%s: cannot set audio effects\n", __func__); return -EINVAL; } - params = kzalloc(params_length, GFP_KERNEL); - if (!params) + params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL); + if (!params) { + pr_err("%s, params memory alloc failed\n", __func__); return -ENOMEM; - + } pr_debug("%s: device: %d\n", __func__, devices); - updt_params = (int *)params; - params_length = 0; + updt_params = (u8 *) params; + /* Set MID and IID once at top and only update param specific fields*/ + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AUDPROC_MODULE_ID_BASS_BOOST; + param_hdr.instance_id = INSTANCE_ID_0; for (i = 0; i < num_commands; i++) { uint32_t command_id = GET_NEXT(values, param_max_offset, rc); @@ -818,23 +777,18 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, pr_debug("%s: BASS_BOOST_ENABLE prev:%d new:%d\n", __func__, prev_enable_flag, bass_boost->enable_flag); - if (prev_enable_flag != bass_boost->enable_flag) { - params_length += COMMAND_PAYLOAD_SZ + - BASS_BOOST_ENABLE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "BASS_BOOST_ENABLE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_BASS_BOOST; - *updt_params++ = - AUDPROC_PARAM_ID_BASS_BOOST_ENABLE; - *updt_params++ = - BASS_BOOST_ENABLE_PARAM_SZ; - *updt_params++ = - bass_boost->enable_flag; - } + if (prev_enable_flag == bass_boost->enable_flag) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + BASS_BOOST_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "BASS_BOOST_ENABLE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_BASS_BOOST_ENABLE; + param_hdr.param_size = BASS_BOOST_ENABLE_PARAM_SZ; + param_data = (u8 *) &bass_boost->enable_flag; break; case BASS_BOOST_MODE: if (length != 1 || index_offset != 0) { @@ -846,23 +800,18 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: BASS_BOOST_MODE val:%d\n", __func__, bass_boost->mode); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - BASS_BOOST_MODE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "BASS_BOOST_MODE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_BASS_BOOST; - *updt_params++ = - AUDPROC_PARAM_ID_BASS_BOOST_MODE; - *updt_params++ = - BASS_BOOST_MODE_PARAM_SZ; - *updt_params++ = - bass_boost->mode; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + BASS_BOOST_MODE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "BASS_BOOST_MODE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_BASS_BOOST_MODE; + param_hdr.param_size = BASS_BOOST_MODE_PARAM_SZ; + param_data = (u8 *) &bass_boost->mode; break; case BASS_BOOST_STRENGTH: if (length != 1 || index_offset != 0) { @@ -874,32 +823,40 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: BASS_BOOST_STRENGTH val:%d\n", __func__, bass_boost->strength); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - BASS_BOOST_STRENGTH_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "BASS_BOOST_STRENGTH", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_BASS_BOOST; - *updt_params++ = - AUDPROC_PARAM_ID_BASS_BOOST_STRENGTH; - *updt_params++ = - BASS_BOOST_STRENGTH_PARAM_SZ; - *updt_params++ = - bass_boost->strength; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + BASS_BOOST_STRENGTH_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "BASS_BOOST_STRENGTH", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_BASS_BOOST_STRENGTH; + param_hdr.param_size = BASS_BOOST_STRENGTH_PARAM_SZ; + param_data = (u8 *) &bass_boost->strength; break; default: pr_err("%s: Invalid command to set config\n", __func__); - break; + continue; } + if (rc) + goto invalid_config; + + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + param_data, &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; + } + + updt_params += packed_data_size; + params_length += packed_data_size; } if (params_length && (rc == 0)) - q6asm_send_audio_effects_params(ac, params, - params_length); + q6asm_set_pp_params(ac, NULL, params, params_length); else pr_debug("%s: did not send pp params\n", __func__); invalid_config: @@ -924,24 +881,33 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac, { long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; char *params = NULL; + u8 *updt_params; int rc = 0; int devices = GET_NEXT(values, param_max_offset, rc); int num_commands = GET_NEXT(values, param_max_offset, rc); - int *updt_params, i, j, prev_enable_flag; - uint32_t params_length = (MAX_INBAND_PARAM_SZ); + int i, prev_enable_flag; + uint32_t max_params_length = 0; + uint32_t params_length = 0; + struct param_hdr_v3 param_hdr; + u8 *param_data = NULL; + u32 packed_data_size = 0; pr_debug("%s\n", __func__); if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { pr_err("%s: cannot set audio effects\n", __func__); return -EINVAL; } - params = kzalloc(params_length, GFP_KERNEL); - if (!params) + params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL); + if (!params) { + pr_err("%s, params memory alloc failed\n", __func__); return -ENOMEM; - + } pr_debug("%s: device: %d\n", __func__, devices); - updt_params = (int *)params; - params_length = 0; + updt_params = (u8 *) params; + /* Set MID and IID once at top and only update param specific fields*/ + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AUDPROC_MODULE_ID_PBE; + param_hdr.instance_id = INSTANCE_ID_0; for (i = 0; i < num_commands; i++) { uint32_t command_id = GET_NEXT(values, param_max_offset, rc); @@ -962,23 +928,18 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac, prev_enable_flag = pbe->enable_flag; pbe->enable_flag = GET_NEXT(values, param_max_offset, rc); - if (prev_enable_flag != pbe->enable_flag) { - params_length += COMMAND_PAYLOAD_SZ + - PBE_ENABLE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "PBE_ENABLE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_PBE; - *updt_params++ = - AUDPROC_PARAM_ID_PBE_ENABLE; - *updt_params++ = - PBE_ENABLE_PARAM_SZ; - *updt_params++ = - pbe->enable_flag; - } + if (prev_enable_flag == pbe->enable_flag) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + PBE_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "PBE_ENABLE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_PBE_ENABLE; + param_hdr.param_size = PBE_ENABLE_PARAM_SZ; + param_data = (u8 *) &pbe->enable_flag; break; case PBE_CONFIG: pr_debug("%s: PBE_PARAM length %u\n", __func__, length); @@ -989,37 +950,38 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac, rc = -EINVAL; goto invalid_config; } - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + length; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "PBE_PARAM", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_PBE; - *updt_params++ = - AUDPROC_PARAM_ID_PBE_PARAM_CONFIG; - *updt_params++ = - length; - for (j = 0; j < length; ) { - j += sizeof(*updt_params); - *updt_params++ = - GET_NEXT( - values, - param_max_offset, - rc); - } - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = + params_length + COMMAND_IID_PAYLOAD_SZ + length; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "PBE_PARAM", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_PBE_PARAM_CONFIG; + param_hdr.param_size = length; + param_data = (u8 *) values; break; default: pr_err("%s: Invalid command to set config\n", __func__); - break; + continue; } + if (rc) + goto invalid_config; + + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + param_data, &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; + } + + updt_params += packed_data_size; + params_length += packed_data_size; } if (params_length && (rc == 0)) - q6asm_send_audio_effects_params(ac, params, - params_length); + q6asm_set_pp_params(ac, NULL, params, params_length); invalid_config: kfree(params); return rc; @@ -1042,24 +1004,36 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, { long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; char *params = NULL; + u8 *updt_params = NULL; int rc = 0; int devices = GET_NEXT(values, param_max_offset, rc); int num_commands = GET_NEXT(values, param_max_offset, rc); - int *updt_params, i, prev_enable_flag; - uint32_t params_length = (MAX_INBAND_PARAM_SZ); + int i, prev_enable_flag; + uint32_t max_params_length = 0; + uint32_t params_length = 0; + struct param_hdr_v3 param_hdr; + u8 *param_data = NULL; + u32 packed_data_size = 0; + u8 *eq_config_data = NULL; + u32 *updt_config_data = NULL; + int config_param_length; pr_debug("%s\n", __func__); if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { pr_err("%s: cannot set audio effects\n", __func__); return -EINVAL; } - params = kzalloc(params_length, GFP_KERNEL); - if (!params) + params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL); + if (!params) { + pr_err("%s, params memory alloc failed\n", __func__); return -ENOMEM; - + } pr_debug("%s: device: %d\n", __func__, devices); - updt_params = (int *)params; - params_length = 0; + updt_params = (u8 *) params; + /* Set MID and IID once at top and only update param specific fields*/ + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; + param_hdr.instance_id = INSTANCE_ID_0; for (i = 0; i < num_commands; i++) { uint32_t command_id = GET_NEXT(values, param_max_offset, rc); @@ -1084,23 +1058,18 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: EQ_ENABLE prev:%d new:%d\n", __func__, prev_enable_flag, eq->enable_flag); - if (prev_enable_flag != eq->enable_flag) { - params_length += COMMAND_PAYLOAD_SZ + - EQ_ENABLE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "EQ_ENABLE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_POPLESS_EQUALIZER; - *updt_params++ = - AUDPROC_PARAM_ID_EQ_ENABLE; - *updt_params++ = - EQ_ENABLE_PARAM_SZ; - *updt_params++ = - eq->enable_flag; - } + if (prev_enable_flag == eq->enable_flag) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + EQ_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "EQ_ENABLE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_EQ_ENABLE; + param_hdr.param_size = EQ_ENABLE_PARAM_SZ; + param_data = (u8 *) &eq->enable_flag; break; case EQ_CONFIG: if (length < EQ_CONFIG_PARAM_LEN || index_offset != 0) { @@ -1149,43 +1118,50 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, eq->per_band_cfg[idx].quality_factor = GET_NEXT(values, param_max_offset, rc); } - if (command_config_state == CONFIG_SET) { - int config_param_length = EQ_CONFIG_PARAM_SZ + - (EQ_CONFIG_PER_BAND_PARAM_SZ* - eq->config.num_bands); - params_length += COMMAND_PAYLOAD_SZ + - config_param_length; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "EQ_CONFIG", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_POPLESS_EQUALIZER; - *updt_params++ = - AUDPROC_PARAM_ID_EQ_CONFIG; - *updt_params++ = - config_param_length; - *updt_params++ = - eq->config.eq_pregain; - *updt_params++ = - eq->config.preset_id; - *updt_params++ = - eq->config.num_bands; - for (idx = 0; idx < MAX_EQ_BANDS; idx++) { - if (eq->per_band_cfg[idx].band_idx < 0) - continue; - *updt_params++ = + if (command_config_state != CONFIG_SET) + break; + config_param_length = EQ_CONFIG_PARAM_SZ + + (EQ_CONFIG_PER_BAND_PARAM_SZ * + eq->config.num_bands); + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + config_param_length; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "EQ_CONFIG", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_EQ_CONFIG; + param_hdr.param_size = config_param_length; + + if (!eq_config_data) + eq_config_data = kzalloc(config_param_length, + GFP_KERNEL); + else + memset(eq_config_data, 0, config_param_length); + if (!eq_config_data) { + pr_err("%s, EQ_CONFIG:memory alloc failed\n", + __func__); + rc = -ENOMEM; + goto invalid_config; + } + param_data = eq_config_data; + updt_config_data = (u32 *) eq_config_data; + *updt_config_data++ = eq->config.eq_pregain; + *updt_config_data++ = eq->config.preset_id; + *updt_config_data++ = eq->config.num_bands; + for (idx = 0; idx < MAX_EQ_BANDS; idx++) { + if (eq->per_band_cfg[idx].band_idx < 0) + continue; + *updt_config_data++ = eq->per_band_cfg[idx].filter_type; - *updt_params++ = + *updt_config_data++ = eq->per_band_cfg[idx].freq_millihertz; - *updt_params++ = + *updt_config_data++ = eq->per_band_cfg[idx].gain_millibels; - *updt_params++ = + *updt_config_data++ = eq->per_band_cfg[idx].quality_factor; - *updt_params++ = + *updt_config_data++ = eq->per_band_cfg[idx].band_idx; - } } break; case EQ_BAND_INDEX: @@ -1203,23 +1179,18 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, eq->band_index = idx; pr_debug("%s: EQ_BAND_INDEX val:%d\n", __func__, eq->band_index); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - EQ_BAND_INDEX_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "EQ_BAND_INDEX", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_POPLESS_EQUALIZER; - *updt_params++ = - AUDPROC_PARAM_ID_EQ_BAND_INDEX; - *updt_params++ = - EQ_BAND_INDEX_PARAM_SZ; - *updt_params++ = - eq->band_index; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + EQ_BAND_INDEX_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "EQ_BAND_INDEX", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_EQ_BAND_INDEX; + param_hdr.param_size = EQ_BAND_INDEX_PARAM_SZ; + param_data = (u8 *) &eq->band_index; break; case EQ_SINGLE_BAND_FREQ: if (length != 1 || index_offset != 0) { @@ -1235,36 +1206,45 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: EQ_SINGLE_BAND_FREQ idx:%d, val:%d\n", __func__, eq->band_index, eq->freq_millihertz); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - EQ_SINGLE_BAND_FREQ_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "EQ_SINGLE_BAND_FREQ", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_POPLESS_EQUALIZER; - *updt_params++ = - AUDPROC_PARAM_ID_EQ_SINGLE_BAND_FREQ; - *updt_params++ = - EQ_SINGLE_BAND_FREQ_PARAM_SZ; - *updt_params++ = - eq->freq_millihertz; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + EQ_SINGLE_BAND_FREQ_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "EQ_SINGLE_BAND_FREQ", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_EQ_SINGLE_BAND_FREQ; + param_hdr.param_size = EQ_SINGLE_BAND_FREQ_PARAM_SZ; + param_data = (u8 *) &eq->freq_millihertz; break; default: pr_err("%s: Invalid command to set config\n", __func__); - break; + continue; } + if (rc) + goto invalid_config; + + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + param_data, &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; + } + + updt_params += packed_data_size; + params_length += packed_data_size; } if (params_length && (rc == 0)) - q6asm_send_audio_effects_params(ac, params, - params_length); + q6asm_set_pp_params(ac, NULL, params, params_length); else pr_debug("%s: did not send pp params\n", __func__); invalid_config: kfree(params); + kfree(eq_config_data); return rc; } EXPORT_SYMBOL(msm_audio_effects_popless_eq_handler); @@ -1277,8 +1257,13 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac, int devices; int num_commands; char *params = NULL; - int *updt_params, i; - uint32_t params_length = (MAX_INBAND_PARAM_SZ); + u8 *updt_params; + int i; + uint32_t vol_gain_2ch = 0; + uint32_t max_params_length = 0; + uint32_t params_length = 0; + struct param_hdr_v3 param_hdr; + u32 packed_data_size = 0; long *param_max_offset; int rc = 0; @@ -1295,12 +1280,15 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac, pr_err("%s: cannot set audio effects\n", __func__); return -EINVAL; } - params = kzalloc(params_length, GFP_KERNEL); - if (!params) + params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL); + if (!params) { + pr_err("%s, params memory alloc failed\n", __func__); return -ENOMEM; - - updt_params = (int *)params; - params_length = 0; + } + updt_params = (u8 *) params; + /* Set MID and IID once at top and only update param specific fields*/ + memset(¶m_hdr, 0, sizeof(param_hdr)); + q6asm_set_soft_volume_module_instance_ids(instance, ¶m_hdr); for (i = 0; i < num_commands; i++) { uint32_t command_id = GET_NEXT(values, param_max_offset, rc); @@ -1322,43 +1310,15 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac, vol->right_gain = GET_NEXT(values, param_max_offset, rc); vol->master_gain = 0x2000; - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - SOFT_VOLUME_GAIN_2CH_PARAM_SZ; - params_length += COMMAND_PAYLOAD_SZ + - SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "VOLUME/VOLUME2_GAIN_2CH", - rc); - if (rc != 0) - goto invalid_config; - if (instance == SOFT_VOLUME_INSTANCE_2) - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL2; - else - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL; - *updt_params++ = - ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN; - *updt_params++ = - SOFT_VOLUME_GAIN_2CH_PARAM_SZ; - *updt_params++ = - (vol->left_gain << 16) | - vol->right_gain; - if (instance == SOFT_VOLUME_INSTANCE_2) - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL2; - else - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL; - *updt_params++ = - ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN; - *updt_params++ = - SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; - *updt_params++ = - vol->master_gain; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + SOFT_VOLUME_GAIN_2CH_PARAM_SZ + + COMMAND_IID_PAYLOAD_SZ + + SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "VOLUME/VOLUME2_GAIN_2CH", rc); break; case SOFT_VOLUME_GAIN_MASTER: case SOFT_VOLUME2_GAIN_MASTER: @@ -1371,53 +1331,57 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac, vol->right_gain = 0x2000; vol->master_gain = GET_NEXT(values, param_max_offset, rc); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - SOFT_VOLUME_GAIN_2CH_PARAM_SZ; - params_length += COMMAND_PAYLOAD_SZ + - SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "VOLUME/VOLUME2_GAIN_MASTER", - rc); - if (rc != 0) - goto invalid_config; - if (instance == SOFT_VOLUME_INSTANCE_2) - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL2; - else - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL; - *updt_params++ = - ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN; - *updt_params++ = - SOFT_VOLUME_GAIN_2CH_PARAM_SZ; - *updt_params++ = - (vol->left_gain << 16) | - vol->right_gain; - if (instance == SOFT_VOLUME_INSTANCE_2) - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL2; - else - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL; - *updt_params++ = - ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN; - *updt_params++ = - SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; - *updt_params++ = - vol->master_gain; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + SOFT_VOLUME_GAIN_2CH_PARAM_SZ + + COMMAND_IID_PAYLOAD_SZ + + SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "VOLUME/VOLUME2_GAIN_MASTER", rc); break; default: pr_err("%s: Invalid command id: %d to set config\n", __func__, command_id); - break; + continue; } + if (rc) + continue; + + /* Set Volume Control for Left/Right */ + param_hdr.param_id = ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN; + param_hdr.param_size = SOFT_VOLUME_GAIN_2CH_PARAM_SZ; + vol_gain_2ch = (vol->left_gain << 16) | vol->right_gain; + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + (u8 *) &vol_gain_2ch, + &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; + } + + updt_params += packed_data_size; + params_length += packed_data_size; + + /* Set Master Volume Control */ + param_hdr.param_id = ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN; + param_hdr.param_size = SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + (u8 *) &vol->master_gain, + &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; + } + + updt_params += packed_data_size; + params_length += packed_data_size; } if (params_length && (rc == 0)) - q6asm_send_audio_effects_params(ac, params, - params_length); + q6asm_set_pp_params(ac, NULL, params, params_length); invalid_config: kfree(params); return rc; diff --git a/dsp/q6asm.c b/dsp/q6asm.c index fe1b39acb8fd..208c7e267827 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -8778,35 +8778,6 @@ fail_cmd: } EXPORT_SYMBOL(q6asm_get_session_time_legacy); -/** - * q6asm_send_audio_effects_params - - * command to send audio effects params - * - * @ac: Audio client handle - * @params: audio effects params - * @params_length: size of params - * - * Returns 0 on success or error on failure - */ -int q6asm_send_audio_effects_params(struct audio_client *ac, char *params, - uint32_t params_length) -{ - int rc; - - pr_debug("%s:\n", __func__); - - /* - * Leave function as wrapper for use by effects. Params must be properly - * packed. Use q6common_pack_pp_param to pack params correctly. - */ - rc = q6asm_set_pp_params(ac, NULL, params, params_length); - if (rc) - pr_err("%s: audio effects set-params send failed\n", __func__); - - return rc; -} -EXPORT_SYMBOL(q6asm_send_audio_effects_params); - /** * q6asm_send_mtmx_strtr_window - * command to send matrix for window params diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h index 693397a73bf3..c92cacf6c892 100644 --- a/include/dsp/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -635,9 +635,6 @@ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp); int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp); -int q6asm_send_audio_effects_params(struct audio_client *ac, char *params, - uint32_t params_length); - int q6asm_send_stream_cmd(struct audio_client *ac, struct msm_adsp_event_data *data); diff --git a/include/uapi/sound/audio_effects.h b/include/uapi/sound/audio_effects.h index 7964c34f890d..f38b2121a56e 100644 --- a/include/uapi/sound/audio_effects.h +++ b/include/uapi/sound/audio_effects.h @@ -145,8 +145,12 @@ #define PBE_ENABLE_PARAM_LEN 1 #define PBE_CONFIG_PARAM_LEN 28 +/* Command Payload length and size for Non-IID commands */ #define COMMAND_PAYLOAD_LEN 3 #define COMMAND_PAYLOAD_SZ (COMMAND_PAYLOAD_LEN * sizeof(uint32_t)) +/* Command Payload length and size for IID commands */ +#define COMMAND_IID_PAYLOAD_LEN 4 +#define COMMAND_IID_PAYLOAD_SZ (COMMAND_IID_PAYLOAD_LEN * sizeof(uint32_t)) #define MAX_INBAND_PARAM_SZ 4096 #define Q27_UNITY (1 << 27) #define Q8_UNITY (1 << 8)