summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAditya Bavanari <abavanar@codeaurora.org>2017-06-23 14:51:55 -0700
committerAditya Bavanari <abavanar@codeaurora.org>2017-12-21 11:11:41 +0530
commit36ed1afb5699eb862a5614ccb2ec4641f5dc5153 (patch)
tree980d789a6d8215c4c0d46b8ac12689aa3f1518a0
parent43f8fb60539f772092a0bd8be508c5af46031eec (diff)
ASoC: msm: qdsp6v2: Update rtac driver to support Instance ID
Add support to set and get rtac 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: Ic07cb109b9e469dccf510f89ba9917e8c9eccbd8 Signed-off-by: Siena Richard <sienar@codeaurora.org> Signed-off-by: Aditya Bavanari <abavanar@codeaurora.org>
-rw-r--r--include/sound/apr_audio-v2.h106
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c20
-rw-r--r--sound/soc/msm/qdsp6v2/q6voice.c10
-rw-r--r--sound/soc/msm/qdsp6v2/rtac.c508
4 files changed, 394 insertions, 250 deletions
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index a33fb8f27b8e..608f58e8cca3 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -501,6 +501,7 @@ struct adm_cmd_device_open_v6 {
/* Sets one or more parameters to a COPP.
*/
#define ADM_CMD_SET_PP_PARAMS_V5 0x00010328
+#define ADM_CMD_SET_PP_PARAMS_V6 0x0001035D
/* Payload of the #ADM_CMD_SET_PP_PARAMS_V5 command.
* If the data_payload_addr_lsw and data_payload_addr_msw element
@@ -723,6 +724,7 @@ struct adm_cmd_rsp_device_open_v5 {
/* This command allows a query of one COPP parameter.
*/
#define ADM_CMD_GET_PP_PARAMS_V5 0x0001032A
+#define ADM_CMD_GET_PP_PARAMS_V6 0x0001035E
/* Payload an #ADM_CMD_GET_PP_PARAMS_V5 command.
*/
@@ -1600,49 +1602,80 @@ struct afe_sidetone_iir_filter_config_params {
#define AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH 0x00010206
/* Used by RTAC */
-struct afe_rtac_set_param_v2 {
+struct afe_rtac_user_data_set_v2 {
+ /* Port interface and direction (Rx or Tx) to start. */
u16 port_id;
-/* Port interface and direction (Rx or Tx) to start.
- */
+ /* Actual size of the payload in bytes.
+ * This is used for parsing the parameter payload.
+ * Supported values: > 0
+ */
u16 payload_size;
-/* Actual size of the payload in bytes.
- * This is used for parsing the parameter payload.
- * Supported values: > 0
- */
-u32 payload_address_lsw;
-/* LSW of 64 bit Payload address.
- * Address should be 32-byte,
- * 4kbyte aligned and must be contiguous memory.
- */
+ /* The header detailing the memory mapping for out of band. */
+ struct mem_mapping_hdr mem_hdr;
-u32 payload_address_msw;
-/* MSW of 64 bit Payload address.
- * In case of 32-bit shared memory address,
- * this field must be set to zero.
- * In case of 36-bit shared memory address,
- * bit-4 to bit-31 must be set to zero.
- * Address should be 32-byte, 4kbyte aligned
- * and must be contiguous memory.
- */
+ /* The parameter header for the parameter data to set */
+ struct param_hdr_v1 param_hdr;
-u32 mem_map_handle;
-/* Memory map handle returned by
- * AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS commands.
- * Supported Values:
- * - NULL -- Message. The parameter data is in-band.
- * - Non-NULL -- The parameter data is Out-band.Pointer to
- * the physical address
- * in shared memory of the payload data.
- * An optional field is available if parameter
- * data is in-band:
- * afe_param_data_v2 param_data[...].
- * For detailed payload content, see the
- * afe_port_param_data_v2 structure.
- */
+ /* The parameter data to be filled when sent inband */
+ u32 *param_data;
+} __packed;
+
+struct afe_rtac_user_data_set_v3 {
+ /* Port interface and direction (Rx or Tx) to start. */
+ u16 port_id;
+ /* Reserved for future enhancements. Must be 0. */
+ u16 reserved;
+
+ /* The header detailing the memory mapping for out of band. */
+ struct mem_mapping_hdr mem_hdr;
+
+ /* The size of the parameter header and parameter data */
+ u32 payload_size;
+
+ /* The parameter header for the parameter data to set */
+ struct param_hdr_v3 param_hdr;
+
+ /* The parameter data to be filled when sent inband */
+ u32 *param_data;
+} __packed;
+
+struct afe_rtac_user_data_get_v2 {
+ /* Port interface and direction (Rx or Tx) to start. */
+ u16 port_id;
+
+ /* Actual size of the payload in bytes.
+ * This is used for parsing the parameter payload.
+ * Supported values: > 0
+ */
+ u16 payload_size;
+
+ /* The header detailing the memory mapping for out of band. */
+ struct mem_mapping_hdr mem_hdr;
+
+ /* The module ID of the parameter to get */
+ u32 module_id;
+
+ /* The parameter ID of the parameter to get */
+ u32 param_id;
+
+ /* The parameter data to be filled when sent inband */
+ struct param_hdr_v1 param_hdr;
} __packed;
+struct afe_rtac_user_data_get_v3 {
+ /* Port interface and direction (Rx or Tx) to start. */
+ u16 port_id;
+ /* Reserved for future enhancements. Must be 0. */
+ u16 reserved;
+
+ /* The header detailing the memory mapping for out of band. */
+ struct mem_mapping_hdr mem_hdr;
+
+ /* The parameter data to be filled when sent inband */
+ struct param_hdr_v3 param_hdr;
+} __packed;
#define AFE_PORT_CMD_SET_PARAM_V2 0x000100EF
struct afe_port_cmd_set_param_v2 {
/* APR Header */
@@ -6503,6 +6536,7 @@ struct asm_stream_cmd_open_transcode_loopback_t {
#define ASM_STREAM_CMD_FLUSH_READBUFS 0x00010C09
#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;
@@ -6556,6 +6590,7 @@ struct asm_stream_param_data_v2 {
} __packed;
#define ASM_STREAM_CMD_GET_PP_PARAMS_V2 0x00010DA2
+#define ASM_STREAM_CMD_GET_PP_PARAMS_V3 0x0001320E
struct asm_stream_cmd_get_pp_params_v2 {
u32 data_payload_addr_lsw;
@@ -6734,6 +6769,7 @@ struct asm_aac_dual_mono_mapping_param {
} __packed;
#define ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 0x00010DA4
+#define ASM_STREAM_CMDRSP_GET_PP_PARAMS_V3 0x0001320F
struct asm_stream_cmdrsp_get_pp_params_v2 {
u32 status;
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index c3d86e6cced2..0538696f8c7f 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -1898,10 +1898,10 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
break;
}
case ASM_STREAM_CMD_GET_PP_PARAMS_V2:
- pr_debug("%s: ASM_STREAM_CMD_GET_PP_PARAMS_V2 session %d opcode 0x%x token 0x%x src %d dest %d\n",
- __func__, ac->session,
- data->opcode, data->token,
- data->src_port, data->dest_port);
+ case ASM_STREAM_CMD_GET_PP_PARAMS_V3:
+ pr_debug("%s: ASM_STREAM_CMD_GET_PP_PARAMS session %d opcode 0x%x token 0x%x src %d dest %d\n",
+ __func__, ac->session, data->opcode,
+ data->token, data->src_port, data->dest_port);
/* Should only come here if there is an APR */
/* error or malformed APR packet. Otherwise */
/* response will be returned as */
@@ -1971,13 +1971,13 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
break;
}
case ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2:
- pr_debug("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 session %d opcode 0x%x token 0x%x src %d dest %d\n",
- __func__, ac->session, data->opcode,
- data->token,
- data->src_port, data->dest_port);
+ case ASM_STREAM_CMDRSP_GET_PP_PARAMS_V3:
+ pr_debug("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS session %d opcode 0x%x token 0x%x src %d dest %d\n",
+ __func__, ac->session, data->opcode, data->token,
+ data->src_port, data->dest_port);
if (payload[0] != 0) {
- pr_err("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 returned error = 0x%x\n",
- __func__, payload[0]);
+ pr_err("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS returned error = 0x%x\n",
+ __func__, payload[0]);
} else if (generic_get_data) {
generic_get_data->valid = 1;
if (generic_get_data->is_inband) {
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 0ee5de66e453..a0f30a32f8e6 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -6728,6 +6728,7 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
data->payload_size);
break;
case VSS_ICOMMON_CMD_GET_PARAM_V2:
+ case VSS_ICOMMON_CMD_GET_PARAM_V3:
pr_debug("%s: VSS_ICOMMON_CMD_GET_PARAM_V2\n",
__func__);
/* Should only come here if there is an APR */
@@ -6860,7 +6861,8 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
pr_debug("Recd VSS_ISTREAM_EVT_NOT_READY\n");
} else if (data->opcode == VSS_ISTREAM_EVT_READY) {
pr_debug("Recd VSS_ISTREAM_EVT_READY\n");
- } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM) {
+ } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM ||
+ VSS_ICOMMON_RSP_GET_PARAM_V3) {
pr_debug("%s: VSS_ICOMMON_RSP_GET_PARAM\n", __func__);
ptr = data->payload;
if (ptr[0] != 0) {
@@ -7020,12 +7022,13 @@ static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv)
data->payload_size);
break;
default:
- pr_debug("%s: invalid token for command VSS_ICOMMON_CMD_SET_PARAM_V2: %d\n",
+ pr_debug("%s: invalid token for command VSS_ICOMMON_CMD_SET_PARAM: %d\n",
__func__, data->token);
break;
}
break;
case VSS_ICOMMON_CMD_GET_PARAM_V2:
+ case VSS_ICOMMON_CMD_GET_PARAM_V3:
pr_debug("%s: VSS_ICOMMON_CMD_GET_PARAM_V2\n",
__func__);
/* Should only come here if there is an APR */
@@ -7092,7 +7095,8 @@ static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv)
break;
}
}
- } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM) {
+ } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM ||
+ VSS_ICOMMON_RSP_GET_PARAM_V3) {
pr_debug("%s: VSS_ICOMMON_RSP_GET_PARAM\n", __func__);
ptr = data->payload;
if (ptr[0] != 0) {
diff --git a/sound/soc/msm/qdsp6v2/rtac.c b/sound/soc/msm/qdsp6v2/rtac.c
index 8e0faf40360e..5e33fb508455 100644
--- a/sound/soc/msm/qdsp6v2/rtac.c
+++ b/sound/soc/msm/qdsp6v2/rtac.c
@@ -27,6 +27,7 @@
#include <sound/q6afe-v2.h>
#include <sound/q6adm-v2.h>
#include <sound/apr_audio-v2.h>
+#include <sound/q6common.h>
#include "q6voice.h"
#include "msm-pcm-routing-v2.h"
#include <sound/adsp_err.h>
@@ -104,14 +105,10 @@ struct rtac_afe_user_data {
uint32_t cmd_size;
uint32_t port_id;
union {
- struct rtac_afe_set {
- struct afe_rtac_set_param_v2 cmd;
- struct param_hdr_v1 data;
- } rtac_afe_set;
- struct rtac_afe_get {
- struct afe_rtac_get_param_v2 cmd;
- struct param_hdr_v1 data;
- } rtac_afe_get;
+ struct afe_rtac_user_data_set_v2 v2_set;
+ struct afe_rtac_user_data_set_v3 v3_set;
+ struct afe_rtac_user_data_get_v2 v2_get;
+ struct afe_rtac_user_data_get_v3 v3_get;
};
} __packed;
@@ -800,7 +797,9 @@ int send_adm_apr(void *buf, u32 opcode)
goto err;
}
- if (opcode == ADM_CMD_SET_PP_PARAMS_V5) {
+ switch (opcode) {
+ case ADM_CMD_SET_PP_PARAMS_V5:
+ case ADM_CMD_SET_PP_PARAMS_V6:
/* set payload size to in-band payload */
/* set data size to actual out of band payload size */
data_size = payload_size - 4 * sizeof(u32);
@@ -818,12 +817,15 @@ int send_adm_apr(void *buf, u32 opcode)
buf + 7 * sizeof(u32), data_size)) {
pr_err("%s: Could not copy payload from user buffer\n",
__func__);
- result = -EINVAL;
+ result = -EFAULT;
goto err;
}
+
/* set payload size in packet */
rtac_adm_buffer[8] = data_size;
- } else {
+ break;
+ case ADM_CMD_GET_PP_PARAMS_V5:
+ case ADM_CMD_GET_PP_PARAMS_V6:
if (payload_size > MAX_PAYLOAD_SIZE) {
pr_err("%s: Invalid payload size = %d\n",
__func__, payload_size);
@@ -837,9 +839,14 @@ int send_adm_apr(void *buf, u32 opcode)
buf + 3 * sizeof(u32), payload_size)) {
pr_err("%s: Could not copy payload from user buffer\n",
__func__);
- result = -EINVAL;
+ result = -EFAULT;
goto err;
}
+ break;
+ default:
+ pr_err("%s: Invalid opcode %d\n", __func__, opcode);
+ result = -EINVAL;
+ goto err;
}
/* Pack header */
@@ -900,33 +907,39 @@ int send_adm_apr(void *buf, u32 opcode)
if (opcode == ADM_CMD_GET_PP_PARAMS_V5) {
bytes_returned = ((u32 *)rtac_cal[ADM_RTAC_CAL].cal_data.
kvaddr)[2] + 3 * sizeof(u32);
+ } else if (opcode == ADM_CMD_GET_PP_PARAMS_V6) {
+ bytes_returned =
+ ((u32 *) rtac_cal[ADM_RTAC_CAL].cal_data.kvaddr)[3] +
+ 4 * sizeof(u32);
+ } else {
+ bytes_returned = data_size;
+ goto unlock;
+ }
- if (bytes_returned > rtac_cal[ADM_RTAC_CAL].
- map_data.map_size) {
- pr_err("%s: Invalid data size = %d\n",
- __func__, bytes_returned);
- result = -EINVAL;
- goto err;
- }
+ if (bytes_returned > rtac_cal[ADM_RTAC_CAL].map_data.map_size) {
+ pr_err("%s: Invalid data size = %d\n", __func__,
+ bytes_returned);
+ result = -EINVAL;
+ goto err;
+ }
- if (bytes_returned > user_buf_size) {
- pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n",
- __func__, user_buf_size, bytes_returned);
- result = -EINVAL;
- goto err;
- }
+ if (bytes_returned > user_buf_size) {
+ pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n",
+ __func__, user_buf_size, bytes_returned);
+ result = -EINVAL;
+ goto err;
+ }
- if (copy_to_user(buf, (void *)
- rtac_cal[ADM_RTAC_CAL].cal_data.kvaddr,
- bytes_returned)) {
- pr_err("%s: Could not copy buffer to user,size = %d\n",
- __func__, bytes_returned);
- result = -EINVAL;
- goto err;
- }
- } else {
- bytes_returned = data_size;
+ if (copy_to_user((void __user *) buf,
+ rtac_cal[ADM_RTAC_CAL].cal_data.kvaddr,
+ bytes_returned)) {
+ pr_err("%s: Could not copy buffer to user,size = %d\n",
+ __func__, bytes_returned);
+ result = -EFAULT;
+ goto err;
}
+
+unlock:
mutex_unlock(&rtac_adm_apr_mutex);
done:
return bytes_returned;
@@ -1027,7 +1040,9 @@ int send_rtac_asm_apr(void *buf, u32 opcode)
goto err;
}
- if (opcode == ASM_STREAM_CMD_SET_PP_PARAMS_V2) {
+ switch (opcode) {
+ case ASM_STREAM_CMD_SET_PP_PARAMS_V2:
+ case ASM_STREAM_CMD_SET_PP_PARAMS_V3:
/* set payload size to in-band payload */
/* set data size to actual out of band payload size */
data_size = payload_size - 4 * sizeof(u32);
@@ -1045,13 +1060,14 @@ int send_rtac_asm_apr(void *buf, u32 opcode)
buf + 7 * sizeof(u32), data_size)) {
pr_err("%s: Could not copy payload from user buffer\n",
__func__);
- result = -EINVAL;
+ result = -EFAULT;
goto err;
}
/* set payload size in packet */
rtac_asm_buffer[8] = data_size;
-
- } else {
+ break;
+ case ASM_STREAM_CMD_GET_PP_PARAMS_V2:
+ case ASM_STREAM_CMD_GET_PP_PARAMS_V3:
if (payload_size > MAX_PAYLOAD_SIZE) {
pr_err("%s: Invalid payload size = %d\n",
__func__, payload_size);
@@ -1065,9 +1081,15 @@ int send_rtac_asm_apr(void *buf, u32 opcode)
buf + 3 * sizeof(u32), payload_size)) {
pr_err("%s: Could not copy payload from user buffer\n",
__func__);
- result = -EINVAL;
+ result = -EFAULT;
goto err;
}
+
+ break;
+ default:
+ pr_err("%s: Invalid opcode %d\n", __func__, opcode);
+ result = -EINVAL;
+ goto err;
}
/* Pack header */
@@ -1130,33 +1152,39 @@ int send_rtac_asm_apr(void *buf, u32 opcode)
if (opcode == ASM_STREAM_CMD_GET_PP_PARAMS_V2) {
bytes_returned = ((u32 *)rtac_cal[ASM_RTAC_CAL].cal_data.
kvaddr)[2] + 3 * sizeof(u32);
+ } else if (opcode == ASM_STREAM_CMD_GET_PP_PARAMS_V3) {
+ bytes_returned =
+ ((u32 *) rtac_cal[ASM_RTAC_CAL].cal_data.kvaddr)[3] +
+ 4 * sizeof(u32);
+ } else {
+ bytes_returned = data_size;
+ goto unlock;
+ }
- if (bytes_returned > rtac_cal[ASM_RTAC_CAL].
- map_data.map_size) {
- pr_err("%s: Invalid data size = %d\n",
- __func__, bytes_returned);
- result = -EINVAL;
- goto err;
- }
+ if (bytes_returned > rtac_cal[ASM_RTAC_CAL].map_data.map_size) {
+ pr_err("%s: Invalid data size = %d\n", __func__,
+ bytes_returned);
+ result = -EINVAL;
+ goto err;
+ }
- if (bytes_returned > user_buf_size) {
- pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n",
- __func__, user_buf_size, bytes_returned);
- result = -EINVAL;
- goto err;
- }
+ if (bytes_returned > user_buf_size) {
+ pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n",
+ __func__, user_buf_size, bytes_returned);
+ result = -EINVAL;
+ goto err;
+ }
- if (copy_to_user(buf, (void *)
- rtac_cal[ASM_RTAC_CAL].cal_data.kvaddr,
- bytes_returned)) {
- pr_err("%s: Could not copy buffer to user,size = %d\n",
- __func__, bytes_returned);
- result = -EINVAL;
- goto err;
- }
- } else {
- bytes_returned = data_size;
+ if (copy_to_user((void __user *) buf,
+ rtac_cal[ASM_RTAC_CAL].cal_data.kvaddr,
+ bytes_returned)) {
+ pr_err("%s: Could not copy buffer to user,size = %d\n",
+ __func__, bytes_returned);
+ result = -EFAULT;
+ goto err;
}
+
+unlock:
mutex_unlock(&rtac_asm_apr_mutex);
done:
return bytes_returned;
@@ -1173,7 +1201,6 @@ void rtac_set_afe_handle(void *handle)
mutex_unlock(&rtac_afe_apr_mutex);
}
-/* Updated in RTAC IID Patch */
bool rtac_make_afe_callback(uint32_t *payload, uint32_t payload_size)
{
pr_debug("%s:cmd_state = %d\n", __func__,
@@ -1214,13 +1241,18 @@ static int fill_afe_apr_hdr(struct apr_hdr *apr_hdr, uint32_t port,
return 0;
}
-static int send_rtac_afe_apr(void *buf, uint32_t opcode)
+static int send_rtac_afe_apr(void __user *buf, uint32_t opcode)
{
int32_t result;
uint32_t bytes_returned = 0;
+ uint32_t payload_size = 0;
uint32_t port_index = 0;
+ uint32_t *afe_cmd = NULL;
uint32_t apr_msg_size = 0;
struct rtac_afe_user_data user_afe_buf;
+ struct mem_mapping_hdr *mem_hdr = NULL;
+ struct param_hdr_v1 *get_resp_v2;
+ struct param_hdr_v3 *get_resp_v3;
pr_debug("%s\n", __func__);
@@ -1268,95 +1300,126 @@ static int send_rtac_afe_apr(void *buf, uint32_t opcode)
result = -EINVAL;
goto err;
}
- if (opcode == AFE_PORT_CMD_SET_PARAM_V2) {
- struct afe_rtac_set_param_v2 *afe_set_apr_msg;
- /* set data size to actual out of band payload size */
- if (user_afe_buf.rtac_afe_set.cmd.payload_size >
- rtac_cal[AFE_RTAC_CAL].map_data.map_size) {
- pr_err("%s: Invalid data size = %d\n",
- __func__,
- user_afe_buf.rtac_afe_set.cmd.payload_size);
+ afe_cmd =
+ (u32 *) rtac_afe_buffer + sizeof(struct apr_hdr) / sizeof(u32);
+
+ switch (opcode) {
+ case AFE_PORT_CMD_SET_PARAM_V2:
+ apr_msg_size = sizeof(struct afe_port_cmd_set_param_v2);
+ payload_size = user_afe_buf.v2_set.payload_size;
+ if (payload_size > rtac_cal[AFE_RTAC_CAL].map_data.map_size) {
+ pr_err("%s: Invalid payload size = %d\n", __func__,
+ payload_size);
result = -EINVAL;
goto err;
}
- /* Copy buffer to out-of-band payload */
- if (copy_from_user(
- (void *) rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr,
- (void __user *) buf +
- offsetof(struct rtac_afe_user_data,
- rtac_afe_set.data),
- user_afe_buf.rtac_afe_set.cmd.payload_size)) {
+ /* Copy the command to the rtac buffer */
+ memcpy(afe_cmd, &user_afe_buf.v2_set,
+ sizeof(user_afe_buf.v2_set));
+
+ /* Copy the param data to the out-of-band location */
+ if (copy_from_user(rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr,
+ (void __user *) buf +
+ offsetof(struct rtac_afe_user_data,
+ v2_set.param_hdr),
+ payload_size)) {
pr_err("%s: Could not copy payload from user buffer\n",
__func__);
+ result = -EFAULT;
+ goto err;
+ }
+ break;
+ case AFE_PORT_CMD_SET_PARAM_V3:
+ apr_msg_size = sizeof(struct afe_port_cmd_set_param_v3);
+ payload_size = user_afe_buf.v3_set.payload_size;
+ if (payload_size > rtac_cal[AFE_RTAC_CAL].map_data.map_size) {
+ pr_err("%s: Invalid payload size = %d\n", __func__,
+ payload_size);
result = -EINVAL;
goto err;
}
- /* Copy AFE APR Message */
- afe_set_apr_msg = (struct afe_rtac_set_param_v2
- *) ((u8 *) rtac_afe_buffer +
- sizeof(struct apr_hdr));
- if (copy_from_user((void *) afe_set_apr_msg,
+ /* Copy the command to the rtac buffer */
+ memcpy(afe_cmd, &user_afe_buf.v3_set,
+ sizeof(user_afe_buf.v3_set));
+
+ /* Copy the param data to the out-of-band location */
+ if (copy_from_user(rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr,
(void __user *) buf +
offsetof(struct rtac_afe_user_data,
- rtac_afe_set.cmd),
- sizeof(struct afe_rtac_set_param_v2))) {
+ v3_get.param_hdr),
+ payload_size)) {
pr_err("%s: Could not copy payload from user buffer\n",
__func__);
- result = -EINVAL;
+ result = -EFAULT;
goto err;
}
+ break;
+ case AFE_PORT_CMD_GET_PARAM_V2:
+ apr_msg_size = sizeof(struct afe_port_cmd_get_param_v2);
- afe_set_apr_msg->payload_address_lsw =
- lower_32_bits(rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
- afe_set_apr_msg->payload_address_msw =
- msm_audio_populate_upper_32_bits(
- rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
- afe_set_apr_msg->mem_map_handle =
- rtac_cal[AFE_RTAC_CAL].map_data.map_handle;
-
- apr_msg_size = sizeof(struct apr_hdr) +
- sizeof(struct afe_rtac_set_param_v2);
+ if (user_afe_buf.cmd_size > MAX_PAYLOAD_SIZE) {
+ pr_err("%s: Invalid payload size = %d\n", __func__,
+ user_afe_buf.cmd_size);
+ result = -EINVAL;
+ goto err;
+ }
- } else {
- struct afe_rtac_get_param_v2 *afe_get_apr_msg;
+ /* Copy the command and param data in-band */
+ if (copy_from_user(afe_cmd,
+ (void __user *) buf +
+ offsetof(struct rtac_afe_user_data,
+ v2_get),
+ user_afe_buf.cmd_size)) {
+ pr_err("%s: Could not copy payload from user buffer\n",
+ __func__);
+ result = -EFAULT;
+ goto err;
+ }
+ break;
+ case AFE_PORT_CMD_GET_PARAM_V3:
+ apr_msg_size = sizeof(struct afe_port_cmd_get_param_v3);
if (user_afe_buf.cmd_size > MAX_PAYLOAD_SIZE) {
- pr_err("%s: Invalid payload size = %d\n",
- __func__, user_afe_buf.cmd_size);
+ pr_err("%s: Invalid payload size = %d\n", __func__,
+ user_afe_buf.cmd_size);
result = -EINVAL;
goto err;
}
- /* Copy buffer to in-band payload */
- afe_get_apr_msg = (struct afe_rtac_get_param_v2
- *) ((u8 *) rtac_afe_buffer +
- sizeof(struct apr_hdr));
- if (copy_from_user((void *) afe_get_apr_msg,
+ /* Copy the command and param data in-band */
+ if (copy_from_user(afe_cmd,
(void __user *) buf +
offsetof(struct rtac_afe_user_data,
- rtac_afe_get.cmd),
- sizeof(struct afe_rtac_get_param_v2))) {
+ v3_get),
+ user_afe_buf.cmd_size)) {
pr_err("%s: Could not copy payload from user buffer\n",
__func__);
- result = -EINVAL;
+ result = -EFAULT;
goto err;
}
-
- afe_get_apr_msg->payload_address_lsw =
- lower_32_bits(rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
- afe_get_apr_msg->payload_address_msw =
- msm_audio_populate_upper_32_bits(
- rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
- afe_get_apr_msg->mem_map_handle =
- rtac_cal[AFE_RTAC_CAL].map_data.map_handle;
- afe_get_apr_msg->payload_size -= sizeof(struct apr_hdr);
- apr_msg_size = sizeof(struct apr_hdr) +
- sizeof(struct afe_rtac_get_param_v2);
+ break;
+ default:
+ pr_err("%s: Invalid opcode %d\n", __func__, opcode);
+ result = -EINVAL;
+ goto err;
}
+ /*
+ * The memory header is in the same location in all commands. Therefore,
+ * it doesn't matter what command the buffer is cast into.
+ */
+ mem_hdr = &((struct afe_port_cmd_set_param_v3 *) rtac_afe_buffer)
+ ->mem_hdr;
+ mem_hdr->data_payload_addr_lsw =
+ lower_32_bits(rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
+ mem_hdr->data_payload_addr_msw = msm_audio_populate_upper_32_bits(
+ rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
+ mem_hdr->mem_map_handle = rtac_cal[AFE_RTAC_CAL].map_data.map_handle;
+
+ /* Fill the APR header at the end so we have the correct message size */
fill_afe_apr_hdr((struct apr_hdr *) rtac_afe_buffer,
port_index, opcode, apr_msg_size);
@@ -1394,41 +1457,44 @@ static int send_rtac_afe_apr(void *buf, uint32_t opcode)
}
if (opcode == AFE_PORT_CMD_GET_PARAM_V2) {
- struct param_hdr_v1 *get_resp;
-
- get_resp = (struct param_hdr_v1 *) rtac_cal[AFE_RTAC_CAL]
- .cal_data.kvaddr;
-
+ get_resp_v2 = (struct param_hdr_v1 *) rtac_cal[AFE_RTAC_CAL]
+ .cal_data.kvaddr;
bytes_returned =
- get_resp->param_size + sizeof(struct param_hdr_v1);
+ get_resp_v2->param_size + sizeof(struct param_hdr_v1);
+ } else if (opcode == AFE_PORT_CMD_GET_PARAM_V3) {
+ get_resp_v3 = (struct param_hdr_v3 *) rtac_cal[AFE_RTAC_CAL]
+ .cal_data.kvaddr;
+ bytes_returned =
+ get_resp_v3->param_size + sizeof(struct param_hdr_v3);
+ } else {
+ bytes_returned = payload_size;
+ goto unlock;
+ }
- if (bytes_returned > rtac_cal[AFE_RTAC_CAL].
- map_data.map_size) {
- pr_err("%s: Invalid data size = %d\n",
- __func__, bytes_returned);
- result = -EINVAL;
- goto err;
- }
+ if (bytes_returned > rtac_cal[AFE_RTAC_CAL].map_data.map_size) {
+ pr_err("%s: Invalid data size = %d\n", __func__,
+ bytes_returned);
+ result = -EINVAL;
+ goto err;
+ }
- if (bytes_returned > user_afe_buf.buf_size) {
- pr_err("%s: user size = 0x%x, returned size = 0x%x\n",
- __func__, user_afe_buf.buf_size,
- bytes_returned);
- result = -EINVAL;
- goto err;
- }
+ if (bytes_returned > user_afe_buf.buf_size) {
+ pr_err("%s: user size = 0x%x, returned size = 0x%x\n", __func__,
+ user_afe_buf.buf_size, bytes_returned);
+ result = -EINVAL;
+ goto err;
+ }
- if (copy_to_user(buf, (void *)
- rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr,
- bytes_returned)) {
- pr_err("%s: Could not copy buffer to user,size = %d\n",
- __func__, bytes_returned);
- result = -EINVAL;
- goto err;
- }
- } else {
- bytes_returned = user_afe_buf.rtac_afe_set.cmd.payload_size;
+ if (copy_to_user((void __user *) buf,
+ rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr,
+ bytes_returned)) {
+ pr_err("%s: Could not copy buffer to user,size = %d\n",
+ __func__, bytes_returned);
+ result = -EFAULT;
+ goto err;
}
+
+unlock:
mutex_unlock(&rtac_afe_apr_mutex);
done:
return bytes_returned;
@@ -1530,7 +1596,9 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode)
goto err;
}
- if (opcode == VSS_ICOMMON_CMD_SET_PARAM_V2) {
+ switch (opcode) {
+ case VSS_ICOMMON_CMD_SET_PARAM_V2:
+ case VSS_ICOMMON_CMD_SET_PARAM_V3:
/* set payload size to in-band payload */
/* set data size to actual out of band payload size */
data_size = payload_size - 4 * sizeof(u32);
@@ -1548,12 +1616,16 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode)
buf + 7 * sizeof(u32), data_size)) {
pr_err("%s: Could not copy payload from user buffer\n",
__func__);
- result = -EINVAL;
+ result = -EFAULT;
goto err;
}
/* set payload size in packet */
rtac_voice_buffer[8] = data_size;
- } else {
+ /* set token for set param case */
+ voice_params.token = VOC_RTAC_SET_PARAM_TOKEN;
+ break;
+ case VSS_ICOMMON_CMD_GET_PARAM_V2:
+ case VSS_ICOMMON_CMD_GET_PARAM_V3:
if (payload_size > MAX_PAYLOAD_SIZE) {
pr_err("%s: Invalid payload size = %d\n",
__func__, payload_size);
@@ -1567,9 +1639,16 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode)
buf + 3 * sizeof(u32), payload_size)) {
pr_err("%s: Could not copy payload from user buffer\n",
__func__);
- result = -EINVAL;
+ result = -EFAULT;
goto err;
}
+ /* set token for get param case */
+ voice_params.token = 0;
+ break;
+ default:
+ pr_err("%s: Invalid opcode %d\n", __func__, opcode);
+ result = -EINVAL;
+ goto err;
}
/* Pack header */
@@ -1583,18 +1662,14 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode)
voice_params.dest_svc = 0;
voice_params.dest_domain = APR_DOMAIN_MODEM;
voice_params.dest_port = (u16)dest_port;
- voice_params.token = (opcode == VSS_ICOMMON_CMD_SET_PARAM_V2) ?
- VOC_RTAC_SET_PARAM_TOKEN :
- 0;
voice_params.opcode = opcode;
/* fill for out-of-band */
rtac_voice_buffer[5] = rtac_cal[VOICE_RTAC_CAL].map_data.map_handle;
rtac_voice_buffer[6] =
lower_32_bits(rtac_cal[VOICE_RTAC_CAL].cal_data.paddr);
- rtac_voice_buffer[7] =
- msm_audio_populate_upper_32_bits(
- rtac_cal[VOICE_RTAC_CAL].cal_data.paddr);
+ rtac_voice_buffer[7] = msm_audio_populate_upper_32_bits(
+ rtac_cal[VOICE_RTAC_CAL].cal_data.paddr);
memcpy(rtac_voice_buffer, &voice_params, sizeof(voice_params));
atomic_set(&rtac_voice_apr_data[mode].cmd_state, 1);
@@ -1633,33 +1708,39 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode)
if (opcode == VSS_ICOMMON_CMD_GET_PARAM_V2) {
bytes_returned = ((u32 *)rtac_cal[VOICE_RTAC_CAL].cal_data.
kvaddr)[2] + 3 * sizeof(u32);
+ } else if (opcode == VSS_ICOMMON_CMD_GET_PARAM_V3) {
+ bytes_returned =
+ ((u32 *) rtac_cal[VOICE_RTAC_CAL].cal_data.kvaddr)[3] +
+ 4 * sizeof(u32);
+ } else {
+ bytes_returned = data_size;
+ goto unlock;
+ }
- if (bytes_returned > rtac_cal[VOICE_RTAC_CAL].
- map_data.map_size) {
- pr_err("%s: Invalid data size = %d\n",
- __func__, bytes_returned);
- result = -EINVAL;
- goto err;
- }
+ if (bytes_returned > rtac_cal[VOICE_RTAC_CAL].map_data.map_size) {
+ pr_err("%s: Invalid data size = %d\n", __func__,
+ bytes_returned);
+ result = -EINVAL;
+ goto err;
+ }
- if (bytes_returned > user_buf_size) {
- pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n",
- __func__, user_buf_size, bytes_returned);
- result = -EINVAL;
- goto err;
- }
+ if (bytes_returned > user_buf_size) {
+ pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n",
+ __func__, user_buf_size, bytes_returned);
+ result = -EINVAL;
+ goto err;
+ }
- if (copy_to_user(buf, (void *)
- rtac_cal[VOICE_RTAC_CAL].cal_data.kvaddr,
- bytes_returned)) {
- pr_err("%s: Could not copy buffer to user, size = %d\n",
- __func__, bytes_returned);
- result = -EINVAL;
- goto err;
- }
- } else {
- bytes_returned = data_size;
+ if (copy_to_user((void __user *) buf,
+ rtac_cal[VOICE_RTAC_CAL].cal_data.kvaddr,
+ bytes_returned)) {
+ pr_err("%s: Could not copy buffer to user, size = %d\n",
+ __func__, bytes_returned);
+ result = -EFAULT;
+ goto err;
}
+
+unlock:
mutex_unlock(&rtac_voice_apr_mutex);
done:
return bytes_returned;
@@ -1679,6 +1760,7 @@ void get_rtac_adm_data(struct rtac_adm *adm_data)
static long rtac_ioctl_shared(struct file *f,
unsigned int cmd, void *arg)
{
+ u32 opcode;
int result = 0;
if (!arg) {
pr_err("%s: No data sent to driver!\n", __func__);
@@ -1717,42 +1799,64 @@ static long rtac_ioctl_shared(struct file *f,
}
case AUDIO_GET_RTAC_ADM_CAL:
- result = send_adm_apr((void *)arg, ADM_CMD_GET_PP_PARAMS_V5);
+ opcode = q6common_is_instance_id_supported() ?
+ ADM_CMD_GET_PP_PARAMS_V6 :
+ ADM_CMD_GET_PP_PARAMS_V5;
+ result = send_adm_apr((void *) arg, opcode);
break;
case AUDIO_SET_RTAC_ADM_CAL:
- result = send_adm_apr((void *)arg, ADM_CMD_SET_PP_PARAMS_V5);
+ opcode = q6common_is_instance_id_supported() ?
+ ADM_CMD_SET_PP_PARAMS_V6 :
+ ADM_CMD_SET_PP_PARAMS_V5;
+ result = send_adm_apr((void *) arg, opcode);
break;
case AUDIO_GET_RTAC_ASM_CAL:
- result = send_rtac_asm_apr((void *)arg,
- ASM_STREAM_CMD_GET_PP_PARAMS_V2);
+ opcode = q6common_is_instance_id_supported() ?
+ ASM_STREAM_CMD_GET_PP_PARAMS_V3 :
+ ASM_STREAM_CMD_GET_PP_PARAMS_V2;
+ result = send_rtac_asm_apr((void *) arg, opcode);
break;
case AUDIO_SET_RTAC_ASM_CAL:
- result = send_rtac_asm_apr((void *)arg,
- ASM_STREAM_CMD_SET_PP_PARAMS_V2);
+ opcode = q6common_is_instance_id_supported() ?
+ ASM_STREAM_CMD_SET_PP_PARAMS_V3 :
+ ASM_STREAM_CMD_SET_PP_PARAMS_V2;
+ result = send_rtac_asm_apr((void *) arg, opcode);
break;
case AUDIO_GET_RTAC_CVS_CAL:
- result = send_voice_apr(RTAC_CVS, (void *) arg,
- VSS_ICOMMON_CMD_GET_PARAM_V2);
+ opcode = q6common_is_instance_id_supported() ?
+ VSS_ICOMMON_CMD_GET_PARAM_V3 :
+ VSS_ICOMMON_CMD_GET_PARAM_V2;
+ result = send_voice_apr(RTAC_CVS, (void *) arg, opcode);
break;
case AUDIO_SET_RTAC_CVS_CAL:
- result = send_voice_apr(RTAC_CVS, (void *) arg,
- VSS_ICOMMON_CMD_SET_PARAM_V2);
+ opcode = q6common_is_instance_id_supported() ?
+ VSS_ICOMMON_CMD_SET_PARAM_V3 :
+ VSS_ICOMMON_CMD_SET_PARAM_V2;
+ result = send_voice_apr(RTAC_CVS, (void *) arg, opcode);
break;
case AUDIO_GET_RTAC_CVP_CAL:
- result = send_voice_apr(RTAC_CVP, (void *) arg,
- VSS_ICOMMON_CMD_GET_PARAM_V2);
+ opcode = q6common_is_instance_id_supported() ?
+ VSS_ICOMMON_CMD_GET_PARAM_V3 :
+ VSS_ICOMMON_CMD_GET_PARAM_V2;
+ result = send_voice_apr(RTAC_CVP, (void *) arg, opcode);
break;
case AUDIO_SET_RTAC_CVP_CAL:
- result = send_voice_apr(RTAC_CVP, (void *) arg,
- VSS_ICOMMON_CMD_SET_PARAM_V2);
+ opcode = q6common_is_instance_id_supported() ?
+ VSS_ICOMMON_CMD_SET_PARAM_V3 :
+ VSS_ICOMMON_CMD_SET_PARAM_V2;
+ result = send_voice_apr(RTAC_CVP, (void *) arg, opcode);
break;
case AUDIO_GET_RTAC_AFE_CAL:
- result = send_rtac_afe_apr((void *)arg,
- AFE_PORT_CMD_GET_PARAM_V2);
+ opcode = q6common_is_instance_id_supported() ?
+ AFE_PORT_CMD_GET_PARAM_V3 :
+ AFE_PORT_CMD_GET_PARAM_V2;
+ result = send_rtac_afe_apr((void __user *) arg, opcode);
break;
case AUDIO_SET_RTAC_AFE_CAL:
- result = send_rtac_afe_apr((void *)arg,
- AFE_PORT_CMD_SET_PARAM_V2);
+ opcode = q6common_is_instance_id_supported() ?
+ AFE_PORT_CMD_SET_PARAM_V3 :
+ AFE_PORT_CMD_SET_PARAM_V2;
+ result = send_rtac_afe_apr((void __user *) arg, opcode);
break;
default:
pr_err("%s: Invalid IOCTL, command = %d!\n",