ASoC: SOF: probe: Merge and clean up the probe and compress files
The probe debug functionality is implemented via compress support and it was spread across two set of files: probe.c/h compress.c/h Merge the two files into sof-probes.s/h and clean them up by removing unused struct definitions, functions. We can also move most of the functions static as they are only used internally. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Link: https://lore.kernel.org/r/20210916103211.1573-5-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Родитель
2dc51106cc
Коммит
7bbdda8009
|
@ -2,7 +2,8 @@
|
|||
|
||||
snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\
|
||||
control.o trace.o utils.o sof-audio.o
|
||||
snd-sof-$(CONFIG_SND_SOC_SOF_DEBUG_PROBES) += probe.o compress.o
|
||||
|
||||
snd-sof-$(CONFIG_SND_SOC_SOF_DEBUG_PROBES) += sof-probes.o
|
||||
|
||||
snd-sof-pci-objs := sof-pci-dev.o
|
||||
snd-sof-acpi-objs := sof-acpi-dev.o
|
||||
|
|
|
@ -1,152 +0,0 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
|
||||
//
|
||||
// This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
// redistributing this file, you may do so under either license.
|
||||
//
|
||||
// Copyright(c) 2019-2020 Intel Corporation. All rights reserved.
|
||||
//
|
||||
// Author: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
//
|
||||
|
||||
#include <sound/soc.h>
|
||||
#include "compress.h"
|
||||
#include "ops.h"
|
||||
#include "probe.h"
|
||||
|
||||
static int sof_probe_compr_open(struct snd_compr_stream *cstream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_sof_dev *sdev =
|
||||
snd_soc_component_get_drvdata(dai->component);
|
||||
int ret;
|
||||
|
||||
ret = snd_sof_probe_compr_assign(sdev, cstream, dai);
|
||||
if (ret < 0) {
|
||||
dev_err(dai->dev, "Failed to assign probe stream: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sdev->extractor_stream_tag = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sof_probe_compr_free(struct snd_compr_stream *cstream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_sof_dev *sdev =
|
||||
snd_soc_component_get_drvdata(dai->component);
|
||||
struct sof_probe_point_desc *desc;
|
||||
size_t num_desc;
|
||||
int i, ret;
|
||||
|
||||
/* disconnect all probe points */
|
||||
ret = sof_ipc_probe_points_info(sdev, &desc, &num_desc);
|
||||
if (ret < 0) {
|
||||
dev_err(dai->dev, "Failed to get probe points: %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_desc; i++)
|
||||
sof_ipc_probe_points_remove(sdev, &desc[i].buffer_id, 1);
|
||||
kfree(desc);
|
||||
|
||||
exit:
|
||||
ret = sof_ipc_probe_deinit(sdev);
|
||||
if (ret < 0)
|
||||
dev_err(dai->dev, "Failed to deinit probe: %d\n", ret);
|
||||
|
||||
sdev->extractor_stream_tag = SOF_PROBE_INVALID_NODE_ID;
|
||||
snd_compr_free_pages(cstream);
|
||||
|
||||
return snd_sof_probe_compr_free(sdev, cstream, dai);
|
||||
}
|
||||
|
||||
static int sof_probe_compr_set_params(struct snd_compr_stream *cstream,
|
||||
struct snd_compr_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_compr_runtime *rtd = cstream->runtime;
|
||||
struct snd_sof_dev *sdev =
|
||||
snd_soc_component_get_drvdata(dai->component);
|
||||
int ret;
|
||||
|
||||
cstream->dma_buffer.dev.type = SNDRV_DMA_TYPE_DEV_SG;
|
||||
cstream->dma_buffer.dev.dev = sdev->dev;
|
||||
ret = snd_compr_malloc_pages(cstream, rtd->buffer_size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = snd_sof_probe_compr_set_params(sdev, cstream, params, dai);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = sof_ipc_probe_init(sdev, sdev->extractor_stream_tag,
|
||||
rtd->dma_bytes);
|
||||
if (ret < 0) {
|
||||
dev_err(dai->dev, "Failed to init probe: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sof_probe_compr_trigger(struct snd_compr_stream *cstream, int cmd,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_sof_dev *sdev =
|
||||
snd_soc_component_get_drvdata(dai->component);
|
||||
|
||||
return snd_sof_probe_compr_trigger(sdev, cstream, cmd, dai);
|
||||
}
|
||||
|
||||
static int sof_probe_compr_pointer(struct snd_compr_stream *cstream,
|
||||
struct snd_compr_tstamp *tstamp,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_sof_dev *sdev =
|
||||
snd_soc_component_get_drvdata(dai->component);
|
||||
|
||||
return snd_sof_probe_compr_pointer(sdev, cstream, tstamp, dai);
|
||||
}
|
||||
|
||||
struct snd_soc_cdai_ops sof_probe_compr_ops = {
|
||||
.startup = sof_probe_compr_open,
|
||||
.shutdown = sof_probe_compr_free,
|
||||
.set_params = sof_probe_compr_set_params,
|
||||
.trigger = sof_probe_compr_trigger,
|
||||
.pointer = sof_probe_compr_pointer,
|
||||
};
|
||||
EXPORT_SYMBOL(sof_probe_compr_ops);
|
||||
|
||||
static int sof_probe_compr_copy(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *cstream,
|
||||
char __user *buf, size_t count)
|
||||
{
|
||||
struct snd_compr_runtime *rtd = cstream->runtime;
|
||||
unsigned int offset, n;
|
||||
void *ptr;
|
||||
int ret;
|
||||
|
||||
if (count > rtd->buffer_size)
|
||||
count = rtd->buffer_size;
|
||||
|
||||
div_u64_rem(rtd->total_bytes_transferred, rtd->buffer_size, &offset);
|
||||
ptr = rtd->dma_area + offset;
|
||||
n = rtd->buffer_size - offset;
|
||||
|
||||
if (count < n) {
|
||||
ret = copy_to_user(buf, ptr, count);
|
||||
} else {
|
||||
ret = copy_to_user(buf, ptr, n);
|
||||
ret += copy_to_user(buf + n, rtd->dma_area, count - n);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return count - ret;
|
||||
return count;
|
||||
}
|
||||
|
||||
const struct snd_compress_ops sof_probe_compressed_ops = {
|
||||
.copy = sof_probe_compr_copy,
|
||||
};
|
||||
EXPORT_SYMBOL(sof_probe_compressed_ops);
|
|
@ -1,19 +0,0 @@
|
|||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
|
||||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* Copyright(c) 2019-2020 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Author: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __SOF_COMPRESS_H
|
||||
#define __SOF_COMPRESS_H
|
||||
|
||||
#include <sound/compress_driver.h>
|
||||
|
||||
extern struct snd_soc_cdai_ops sof_probe_compr_ops;
|
||||
extern const struct snd_compress_ops sof_probe_compressed_ops;
|
||||
|
||||
#endif
|
|
@ -15,7 +15,7 @@
|
|||
#include "sof-priv.h"
|
||||
#include "ops.h"
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
|
||||
#include "probe.h"
|
||||
#include "sof-probes.h"
|
||||
#endif
|
||||
|
||||
/* see SOF_DBG_ flags */
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "ops.h"
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
|
||||
#include "probe.h"
|
||||
#include "sof-probes.h"
|
||||
|
||||
/**
|
||||
* strsplit_u32 - Split string into sequence of u32 tokens
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
|
||||
#include "../compress.h"
|
||||
#include "../sof-probes.h"
|
||||
#endif
|
||||
|
||||
struct hda_pipe_params {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "sof-audio.h"
|
||||
#include "ops.h"
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
|
||||
#include "compress.h"
|
||||
#include "sof-probes.h"
|
||||
#endif
|
||||
|
||||
/* Create DMA buffer page table for DSP */
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
|
||||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* Copyright(c) 2019-2020 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Author: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __SOF_PROBE_H
|
||||
#define __SOF_PROBE_H
|
||||
|
||||
#include <sound/sof/header.h>
|
||||
|
||||
struct snd_sof_dev;
|
||||
|
||||
#define SOF_PROBE_INVALID_NODE_ID UINT_MAX
|
||||
|
||||
struct sof_probe_dma {
|
||||
unsigned int stream_tag;
|
||||
unsigned int dma_buffer_size;
|
||||
} __packed;
|
||||
|
||||
enum sof_connection_purpose {
|
||||
SOF_CONNECTION_PURPOSE_EXTRACT = 1,
|
||||
SOF_CONNECTION_PURPOSE_INJECT,
|
||||
};
|
||||
|
||||
struct sof_probe_point_desc {
|
||||
unsigned int buffer_id;
|
||||
unsigned int purpose;
|
||||
unsigned int stream_tag;
|
||||
} __packed;
|
||||
|
||||
struct sof_ipc_probe_dma_add_params {
|
||||
struct sof_ipc_cmd_hdr hdr;
|
||||
unsigned int num_elems;
|
||||
struct sof_probe_dma dma[];
|
||||
} __packed;
|
||||
|
||||
struct sof_ipc_probe_info_params {
|
||||
struct sof_ipc_reply rhdr;
|
||||
unsigned int num_elems;
|
||||
union {
|
||||
struct sof_probe_dma dma[0];
|
||||
struct sof_probe_point_desc desc[0];
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct sof_ipc_probe_dma_remove_params {
|
||||
struct sof_ipc_cmd_hdr hdr;
|
||||
unsigned int num_elems;
|
||||
unsigned int stream_tag[];
|
||||
} __packed;
|
||||
|
||||
struct sof_ipc_probe_point_add_params {
|
||||
struct sof_ipc_cmd_hdr hdr;
|
||||
unsigned int num_elems;
|
||||
struct sof_probe_point_desc desc[];
|
||||
} __packed;
|
||||
|
||||
struct sof_ipc_probe_point_remove_params {
|
||||
struct sof_ipc_cmd_hdr hdr;
|
||||
unsigned int num_elems;
|
||||
unsigned int buffer_id[];
|
||||
} __packed;
|
||||
|
||||
int sof_ipc_probe_init(struct snd_sof_dev *sdev,
|
||||
u32 stream_tag, size_t buffer_size);
|
||||
int sof_ipc_probe_deinit(struct snd_sof_dev *sdev);
|
||||
int sof_ipc_probe_dma_info(struct snd_sof_dev *sdev,
|
||||
struct sof_probe_dma **dma, size_t *num_dma);
|
||||
int sof_ipc_probe_dma_add(struct snd_sof_dev *sdev,
|
||||
struct sof_probe_dma *dma, size_t num_dma);
|
||||
int sof_ipc_probe_dma_remove(struct snd_sof_dev *sdev,
|
||||
unsigned int *stream_tag, size_t num_stream_tag);
|
||||
int sof_ipc_probe_points_info(struct snd_sof_dev *sdev,
|
||||
struct sof_probe_point_desc **desc, size_t *num_desc);
|
||||
int sof_ipc_probe_points_add(struct snd_sof_dev *sdev,
|
||||
struct sof_probe_point_desc *desc, size_t num_desc);
|
||||
int sof_ipc_probe_points_remove(struct snd_sof_dev *sdev,
|
||||
unsigned int *buffer_id, size_t num_buffer_id);
|
||||
|
||||
#endif
|
|
@ -3,13 +3,46 @@
|
|||
// This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
// redistributing this file, you may do so under either license.
|
||||
//
|
||||
// Copyright(c) 2019-2020 Intel Corporation. All rights reserved.
|
||||
//
|
||||
// Copyright(c) 2019-2021 Intel Corporation. All rights reserved.
|
||||
// Author: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
//
|
||||
|
||||
#include <sound/soc.h>
|
||||
#include "ops.h"
|
||||
#include "sof-priv.h"
|
||||
#include "probe.h"
|
||||
#include "sof-probes.h"
|
||||
|
||||
struct sof_probe_dma {
|
||||
unsigned int stream_tag;
|
||||
unsigned int dma_buffer_size;
|
||||
} __packed;
|
||||
|
||||
struct sof_ipc_probe_dma_add_params {
|
||||
struct sof_ipc_cmd_hdr hdr;
|
||||
unsigned int num_elems;
|
||||
struct sof_probe_dma dma[];
|
||||
} __packed;
|
||||
|
||||
struct sof_ipc_probe_info_params {
|
||||
struct sof_ipc_reply rhdr;
|
||||
unsigned int num_elems;
|
||||
union {
|
||||
struct sof_probe_dma dma[0];
|
||||
struct sof_probe_point_desc desc[0];
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct sof_ipc_probe_point_add_params {
|
||||
struct sof_ipc_cmd_hdr hdr;
|
||||
unsigned int num_elems;
|
||||
struct sof_probe_point_desc desc[];
|
||||
} __packed;
|
||||
|
||||
struct sof_ipc_probe_point_remove_params {
|
||||
struct sof_ipc_cmd_hdr hdr;
|
||||
unsigned int num_elems;
|
||||
unsigned int buffer_id[];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* sof_ipc_probe_init - initialize data probing
|
||||
|
@ -25,8 +58,8 @@
|
|||
* Probing is initialized only once and each INIT request must be
|
||||
* matched by DEINIT call.
|
||||
*/
|
||||
int sof_ipc_probe_init(struct snd_sof_dev *sdev,
|
||||
u32 stream_tag, size_t buffer_size)
|
||||
static int sof_ipc_probe_init(struct snd_sof_dev *sdev, u32 stream_tag,
|
||||
size_t buffer_size)
|
||||
{
|
||||
struct sof_ipc_probe_dma_add_params *msg;
|
||||
struct sof_ipc_reply reply;
|
||||
|
@ -47,7 +80,6 @@ int sof_ipc_probe_init(struct snd_sof_dev *sdev,
|
|||
kfree(msg);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(sof_ipc_probe_init);
|
||||
|
||||
/**
|
||||
* sof_ipc_probe_deinit - cleanup after data probing
|
||||
|
@ -57,7 +89,7 @@ EXPORT_SYMBOL(sof_ipc_probe_init);
|
|||
* on DSP side once it is no longer needed. DEINIT only when there
|
||||
* are no probes connected and with all injectors detached.
|
||||
*/
|
||||
int sof_ipc_probe_deinit(struct snd_sof_dev *sdev)
|
||||
static int sof_ipc_probe_deinit(struct snd_sof_dev *sdev)
|
||||
{
|
||||
struct sof_ipc_cmd_hdr msg;
|
||||
struct sof_ipc_reply reply;
|
||||
|
@ -68,10 +100,9 @@ int sof_ipc_probe_deinit(struct snd_sof_dev *sdev)
|
|||
return sof_ipc_tx_message(sdev->ipc, msg.cmd, &msg, msg.size,
|
||||
&reply, sizeof(reply));
|
||||
}
|
||||
EXPORT_SYMBOL(sof_ipc_probe_deinit);
|
||||
|
||||
static int sof_ipc_probe_info(struct snd_sof_dev *sdev, unsigned int cmd,
|
||||
void **params, size_t *num_params)
|
||||
void **params, size_t *num_params)
|
||||
{
|
||||
struct sof_ipc_probe_info_params msg = {{{0}}};
|
||||
struct sof_ipc_probe_info_params *reply;
|
||||
|
@ -112,97 +143,6 @@ exit:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* sof_ipc_probe_dma_info - retrieve list of active injection dmas
|
||||
* @sdev: SOF sound device
|
||||
* @dma: Returned list of active dmas
|
||||
* @num_dma: Returned count of active dmas
|
||||
*
|
||||
* Host sends DMA_INFO request to obtain list of injection dmas it
|
||||
* can use to transfer data over with.
|
||||
*
|
||||
* Note that list contains only injection dmas as there is only one
|
||||
* extractor (dma) and it is always assigned on probing init.
|
||||
* DSP knows exactly where data from extraction probes is going to,
|
||||
* which is not the case for injection where multiple streams
|
||||
* could be engaged.
|
||||
*/
|
||||
int sof_ipc_probe_dma_info(struct snd_sof_dev *sdev,
|
||||
struct sof_probe_dma **dma, size_t *num_dma)
|
||||
{
|
||||
return sof_ipc_probe_info(sdev, SOF_IPC_PROBE_DMA_INFO,
|
||||
(void **)dma, num_dma);
|
||||
}
|
||||
EXPORT_SYMBOL(sof_ipc_probe_dma_info);
|
||||
|
||||
/**
|
||||
* sof_ipc_probe_dma_add - attach to specified dmas
|
||||
* @sdev: SOF sound device
|
||||
* @dma: List of streams (dmas) to attach to
|
||||
* @num_dma: Number of elements in @dma
|
||||
*
|
||||
* Contrary to extraction, injection streams are never assigned
|
||||
* on init. Before attempting any data injection, host is responsible
|
||||
* for specifying streams which will be later used to transfer data
|
||||
* to connected probe points.
|
||||
*/
|
||||
int sof_ipc_probe_dma_add(struct snd_sof_dev *sdev,
|
||||
struct sof_probe_dma *dma, size_t num_dma)
|
||||
{
|
||||
struct sof_ipc_probe_dma_add_params *msg;
|
||||
struct sof_ipc_reply reply;
|
||||
size_t size = struct_size(msg, dma, num_dma);
|
||||
int ret;
|
||||
|
||||
msg = kmalloc(size, GFP_KERNEL);
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
msg->hdr.size = size;
|
||||
msg->num_elems = num_dma;
|
||||
msg->hdr.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_DMA_ADD;
|
||||
memcpy(&msg->dma[0], dma, size - sizeof(*msg));
|
||||
|
||||
ret = sof_ipc_tx_message(sdev->ipc, msg->hdr.cmd, msg, msg->hdr.size,
|
||||
&reply, sizeof(reply));
|
||||
kfree(msg);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(sof_ipc_probe_dma_add);
|
||||
|
||||
/**
|
||||
* sof_ipc_probe_dma_remove - detach from specified dmas
|
||||
* @sdev: SOF sound device
|
||||
* @stream_tag: List of stream tags to detach from
|
||||
* @num_stream_tag: Number of elements in @stream_tag
|
||||
*
|
||||
* Host sends DMA_REMOVE request to free previously attached stream
|
||||
* from being occupied for injection. Each detach operation should
|
||||
* match equivalent DMA_ADD. Detach only when all probes tied to
|
||||
* given stream have been disconnected.
|
||||
*/
|
||||
int sof_ipc_probe_dma_remove(struct snd_sof_dev *sdev,
|
||||
unsigned int *stream_tag, size_t num_stream_tag)
|
||||
{
|
||||
struct sof_ipc_probe_dma_remove_params *msg;
|
||||
struct sof_ipc_reply reply;
|
||||
size_t size = struct_size(msg, stream_tag, num_stream_tag);
|
||||
int ret;
|
||||
|
||||
msg = kmalloc(size, GFP_KERNEL);
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
msg->hdr.size = size;
|
||||
msg->num_elems = num_stream_tag;
|
||||
msg->hdr.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_DMA_REMOVE;
|
||||
memcpy(&msg->stream_tag[0], stream_tag, size - sizeof(*msg));
|
||||
|
||||
ret = sof_ipc_tx_message(sdev->ipc, msg->hdr.cmd, msg, msg->hdr.size,
|
||||
&reply, sizeof(reply));
|
||||
kfree(msg);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(sof_ipc_probe_dma_remove);
|
||||
|
||||
/**
|
||||
* sof_ipc_probe_points_info - retrieve list of active probe points
|
||||
* @sdev: SOF sound device
|
||||
|
@ -214,7 +154,8 @@ EXPORT_SYMBOL(sof_ipc_probe_dma_remove);
|
|||
* required.
|
||||
*/
|
||||
int sof_ipc_probe_points_info(struct snd_sof_dev *sdev,
|
||||
struct sof_probe_point_desc **desc, size_t *num_desc)
|
||||
struct sof_probe_point_desc **desc,
|
||||
size_t *num_desc)
|
||||
{
|
||||
return sof_ipc_probe_info(sdev, SOF_IPC_PROBE_POINT_INFO,
|
||||
(void **)desc, num_desc);
|
||||
|
@ -235,7 +176,7 @@ EXPORT_SYMBOL(sof_ipc_probe_points_info);
|
|||
* request when no longer needed.
|
||||
*/
|
||||
int sof_ipc_probe_points_add(struct snd_sof_dev *sdev,
|
||||
struct sof_probe_point_desc *desc, size_t num_desc)
|
||||
struct sof_probe_point_desc *desc, size_t num_desc)
|
||||
{
|
||||
struct sof_ipc_probe_point_add_params *msg;
|
||||
struct sof_ipc_reply reply;
|
||||
|
@ -267,7 +208,7 @@ EXPORT_SYMBOL(sof_ipc_probe_points_add);
|
|||
* points and frees all resources on DSP side.
|
||||
*/
|
||||
int sof_ipc_probe_points_remove(struct snd_sof_dev *sdev,
|
||||
unsigned int *buffer_id, size_t num_buffer_id)
|
||||
unsigned int *buffer_id, size_t num_buffer_id)
|
||||
{
|
||||
struct sof_ipc_probe_point_remove_params *msg;
|
||||
struct sof_ipc_reply reply;
|
||||
|
@ -288,3 +229,136 @@ int sof_ipc_probe_points_remove(struct snd_sof_dev *sdev,
|
|||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(sof_ipc_probe_points_remove);
|
||||
|
||||
static int sof_probe_compr_open(struct snd_compr_stream *cstream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component);
|
||||
int ret;
|
||||
|
||||
ret = snd_sof_probe_compr_assign(sdev, cstream, dai);
|
||||
if (ret < 0) {
|
||||
dev_err(dai->dev, "Failed to assign probe stream: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sdev->extractor_stream_tag = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sof_probe_compr_free(struct snd_compr_stream *cstream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component);
|
||||
struct sof_probe_point_desc *desc;
|
||||
size_t num_desc;
|
||||
int i, ret;
|
||||
|
||||
/* disconnect all probe points */
|
||||
ret = sof_ipc_probe_points_info(sdev, &desc, &num_desc);
|
||||
if (ret < 0) {
|
||||
dev_err(dai->dev, "Failed to get probe points: %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_desc; i++)
|
||||
sof_ipc_probe_points_remove(sdev, &desc[i].buffer_id, 1);
|
||||
kfree(desc);
|
||||
|
||||
exit:
|
||||
ret = sof_ipc_probe_deinit(sdev);
|
||||
if (ret < 0)
|
||||
dev_err(dai->dev, "Failed to deinit probe: %d\n", ret);
|
||||
|
||||
sdev->extractor_stream_tag = SOF_PROBE_INVALID_NODE_ID;
|
||||
snd_compr_free_pages(cstream);
|
||||
|
||||
return snd_sof_probe_compr_free(sdev, cstream, dai);
|
||||
}
|
||||
|
||||
static int sof_probe_compr_set_params(struct snd_compr_stream *cstream,
|
||||
struct snd_compr_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component);
|
||||
struct snd_compr_runtime *rtd = cstream->runtime;
|
||||
int ret;
|
||||
|
||||
cstream->dma_buffer.dev.type = SNDRV_DMA_TYPE_DEV_SG;
|
||||
cstream->dma_buffer.dev.dev = sdev->dev;
|
||||
ret = snd_compr_malloc_pages(cstream, rtd->buffer_size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = snd_sof_probe_compr_set_params(sdev, cstream, params, dai);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = sof_ipc_probe_init(sdev, sdev->extractor_stream_tag,
|
||||
rtd->dma_bytes);
|
||||
if (ret < 0) {
|
||||
dev_err(dai->dev, "Failed to init probe: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sof_probe_compr_trigger(struct snd_compr_stream *cstream, int cmd,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component);
|
||||
|
||||
return snd_sof_probe_compr_trigger(sdev, cstream, cmd, dai);
|
||||
}
|
||||
|
||||
static int sof_probe_compr_pointer(struct snd_compr_stream *cstream,
|
||||
struct snd_compr_tstamp *tstamp,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component);
|
||||
|
||||
return snd_sof_probe_compr_pointer(sdev, cstream, tstamp, dai);
|
||||
}
|
||||
|
||||
struct snd_soc_cdai_ops sof_probe_compr_ops = {
|
||||
.startup = sof_probe_compr_open,
|
||||
.shutdown = sof_probe_compr_free,
|
||||
.set_params = sof_probe_compr_set_params,
|
||||
.trigger = sof_probe_compr_trigger,
|
||||
.pointer = sof_probe_compr_pointer,
|
||||
};
|
||||
EXPORT_SYMBOL(sof_probe_compr_ops);
|
||||
|
||||
static int sof_probe_compr_copy(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *cstream,
|
||||
char __user *buf, size_t count)
|
||||
{
|
||||
struct snd_compr_runtime *rtd = cstream->runtime;
|
||||
unsigned int offset, n;
|
||||
void *ptr;
|
||||
int ret;
|
||||
|
||||
if (count > rtd->buffer_size)
|
||||
count = rtd->buffer_size;
|
||||
|
||||
div_u64_rem(rtd->total_bytes_transferred, rtd->buffer_size, &offset);
|
||||
ptr = rtd->dma_area + offset;
|
||||
n = rtd->buffer_size - offset;
|
||||
|
||||
if (count < n) {
|
||||
ret = copy_to_user(buf, ptr, count);
|
||||
} else {
|
||||
ret = copy_to_user(buf, ptr, n);
|
||||
ret += copy_to_user(buf + n, rtd->dma_area, count - n);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return count - ret;
|
||||
return count;
|
||||
}
|
||||
|
||||
const struct snd_compress_ops sof_probe_compressed_ops = {
|
||||
.copy = sof_probe_compr_copy,
|
||||
};
|
||||
EXPORT_SYMBOL(sof_probe_compressed_ops);
|
|
@ -0,0 +1,38 @@
|
|||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
|
||||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* Copyright(c) 2019-2021 Intel Corporation. All rights reserved.
|
||||
* Author: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __SOF_PROBES_H
|
||||
#define __SOF_PROBES_H
|
||||
|
||||
#include <sound/compress_driver.h>
|
||||
#include <sound/sof/header.h>
|
||||
|
||||
struct snd_sof_dev;
|
||||
|
||||
#define SOF_PROBE_INVALID_NODE_ID UINT_MAX
|
||||
|
||||
struct sof_probe_point_desc {
|
||||
unsigned int buffer_id;
|
||||
unsigned int purpose;
|
||||
unsigned int stream_tag;
|
||||
} __packed;
|
||||
|
||||
int sof_ipc_probe_points_info(struct snd_sof_dev *sdev,
|
||||
struct sof_probe_point_desc **desc,
|
||||
size_t *num_desc);
|
||||
int sof_ipc_probe_points_add(struct snd_sof_dev *sdev,
|
||||
struct sof_probe_point_desc *desc,
|
||||
size_t num_desc);
|
||||
int sof_ipc_probe_points_remove(struct snd_sof_dev *sdev,
|
||||
unsigned int *buffer_id, size_t num_buffer_id);
|
||||
|
||||
extern struct snd_soc_cdai_ops sof_probe_compr_ops;
|
||||
extern const struct snd_compress_ops sof_probe_compressed_ops;
|
||||
|
||||
#endif
|
Загрузка…
Ссылка в новой задаче