Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) // This file is provided under a dual BSD/GPLv2 license.  When using or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) // redistributing this file, you may do so under either license.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) // Copyright(c) 2019-2020 Intel Corporation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) // Author: Cezary Rojewski <cezary.rojewski@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include "sof-priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include "probe.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * sof_ipc_probe_init - initialize data probing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * @sdev:		SOF sound device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * @stream_tag:		Extractor stream tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * @buffer_size:	DMA buffer size to set for extractor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * Host chooses whether extraction is supported or not by providing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * valid stream tag to DSP. Once specified, stream described by that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * tag will be tied to DSP for extraction for the entire lifetime of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * probe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * Probing is initialized only once and each INIT request must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * matched by DEINIT call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) int sof_ipc_probe_init(struct snd_sof_dev *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 		u32 stream_tag, size_t buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	struct sof_ipc_probe_dma_add_params *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	struct sof_ipc_reply reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	size_t size = struct_size(msg, dma, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	msg = kmalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	msg->hdr.size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	msg->hdr.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	msg->num_elems = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	msg->dma[0].stream_tag = stream_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	msg->dma[0].dma_buffer_size = buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	ret = sof_ipc_tx_message(sdev->ipc, msg->hdr.cmd, msg, msg->hdr.size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 			&reply, sizeof(reply));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	kfree(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) EXPORT_SYMBOL(sof_ipc_probe_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * sof_ipc_probe_deinit - cleanup after data probing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * @sdev:	SOF sound device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  * Host sends DEINIT request to free previously initialized probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  * on DSP side once it is no longer needed. DEINIT only when there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  * are no probes connected and with all injectors detached.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) int sof_ipc_probe_deinit(struct snd_sof_dev *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	struct sof_ipc_cmd_hdr msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	struct sof_ipc_reply reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	msg.size = sizeof(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	msg.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_DEINIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	return sof_ipc_tx_message(sdev->ipc, msg.cmd, &msg, msg.size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 			&reply, sizeof(reply));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) EXPORT_SYMBOL(sof_ipc_probe_deinit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) static int sof_ipc_probe_info(struct snd_sof_dev *sdev, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		void **params, size_t *num_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	struct sof_ipc_probe_info_params msg = {{{0}}};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	struct sof_ipc_probe_info_params *reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	size_t bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	*params = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	*num_params = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	reply = kzalloc(SOF_IPC_MSG_MAX_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	if (!reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	msg.rhdr.hdr.size = sizeof(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	msg.rhdr.hdr.cmd = SOF_IPC_GLB_PROBE | cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	ret = sof_ipc_tx_message(sdev->ipc, msg.rhdr.hdr.cmd, &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 			msg.rhdr.hdr.size, reply, SOF_IPC_MSG_MAX_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	if (ret < 0 || reply->rhdr.error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	if (!reply->num_elems)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	if (cmd == SOF_IPC_PROBE_DMA_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		bytes = sizeof(reply->dma[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		bytes = sizeof(reply->desc[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	bytes *= reply->num_elems;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	*params = kmemdup(&reply->dma[0], bytes, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	if (!*params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	*num_params = reply->num_elems;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	kfree(reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)  * sof_ipc_probe_dma_info - retrieve list of active injection dmas
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)  * @sdev:	SOF sound device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  * @dma:	Returned list of active dmas
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)  * @num_dma:	Returned count of active dmas
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  * Host sends DMA_INFO request to obtain list of injection dmas it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  * can use to transfer data over with.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * Note that list contains only injection dmas as there is only one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  * extractor (dma) and it is always assigned on probing init.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  * DSP knows exactly where data from extraction probes is going to,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  * which is not the case for injection where multiple streams
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  * could be engaged.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) int sof_ipc_probe_dma_info(struct snd_sof_dev *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		struct sof_probe_dma **dma, size_t *num_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	return sof_ipc_probe_info(sdev, SOF_IPC_PROBE_DMA_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 			(void **)dma, num_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) EXPORT_SYMBOL(sof_ipc_probe_dma_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  * sof_ipc_probe_dma_add - attach to specified dmas
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  * @sdev:	SOF sound device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * @dma:	List of streams (dmas) to attach to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  * @num_dma:	Number of elements in @dma
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  * Contrary to extraction, injection streams are never assigned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  * on init. Before attempting any data injection, host is responsible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  * for specifying streams which will be later used to transfer data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  * to connected probe points.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int sof_ipc_probe_dma_add(struct snd_sof_dev *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		struct sof_probe_dma *dma, size_t num_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	struct sof_ipc_probe_dma_add_params *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	struct sof_ipc_reply reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	size_t size = struct_size(msg, dma, num_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	msg = kmalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	msg->hdr.size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	msg->num_elems = num_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	msg->hdr.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_DMA_ADD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	memcpy(&msg->dma[0], dma, size - sizeof(*msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	ret = sof_ipc_tx_message(sdev->ipc, msg->hdr.cmd, msg, msg->hdr.size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			&reply, sizeof(reply));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	kfree(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) EXPORT_SYMBOL(sof_ipc_probe_dma_add);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  * sof_ipc_probe_dma_remove - detach from specified dmas
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  * @sdev:		SOF sound device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  * @stream_tag:		List of stream tags to detach from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)  * @num_stream_tag:	Number of elements in @stream_tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  * Host sends DMA_REMOVE request to free previously attached stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)  * from being occupied for injection. Each detach operation should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)  * match equivalent DMA_ADD. Detach only when all probes tied to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  * given stream have been disconnected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) int sof_ipc_probe_dma_remove(struct snd_sof_dev *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		unsigned int *stream_tag, size_t num_stream_tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	struct sof_ipc_probe_dma_remove_params *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	struct sof_ipc_reply reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	size_t size = struct_size(msg, stream_tag, num_stream_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	msg = kmalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	msg->hdr.size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	msg->num_elems = num_stream_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	msg->hdr.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_DMA_REMOVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	memcpy(&msg->stream_tag[0], stream_tag, size - sizeof(*msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	ret = sof_ipc_tx_message(sdev->ipc, msg->hdr.cmd, msg, msg->hdr.size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 			&reply, sizeof(reply));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	kfree(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) EXPORT_SYMBOL(sof_ipc_probe_dma_remove);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)  * sof_ipc_probe_points_info - retrieve list of active probe points
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)  * @sdev:	SOF sound device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)  * @desc:	Returned list of active probes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)  * @num_desc:	Returned count of active probes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)  * Host sends PROBE_POINT_INFO request to obtain list of active probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  * points, valid for disconnection when given probe is no longer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  * required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) int sof_ipc_probe_points_info(struct snd_sof_dev *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		struct sof_probe_point_desc **desc, size_t *num_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	return sof_ipc_probe_info(sdev, SOF_IPC_PROBE_POINT_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 				 (void **)desc, num_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) EXPORT_SYMBOL(sof_ipc_probe_points_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)  * sof_ipc_probe_points_add - connect specified probes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)  * @sdev:	SOF sound device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)  * @desc:	List of probe points to connect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)  * @num_desc:	Number of elements in @desc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)  * Dynamically connects to provided set of endpoints. Immediately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)  * after connection is established, host must be prepared to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)  * transfer data from or to target stream given the probing purpose.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)  * Each probe point should be removed using PROBE_POINT_REMOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)  * request when no longer needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) int sof_ipc_probe_points_add(struct snd_sof_dev *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		struct sof_probe_point_desc *desc, size_t num_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	struct sof_ipc_probe_point_add_params *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	struct sof_ipc_reply reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	size_t size = struct_size(msg, desc, num_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	msg = kmalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	msg->hdr.size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	msg->num_elems = num_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	msg->hdr.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_POINT_ADD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	memcpy(&msg->desc[0], desc, size - sizeof(*msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	ret = sof_ipc_tx_message(sdev->ipc, msg->hdr.cmd, msg, msg->hdr.size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 			&reply, sizeof(reply));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	kfree(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) EXPORT_SYMBOL(sof_ipc_probe_points_add);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)  * sof_ipc_probe_points_remove - disconnect specified probes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)  * @sdev:		SOF sound device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)  * @buffer_id:		List of probe points to disconnect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)  * @num_buffer_id:	Number of elements in @desc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)  * Removes previously connected probes from list of active probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)  * points and frees all resources on DSP side.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int sof_ipc_probe_points_remove(struct snd_sof_dev *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		unsigned int *buffer_id, size_t num_buffer_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	struct sof_ipc_probe_point_remove_params *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	struct sof_ipc_reply reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	size_t size = struct_size(msg, buffer_id, num_buffer_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	msg = kmalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	msg->hdr.size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	msg->num_elems = num_buffer_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	msg->hdr.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_POINT_REMOVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	memcpy(&msg->buffer_id[0], buffer_id, size - sizeof(*msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	ret = sof_ipc_tx_message(sdev->ipc, msg->hdr.cmd, msg, msg->hdr.size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 			&reply, sizeof(reply));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	kfree(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) EXPORT_SYMBOL(sof_ipc_probe_points_remove);