ASoC: msm-cpe-lsm: Add support for openCPE
openCPE framework allows third party vendors to integrate audio/voice processing algorithms into CPE. Add support for openCPE. Change-Id: I8a0e00fa3dd74753834ba653b7ee3c84e72fd39e Signed-off-by: Bhalchandra Gajare <gajare@codeaurora.org>
This commit is contained in:
parent
86ef8db1b1
commit
c64ce2fc17
|
@ -57,9 +57,14 @@
|
|||
#define CPE_LSM_SESSION_CMDRSP_SHARED_MEM_ALLOC (0x2009)
|
||||
#define CPE_LSM_SESSION_CMD_SHARED_MEM_DEALLOC (0x200A)
|
||||
#define CPE_LSM_SESSION_CMD_TX_BUFF_OUTPUT_CONFIG (0x200f)
|
||||
#define CPE_LSM_SESSION_CMD_OPEN_TX_V2 (0x200D)
|
||||
#define CPE_LSM_SESSION_CMD_SET_PARAMS_V2 (0x200E)
|
||||
|
||||
/* LSM Service module and param IDs */
|
||||
#define CPE_LSM_MODULE_ID_VOICE_WAKEUP (0x00012C00)
|
||||
#define CPE_LSM_MODULE_ID_VOICE_WAKEUP_V2 (0x00012C0D)
|
||||
#define CPE_LSM_MODULE_FRAMEWORK (0x00012C0E)
|
||||
|
||||
#define CPE_LSM_PARAM_ID_ENDPOINT_DETECT_THRESHOLD (0x00012C01)
|
||||
#define CPE_LSM_PARAM_ID_OPERATION_MODE (0x00012C02)
|
||||
#define CPE_LSM_PARAM_ID_GAIN (0x00012C03)
|
||||
|
@ -73,6 +78,8 @@
|
|||
#define CPE_LSM_PARAM_ID_LAB_ENABLE 0x00012C09
|
||||
/* used for T in LAB config DSP internal buffer*/
|
||||
#define CPE_LSM_PARAM_ID_LAB_CONFIG 0x00012C0A
|
||||
#define CPE_LSM_PARAM_ID_REGISTER_SOUND_MODEL (0x00012C14)
|
||||
#define CPE_LSM_PARAM_ID_DEREGISTER_SOUND_MODEL (0x00012C15)
|
||||
|
||||
/* AFE Service command opcodes */
|
||||
#define CPE_AFE_PORT_CMD_START (0x1001)
|
||||
|
@ -263,6 +270,11 @@ struct cpe_lsm_cmd_open_tx {
|
|||
u32 sampling_rate;
|
||||
} __packed;
|
||||
|
||||
struct cpe_lsm_cmd_open_tx_v2 {
|
||||
struct cmi_hdr hdr;
|
||||
u32 topology_id;
|
||||
} __packed;
|
||||
|
||||
struct cpe_cmd_shmem_alloc {
|
||||
struct cmi_hdr hdr;
|
||||
u32 size;
|
||||
|
@ -285,10 +297,35 @@ struct cpe_lsm_event_detect_v2 {
|
|||
u8 payload[0];
|
||||
} __packed;
|
||||
|
||||
struct cpe_lsm_psize_res {
|
||||
u16 param_size;
|
||||
u16 reserved;
|
||||
} __packed;
|
||||
|
||||
union cpe_lsm_param_size {
|
||||
u32 param_size;
|
||||
struct cpe_lsm_psize_res sr;
|
||||
} __packed;
|
||||
|
||||
struct cpe_param_data {
|
||||
u32 module_id;
|
||||
u32 param_id;
|
||||
u16 param_size;
|
||||
union cpe_lsm_param_size p_size;
|
||||
} __packed;
|
||||
|
||||
struct cpe_lsm_param_epd_thres {
|
||||
struct cmi_hdr hdr;
|
||||
struct cpe_param_data param;
|
||||
u32 minor_version;
|
||||
u32 epd_begin;
|
||||
u32 epd_end;
|
||||
} __packed;
|
||||
|
||||
struct cpe_lsm_param_gain {
|
||||
struct cmi_hdr hdr;
|
||||
struct cpe_param_data param;
|
||||
u32 minor_version;
|
||||
u16 gain;
|
||||
u16 reserved;
|
||||
} __packed;
|
||||
|
||||
|
@ -319,14 +356,14 @@ struct cpe_afe_params {
|
|||
struct cmi_hdr hdr;
|
||||
struct cpe_afe_hw_mad_ctrl hw_mad_ctrl;
|
||||
struct cpe_afe_port_cfg port_cfg;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct cpe_afe_svc_cmd_mode {
|
||||
struct cmi_hdr hdr;
|
||||
u8 mode;
|
||||
} __packed;
|
||||
|
||||
struct cpe_lsm_operation_mode {
|
||||
struct cpe_lsm_param_opmode {
|
||||
struct cmi_hdr hdr;
|
||||
struct cpe_param_data param;
|
||||
u32 minor_version;
|
||||
|
@ -334,7 +371,7 @@ struct cpe_lsm_operation_mode {
|
|||
u16 reserved;
|
||||
} __packed;
|
||||
|
||||
struct cpe_lsm_connect_to_port {
|
||||
struct cpe_lsm_param_connectport {
|
||||
struct cmi_hdr hdr;
|
||||
struct cpe_param_data param;
|
||||
u32 minor_version;
|
||||
|
@ -393,12 +430,6 @@ struct cpe_lsm_lab_latency_config {
|
|||
sizeof(struct cmi_hdr))
|
||||
#define PARAM_SIZE_LSM_CONTROL_SIZE (sizeof(struct cpe_lsm_lab_enable) - \
|
||||
sizeof(struct cpe_param_data))
|
||||
#define PARAM_SIZE_LSM_OP_MODE (sizeof(struct cpe_lsm_operation_mode) - \
|
||||
sizeof(struct cmi_hdr) - \
|
||||
sizeof(struct cpe_param_data))
|
||||
#define PARAM_SIZE_LSM_CONNECT_PORT (sizeof(struct cpe_lsm_connect_to_port) - \
|
||||
sizeof(struct cmi_hdr) - \
|
||||
sizeof(struct cpe_param_data))
|
||||
#define PARAM_SIZE_AFE_HW_MAD_CTRL (sizeof(struct cpe_afe_hw_mad_ctrl) - \
|
||||
sizeof(struct cpe_param_data))
|
||||
#define PARAM_SIZE_AFE_PORT_CFG (sizeof(struct cpe_afe_port_cfg) - \
|
||||
|
@ -408,7 +439,8 @@ struct cpe_lsm_lab_latency_config {
|
|||
|
||||
#define OPEN_CMD_PAYLOAD_SIZE (sizeof(struct cpe_lsm_cmd_open_tx) - \
|
||||
sizeof(struct cmi_hdr))
|
||||
|
||||
#define OPEN_V2_CMD_PAYLOAD_SIZE (sizeof(struct cpe_lsm_cmd_open_tx_v2) - \
|
||||
sizeof(struct cmi_hdr))
|
||||
#define SHMEM_ALLOC_CMD_PLD_SIZE (sizeof(struct cpe_cmd_shmem_alloc) - \
|
||||
sizeof(struct cmi_hdr))
|
||||
|
||||
|
@ -425,4 +457,21 @@ struct cpe_lsm_lab_latency_config {
|
|||
#define CPE_AFE_CMD_MODE_PAYLOAD_SIZE \
|
||||
(sizeof(struct cpe_afe_svc_cmd_mode) - \
|
||||
sizeof(struct cmi_hdr))
|
||||
#define CPE_CMD_EPD_THRES_PLD_SIZE (sizeof(struct cpe_lsm_param_epd_thres) - \
|
||||
sizeof(struct cmi_hdr))
|
||||
#define CPE_EPD_THRES_PARAM_SIZE ((CPE_CMD_EPD_THRES_PLD_SIZE) - \
|
||||
sizeof(struct cpe_param_data))
|
||||
#define CPE_CMD_OPMODE_PLD_SIZE (sizeof(struct cpe_lsm_param_opmode) - \
|
||||
sizeof(struct cmi_hdr))
|
||||
#define CPE_OPMODE_PARAM_SIZE ((CPE_CMD_OPMODE_PLD_SIZE) -\
|
||||
sizeof(struct cpe_param_data))
|
||||
#define CPE_CMD_CONNECTPORT_PLD_SIZE \
|
||||
(sizeof(struct cpe_lsm_param_connectport) - \
|
||||
sizeof(struct cmi_hdr))
|
||||
#define CPE_CONNECTPORT_PARAM_SIZE ((CPE_CMD_CONNECTPORT_PLD_SIZE) - \
|
||||
sizeof(struct cpe_param_data))
|
||||
#define CPE_CMD_GAIN_PLD_SIZE (sizeof(struct cpe_lsm_param_gain) - \
|
||||
sizeof(struct cmi_hdr))
|
||||
#define CPE_GAIN_PARAM_SIZE ((CPE_CMD_GAIN_PLD_SIZE) - \
|
||||
sizeof(struct cpe_param_data))
|
||||
#endif /* __CPE_CMI_H__ */
|
||||
|
|
|
@ -74,6 +74,8 @@ struct cpe_lsm_session {
|
|||
|
||||
u32 lab_enable;
|
||||
struct lsm_out_fmt_cfg out_fmt_cfg;
|
||||
|
||||
bool is_topology_used;
|
||||
};
|
||||
|
||||
struct wcd_cpe_afe_ops {
|
||||
|
@ -149,6 +151,13 @@ struct wcd_cpe_lsm_ops {
|
|||
|
||||
int (*lsm_set_port)(void *core_handle,
|
||||
struct cpe_lsm_session *session);
|
||||
int (*lsm_set_one_param)(void *core_handle,
|
||||
struct cpe_lsm_session *session,
|
||||
struct lsm_params_info *p_info,
|
||||
void *data, enum LSM_PARAM_TYPE param_type);
|
||||
void (*lsm_get_snd_model_offset)
|
||||
(void *core_handle, struct cpe_lsm_session *,
|
||||
size_t *offset);
|
||||
};
|
||||
|
||||
int wcd_cpe_get_lsm_ops(struct wcd_cpe_lsm_ops *);
|
||||
|
|
|
@ -94,6 +94,11 @@ struct wcd_cmi_afe_port_data {
|
|||
u32 mem_handle;
|
||||
};
|
||||
|
||||
struct cpe_lsm_ids {
|
||||
u32 module_id;
|
||||
u32 param_id;
|
||||
};
|
||||
|
||||
static struct wcd_cpe_core *core_d;
|
||||
static struct cpe_lsm_session
|
||||
*lsm_sessions[WCD_CPE_LSM_MAX_SESSIONS + 1];
|
||||
|
@ -2200,6 +2205,88 @@ static int wcd_cpe_is_valid_lsm_session(struct wcd_cpe_core *core,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int wcd_cpe_cmd_lsm_open_tx_v2(
|
||||
struct wcd_cpe_core *core,
|
||||
struct cpe_lsm_session *session)
|
||||
{
|
||||
struct cpe_lsm_cmd_open_tx_v2 cmd_open_tx_v2;
|
||||
struct cal_block_data *top_cal = NULL;
|
||||
struct audio_cal_info_lsm_top *lsm_top;
|
||||
int ret = 0;
|
||||
|
||||
ret = wcd_cpe_is_valid_lsm_session(core, session,
|
||||
__func__);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (core->cal_data[WCD_CPE_LSM_CAL_TOPOLOGY_ID] == NULL) {
|
||||
dev_err(core->dev,
|
||||
"%s: LSM_TOPOLOGY cal not allocated!\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&core->cal_data[WCD_CPE_LSM_CAL_TOPOLOGY_ID]->lock);
|
||||
top_cal = cal_utils_get_only_cal_block(
|
||||
core->cal_data[WCD_CPE_LSM_CAL_TOPOLOGY_ID]);
|
||||
if (!top_cal) {
|
||||
dev_err(core->dev,
|
||||
"%s: Failed to get LSM TOPOLOGY cal block\n",
|
||||
__func__);
|
||||
ret = -EINVAL;
|
||||
goto unlock_cal_mutex;
|
||||
}
|
||||
|
||||
lsm_top = (struct audio_cal_info_lsm_top *)
|
||||
top_cal->cal_info;
|
||||
|
||||
if (!lsm_top) {
|
||||
dev_err(core->dev,
|
||||
"%s: cal_info for LSM_TOPOLOGY not found\n",
|
||||
__func__);
|
||||
ret = -EINVAL;
|
||||
goto unlock_cal_mutex;
|
||||
}
|
||||
|
||||
dev_dbg(core->dev,
|
||||
"%s: topology_id = 0x%x, acdb_id = 0x%x, app_type = 0x%x\n",
|
||||
__func__, lsm_top->topology, lsm_top->acdb_id,
|
||||
lsm_top->app_type);
|
||||
|
||||
if (lsm_top->topology == 0) {
|
||||
dev_err(core->dev,
|
||||
"%s: topology id not sent for app_type 0x%x\n",
|
||||
__func__, lsm_top->app_type);
|
||||
ret = -EINVAL;
|
||||
goto unlock_cal_mutex;
|
||||
}
|
||||
|
||||
WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm");
|
||||
|
||||
memset(&cmd_open_tx_v2, 0, sizeof(struct cpe_lsm_cmd_open_tx_v2));
|
||||
if (fill_lsm_cmd_header_v0_inband(&cmd_open_tx_v2.hdr,
|
||||
session->id, OPEN_V2_CMD_PAYLOAD_SIZE,
|
||||
CPE_LSM_SESSION_CMD_OPEN_TX_V2)) {
|
||||
ret = -EINVAL;
|
||||
goto end_ret;
|
||||
}
|
||||
|
||||
cmd_open_tx_v2.topology_id = lsm_top->topology;
|
||||
ret = wcd_cpe_cmi_send_lsm_msg(core, session, &cmd_open_tx_v2);
|
||||
if (ret)
|
||||
dev_err(core->dev,
|
||||
"%s: failed to send open_tx_v2 cmd, err = %d\n",
|
||||
__func__, ret);
|
||||
else
|
||||
session->is_topology_used = true;
|
||||
end_ret:
|
||||
WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm");
|
||||
|
||||
unlock_cal_mutex:
|
||||
mutex_unlock(&core->cal_data[WCD_CPE_LSM_CAL_TOPOLOGY_ID]->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* wcd_cpe_cmd_lsm_open_tx: compose and send lsm open command
|
||||
* @core_handle: handle to cpe core
|
||||
|
@ -2220,6 +2307,14 @@ static int wcd_cpe_cmd_lsm_open_tx(void *core_handle,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Try to open with topology first */
|
||||
ret = wcd_cpe_cmd_lsm_open_tx_v2(core, session);
|
||||
if (!ret)
|
||||
goto done;
|
||||
|
||||
dev_dbg(core->dev, "%s: Try open_tx without topology\n",
|
||||
__func__);
|
||||
|
||||
WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm");
|
||||
|
||||
memset(&cmd_open_tx, 0, sizeof(struct cpe_lsm_cmd_open_tx));
|
||||
|
@ -2240,6 +2335,7 @@ static int wcd_cpe_cmd_lsm_open_tx(void *core_handle,
|
|||
__func__, ret);
|
||||
end_ret:
|
||||
WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm");
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2274,12 +2370,13 @@ static int wcd_cpe_cmd_lsm_close_tx(void *core_handle,
|
|||
dev_err(core->dev,
|
||||
"%s: lsm close_tx cmd failed, err = %d\n",
|
||||
__func__, ret);
|
||||
else
|
||||
session->is_topology_used = false;
|
||||
end_ret:
|
||||
WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* wcd_cpe_cmd_shmem_alloc: compose and send lsm shared
|
||||
* memory allocation command
|
||||
|
@ -2442,68 +2539,151 @@ unlock_cal_mutex:
|
|||
|
||||
}
|
||||
|
||||
/*
|
||||
* wcd_cpe_lsm_set_opmode: set operation mode for listen
|
||||
* @core: handle to cpe core
|
||||
* @session: session for which the parameters are to be set
|
||||
* @detect_mode: mode for detection
|
||||
* @detect_failure: flag indicating failure detection enabled/disabled
|
||||
*
|
||||
*/
|
||||
static int wcd_cpe_lsm_set_opmode(
|
||||
struct wcd_cpe_core *core,
|
||||
struct cpe_lsm_session *session,
|
||||
enum lsm_detection_mode detect_mode,
|
||||
bool detect_failure)
|
||||
static void wcd_cpe_set_param_data(struct cpe_param_data *param_d,
|
||||
struct cpe_lsm_ids *ids, u32 p_size,
|
||||
u32 set_param_cmd)
|
||||
{
|
||||
struct cpe_lsm_operation_mode op_mode;
|
||||
struct cmi_hdr *hdr = &op_mode.hdr;
|
||||
struct cpe_param_data *param_d = &op_mode.param;
|
||||
int ret = 0;
|
||||
u8 pld_size = 0;
|
||||
param_d->module_id = ids->module_id;
|
||||
param_d->param_id = ids->param_id;
|
||||
|
||||
ret = wcd_cpe_send_lsm_cal(core, session);
|
||||
if (ret) {
|
||||
pr_err("%s: fail to sent acdb cal, err = %d\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
switch (set_param_cmd) {
|
||||
case CPE_LSM_SESSION_CMD_SET_PARAMS_V2:
|
||||
param_d->p_size.param_size = p_size;
|
||||
break;
|
||||
case CPE_LSM_SESSION_CMD_SET_PARAMS:
|
||||
default:
|
||||
param_d->p_size.sr.param_size =
|
||||
(u16) p_size;
|
||||
param_d->p_size.sr.reserved = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memset(&op_mode, 0, sizeof(struct cpe_lsm_operation_mode));
|
||||
static int wcd_cpe_send_param_epd_thres(struct wcd_cpe_core *core,
|
||||
struct cpe_lsm_session *session,
|
||||
void *data, struct cpe_lsm_ids *ids)
|
||||
{
|
||||
struct snd_lsm_ep_det_thres *ep_det_data;
|
||||
struct cpe_lsm_param_epd_thres epd_cmd;
|
||||
struct cmi_hdr *msg_hdr = &epd_cmd.hdr;
|
||||
struct cpe_param_data *param_d =
|
||||
&epd_cmd.param;
|
||||
int rc;
|
||||
|
||||
pld_size = (sizeof(struct cpe_lsm_operation_mode) -
|
||||
sizeof(struct cmi_hdr));
|
||||
|
||||
if (fill_lsm_cmd_header_v0_inband(hdr,
|
||||
memset(&epd_cmd, 0, sizeof(epd_cmd));
|
||||
ep_det_data = (struct snd_lsm_ep_det_thres *) data;
|
||||
if (fill_lsm_cmd_header_v0_inband(msg_hdr,
|
||||
session->id,
|
||||
pld_size,
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS)) {
|
||||
ret = -EINVAL;
|
||||
CPE_CMD_EPD_THRES_PLD_SIZE,
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS_V2)) {
|
||||
rc = -EINVAL;
|
||||
goto err_ret;
|
||||
}
|
||||
|
||||
param_d->module_id = CPE_LSM_MODULE_ID_VOICE_WAKEUP;
|
||||
param_d->param_id = CPE_LSM_PARAM_ID_OPERATION_MODE;
|
||||
param_d->param_size = PARAM_SIZE_LSM_OP_MODE;
|
||||
param_d->reserved = 0;
|
||||
wcd_cpe_set_param_data(param_d, ids,
|
||||
CPE_EPD_THRES_PARAM_SIZE,
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS_V2);
|
||||
|
||||
op_mode.minor_version = 1;
|
||||
if (detect_mode == LSM_MODE_KEYWORD_ONLY_DETECTION)
|
||||
op_mode.mode = 1;
|
||||
else
|
||||
op_mode.mode = 3;
|
||||
epd_cmd.minor_version = 0;
|
||||
epd_cmd.epd_begin = ep_det_data->epd_begin;
|
||||
epd_cmd.epd_end = ep_det_data->epd_end;
|
||||
|
||||
if (detect_failure)
|
||||
op_mode.mode |= 0x04;
|
||||
|
||||
op_mode.reserved = 0;
|
||||
|
||||
ret = wcd_cpe_cmi_send_lsm_msg(core, session, &op_mode);
|
||||
if (ret)
|
||||
pr_err("%s: lsm_set_opmode failed, rc %d\n",
|
||||
__func__, ret);
|
||||
WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm");
|
||||
rc = wcd_cpe_cmi_send_lsm_msg(core, session, &epd_cmd);
|
||||
if (unlikely(rc))
|
||||
dev_err(core->dev,
|
||||
"%s: set_param(EPD Threshold) failed, rc %dn",
|
||||
__func__, rc);
|
||||
WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm");
|
||||
err_ret:
|
||||
return ret;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int wcd_cpe_send_param_opmode(struct wcd_cpe_core *core,
|
||||
struct cpe_lsm_session *session,
|
||||
void *data, struct cpe_lsm_ids *ids)
|
||||
{
|
||||
struct snd_lsm_detect_mode *opmode_d;
|
||||
struct cpe_lsm_param_opmode opmode_cmd;
|
||||
struct cmi_hdr *msg_hdr = &opmode_cmd.hdr;
|
||||
struct cpe_param_data *param_d =
|
||||
&opmode_cmd.param;
|
||||
int rc;
|
||||
|
||||
memset(&opmode_cmd, 0, sizeof(opmode_cmd));
|
||||
opmode_d = (struct snd_lsm_detect_mode *) data;
|
||||
if (fill_lsm_cmd_header_v0_inband(msg_hdr,
|
||||
session->id,
|
||||
CPE_CMD_OPMODE_PLD_SIZE,
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS_V2)) {
|
||||
rc = -EINVAL;
|
||||
goto err_ret;
|
||||
}
|
||||
|
||||
wcd_cpe_set_param_data(param_d, ids,
|
||||
CPE_OPMODE_PARAM_SIZE,
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS_V2);
|
||||
|
||||
opmode_cmd.minor_version = 0;
|
||||
if (opmode_d->mode == LSM_MODE_KEYWORD_ONLY_DETECTION)
|
||||
opmode_cmd.mode = 1;
|
||||
else
|
||||
opmode_cmd.mode = 3;
|
||||
|
||||
if (opmode_d->detect_failure)
|
||||
opmode_cmd.mode |= 0x04;
|
||||
|
||||
opmode_cmd.reserved = 0;
|
||||
|
||||
WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm");
|
||||
rc = wcd_cpe_cmi_send_lsm_msg(core, session, &opmode_cmd);
|
||||
if (unlikely(rc))
|
||||
dev_err(core->dev,
|
||||
"%s: set_param(operation_mode) failed, rc %dn",
|
||||
__func__, rc);
|
||||
WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm");
|
||||
err_ret:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int wcd_cpe_send_param_gain(struct wcd_cpe_core *core,
|
||||
struct cpe_lsm_session *session,
|
||||
void *data, struct cpe_lsm_ids *ids)
|
||||
{
|
||||
struct snd_lsm_gain *gain_d;
|
||||
struct cpe_lsm_param_gain gain_cmd;
|
||||
struct cmi_hdr *msg_hdr = &gain_cmd.hdr;
|
||||
struct cpe_param_data *param_d =
|
||||
&gain_cmd.param;
|
||||
int rc;
|
||||
|
||||
memset(&gain_cmd, 0, sizeof(gain_cmd));
|
||||
gain_d = (struct snd_lsm_gain *) data;
|
||||
if (fill_lsm_cmd_header_v0_inband(msg_hdr,
|
||||
session->id,
|
||||
CPE_CMD_GAIN_PLD_SIZE,
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS_V2)) {
|
||||
rc = -EINVAL;
|
||||
goto err_ret;
|
||||
}
|
||||
|
||||
wcd_cpe_set_param_data(param_d, ids,
|
||||
CPE_GAIN_PARAM_SIZE,
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS_V2);
|
||||
|
||||
gain_cmd.minor_version = 0;
|
||||
gain_cmd.gain = gain_d->gain;
|
||||
gain_cmd.reserved = 0;
|
||||
|
||||
WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm");
|
||||
rc = wcd_cpe_cmi_send_lsm_msg(core, session, &gain_cmd);
|
||||
if (unlikely(rc))
|
||||
dev_err(core->dev,
|
||||
"%s: set_param(lsm_gain) failed, rc %dn",
|
||||
__func__, rc);
|
||||
WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm");
|
||||
err_ret:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2511,65 +2691,58 @@ err_ret:
|
|||
* @core: handle to cpe core
|
||||
* @session: session for which the parameters are to be set
|
||||
*/
|
||||
static int wcd_cpe_lsm_set_port(void *core_handle,
|
||||
struct cpe_lsm_session *session)
|
||||
static int wcd_cpe_send_param_connectport(void *core_handle,
|
||||
struct cpe_lsm_session *session)
|
||||
{
|
||||
struct cpe_lsm_connect_to_port connect_port;
|
||||
struct cmi_hdr *hdr = &connect_port.hdr;
|
||||
struct cpe_param_data *param_d = &connect_port.param;
|
||||
struct wcd_cpe_core *core = core_handle;
|
||||
int ret = 0;
|
||||
u8 pld_size = 0;
|
||||
struct cpe_lsm_param_connectport con_port_cmd;
|
||||
struct cpe_lsm_ids ids;
|
||||
struct cmi_hdr *msg_hdr = &con_port_cmd.hdr;
|
||||
struct cpe_param_data *param_d =
|
||||
&con_port_cmd.param;
|
||||
int rc;
|
||||
|
||||
ret = wcd_cpe_is_valid_lsm_session(core, session,
|
||||
__func__);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (session->is_topology_used) {
|
||||
ids.module_id = LSM_MODULE_ID_FRAMEWORK;
|
||||
ids.param_id = CPE_LSM_PARAM_ID_CONNECT_TO_PORT;
|
||||
|
||||
WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm");
|
||||
} else {
|
||||
ids.module_id = CPE_LSM_MODULE_ID_VOICE_WAKEUP;
|
||||
ids.param_id = CPE_LSM_PARAM_ID_CONNECT_TO_PORT;
|
||||
}
|
||||
|
||||
memset(&connect_port, 0, sizeof(struct cpe_lsm_connect_to_port));
|
||||
|
||||
pld_size = (sizeof(struct cpe_lsm_connect_to_port) -
|
||||
sizeof(struct cmi_hdr));
|
||||
|
||||
if (fill_lsm_cmd_header_v0_inband(hdr,
|
||||
memset(&con_port_cmd, 0, sizeof(con_port_cmd));
|
||||
if (fill_lsm_cmd_header_v0_inband(msg_hdr,
|
||||
session->id,
|
||||
pld_size,
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS)) {
|
||||
ret = -EINVAL;
|
||||
CPE_CMD_CONNECTPORT_PLD_SIZE,
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS_V2)) {
|
||||
rc = -EINVAL;
|
||||
goto err_ret;
|
||||
}
|
||||
|
||||
param_d->module_id = CPE_LSM_MODULE_ID_VOICE_WAKEUP;
|
||||
param_d->param_id = CPE_LSM_PARAM_ID_CONNECT_TO_PORT;
|
||||
param_d->param_size = PARAM_SIZE_LSM_CONNECT_PORT;
|
||||
param_d->reserved = 0;
|
||||
wcd_cpe_set_param_data(param_d, &ids,
|
||||
CPE_CONNECTPORT_PARAM_SIZE,
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS_V2);
|
||||
|
||||
connect_port.minor_version = 1;
|
||||
connect_port.afe_port_id = CPE_AFE_PORT_1_TX;
|
||||
connect_port.reserved = 0;
|
||||
con_port_cmd.minor_version = 1;
|
||||
con_port_cmd.afe_port_id = CPE_AFE_PORT_1_TX;
|
||||
con_port_cmd.reserved = 0;
|
||||
|
||||
ret = wcd_cpe_cmi_send_lsm_msg(core, session, &connect_port);
|
||||
if (ret)
|
||||
pr_err("%s: lsm_set_port failed, rc %d\n",
|
||||
__func__, ret);
|
||||
err_ret:
|
||||
WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm");
|
||||
rc = wcd_cpe_cmi_send_lsm_msg(core, session, &con_port_cmd);
|
||||
if (unlikely(rc))
|
||||
dev_err(core->dev,
|
||||
"%s: set_param(connect_port) failed, rc %dn",
|
||||
__func__, rc);
|
||||
WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm");
|
||||
return ret;
|
||||
err_ret:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* wcd_cpe_lsm_set_conf_levels: send the confidence levels for listen
|
||||
* @core: handle to cpe core
|
||||
* @session: session for which the confidence levels are to be set
|
||||
*
|
||||
* The actual confidence levels are part of the session.
|
||||
*/
|
||||
static int wcd_cpe_lsm_set_conf_levels(
|
||||
struct wcd_cpe_core *core,
|
||||
struct cpe_lsm_session *session)
|
||||
static int wcd_cpe_send_param_conf_levels(
|
||||
struct wcd_cpe_core *core,
|
||||
struct cpe_lsm_session *session,
|
||||
struct cpe_lsm_ids *ids)
|
||||
{
|
||||
struct cpe_lsm_conf_level conf_level_data;
|
||||
struct cmi_hdr *hdr = &(conf_level_data.hdr);
|
||||
|
@ -2588,13 +2761,11 @@ static int wcd_cpe_lsm_set_conf_levels(
|
|||
|
||||
fill_cmi_header(hdr, session->id, CMI_CPE_LSM_SERVICE_ID,
|
||||
false, pld_size,
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS, false);
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS_V2, false);
|
||||
|
||||
param_d->module_id = CPE_LSM_MODULE_ID_VOICE_WAKEUP;
|
||||
param_d->param_id = CPE_LSM_PARAM_ID_MIN_CONFIDENCE_LEVELS;
|
||||
param_d->param_size = pld_size -
|
||||
sizeof(struct cpe_param_data);
|
||||
param_d->reserved = 0;
|
||||
wcd_cpe_set_param_data(param_d, ids,
|
||||
pld_size - sizeof(struct cpe_param_data),
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS_V2);
|
||||
|
||||
conf_level_data.num_active_models = session->num_confidence_levels;
|
||||
|
||||
|
@ -2611,11 +2782,228 @@ static int wcd_cpe_lsm_set_conf_levels(
|
|||
memcpy(((u8 *) message) + sizeof(struct cpe_lsm_conf_level),
|
||||
session->conf_levels, conf_level_data.num_active_models);
|
||||
|
||||
WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm");
|
||||
ret = wcd_cpe_cmi_send_lsm_msg(core, session, message);
|
||||
if (ret)
|
||||
pr_err("%s: lsm_set_conf_levels failed, err = %d\n",
|
||||
__func__, ret);
|
||||
kfree(message);
|
||||
WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wcd_cpe_send_param_snd_model(struct wcd_cpe_core *core,
|
||||
struct cpe_lsm_session *session, struct cpe_lsm_ids *ids)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cmi_obm_msg obm_msg;
|
||||
struct cpe_param_data *param_d;
|
||||
|
||||
|
||||
ret = fill_cmi_header(&obm_msg.hdr, session->id,
|
||||
CMI_CPE_LSM_SERVICE_ID, 0, 20,
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS_V2, true);
|
||||
if (ret) {
|
||||
dev_err(core->dev,
|
||||
"%s: Invalid parameters, rc = %d\n",
|
||||
__func__, ret);
|
||||
goto err_ret;
|
||||
}
|
||||
|
||||
obm_msg.pld.version = 0;
|
||||
obm_msg.pld.size = session->snd_model_size;
|
||||
obm_msg.pld.data_ptr.kvaddr = session->snd_model_data;
|
||||
obm_msg.pld.mem_handle = session->lsm_mem_handle;
|
||||
|
||||
param_d = (struct cpe_param_data *) session->snd_model_data;
|
||||
wcd_cpe_set_param_data(param_d, ids,
|
||||
(session->snd_model_size - sizeof(*param_d)),
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS_V2);
|
||||
|
||||
WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm");
|
||||
ret = wcd_cpe_cmi_send_lsm_msg(core, session, &obm_msg);
|
||||
if (ret)
|
||||
dev_err(core->dev,
|
||||
"%s: snd_model_register failed, %d\n",
|
||||
__func__, ret);
|
||||
WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm");
|
||||
|
||||
err_ret:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wcd_cpe_send_param_dereg_model(
|
||||
struct wcd_cpe_core *core,
|
||||
struct cpe_lsm_session *session,
|
||||
struct cpe_lsm_ids *ids)
|
||||
{
|
||||
struct cmi_hdr *hdr;
|
||||
struct cpe_param_data *param_d;
|
||||
u8 *message;
|
||||
u32 pld_size;
|
||||
int rc = 0;
|
||||
|
||||
pld_size = sizeof(*hdr) + sizeof(*param_d);
|
||||
|
||||
message = kzalloc(pld_size, GFP_KERNEL);
|
||||
if (!message)
|
||||
return -ENOMEM;
|
||||
|
||||
hdr = (struct cmi_hdr *) message;
|
||||
param_d = (struct cpe_param_data *)
|
||||
(((u8 *) message) + sizeof(*hdr));
|
||||
|
||||
if (fill_lsm_cmd_header_v0_inband(hdr,
|
||||
session->id,
|
||||
sizeof(*param_d),
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS_V2)) {
|
||||
rc = -EINVAL;
|
||||
goto err_ret;
|
||||
}
|
||||
wcd_cpe_set_param_data(param_d, ids, 0,
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS_V2);
|
||||
WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm");
|
||||
rc = wcd_cpe_cmi_send_lsm_msg(core, session, message);
|
||||
if (rc)
|
||||
dev_err(core->dev,
|
||||
"%s: snd_model_deregister failed, %d\n",
|
||||
__func__, rc);
|
||||
WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm");
|
||||
err_ret:
|
||||
kfree(message);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int wcd_cpe_send_custom_param(
|
||||
struct wcd_cpe_core *core,
|
||||
struct cpe_lsm_session *session,
|
||||
void *data, u32 msg_size)
|
||||
{
|
||||
u8 *msg;
|
||||
struct cmi_hdr *hdr;
|
||||
u8 *msg_pld;
|
||||
int rc;
|
||||
|
||||
if (msg_size > CMI_INBAND_MESSAGE_SIZE) {
|
||||
dev_err(core->dev,
|
||||
"%s: out of band custom params not supported\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
msg = kzalloc(sizeof(*hdr) + msg_size, GFP_KERNEL);
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
hdr = (struct cmi_hdr *) msg;
|
||||
msg_pld = msg + sizeof(struct cmi_hdr);
|
||||
|
||||
if (fill_lsm_cmd_header_v0_inband(hdr,
|
||||
session->id,
|
||||
msg_size,
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS_V2)) {
|
||||
rc = -EINVAL;
|
||||
goto err_ret;
|
||||
}
|
||||
|
||||
memcpy(msg_pld, data, msg_size);
|
||||
WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm");
|
||||
rc = wcd_cpe_cmi_send_lsm_msg(core, session, msg);
|
||||
if (rc)
|
||||
dev_err(core->dev,
|
||||
"%s: custom params send failed, err = %d\n",
|
||||
__func__, rc);
|
||||
WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm");
|
||||
err_ret:
|
||||
kfree(msg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int wcd_cpe_set_one_param(void *core_handle,
|
||||
struct cpe_lsm_session *session, struct lsm_params_info *p_info,
|
||||
void *data, enum LSM_PARAM_TYPE param_type)
|
||||
{
|
||||
struct wcd_cpe_core *core = core_handle;
|
||||
int rc = 0;
|
||||
struct cpe_lsm_ids ids;
|
||||
|
||||
memset(&ids, 0, sizeof(ids));
|
||||
ids.module_id = p_info->module_id;
|
||||
ids.param_id = p_info->param_id;
|
||||
|
||||
switch (param_type) {
|
||||
case LSM_ENDPOINT_DETECT_THRESHOLD:
|
||||
rc = wcd_cpe_send_param_epd_thres(core, session,
|
||||
data, &ids);
|
||||
break;
|
||||
case LSM_OPERATION_MODE:
|
||||
rc = wcd_cpe_send_param_opmode(core, session,
|
||||
data, &ids);
|
||||
break;
|
||||
case LSM_GAIN:
|
||||
rc = wcd_cpe_send_param_gain(core, session, data, &ids);
|
||||
break;
|
||||
case LSM_MIN_CONFIDENCE_LEVELS:
|
||||
rc = wcd_cpe_send_param_conf_levels(core, session, &ids);
|
||||
break;
|
||||
case LSM_REG_SND_MODEL:
|
||||
rc = wcd_cpe_send_param_snd_model(core, session, &ids);
|
||||
break;
|
||||
case LSM_DEREG_SND_MODEL:
|
||||
rc = wcd_cpe_send_param_dereg_model(core, session, &ids);
|
||||
break;
|
||||
case LSM_CUSTOM_PARAMS:
|
||||
rc = wcd_cpe_send_custom_param(core, session,
|
||||
data, p_info->param_size);
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: wrong param_type 0x%x\n",
|
||||
__func__, p_info->param_type);
|
||||
}
|
||||
|
||||
if (rc)
|
||||
dev_err(core->dev,
|
||||
"%s: send_param(%d) failed, err %d\n",
|
||||
__func__, p_info->param_type, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* wcd_cpe_lsm_set_params: set the parameters for lsm service
|
||||
* @core: handle to cpe core
|
||||
* @session: session for which the parameters are to be set
|
||||
* @detect_mode: mode for detection
|
||||
* @detect_failure: flag indicating failure detection enabled/disabled
|
||||
*
|
||||
*/
|
||||
static int wcd_cpe_lsm_set_params(struct wcd_cpe_core *core,
|
||||
struct cpe_lsm_session *session,
|
||||
enum lsm_detection_mode detect_mode, bool detect_failure)
|
||||
{
|
||||
struct cpe_lsm_ids ids;
|
||||
struct snd_lsm_detect_mode det_mode;
|
||||
|
||||
int ret = 0;
|
||||
|
||||
/* Send lsm calibration */
|
||||
ret = wcd_cpe_send_lsm_cal(core, session);
|
||||
if (ret) {
|
||||
pr_err("%s: fail to sent acdb cal, err = %d",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Send operation mode */
|
||||
ids.module_id = CPE_LSM_MODULE_ID_VOICE_WAKEUP;
|
||||
ids.param_id = CPE_LSM_PARAM_ID_OPERATION_MODE;
|
||||
det_mode.mode = detect_mode;
|
||||
det_mode.detect_failure = detect_failure;
|
||||
ret = wcd_cpe_send_param_opmode(core, session,
|
||||
&det_mode, &ids);
|
||||
if (ret)
|
||||
dev_err(core->dev,
|
||||
"%s: Failed to set opmode, err=%d\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2625,11 +3013,11 @@ int wcd_cpe_lsm_set_data(void *core_handle,
|
|||
bool detect_failure)
|
||||
{
|
||||
struct wcd_cpe_core *core = core_handle;
|
||||
struct cpe_lsm_ids ids;
|
||||
int ret = 0;
|
||||
|
||||
WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm");
|
||||
if (session->num_confidence_levels > 0) {
|
||||
ret = wcd_cpe_lsm_set_opmode(core, session, detect_mode,
|
||||
ret = wcd_cpe_lsm_set_params(core, session, detect_mode,
|
||||
detect_failure);
|
||||
if (ret) {
|
||||
dev_err(core->dev,
|
||||
|
@ -2638,7 +3026,9 @@ int wcd_cpe_lsm_set_data(void *core_handle,
|
|||
goto err_ret;
|
||||
}
|
||||
|
||||
ret = wcd_cpe_lsm_set_conf_levels(core, session);
|
||||
ids.module_id = CPE_LSM_MODULE_ID_VOICE_WAKEUP;
|
||||
ids.param_id = CPE_LSM_PARAM_ID_MIN_CONFIDENCE_LEVELS;
|
||||
ret = wcd_cpe_send_param_conf_levels(core, session, &ids);
|
||||
if (ret) {
|
||||
dev_err(core->dev,
|
||||
"%s: lsm confidence levels failed, rc = %d\n",
|
||||
|
@ -2652,7 +3042,6 @@ int wcd_cpe_lsm_set_data(void *core_handle,
|
|||
}
|
||||
|
||||
err_ret:
|
||||
WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm");
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(wcd_cpe_lsm_set_data);
|
||||
|
@ -2946,9 +3335,11 @@ static int wcd_cpe_lsm_config_lab_latency(
|
|||
int ret = 0, pld_size = CPE_PARAM_LSM_LAB_LATENCY_SIZE;
|
||||
struct cpe_lsm_lab_latency_config cpe_lab_latency;
|
||||
struct cpe_lsm_lab_config *lab_lat = &cpe_lab_latency.latency_cfg;
|
||||
struct cpe_param_data *param_d = &lab_lat->param;
|
||||
struct cpe_lsm_ids ids;
|
||||
|
||||
if (fill_lsm_cmd_header_v0_inband(&cpe_lab_latency.hdr, session->id,
|
||||
(u8) pld_size, CPE_LSM_SESSION_CMD_SET_PARAMS)) {
|
||||
(u8) pld_size, CPE_LSM_SESSION_CMD_SET_PARAMS_V2)) {
|
||||
pr_err("%s: Failed to create header\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -2961,13 +3352,15 @@ static int wcd_cpe_lsm_config_lab_latency(
|
|||
}
|
||||
|
||||
lab_lat->minor_ver = 1;
|
||||
lab_lat->param.module_id = CPE_LSM_MODULE_ID_LAB;
|
||||
lab_lat->param.param_id = CPE_LSM_PARAM_ID_LAB_CONFIG;
|
||||
lab_lat->param.param_size = PARAM_SIZE_LSM_LATENCY_SIZE;
|
||||
lab_lat->param.reserved = 0;
|
||||
pr_debug("%s: Module 0x%x Param 0x%x size 0x%x pld_size 0x%x\n",
|
||||
ids.module_id = CPE_LSM_MODULE_ID_LAB;
|
||||
ids.param_id = CPE_LSM_PARAM_ID_LAB_CONFIG;
|
||||
wcd_cpe_set_param_data(param_d, &ids,
|
||||
PARAM_SIZE_LSM_LATENCY_SIZE,
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS_V2);
|
||||
|
||||
pr_debug("%s: Module 0x%x Param 0x%x size %ld pld_size 0x%x\n",
|
||||
__func__, lab_lat->param.module_id,
|
||||
lab_lat->param.param_id, lab_lat->param.param_size,
|
||||
lab_lat->param.param_id, (long int)PARAM_SIZE_LSM_LATENCY_SIZE,
|
||||
pld_size);
|
||||
|
||||
ret = wcd_cpe_cmi_send_lsm_msg(core, session, &cpe_lab_latency);
|
||||
|
@ -2994,26 +3387,31 @@ static int wcd_cpe_lsm_lab_control(
|
|||
int ret = 0, pld_size = CPE_PARAM_SIZE_LSM_LAB_CONTROL;
|
||||
struct cpe_lsm_control_lab cpe_lab_enable;
|
||||
struct cpe_lsm_lab_enable *lab_enable = &cpe_lab_enable.lab_enable;
|
||||
struct cpe_param_data *param_d = &lab_enable->param;
|
||||
struct cpe_lsm_ids ids;
|
||||
|
||||
pr_debug("%s: enter payload_size = %d Enable %d\n",
|
||||
__func__, pld_size, enable);
|
||||
|
||||
if (fill_lsm_cmd_header_v0_inband(&cpe_lab_enable.hdr, session->id,
|
||||
(u8) pld_size, CPE_LSM_SESSION_CMD_SET_PARAMS)) {
|
||||
(u8) pld_size, CPE_LSM_SESSION_CMD_SET_PARAMS_V2)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (enable == true)
|
||||
lab_enable->enable = 1;
|
||||
else
|
||||
lab_enable->enable = 0;
|
||||
lab_enable->param.module_id = CPE_LSM_MODULE_ID_LAB;
|
||||
lab_enable->param.param_id = CPE_LSM_PARAM_ID_LAB_ENABLE;
|
||||
lab_enable->param.param_size = PARAM_SIZE_LSM_CONTROL_SIZE;
|
||||
lab_enable->param.reserved = 0;
|
||||
pr_debug("%s: Module 0x%x, Param 0x%x size 0x%x pld_size 0x%x\n",
|
||||
|
||||
ids.module_id = CPE_LSM_MODULE_ID_LAB;
|
||||
ids.param_id = CPE_LSM_PARAM_ID_LAB_ENABLE;
|
||||
wcd_cpe_set_param_data(param_d, &ids,
|
||||
PARAM_SIZE_LSM_CONTROL_SIZE,
|
||||
CPE_LSM_SESSION_CMD_SET_PARAMS_V2);
|
||||
|
||||
pr_debug("%s: Module 0x%x, Param 0x%x size %ld pld_size 0x%x\n",
|
||||
__func__, lab_enable->param.module_id,
|
||||
lab_enable->param.param_id, lab_enable->param.param_size,
|
||||
pld_size);
|
||||
lab_enable->param.param_id,
|
||||
(long int)PARAM_SIZE_LSM_CONTROL_SIZE, pld_size);
|
||||
ret = wcd_cpe_cmi_send_lsm_msg(core, session, &cpe_lab_enable);
|
||||
if (ret != 0) {
|
||||
pr_err("%s: lsm_set_params failed, error = %d\n",
|
||||
|
@ -3256,6 +3654,12 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void wcd_cpe_snd_model_offset(void *core_handle,
|
||||
struct cpe_lsm_session *session, size_t *offset)
|
||||
{
|
||||
*offset = sizeof(struct cpe_param_data);
|
||||
}
|
||||
|
||||
/*
|
||||
* wcd_cpe_get_lsm_ops: register lsm driver to codec
|
||||
* @lsm_ops: structure with lsm callbacks
|
||||
|
@ -3277,7 +3681,9 @@ int wcd_cpe_get_lsm_ops(struct wcd_cpe_lsm_ops *lsm_ops)
|
|||
lsm_ops->lab_ch_setup = wcd_cpe_lab_ch_setup;
|
||||
lsm_ops->lsm_set_data = wcd_cpe_lsm_set_data;
|
||||
lsm_ops->lsm_set_fmt_cfg = wcd_cpe_lsm_set_fmt_cfg;
|
||||
lsm_ops->lsm_set_port = wcd_cpe_lsm_set_port;
|
||||
lsm_ops->lsm_set_port = wcd_cpe_send_param_connectport;
|
||||
lsm_ops->lsm_set_one_param = wcd_cpe_set_one_param;
|
||||
lsm_ops->lsm_get_snd_model_offset = wcd_cpe_snd_model_offset;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(wcd_cpe_get_lsm_ops);
|
||||
|
@ -3731,16 +4137,16 @@ static int wcd_cpe_afe_set_params(void *core_handle,
|
|||
|
||||
hw_mad_ctrl->param.module_id = CPE_AFE_MODULE_HW_MAD;
|
||||
hw_mad_ctrl->param.param_id = CPE_AFE_PARAM_ID_HW_MAD_CTL;
|
||||
hw_mad_ctrl->param.param_size = PARAM_SIZE_AFE_HW_MAD_CTRL;
|
||||
hw_mad_ctrl->param.reserved = 0;
|
||||
hw_mad_ctrl->param.p_size.sr.param_size = PARAM_SIZE_AFE_HW_MAD_CTRL;
|
||||
hw_mad_ctrl->param.p_size.sr.reserved = 0;
|
||||
hw_mad_ctrl->minor_version = 1;
|
||||
hw_mad_ctrl->mad_type = MAD_TYPE_AUDIO;
|
||||
hw_mad_ctrl->mad_enable = 1;
|
||||
|
||||
port_cfg->param.module_id = CPE_AFE_MODULE_AUDIO_DEV_INTERFACE;
|
||||
port_cfg->param.param_id = CPE_AFE_PARAM_ID_GENERIC_PORT_CONFIG;
|
||||
port_cfg->param.param_size = PARAM_SIZE_AFE_PORT_CFG;
|
||||
port_cfg->param.reserved = 0;
|
||||
port_cfg->param.p_size.sr.param_size = PARAM_SIZE_AFE_PORT_CFG;
|
||||
port_cfg->param.p_size.sr.reserved = 0;
|
||||
port_cfg->minor_version = 1;
|
||||
port_cfg->bit_width = afe_cfg->bit_width;
|
||||
port_cfg->num_channels = afe_cfg->num_channels;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#define LISTEN_MAX_PERIOD_SIZE 4096
|
||||
#define LISTEN_MIN_PERIOD_SIZE 320
|
||||
#define LISTEN_MAX_STATUS_PAYLOAD_SIZE 256
|
||||
#define MSM_CPE_MAX_CUSTOM_PARAM_SIZE 2048
|
||||
|
||||
#define MSM_CPE_LAB_THREAD_TIMEOUT (3 * (HZ/10))
|
||||
|
||||
|
@ -1591,6 +1592,446 @@ static int msm_cpe_lsm_lab_start(struct snd_pcm_substream *substream,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool msm_cpe_lsm_is_valid_stream(struct snd_pcm_substream *substream,
|
||||
const char *func)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd;
|
||||
struct cpe_lsm_data *lsm_d = NULL;
|
||||
struct cpe_priv *cpe = NULL;
|
||||
struct cpe_lsm_session *session = NULL;
|
||||
struct wcd_cpe_lsm_ops *lsm_ops;
|
||||
|
||||
if (!substream || !substream->private_data) {
|
||||
pr_err("%s: invalid substream (%p)\n",
|
||||
func, substream);
|
||||
return false;
|
||||
}
|
||||
|
||||
rtd = substream->private_data;
|
||||
lsm_d = cpe_get_lsm_data(substream);
|
||||
cpe = cpe_get_private_data(substream);
|
||||
|
||||
if (!cpe || !cpe->core_handle) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: Invalid private data\n",
|
||||
func);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!lsm_d || !lsm_d->lsm_session) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: Invalid session data\n",
|
||||
func);
|
||||
return false;
|
||||
}
|
||||
|
||||
session = lsm_d->lsm_session;
|
||||
lsm_ops = &cpe->lsm_ops;
|
||||
|
||||
if (!lsm_ops) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: Invalid lsm_ops\n", func);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int msm_cpe_lsm_set_epd(struct snd_pcm_substream *substream,
|
||||
struct lsm_params_info *p_info)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd;
|
||||
struct cpe_lsm_data *lsm_d = NULL;
|
||||
struct cpe_priv *cpe = NULL;
|
||||
struct cpe_lsm_session *session = NULL;
|
||||
struct wcd_cpe_lsm_ops *lsm_ops;
|
||||
struct snd_lsm_ep_det_thres epd_thres;
|
||||
int rc;
|
||||
|
||||
if (!msm_cpe_lsm_is_valid_stream(substream, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
rtd = substream->private_data;
|
||||
lsm_d = cpe_get_lsm_data(substream);
|
||||
cpe = cpe_get_private_data(substream);
|
||||
session = lsm_d->lsm_session;
|
||||
lsm_ops = &cpe->lsm_ops;
|
||||
|
||||
if (p_info->param_size != sizeof(epd_thres)) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: Invalid param_size %d\n",
|
||||
__func__, p_info->param_size);
|
||||
rc = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (copy_from_user(&epd_thres, p_info->param_data,
|
||||
p_info->param_size)) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: copy_from_user failed, size = %d\n",
|
||||
__func__, p_info->param_size);
|
||||
rc = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = lsm_ops->lsm_set_one_param(cpe->core_handle,
|
||||
session, p_info, &epd_thres,
|
||||
LSM_ENDPOINT_DETECT_THRESHOLD);
|
||||
if (unlikely(rc))
|
||||
dev_err(rtd->dev,
|
||||
"%s: set_one_param(epd_threshold) failed, rc %d\n",
|
||||
__func__, rc);
|
||||
done:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_cpe_lsm_set_mode(struct snd_pcm_substream *substream,
|
||||
struct lsm_params_info *p_info)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd;
|
||||
struct cpe_lsm_data *lsm_d = NULL;
|
||||
struct cpe_priv *cpe = NULL;
|
||||
struct cpe_lsm_session *session = NULL;
|
||||
struct wcd_cpe_lsm_ops *lsm_ops;
|
||||
struct snd_lsm_detect_mode det_mode;
|
||||
int rc;
|
||||
|
||||
if (!msm_cpe_lsm_is_valid_stream(substream, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
rtd = substream->private_data;
|
||||
lsm_d = cpe_get_lsm_data(substream);
|
||||
cpe = cpe_get_private_data(substream);
|
||||
session = lsm_d->lsm_session;
|
||||
lsm_ops = &cpe->lsm_ops;
|
||||
|
||||
if (p_info->param_size != sizeof(det_mode)) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: Invalid param_size %d\n",
|
||||
__func__, p_info->param_size);
|
||||
rc = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (copy_from_user(&det_mode, p_info->param_data,
|
||||
p_info->param_size)) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: copy_from_user failed, size = %d\n",
|
||||
__func__, p_info->param_size);
|
||||
rc = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = lsm_ops->lsm_set_one_param(cpe->core_handle,
|
||||
session, p_info, &det_mode,
|
||||
LSM_OPERATION_MODE);
|
||||
if (unlikely(rc))
|
||||
dev_err(rtd->dev,
|
||||
"%s: set_one_param(epd_threshold) failed, rc %d\n",
|
||||
__func__, rc);
|
||||
done:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_cpe_lsm_set_gain(struct snd_pcm_substream *substream,
|
||||
struct lsm_params_info *p_info)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd;
|
||||
struct cpe_lsm_data *lsm_d = NULL;
|
||||
struct cpe_priv *cpe = NULL;
|
||||
struct cpe_lsm_session *session = NULL;
|
||||
struct wcd_cpe_lsm_ops *lsm_ops;
|
||||
struct snd_lsm_gain gain;
|
||||
int rc;
|
||||
|
||||
if (!msm_cpe_lsm_is_valid_stream(substream, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
rtd = substream->private_data;
|
||||
lsm_d = cpe_get_lsm_data(substream);
|
||||
cpe = cpe_get_private_data(substream);
|
||||
session = lsm_d->lsm_session;
|
||||
lsm_ops = &cpe->lsm_ops;
|
||||
|
||||
if (p_info->param_size != sizeof(gain)) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: Invalid param_size %d\n",
|
||||
__func__, p_info->param_size);
|
||||
rc = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (copy_from_user(&gain, p_info->param_data,
|
||||
p_info->param_size)) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: copy_from_user failed, size = %d\n",
|
||||
__func__, p_info->param_size);
|
||||
rc = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = lsm_ops->lsm_set_one_param(cpe->core_handle,
|
||||
session, p_info, &gain,
|
||||
LSM_GAIN);
|
||||
if (unlikely(rc))
|
||||
dev_err(rtd->dev,
|
||||
"%s: set_one_param(epd_threshold) failed, rc %d\n",
|
||||
__func__, rc);
|
||||
done:
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
static int msm_cpe_lsm_set_conf(struct snd_pcm_substream *substream,
|
||||
struct lsm_params_info *p_info)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd;
|
||||
struct cpe_lsm_data *lsm_d = NULL;
|
||||
struct cpe_priv *cpe = NULL;
|
||||
struct cpe_lsm_session *session = NULL;
|
||||
struct wcd_cpe_lsm_ops *lsm_ops;
|
||||
int rc;
|
||||
|
||||
if (!msm_cpe_lsm_is_valid_stream(substream, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
rtd = substream->private_data;
|
||||
lsm_d = cpe_get_lsm_data(substream);
|
||||
cpe = cpe_get_private_data(substream);
|
||||
session = lsm_d->lsm_session;
|
||||
lsm_ops = &cpe->lsm_ops;
|
||||
|
||||
session->num_confidence_levels =
|
||||
p_info->param_size;
|
||||
rc = msm_cpe_lsm_get_conf_levels(session,
|
||||
p_info->param_data);
|
||||
if (rc) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: get_conf_levels failed, err = %d\n",
|
||||
__func__, rc);
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = lsm_ops->lsm_set_one_param(cpe->core_handle,
|
||||
session, p_info, NULL,
|
||||
LSM_MIN_CONFIDENCE_LEVELS);
|
||||
if (unlikely(rc))
|
||||
dev_err(rtd->dev,
|
||||
"%s: set_one_param(conf_levels) failed, rc %d\n",
|
||||
__func__, rc);
|
||||
done:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_cpe_lsm_reg_model(struct snd_pcm_substream *substream,
|
||||
struct lsm_params_info *p_info)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd;
|
||||
struct cpe_lsm_data *lsm_d = NULL;
|
||||
struct cpe_priv *cpe = NULL;
|
||||
struct cpe_lsm_session *session = NULL;
|
||||
struct wcd_cpe_lsm_ops *lsm_ops;
|
||||
int rc;
|
||||
size_t offset;
|
||||
u8 *snd_model_ptr;
|
||||
|
||||
if (!msm_cpe_lsm_is_valid_stream(substream, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
rtd = substream->private_data;
|
||||
lsm_d = cpe_get_lsm_data(substream);
|
||||
cpe = cpe_get_private_data(substream);
|
||||
session = lsm_d->lsm_session;
|
||||
lsm_ops = &cpe->lsm_ops;
|
||||
|
||||
lsm_ops->lsm_get_snd_model_offset(cpe->core_handle,
|
||||
session, &offset);
|
||||
session->snd_model_size = p_info->param_size + offset;
|
||||
|
||||
session->snd_model_data = vzalloc(session->snd_model_size);
|
||||
if (!session->snd_model_data)
|
||||
return -ENOMEM;
|
||||
snd_model_ptr = ((u8 *) session->snd_model_data) + offset;
|
||||
|
||||
if (copy_from_user(snd_model_ptr,
|
||||
p_info->param_data, p_info->param_size)) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: copy_from_user for snd_model failed\n",
|
||||
__func__);
|
||||
rc = -EFAULT;
|
||||
goto free_snd_model_data;
|
||||
}
|
||||
|
||||
rc = lsm_ops->lsm_shmem_alloc(cpe->core_handle, session,
|
||||
session->snd_model_size);
|
||||
if (rc != 0) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: shared memory allocation failed, err = %d\n",
|
||||
__func__, rc);
|
||||
rc = -EINVAL;
|
||||
goto free_snd_model_data;
|
||||
}
|
||||
|
||||
rc = lsm_ops->lsm_set_one_param(cpe->core_handle,
|
||||
session, p_info, NULL,
|
||||
LSM_REG_SND_MODEL);
|
||||
if (unlikely(rc)) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: set_one_param(snd_model) failed, rc %d\n",
|
||||
__func__, rc);
|
||||
goto dealloc_shmem;
|
||||
}
|
||||
return 0;
|
||||
|
||||
dealloc_shmem:
|
||||
lsm_ops->lsm_shmem_dealloc(cpe->core_handle, session);
|
||||
|
||||
free_snd_model_data:
|
||||
vfree(session->snd_model_data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_cpe_lsm_dereg_model(struct snd_pcm_substream *substream,
|
||||
struct lsm_params_info *p_info)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd;
|
||||
struct cpe_lsm_data *lsm_d = NULL;
|
||||
struct cpe_priv *cpe = NULL;
|
||||
struct cpe_lsm_session *session = NULL;
|
||||
struct wcd_cpe_lsm_ops *lsm_ops;
|
||||
int rc;
|
||||
|
||||
if (!msm_cpe_lsm_is_valid_stream(substream, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
rtd = substream->private_data;
|
||||
lsm_d = cpe_get_lsm_data(substream);
|
||||
cpe = cpe_get_private_data(substream);
|
||||
session = lsm_d->lsm_session;
|
||||
lsm_ops = &cpe->lsm_ops;
|
||||
|
||||
rc = lsm_ops->lsm_set_one_param(cpe->core_handle,
|
||||
session, p_info, NULL,
|
||||
LSM_DEREG_SND_MODEL);
|
||||
if (rc)
|
||||
dev_err(rtd->dev,
|
||||
"%s: dereg_snd_model failed\n",
|
||||
__func__);
|
||||
return lsm_ops->lsm_shmem_dealloc(cpe->core_handle, session);
|
||||
}
|
||||
|
||||
static int msm_cpe_lsm_set_custom(struct snd_pcm_substream *substream,
|
||||
struct lsm_params_info *p_info)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd;
|
||||
struct cpe_lsm_data *lsm_d = NULL;
|
||||
struct cpe_priv *cpe = NULL;
|
||||
struct cpe_lsm_session *session = NULL;
|
||||
struct wcd_cpe_lsm_ops *lsm_ops;
|
||||
u8 *data;
|
||||
int rc;
|
||||
|
||||
if (!msm_cpe_lsm_is_valid_stream(substream, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
rtd = substream->private_data;
|
||||
lsm_d = cpe_get_lsm_data(substream);
|
||||
cpe = cpe_get_private_data(substream);
|
||||
session = lsm_d->lsm_session;
|
||||
lsm_ops = &cpe->lsm_ops;
|
||||
|
||||
if (p_info->param_size > MSM_CPE_MAX_CUSTOM_PARAM_SIZE) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: invalid size %d, max allowed %d\n",
|
||||
__func__, p_info->param_size,
|
||||
MSM_CPE_MAX_CUSTOM_PARAM_SIZE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data = kzalloc(p_info->param_size, GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
if (copy_from_user(data, p_info->param_data,
|
||||
p_info->param_size)) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: copy_from_user failed for custom params, size = %d\n",
|
||||
__func__, p_info->param_size);
|
||||
rc = -EFAULT;
|
||||
goto err_ret;
|
||||
}
|
||||
|
||||
rc = lsm_ops->lsm_set_one_param(cpe->core_handle,
|
||||
session, p_info, data,
|
||||
LSM_CUSTOM_PARAMS);
|
||||
if (rc)
|
||||
dev_err(rtd->dev,
|
||||
"%s: custom_params failed, err = %d\n",
|
||||
__func__, rc);
|
||||
err_ret:
|
||||
kfree(data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_cpe_lsm_process_params(struct snd_pcm_substream *substream,
|
||||
struct snd_lsm_module_params *p_data,
|
||||
void *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct lsm_params_info *p_info;
|
||||
int i;
|
||||
int rc = 0;
|
||||
|
||||
p_info = (struct lsm_params_info *) params;
|
||||
|
||||
for (i = 0; i < p_data->num_params; i++) {
|
||||
dev_dbg(rtd->dev,
|
||||
"%s: param (%d), module_id = 0x%x, param_id = 0x%x, param_size = 0x%x, param_type = 0x%x\n",
|
||||
__func__, i, p_info->module_id,
|
||||
p_info->param_id, p_info->param_size,
|
||||
p_info->param_type);
|
||||
|
||||
switch (p_info->param_type) {
|
||||
case LSM_ENDPOINT_DETECT_THRESHOLD:
|
||||
rc = msm_cpe_lsm_set_epd(substream, p_info);
|
||||
break;
|
||||
case LSM_OPERATION_MODE:
|
||||
rc = msm_cpe_lsm_set_mode(substream, p_info);
|
||||
break;
|
||||
case LSM_GAIN:
|
||||
rc = msm_cpe_lsm_set_gain(substream, p_info);
|
||||
break;
|
||||
case LSM_MIN_CONFIDENCE_LEVELS:
|
||||
rc = msm_cpe_lsm_set_conf(substream, p_info);
|
||||
break;
|
||||
case LSM_REG_SND_MODEL:
|
||||
rc = msm_cpe_lsm_reg_model(substream, p_info);
|
||||
break;
|
||||
case LSM_DEREG_SND_MODEL:
|
||||
rc = msm_cpe_lsm_dereg_model(substream, p_info);
|
||||
break;
|
||||
case LSM_CUSTOM_PARAMS:
|
||||
rc = msm_cpe_lsm_set_custom(substream, p_info);
|
||||
break;
|
||||
default:
|
||||
dev_err(rtd->dev,
|
||||
"%s: Invalid param_type %d\n",
|
||||
__func__, p_info->param_type);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
if (rc) {
|
||||
pr_err("%s: set_param fail for param_type %d\n",
|
||||
__func__, p_info->param_type);
|
||||
break;
|
||||
}
|
||||
|
||||
p_info++;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_cpe_lsm_ioctl(struct snd_pcm_substream *substream,
|
||||
unsigned int cmd, void *arg)
|
||||
{
|
||||
|
@ -1634,6 +2075,15 @@ static int msm_cpe_lsm_ioctl(struct snd_pcm_substream *substream,
|
|||
switch (cmd) {
|
||||
case SNDRV_LSM_REG_SND_MODEL_V2: {
|
||||
struct snd_lsm_sound_model_v2 snd_model;
|
||||
|
||||
if (session->is_topology_used) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: %s: not supported if using topology\n",
|
||||
__func__, "LSM_REG_SND_MODEL_V2");
|
||||
err = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (copy_from_user(&snd_model, (void *)arg,
|
||||
sizeof(struct snd_lsm_sound_model_v2))) {
|
||||
dev_err(rtd->dev,
|
||||
|
@ -1707,6 +2157,14 @@ static int msm_cpe_lsm_ioctl(struct snd_pcm_substream *substream,
|
|||
case SNDRV_LSM_SET_PARAMS: {
|
||||
struct snd_lsm_detection_params det_params;
|
||||
|
||||
if (session->is_topology_used) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: %s: not supported if using topology\n",
|
||||
__func__, "SNDRV_LSM_SET_PARAMS");
|
||||
err = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (copy_from_user(&det_params, (void *) arg,
|
||||
sizeof(det_params))) {
|
||||
dev_err(rtd->dev,
|
||||
|
@ -1721,6 +2179,81 @@ static int msm_cpe_lsm_ioctl(struct snd_pcm_substream *substream,
|
|||
&det_params);
|
||||
}
|
||||
break;
|
||||
|
||||
case SNDRV_LSM_SET_MODULE_PARAMS: {
|
||||
struct snd_lsm_module_params p_data;
|
||||
size_t p_size;
|
||||
u8 *params;
|
||||
|
||||
if (!session->is_topology_used) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: %s: not supported if not using topology\n",
|
||||
__func__, "SET_MODULE_PARAMS");
|
||||
err = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!arg) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: %s: No Param data to set\n",
|
||||
__func__, "SET_MODULE_PARAMS");
|
||||
err = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (copy_from_user(&p_data, arg,
|
||||
sizeof(p_data))) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: %s: copy_from_user failed, size = %zd\n",
|
||||
__func__, "p_data", sizeof(p_data));
|
||||
err = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (p_data.num_params > LSM_PARAMS_MAX) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: %s: Invalid num_params %d\n",
|
||||
__func__, "SET_MODULE_PARAMS",
|
||||
p_data.num_params);
|
||||
err = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
p_size = p_data.num_params *
|
||||
sizeof(struct lsm_params_info);
|
||||
|
||||
if (p_data.data_size != p_size) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: %s: Invalid size %zd\n",
|
||||
__func__, "SET_MODULE_PARAMS", p_size);
|
||||
err = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
params = kzalloc(p_size, GFP_KERNEL);
|
||||
if (!params) {
|
||||
err = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (copy_from_user(params, p_data.params,
|
||||
p_data.data_size)) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: %s: copy_from_user failed, size = %d\n",
|
||||
__func__, "params", p_data.data_size);
|
||||
kfree(params);
|
||||
err = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = msm_cpe_lsm_process_params(substream, &p_data, params);
|
||||
if (err)
|
||||
dev_err(rtd->dev,
|
||||
"%s: %s: Failed to set params, err = %d\n",
|
||||
__func__, "SET_MODULE_PARAMS", err);
|
||||
kfree(params);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
err = msm_cpe_lsm_ioctl_shared(substream, cmd, arg);
|
||||
break;
|
||||
|
@ -1755,6 +2288,20 @@ struct snd_lsm_detection_params_32 {
|
|||
bool detect_failure;
|
||||
};
|
||||
|
||||
struct lsm_params_info_32 {
|
||||
u32 module_id;
|
||||
u32 param_id;
|
||||
u32 param_size;
|
||||
compat_uptr_t param_data;
|
||||
enum LSM_PARAM_TYPE param_type;
|
||||
};
|
||||
|
||||
struct snd_lsm_module_params_32 {
|
||||
compat_uptr_t params;
|
||||
u32 num_params;
|
||||
u32 data_size;
|
||||
};
|
||||
|
||||
enum {
|
||||
SNDRV_LSM_EVENT_STATUS32 =
|
||||
_IOW('U', 0x02, struct snd_lsm_event_status32),
|
||||
|
@ -1762,6 +2309,8 @@ enum {
|
|||
_IOW('U', 0x07, struct snd_lsm_sound_model_v2_32),
|
||||
SNDRV_LSM_SET_PARAMS32 =
|
||||
_IOW('U', 0x0A, struct snd_lsm_detection_params_32),
|
||||
SNDRV_LSM_SET_MODULE_PARAMS_32 =
|
||||
_IOW('U', 0x0B, struct snd_lsm_module_params_32),
|
||||
};
|
||||
|
||||
static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream,
|
||||
|
@ -1809,6 +2358,14 @@ static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream,
|
|||
struct snd_lsm_sound_model_v2 snd_model;
|
||||
struct snd_lsm_sound_model_v2_32 snd_model32;
|
||||
|
||||
if (session->is_topology_used) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: %s: not supported if using topology\n",
|
||||
__func__, "LSM_REG_SND_MODEL_V2_32");
|
||||
err = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
dev_dbg(rtd->dev,
|
||||
"%s: ioctl %s\n", __func__,
|
||||
"SNDRV_LSM_REG_SND_MODEL_V2_32");
|
||||
|
@ -1932,6 +2489,15 @@ static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream,
|
|||
case SNDRV_LSM_SET_PARAMS32: {
|
||||
struct snd_lsm_detection_params_32 det_params32;
|
||||
struct snd_lsm_detection_params det_params;
|
||||
|
||||
if (session->is_topology_used) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: %s: not supported if using topology\n",
|
||||
__func__, "SNDRV_LSM_SET_PARAMS32");
|
||||
err = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (copy_from_user(&det_params32, arg,
|
||||
sizeof(det_params32))) {
|
||||
err = -EFAULT;
|
||||
|
@ -1960,6 +2526,115 @@ static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream,
|
|||
break;
|
||||
}
|
||||
|
||||
case SNDRV_LSM_SET_MODULE_PARAMS_32: {
|
||||
struct snd_lsm_module_params_32 p_data_32;
|
||||
struct snd_lsm_module_params p_data;
|
||||
u8 *params, *params32;
|
||||
size_t p_size;
|
||||
struct lsm_params_info_32 *p_info_32;
|
||||
struct lsm_params_info *p_info;
|
||||
int i;
|
||||
|
||||
if (!session->is_topology_used) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: %s: not supported if not using topology\n",
|
||||
__func__, "SET_MODULE_PARAMS_32");
|
||||
err = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!arg) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: %s: No Param data to set\n",
|
||||
__func__, "SET_MODULE_PARAMS_32");
|
||||
err = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (copy_from_user(&p_data_32, arg,
|
||||
sizeof(p_data_32))) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: %s: copy_from_user failed, size = %zd\n",
|
||||
__func__, "SET_MODULE_PARAMS_32",
|
||||
sizeof(p_data_32));
|
||||
err = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
p_data.params = compat_ptr(p_data_32.params);
|
||||
p_data.num_params = p_data_32.num_params;
|
||||
p_data.data_size = p_data_32.data_size;
|
||||
|
||||
if (p_data.num_params > LSM_PARAMS_MAX) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: %s: Invalid num_params %d\n",
|
||||
__func__, "SET_MODULE_PARAMS_32",
|
||||
p_data.num_params);
|
||||
err = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (p_data.data_size !=
|
||||
(p_data.num_params * sizeof(struct lsm_params_info_32))) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: %s: Invalid size %d\n",
|
||||
__func__, "SET_MODULE_PARAMS_32",
|
||||
p_data.data_size);
|
||||
err = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
p_size = sizeof(struct lsm_params_info_32) *
|
||||
p_data.num_params;
|
||||
|
||||
params32 = kzalloc(p_size, GFP_KERNEL);
|
||||
if (!params32) {
|
||||
err = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
p_size = sizeof(struct lsm_params_info) * p_data.num_params;
|
||||
params = kzalloc(p_size, GFP_KERNEL);
|
||||
if (!params) {
|
||||
kfree(params32);
|
||||
err = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (copy_from_user(params32, p_data.params,
|
||||
p_data.data_size)) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: %s: copy_from_user failed, size = %d\n",
|
||||
__func__, "params32", p_data.data_size);
|
||||
kfree(params32);
|
||||
kfree(params);
|
||||
err = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
p_info_32 = (struct lsm_params_info_32 *) params32;
|
||||
p_info = (struct lsm_params_info *) params;
|
||||
for (i = 0; i < p_data.num_params; i++) {
|
||||
p_info->module_id = p_info_32->module_id;
|
||||
p_info->param_id = p_info_32->param_id;
|
||||
p_info->param_size = p_info_32->param_size;
|
||||
p_info->param_data = compat_ptr(p_info_32->param_data);
|
||||
p_info->param_type = p_info_32->param_type;
|
||||
|
||||
p_info_32++;
|
||||
p_info++;
|
||||
}
|
||||
|
||||
err = msm_cpe_lsm_process_params(substream,
|
||||
&p_data, params);
|
||||
if (err)
|
||||
dev_err(rtd->dev,
|
||||
"%s: Failed to process params, err = %d\n",
|
||||
__func__, err);
|
||||
kfree(params);
|
||||
kfree(params32);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
err = msm_cpe_lsm_ioctl_shared(substream, cmd, arg);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue