summaryrefslogtreecommitdiff
path: root/sound/soc/msm
diff options
context:
space:
mode:
authorStephen Oglesby <soglesby@codeaurora.org>2016-03-07 16:08:19 -0800
committerJeevan Shriram <jshriram@codeaurora.org>2016-04-22 15:02:18 -0700
commit634f85a4ab74cc78b5cc52e5ecf48b1d50e739eb (patch)
tree108b7678f9e441123d72e02c3652fc7bfd78ccb8 /sound/soc/msm
parentde210aad0f8eb08c05b8088210f3955aad03389e (diff)
ASoC: msm: qdsp6v2: Limit codec register config packet size
APR packet size is now capped at 512 bytes. The codec register config data is 740 bytes. We now break up this data into multiple packets no larger than the defined maximum. CRs-fixed: 974874 Change-Id: I2bd3cb01ff389ffd1d319239019e11d35d8c16b6 Signed-off-by: Stephen Oglesby <soglesby@codeaurora.org>
Diffstat (limited to 'sound/soc/msm')
-rw-r--r--sound/soc/msm/qdsp6v2/q6afe.c101
1 files changed, 62 insertions, 39 deletions
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index 5c9dceaca130..7a1e61e29381 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -26,6 +26,7 @@
#include "msm-pcm-routing-v2.h"
#include <sound/audio_cal_utils.h>
#include <sound/adsp_err.h>
+#include <linux/qdsp6v2/apr_tal.h>
#define WAKELOCK_TIMEOUT 5000
enum {
@@ -1503,53 +1504,75 @@ static int afe_send_codec_reg_page_config(
static int afe_send_codec_reg_config(
struct afe_param_cdc_reg_cfg_data *cdc_reg_cfg)
{
- int i, ret;
- int pkt_size, payload_size;
+ int i, j, ret;
+ int pkt_size, payload_size, reg_per_pkt, num_pkts, num_regs;
struct afe_svc_cmd_cdc_reg_cfg *config;
struct afe_svc_cmd_set_param *param;
- payload_size = sizeof(struct afe_param_cdc_reg_cfg_payload) *
- cdc_reg_cfg->num_registers;
- pkt_size = sizeof(*config) + payload_size;
-
- pr_debug("%s: pkt_size %d, payload_size %d\n", __func__, pkt_size,
- payload_size);
- config = kzalloc(pkt_size, GFP_KERNEL);
- if (!config) {
- pr_warn("%s: Not enought memory, pkt_size %d\n", __func__,
- pkt_size);
- return -ENOMEM;
+ reg_per_pkt = (APR_MAX_BUF - sizeof(*config)) /
+ sizeof(struct afe_param_cdc_reg_cfg_payload);
+ if (reg_per_pkt > 0) {
+ num_pkts = (cdc_reg_cfg->num_registers / reg_per_pkt) +
+ (cdc_reg_cfg->num_registers % reg_per_pkt == 0 ? 0 : 1);
+ } else {
+ pr_err("%s: Failed to build codec reg config APR packet\n",
+ __func__);
+ return -EINVAL;
}
- config->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE),
- APR_PKT_VER);
- config->hdr.pkt_size = pkt_size;
- config->hdr.src_port = 0;
- config->hdr.dest_port = 0;
- config->hdr.token = IDX_GLOBAL_CFG;
- config->hdr.opcode = AFE_SVC_CMD_SET_PARAM;
-
- param = &config->param;
- param->payload_size = payload_size;
- param->payload_address_lsw = 0x00;
- param->payload_address_msw = 0x00;
- param->mem_map_handle = 0x00;
+ for (j = 0; j < num_pkts; ++j) {
+ /*
+ * num_regs is set to reg_per_pkt on each pass through the loop
+ * except the last, when it is set to the number of registers
+ * remaining from the total
+ */
+ num_regs = (j < (num_pkts - 1) ? reg_per_pkt :
+ cdc_reg_cfg->num_registers - (reg_per_pkt * j));
+ payload_size = sizeof(struct afe_param_cdc_reg_cfg_payload) *
+ num_regs;
+ pkt_size = sizeof(*config) + payload_size;
+ pr_debug("%s: pkt_size %d, payload_size %d\n", __func__,
+ pkt_size, payload_size);
+ config = kzalloc(pkt_size, GFP_KERNEL);
+ if (!config)
+ return -ENOMEM;
+
+ config->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ config->hdr.pkt_size = pkt_size;
+ config->hdr.src_port = 0;
+ config->hdr.dest_port = 0;
+ config->hdr.token = IDX_GLOBAL_CFG;
+ config->hdr.opcode = AFE_SVC_CMD_SET_PARAM;
+
+ param = &config->param;
+ param->payload_size = payload_size;
+ param->payload_address_lsw = 0x00;
+ param->payload_address_msw = 0x00;
+ param->mem_map_handle = 0x00;
+
+ for (i = 0; i < num_regs; i++) {
+ config->reg_data[i].common.module_id =
+ AFE_MODULE_CDC_DEV_CFG;
+ config->reg_data[i].common.param_id =
+ AFE_PARAM_ID_CDC_REG_CFG;
+ config->reg_data[i].common.param_size =
+ sizeof(config->reg_data[i].reg_cfg);
+ config->reg_data[i].reg_cfg =
+ cdc_reg_cfg->reg_data[i + (j * reg_per_pkt)];
+ }
- for (i = 0; i < cdc_reg_cfg->num_registers; i++) {
- config->reg_data[i].common.module_id = AFE_MODULE_CDC_DEV_CFG;
- config->reg_data[i].common.param_id = AFE_PARAM_ID_CDC_REG_CFG;
- config->reg_data[i].common.param_size =
- sizeof(config->reg_data[i].reg_cfg);
- config->reg_data[i].reg_cfg = cdc_reg_cfg->reg_data[i];
+ ret = afe_apr_send_pkt(config, &this_afe.wait[IDX_GLOBAL_CFG]);
+ if (ret) {
+ pr_err("%s: AFE_PARAM_ID_CDC_REG_CFG failed %d\n",
+ __func__, ret);
+ kfree(config);
+ break;
+ }
+ kfree(config);
}
- ret = afe_apr_send_pkt(config, &this_afe.wait[IDX_GLOBAL_CFG]);
- if (ret)
- pr_err("%s: AFE_PARAM_ID_CDC_REG_CFG failed %d\n", __func__,
- ret);
-
- kfree(config);
return ret;
}