ASoC: msm-cpe-lsm: Add support for SVA device switch

Changes are to support device switch for SVA.
Also make changes to unblock pcm_read in case LAB is stopped.

Change-Id: I1e791159520389e3af2b361ff44e2b03a74a9f89
Signed-off-by: Chaithanya Krishna Bacharaju <chaithan@codeaurora.org>
This commit is contained in:
Chaithanya Krishna Bacharaju 2015-07-10 10:27:16 +05:30 committed by Gerrit - the friendly Code Review server
parent 3c0fcaf34d
commit b9ed0d9be0
4 changed files with 103 additions and 40 deletions

View file

@ -327,6 +327,7 @@ struct cpe_afe_svc_cmd_mode {
} __packed;
struct cpe_lsm_operation_mode {
struct cmi_hdr hdr;
struct cpe_param_data param;
u32 minor_version;
u16 mode;
@ -334,6 +335,7 @@ struct cpe_lsm_operation_mode {
} __packed;
struct cpe_lsm_connect_to_port {
struct cmi_hdr hdr;
struct cpe_param_data param;
u32 minor_version;
u16 afe_port_id;
@ -357,12 +359,6 @@ struct cpe_lsm_output_format_cfg {
u8 data_path_events;
} __packed;
struct cpe_lsm_params {
struct cmi_hdr hdr;
struct cpe_lsm_operation_mode op_mode;
struct cpe_lsm_connect_to_port connect_port;
} __packed;
struct cpe_lsm_lab_enable {
struct cpe_param_data param;
u16 enable;
@ -398,11 +394,11 @@ struct cpe_lsm_lab_latency_config {
#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 CPE_PARAM_PAYLOAD_SIZE (sizeof(struct cpe_lsm_params) - \
sizeof(struct cmi_hdr))
#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) - \

View file

@ -146,6 +146,9 @@ struct wcd_cpe_lsm_ops {
bool detect_failure);
int (*lsm_set_fmt_cfg)(void *core_handle,
struct cpe_lsm_session *session);
int (*lsm_set_port)(void *core_handle,
struct cpe_lsm_session *session);
};
int wcd_cpe_get_lsm_ops(struct wcd_cpe_lsm_ops *);

View file

@ -2241,36 +2241,38 @@ unlock_cal_mutex:
}
/*
* wcd_cpe_lsm_set_params: set the parameters for lsm service
* 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_params(
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)
{
struct cpe_lsm_params lsm_params;
struct cpe_lsm_operation_mode *op_mode = &lsm_params.op_mode;
struct cpe_lsm_connect_to_port *connect_port =
&lsm_params.connect_port;
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 = CPE_PARAM_PAYLOAD_SIZE;
u8 pld_size = 0;
ret = wcd_cpe_send_lsm_cal(core, session);
if (ret) {
pr_err("%s: fail to sent acdb cal, err = %d",
pr_err("%s: fail to sent acdb cal, err = %d\n",
__func__, ret);
return ret;
}
memset(&lsm_params, 0, sizeof(lsm_params));
memset(&op_mode, 0, sizeof(struct cpe_lsm_operation_mode));
if (fill_lsm_cmd_header_v0_inband(&lsm_params.hdr,
pld_size = (sizeof(struct cpe_lsm_operation_mode) -
sizeof(struct cmi_hdr));
if (fill_lsm_cmd_header_v0_inband(hdr,
session->id,
pld_size,
CPE_LSM_SESSION_CMD_SET_PARAMS)) {
@ -2278,37 +2280,84 @@ static int wcd_cpe_lsm_set_params(
goto err_ret;
}
op_mode->param.module_id = CPE_LSM_MODULE_ID_VOICE_WAKEUP;
op_mode->param.param_id = CPE_LSM_PARAM_ID_OPERATION_MODE;
op_mode->param.param_size = PARAM_SIZE_LSM_OP_MODE;
op_mode->param.reserved = 0;
op_mode->minor_version = 1;
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;
op_mode.minor_version = 1;
if (detect_mode == LSM_MODE_KEYWORD_ONLY_DETECTION)
op_mode->mode = 1;
op_mode.mode = 1;
else
op_mode->mode = 3;
op_mode.mode = 3;
if (detect_failure)
op_mode->mode |= 0x04;
op_mode.mode |= 0x04;
op_mode->reserved = 0;
op_mode.reserved = 0;
connect_port->param.module_id = CPE_LSM_MODULE_ID_VOICE_WAKEUP;
connect_port->param.param_id = CPE_LSM_PARAM_ID_CONNECT_TO_PORT;
connect_port->param.param_size = PARAM_SIZE_LSM_CONNECT_PORT;
connect_port->param.reserved = 0;
connect_port->minor_version = 1;
connect_port->afe_port_id = CPE_AFE_PORT_1_TX;
connect_port->reserved = 0;
ret = wcd_cpe_cmi_send_lsm_msg(core, session, &lsm_params);
ret = wcd_cpe_cmi_send_lsm_msg(core, session, &op_mode);
if (ret)
pr_err("%s: lsm_set_params failed, rc %dn",
pr_err("%s: lsm_set_opmode failed, rc %d\n",
__func__, ret);
err_ret:
return ret;
}
/*
* wcd_cpe_lsm_set_port: send the afe port connected
* @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)
{
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;
ret = wcd_cpe_is_valid_lsm_session(core, session,
__func__);
if (ret)
return ret;
WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm");
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,
session->id,
pld_size,
CPE_LSM_SESSION_CMD_SET_PARAMS)) {
ret = -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;
connect_port.minor_version = 1;
connect_port.afe_port_id = CPE_AFE_PORT_1_TX;
connect_port.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_REL_LOCK(&session->lsm_lock, "lsm");
return ret;
}
/*
* wcd_cpe_lsm_set_conf_levels: send the confidence levels for listen
* @core: handle to cpe core
@ -2378,7 +2427,7 @@ int wcd_cpe_lsm_set_data(void *core_handle,
WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm");
if (session->num_confidence_levels > 0) {
ret = wcd_cpe_lsm_set_params(core, session, detect_mode,
ret = wcd_cpe_lsm_set_opmode(core, session, detect_mode,
detect_failure);
if (ret) {
dev_err(core->dev,
@ -3009,6 +3058,7 @@ 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;
return 0;
}
EXPORT_SYMBOL(wcd_cpe_get_lsm_ops);

View file

@ -667,7 +667,7 @@ static int msm_cpe_lab_thread(void *data)
if (done_len ||
((!done_len) &&
lab_d->thread_status == MSM_LSM_LAB_THREAD_ERROR)) {
lab_d->thread_status != MSM_LSM_LAB_THREAD_RUNNING)) {
atomic_inc(&lab_d->in_count);
lab_d->dma_write += snd_pcm_lib_period_bytes(substream);
snd_pcm_period_elapsed(substream);
@ -1474,6 +1474,19 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream,
}
break;
case SNDRV_LSM_SET_PORT:
dev_dbg(rtd->dev,
"%s: %s\n",
__func__, "SNDRV_LSM_SET_PORT");
rc = lsm_ops->lsm_set_port(cpe->core_handle, session);
if (rc) {
dev_err(rtd->dev,
"%s: lsm_set_port failed, err = %d\n",
__func__, rc);
return rc;
}
break;
default:
dev_dbg(rtd->dev,
"%s: Default snd_lib_ioctl cmd 0x%x\n",
@ -1557,6 +1570,7 @@ static int msm_cpe_lsm_lab_start(struct snd_pcm_substream *substream,
}
atomic_set(&lab_d->abort_read, 0);
atomic_set(&lab_d->in_count, 0);
dev_dbg(rtd->dev,
"%s: KW detected, scheduling LAB thread\n",
__func__);
@ -2223,7 +2237,7 @@ static int msm_cpe_lsm_copy(struct snd_pcm_substream *substream, int a,
(2 * HZ));
if (atomic_read(&lab_d->abort_read)) {
pr_debug("%s: LSM LAB Abort read\n", __func__);
return -EIO;
return 0;
}
if (lab_d->thread_status != MSM_LSM_LAB_THREAD_RUNNING) {
pr_err("%s: Lab stopped\n", __func__);