Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a8b7df01 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

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

parents 25c4cbcf a5fc56e6
Loading
Loading
Loading
Loading
+2 −18
Original line number Diff line number Diff line
@@ -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)
	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;
+222 −26
Original line number Diff line number Diff line
@@ -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,6 +1351,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,
@@ -1354,20 +1365,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:
@@ -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);