^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 <sound/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "compress.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "ops.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "probe.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) struct snd_compress_ops sof_probe_compressed_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) .copy = sof_probe_compr_copy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) EXPORT_SYMBOL(sof_probe_compressed_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) int sof_probe_compr_open(struct snd_compr_stream *cstream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct snd_sof_dev *sdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) snd_soc_component_get_drvdata(dai->component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) ret = snd_sof_probe_compr_assign(sdev, cstream, dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) dev_err(dai->dev, "Failed to assign probe stream: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) sdev->extractor_stream_tag = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) EXPORT_SYMBOL(sof_probe_compr_open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int sof_probe_compr_free(struct snd_compr_stream *cstream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct snd_sof_dev *sdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) snd_soc_component_get_drvdata(dai->component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct sof_probe_point_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) size_t num_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* disconnect all probe points */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) ret = sof_ipc_probe_points_info(sdev, &desc, &num_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) dev_err(dai->dev, "Failed to get probe points: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) for (i = 0; i < num_desc; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) sof_ipc_probe_points_remove(sdev, &desc[i].buffer_id, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) kfree(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) ret = sof_ipc_probe_deinit(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) dev_err(dai->dev, "Failed to deinit probe: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) sdev->extractor_stream_tag = SOF_PROBE_INVALID_NODE_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) snd_compr_free_pages(cstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return snd_sof_probe_compr_free(sdev, cstream, dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) EXPORT_SYMBOL(sof_probe_compr_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) int sof_probe_compr_set_params(struct snd_compr_stream *cstream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct snd_compr_params *params, struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct snd_compr_runtime *rtd = cstream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct snd_sof_dev *sdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) snd_soc_component_get_drvdata(dai->component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) cstream->dma_buffer.dev.type = SNDRV_DMA_TYPE_DEV_SG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) cstream->dma_buffer.dev.dev = sdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) ret = snd_compr_malloc_pages(cstream, rtd->buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ret = snd_sof_probe_compr_set_params(sdev, cstream, params, dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) ret = sof_ipc_probe_init(sdev, sdev->extractor_stream_tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) rtd->dma_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) dev_err(dai->dev, "Failed to init probe: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) EXPORT_SYMBOL(sof_probe_compr_set_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) int sof_probe_compr_trigger(struct snd_compr_stream *cstream, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct snd_sof_dev *sdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) snd_soc_component_get_drvdata(dai->component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return snd_sof_probe_compr_trigger(sdev, cstream, cmd, dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) EXPORT_SYMBOL(sof_probe_compr_trigger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int sof_probe_compr_pointer(struct snd_compr_stream *cstream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct snd_compr_tstamp *tstamp, struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct snd_sof_dev *sdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) snd_soc_component_get_drvdata(dai->component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return snd_sof_probe_compr_pointer(sdev, cstream, tstamp, dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) EXPORT_SYMBOL(sof_probe_compr_pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int sof_probe_compr_copy(struct snd_soc_component *component,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct snd_compr_stream *cstream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) char __user *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct snd_compr_runtime *rtd = cstream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned int offset, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) void *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (count > rtd->buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) count = rtd->buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) div_u64_rem(rtd->total_bytes_transferred, rtd->buffer_size, &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) ptr = rtd->dma_area + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) n = rtd->buffer_size - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (count < n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ret = copy_to_user(buf, ptr, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ret = copy_to_user(buf, ptr, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) ret += copy_to_user(buf + n, rtd->dma_area, count - n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return count - ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) EXPORT_SYMBOL(sof_probe_compr_copy);