^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);