Merge "ASoC: msm-cpe: Add timestamp support for lsm event status"

This commit is contained in:
Linux Build Service Account 2017-02-03 06:26:35 -08:00 committed by Gerrit - the friendly Code Review server
commit a8b7df01a1
2 changed files with 224 additions and 44 deletions

View file

@ -3044,25 +3044,9 @@ static int wcd_cpe_set_one_param(void *core_handle,
rc = wcd_cpe_send_param_epd_thres(core, session,
data, &ids);
break;
case LSM_OPERATION_MODE: {
struct cpe_lsm_ids connectport_ids;
rc = wcd_cpe_send_param_opmode(core, session,
data, &ids);
if (rc)
break;
connectport_ids.module_id = LSM_MODULE_ID_FRAMEWORK;
connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT;
rc = wcd_cpe_send_param_connectport(core, session, NULL,
&connectport_ids, CPE_AFE_PORT_1_TX);
if (rc)
dev_err(core->dev,
"%s: send_param_connectport failed, err %d\n",
__func__, rc);
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;

View file

@ -1049,7 +1049,6 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream,
struct cpe_lsm_lab *lab_d = &lsm_d->lab;
struct snd_dma_buffer *dma_buf = &substream->dma_buffer;
struct msm_slim_dma_data *dma_data = NULL;
struct snd_lsm_event_status *user;
struct snd_lsm_detection_params det_params;
int rc = 0;
@ -1318,11 +1317,20 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream,
break;
case SNDRV_LSM_EVENT_STATUS:
case SNDRV_LSM_EVENT_STATUS_V3: {
struct snd_lsm_event_status *user;
struct snd_lsm_event_status_v3 *user_v3;
dev_dbg(rtd->dev,
"%s: %s\n",
__func__, "SNDRV_LSM_EVENT_STATUS");
user = arg;
__func__, "SNDRV_LSM_EVENT_STATUS(_V3)");
if (!arg) {
dev_err(rtd->dev,
"%s: Invalid argument to ioctl %s\n",
__func__,
"SNDRV_LSM_EVENT_STATUS(_V3)");
return -EINVAL;
}
/*
* Release the api lock before wait to allow
@ -1343,31 +1351,62 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream,
if (atomic_read(&lsm_d->event_avail) == 1) {
rc = 0;
atomic_set(&lsm_d->event_avail, 0);
if (lsm_d->ev_det_pld_size >
user->payload_size) {
dev_err(rtd->dev,
"%s: avail pld_bytes = %u, needed = %u\n",
__func__,
user->payload_size,
lsm_d->ev_det_pld_size);
return -EINVAL;
if (cmd == SNDRV_LSM_EVENT_STATUS) {
user = arg;
if (lsm_d->ev_det_pld_size >
user->payload_size) {
dev_err(rtd->dev,
"%s: avail pld_bytes = %u, needed = %u\n",
__func__,
user->payload_size,
lsm_d->ev_det_pld_size);
return -EINVAL;
}
user->status = lsm_d->ev_det_status;
user->payload_size =
lsm_d->ev_det_pld_size;
memcpy(user->payload,
lsm_d->ev_det_payload,
lsm_d->ev_det_pld_size);
} else {
user_v3 = arg;
if (lsm_d->ev_det_pld_size >
user_v3->payload_size) {
dev_err(rtd->dev,
"%s: avail pld_bytes = %u, needed = %u\n",
__func__,
user_v3->payload_size,
lsm_d->ev_det_pld_size);
return -EINVAL;
}
/* event status timestamp not supported
* on CPE mode. Set msw and lsw to 0.
*/
user_v3->timestamp_lsw = 0;
user_v3->timestamp_msw = 0;
user_v3->status = lsm_d->ev_det_status;
user_v3->payload_size =
lsm_d->ev_det_pld_size;
memcpy(user_v3->payload,
lsm_d->ev_det_payload,
lsm_d->ev_det_pld_size);
}
user->status = lsm_d->ev_det_status;
user->payload_size = lsm_d->ev_det_pld_size;
memcpy(user->payload,
lsm_d->ev_det_payload,
lsm_d->ev_det_pld_size);
} else if (atomic_read(&lsm_d->event_stop) == 1) {
dev_dbg(rtd->dev,
"%s: wait_aborted\n", __func__);
user->payload_size = 0;
if (cmd == SNDRV_LSM_EVENT_STATUS) {
user = arg;
user->payload_size = 0;
} else {
user_v3 = arg;
user_v3->payload_size = 0;
}
rc = 0;
}
}
}
break;
case SNDRV_LSM_ABORT_EVENT:
@ -1499,6 +1538,20 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream,
}
break;
case SNDRV_LSM_SET_PORT: {
u32 port_id = cpe->input_port_id;
dev_dbg(rtd->dev, "%s: %s\n", __func__, "SNDRV_LSM_SET_PORT");
rc = lsm_ops->lsm_set_port(cpe->core_handle, session, &port_id);
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",
@ -1510,7 +1563,7 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream,
}
static int msm_cpe_lsm_lab_start(struct snd_pcm_substream *substream,
struct snd_lsm_event_status *event_status)
u16 event_det_status)
{
struct snd_soc_pcm_runtime *rtd;
struct cpe_lsm_data *lsm_d = NULL;
@ -1563,7 +1616,7 @@ static int msm_cpe_lsm_lab_start(struct snd_pcm_substream *substream,
reinit_completion(&lab_d->thread_complete);
if (session->lab_enable &&
event_status->status ==
event_det_status ==
LSM_VOICE_WAKEUP_STATUS_DETECTED) {
out_port = &session->afe_out_port_cfg;
out_port->port_id = session->afe_out_port_id;
@ -2167,7 +2220,60 @@ static int msm_cpe_lsm_ioctl(struct snd_pcm_substream *substream,
goto done;
}
msm_cpe_lsm_lab_start(substream, event_status);
msm_cpe_lsm_lab_start(substream, event_status->status);
msm_cpe_process_event_status_done(lsm_d);
kfree(event_status);
}
break;
case SNDRV_LSM_EVENT_STATUS_V3: {
struct snd_lsm_event_status_v3 u_event_status;
struct snd_lsm_event_status_v3 *event_status = NULL;
int u_pld_size = 0;
if (copy_from_user(&u_event_status, (void *)arg,
sizeof(struct snd_lsm_event_status_v3))) {
dev_err(rtd->dev,
"%s: event status copy from user failed, size %zd\n",
__func__,
sizeof(struct snd_lsm_event_status_v3));
err = -EFAULT;
goto done;
}
if (u_event_status.payload_size >
LISTEN_MAX_STATUS_PAYLOAD_SIZE) {
dev_err(rtd->dev,
"%s: payload_size %d is invalid, max allowed = %d\n",
__func__, u_event_status.payload_size,
LISTEN_MAX_STATUS_PAYLOAD_SIZE);
err = -EINVAL;
goto done;
}
u_pld_size = sizeof(struct snd_lsm_event_status_v3) +
u_event_status.payload_size;
event_status = kzalloc(u_pld_size, GFP_KERNEL);
if (!event_status) {
err = -ENOMEM;
goto done;
} else {
event_status->payload_size =
u_event_status.payload_size;
err = msm_cpe_lsm_ioctl_shared(substream,
cmd, event_status);
}
if (!err && copy_to_user(arg, event_status, u_pld_size)) {
dev_err(rtd->dev,
"%s: copy to user failed\n",
__func__);
kfree(event_status);
err = -EFAULT;
goto done;
}
msm_cpe_lsm_lab_start(substream, event_status->status);
msm_cpe_process_event_status_done(lsm_d);
kfree(event_status);
}
@ -2480,7 +2586,97 @@ static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream,
goto done;
}
msm_cpe_lsm_lab_start(substream, event_status);
msm_cpe_lsm_lab_start(substream, event_status->status);
msm_cpe_process_event_status_done(lsm_d);
kfree(event_status);
kfree(udata_32);
}
break;
case SNDRV_LSM_EVENT_STATUS_V3: {
struct snd_lsm_event_status_v3 *event_status = NULL;
struct snd_lsm_event_status_v3 u_event_status32;
struct snd_lsm_event_status_v3 *udata_32 = NULL;
int u_pld_size = 0;
dev_dbg(rtd->dev,
"%s: ioctl %s\n", __func__,
"SNDRV_LSM_EVENT_STATUS_V3_32");
if (copy_from_user(&u_event_status32, (void *)arg,
sizeof(struct snd_lsm_event_status_v3))) {
dev_err(rtd->dev,
"%s: event status copy from user failed, size %zd\n",
__func__,
sizeof(struct snd_lsm_event_status_v3));
err = -EFAULT;
goto done;
}
if (u_event_status32.payload_size >
LISTEN_MAX_STATUS_PAYLOAD_SIZE) {
dev_err(rtd->dev,
"%s: payload_size %d is invalid, max allowed = %d\n",
__func__, u_event_status32.payload_size,
LISTEN_MAX_STATUS_PAYLOAD_SIZE);
err = -EINVAL;
goto done;
}
u_pld_size = sizeof(struct snd_lsm_event_status_v3) +
u_event_status32.payload_size;
event_status = kzalloc(u_pld_size, GFP_KERNEL);
if (!event_status) {
dev_err(rtd->dev,
"%s: No memory for event status\n",
__func__);
err = -ENOMEM;
goto done;
} else {
event_status->payload_size =
u_event_status32.payload_size;
err = msm_cpe_lsm_ioctl_shared(substream,
cmd, event_status);
if (err)
dev_err(rtd->dev,
"%s: %s failed, error = %d\n",
__func__,
"SNDRV_LSM_EVENT_STATUS_V3_32",
err);
}
if (!err) {
udata_32 = kzalloc(u_pld_size, GFP_KERNEL);
if (!udata_32) {
dev_err(rtd->dev,
"%s: nomem for udata\n",
__func__);
err = -EFAULT;
} else {
udata_32->timestamp_lsw =
event_status->timestamp_lsw;
udata_32->timestamp_msw =
event_status->timestamp_msw;
udata_32->status = event_status->status;
udata_32->payload_size =
event_status->payload_size;
memcpy(udata_32->payload,
event_status->payload,
u_pld_size);
}
}
if (!err && copy_to_user(arg, udata_32,
u_pld_size)) {
dev_err(rtd->dev,
"%s: copy to user failed\n",
__func__);
kfree(event_status);
kfree(udata_32);
err = -EFAULT;
goto done;
}
msm_cpe_lsm_lab_start(substream, event_status->status);
msm_cpe_process_event_status_done(lsm_d);
kfree(event_status);
kfree(udata_32);