Loading include/uapi/sound/lsm_params.h +28 −2 Original line number Diff line number Diff line #ifndef _UAPI_LSM_PARAMS_H__ #define _UAPI_LSM_PARAMS_H__ #define LSM_POLLING_ENABLE_SUPPORT #define LSM_EVENT_TIMESTAMP_MODE_SUPPORT #include <linux/types.h> #include <sound/asound.h> Loading @@ -18,6 +21,9 @@ #define LSM_OUT_TRANSFER_MODE_RT (0) #define LSM_OUT_TRANSFER_MODE_FTRT (1) #define LSM_EVENT_NON_TIME_STAMP_MODE (0) #define LSM_EVENT_TIME_STAMP_MODE (1) enum lsm_app_id { LSM_VOICE_WAKEUP_APP_ID = 1, LSM_VOICE_WAKEUP_APP_ID_V2 = 2, Loading @@ -43,8 +49,7 @@ enum LSM_PARAM_TYPE { LSM_REG_SND_MODEL, LSM_DEREG_SND_MODEL, LSM_CUSTOM_PARAMS, /* driver ioctl will parse only so many params */ LSM_PARAMS_MAX, LSM_POLLING_ENABLE, }; /* Loading Loading @@ -75,6 +80,14 @@ struct snd_lsm_gain { __u16 gain; }; /* * Data for LSM_POLLING_ENABLE param_type * @poll_en: Polling enable or disable */ struct snd_lsm_poll_enable { bool poll_en; }; struct snd_lsm_sound_model_v2 { __u8 __user *data; Loading @@ -95,11 +108,20 @@ struct snd_lsm_event_status { __u8 payload[0]; }; struct snd_lsm_event_status_v3 { __u32 timestamp_lsw; __u32 timestamp_msw; __u16 status; __u16 payload_size; __u8 payload[0]; }; struct snd_lsm_detection_params { __u8 *conf_level; enum lsm_detection_mode detect_mode; __u8 num_confidence_levels; bool detect_failure; bool poll_enable; }; /* Loading Loading @@ -171,5 +193,9 @@ struct snd_lsm_output_format_cfg { struct snd_lsm_module_params) #define SNDRV_LSM_OUT_FORMAT_CFG _IOW('U', 0x0C, \ struct snd_lsm_output_format_cfg) #define SNDRV_LSM_SET_PORT _IO('U', 0x0D) #define SNDRV_LSM_SET_FWK_MODE_CONFIG _IOW('U', 0x0E, uint32_t) #define SNDRV_LSM_EVENT_STATUS_V3 _IOW('U', 0x0F, \ struct snd_lsm_event_status_v3) #endif sound/soc/codecs/wcd_cpe_core.c +2 −18 Original line number Diff line number Diff line Loading @@ -3051,25 +3051,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) case LSM_OPERATION_MODE: rc = wcd_cpe_send_param_opmode(core, session, data, &ids); 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); break; } case LSM_GAIN: rc = wcd_cpe_send_param_gain(core, session, data, &ids); break; Loading sound/soc/msm/msm-cpe-lsm.c +233 −27 Original line number Diff line number Diff line Loading @@ -43,6 +43,12 @@ #define MSM_CPE_LAB_THREAD_TIMEOUT (3 * (HZ/10)) /* * Driver ioctl will parse only so many params * size of LSM_PARAMS_MAX is last LSM_PARAM_TYPE + 1 */ #define LSM_PARAMS_MAX (LSM_POLLING_ENABLE + 1) #define MSM_CPE_LSM_GRAB_LOCK(lock, name) \ { \ pr_debug("%s: %s lock acquire\n", \ Loading Loading @@ -1060,7 +1066,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; Loading Loading @@ -1336,19 +1341,21 @@ 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"); __func__, "SNDRV_LSM_EVENT_STATUS(_V3)"); if (!arg) { dev_err(rtd->dev, "%s: Invalid argument to ioctl %s\n", __func__, "SNDRV_LSM_EVENT_STATUS"); "SNDRV_LSM_EVENT_STATUS(_V3)"); return -EINVAL; } user = arg; /* * Release the api lock before wait to allow * other IOCTLs to be invoked while waiting Loading @@ -1368,6 +1375,9 @@ 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 (cmd == SNDRV_LSM_EVENT_STATUS) { user = arg; if (lsm_d->ev_det_pld_size > user->payload_size) { dev_err(rtd->dev, Loading @@ -1379,20 +1389,48 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream, } user->status = lsm_d->ev_det_status; user->payload_size = lsm_d->ev_det_pld_size; 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); } } else if (atomic_read(&lsm_d->event_stop) == 1) { dev_dbg(rtd->dev, "%s: wait_aborted\n", __func__); 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: Loading Loading @@ -1530,6 +1568,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", Loading @@ -1541,7 +1593,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; Loading Loading @@ -1594,7 +1646,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; Loading Loading @@ -2191,7 +2243,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); } Loading Loading @@ -2306,6 +2411,14 @@ struct snd_lsm_event_status32 { u8 payload[0]; }; struct snd_lsm_event_status_v3_32 { u32 timestamp_lsw; u32 timestamp_msw; u16 status; u16 payload_size; u8 payload[0]; }; struct snd_lsm_sound_model_v2_32 { compat_uptr_t data; compat_uptr_t confidence_level; Loading Loading @@ -2345,6 +2458,8 @@ enum { _IOW('U', 0x0A, struct snd_lsm_detection_params_32), SNDRV_LSM_SET_MODULE_PARAMS_32 = _IOW('U', 0x0B, struct snd_lsm_module_params_32), SNDRV_LSM_EVENT_STATUS_V3_32 = _IOW('U', 0x0F, struct snd_lsm_event_status_v3_32), }; static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream, Loading Loading @@ -2513,7 +2628,98 @@ 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_32: { struct snd_lsm_event_status_v3 *event_status = NULL; struct snd_lsm_event_status_v3_32 u_event_status32; struct snd_lsm_event_status_v3_32 *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; cmd = SNDRV_LSM_EVENT_STATUS_V3; 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); Loading sound/soc/msm/qdsp6v2/msm-lsm-client.c +6 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,12 @@ #define LAB_BUFFER_ALLOC 1 #define LAB_BUFFER_DEALLOC 0 /* * Driver ioctl will parse only so many params * size of LSM_PARAMS_MAX is last LSM_PARAM_TYPE + 1 */ #define LSM_PARAMS_MAX (LSM_POLLING_ENABLE + 1) static struct snd_pcm_hardware msm_pcm_hardware_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BLOCK_TRANSFER | Loading Loading
include/uapi/sound/lsm_params.h +28 −2 Original line number Diff line number Diff line #ifndef _UAPI_LSM_PARAMS_H__ #define _UAPI_LSM_PARAMS_H__ #define LSM_POLLING_ENABLE_SUPPORT #define LSM_EVENT_TIMESTAMP_MODE_SUPPORT #include <linux/types.h> #include <sound/asound.h> Loading @@ -18,6 +21,9 @@ #define LSM_OUT_TRANSFER_MODE_RT (0) #define LSM_OUT_TRANSFER_MODE_FTRT (1) #define LSM_EVENT_NON_TIME_STAMP_MODE (0) #define LSM_EVENT_TIME_STAMP_MODE (1) enum lsm_app_id { LSM_VOICE_WAKEUP_APP_ID = 1, LSM_VOICE_WAKEUP_APP_ID_V2 = 2, Loading @@ -43,8 +49,7 @@ enum LSM_PARAM_TYPE { LSM_REG_SND_MODEL, LSM_DEREG_SND_MODEL, LSM_CUSTOM_PARAMS, /* driver ioctl will parse only so many params */ LSM_PARAMS_MAX, LSM_POLLING_ENABLE, }; /* Loading Loading @@ -75,6 +80,14 @@ struct snd_lsm_gain { __u16 gain; }; /* * Data for LSM_POLLING_ENABLE param_type * @poll_en: Polling enable or disable */ struct snd_lsm_poll_enable { bool poll_en; }; struct snd_lsm_sound_model_v2 { __u8 __user *data; Loading @@ -95,11 +108,20 @@ struct snd_lsm_event_status { __u8 payload[0]; }; struct snd_lsm_event_status_v3 { __u32 timestamp_lsw; __u32 timestamp_msw; __u16 status; __u16 payload_size; __u8 payload[0]; }; struct snd_lsm_detection_params { __u8 *conf_level; enum lsm_detection_mode detect_mode; __u8 num_confidence_levels; bool detect_failure; bool poll_enable; }; /* Loading Loading @@ -171,5 +193,9 @@ struct snd_lsm_output_format_cfg { struct snd_lsm_module_params) #define SNDRV_LSM_OUT_FORMAT_CFG _IOW('U', 0x0C, \ struct snd_lsm_output_format_cfg) #define SNDRV_LSM_SET_PORT _IO('U', 0x0D) #define SNDRV_LSM_SET_FWK_MODE_CONFIG _IOW('U', 0x0E, uint32_t) #define SNDRV_LSM_EVENT_STATUS_V3 _IOW('U', 0x0F, \ struct snd_lsm_event_status_v3) #endif
sound/soc/codecs/wcd_cpe_core.c +2 −18 Original line number Diff line number Diff line Loading @@ -3051,25 +3051,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) case LSM_OPERATION_MODE: rc = wcd_cpe_send_param_opmode(core, session, data, &ids); 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); break; } case LSM_GAIN: rc = wcd_cpe_send_param_gain(core, session, data, &ids); break; Loading
sound/soc/msm/msm-cpe-lsm.c +233 −27 Original line number Diff line number Diff line Loading @@ -43,6 +43,12 @@ #define MSM_CPE_LAB_THREAD_TIMEOUT (3 * (HZ/10)) /* * Driver ioctl will parse only so many params * size of LSM_PARAMS_MAX is last LSM_PARAM_TYPE + 1 */ #define LSM_PARAMS_MAX (LSM_POLLING_ENABLE + 1) #define MSM_CPE_LSM_GRAB_LOCK(lock, name) \ { \ pr_debug("%s: %s lock acquire\n", \ Loading Loading @@ -1060,7 +1066,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; Loading Loading @@ -1336,19 +1341,21 @@ 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"); __func__, "SNDRV_LSM_EVENT_STATUS(_V3)"); if (!arg) { dev_err(rtd->dev, "%s: Invalid argument to ioctl %s\n", __func__, "SNDRV_LSM_EVENT_STATUS"); "SNDRV_LSM_EVENT_STATUS(_V3)"); return -EINVAL; } user = arg; /* * Release the api lock before wait to allow * other IOCTLs to be invoked while waiting Loading @@ -1368,6 +1375,9 @@ 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 (cmd == SNDRV_LSM_EVENT_STATUS) { user = arg; if (lsm_d->ev_det_pld_size > user->payload_size) { dev_err(rtd->dev, Loading @@ -1379,20 +1389,48 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream, } user->status = lsm_d->ev_det_status; user->payload_size = lsm_d->ev_det_pld_size; 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); } } else if (atomic_read(&lsm_d->event_stop) == 1) { dev_dbg(rtd->dev, "%s: wait_aborted\n", __func__); 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: Loading Loading @@ -1530,6 +1568,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", Loading @@ -1541,7 +1593,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; Loading Loading @@ -1594,7 +1646,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; Loading Loading @@ -2191,7 +2243,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); } Loading Loading @@ -2306,6 +2411,14 @@ struct snd_lsm_event_status32 { u8 payload[0]; }; struct snd_lsm_event_status_v3_32 { u32 timestamp_lsw; u32 timestamp_msw; u16 status; u16 payload_size; u8 payload[0]; }; struct snd_lsm_sound_model_v2_32 { compat_uptr_t data; compat_uptr_t confidence_level; Loading Loading @@ -2345,6 +2458,8 @@ enum { _IOW('U', 0x0A, struct snd_lsm_detection_params_32), SNDRV_LSM_SET_MODULE_PARAMS_32 = _IOW('U', 0x0B, struct snd_lsm_module_params_32), SNDRV_LSM_EVENT_STATUS_V3_32 = _IOW('U', 0x0F, struct snd_lsm_event_status_v3_32), }; static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream, Loading Loading @@ -2513,7 +2628,98 @@ 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_32: { struct snd_lsm_event_status_v3 *event_status = NULL; struct snd_lsm_event_status_v3_32 u_event_status32; struct snd_lsm_event_status_v3_32 *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; cmd = SNDRV_LSM_EVENT_STATUS_V3; 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); Loading
sound/soc/msm/qdsp6v2/msm-lsm-client.c +6 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,12 @@ #define LAB_BUFFER_ALLOC 1 #define LAB_BUFFER_DEALLOC 0 /* * Driver ioctl will parse only so many params * size of LSM_PARAMS_MAX is last LSM_PARAM_TYPE + 1 */ #define LSM_PARAMS_MAX (LSM_POLLING_ENABLE + 1) static struct snd_pcm_hardware msm_pcm_hardware_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BLOCK_TRANSFER | Loading