1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
3 // This file is provided under a dual BSD/GPLv2 license. When using or
4 // redistributing this file, you may do so under either license.
6 // Copyright(c) 2019-2020 Intel Corporation. All rights reserved.
8 // Author: Cezary Rojewski <cezary.rojewski@intel.com>
11 #include <sound/soc.h>
16 struct snd_compress_ops sof_probe_compressed_ops
= {
17 .copy
= sof_probe_compr_copy
,
19 EXPORT_SYMBOL(sof_probe_compressed_ops
);
21 int sof_probe_compr_open(struct snd_compr_stream
*cstream
,
22 struct snd_soc_dai
*dai
)
24 struct snd_sof_dev
*sdev
=
25 snd_soc_component_get_drvdata(dai
->component
);
28 ret
= snd_sof_probe_compr_assign(sdev
, cstream
, dai
);
30 dev_err(dai
->dev
, "Failed to assign probe stream: %d\n", ret
);
34 sdev
->extractor_stream_tag
= ret
;
37 EXPORT_SYMBOL(sof_probe_compr_open
);
39 int sof_probe_compr_free(struct snd_compr_stream
*cstream
,
40 struct snd_soc_dai
*dai
)
42 struct snd_sof_dev
*sdev
=
43 snd_soc_component_get_drvdata(dai
->component
);
44 struct sof_probe_point_desc
*desc
;
48 /* disconnect all probe points */
49 ret
= sof_ipc_probe_points_info(sdev
, &desc
, &num_desc
);
51 dev_err(dai
->dev
, "Failed to get probe points: %d\n", ret
);
55 for (i
= 0; i
< num_desc
; i
++)
56 sof_ipc_probe_points_remove(sdev
, &desc
[i
].buffer_id
, 1);
60 ret
= sof_ipc_probe_deinit(sdev
);
62 dev_err(dai
->dev
, "Failed to deinit probe: %d\n", ret
);
64 sdev
->extractor_stream_tag
= SOF_PROBE_INVALID_NODE_ID
;
65 snd_compr_free_pages(cstream
);
67 return snd_sof_probe_compr_free(sdev
, cstream
, dai
);
69 EXPORT_SYMBOL(sof_probe_compr_free
);
71 int sof_probe_compr_set_params(struct snd_compr_stream
*cstream
,
72 struct snd_compr_params
*params
, struct snd_soc_dai
*dai
)
74 struct snd_compr_runtime
*rtd
= cstream
->runtime
;
75 struct snd_sof_dev
*sdev
=
76 snd_soc_component_get_drvdata(dai
->component
);
79 cstream
->dma_buffer
.dev
.type
= SNDRV_DMA_TYPE_DEV_SG
;
80 cstream
->dma_buffer
.dev
.dev
= sdev
->dev
;
81 ret
= snd_compr_malloc_pages(cstream
, rtd
->buffer_size
);
85 ret
= snd_sof_probe_compr_set_params(sdev
, cstream
, params
, dai
);
89 ret
= sof_ipc_probe_init(sdev
, sdev
->extractor_stream_tag
,
92 dev_err(dai
->dev
, "Failed to init probe: %d\n", ret
);
98 EXPORT_SYMBOL(sof_probe_compr_set_params
);
100 int sof_probe_compr_trigger(struct snd_compr_stream
*cstream
, int cmd
,
101 struct snd_soc_dai
*dai
)
103 struct snd_sof_dev
*sdev
=
104 snd_soc_component_get_drvdata(dai
->component
);
106 return snd_sof_probe_compr_trigger(sdev
, cstream
, cmd
, dai
);
108 EXPORT_SYMBOL(sof_probe_compr_trigger
);
110 int sof_probe_compr_pointer(struct snd_compr_stream
*cstream
,
111 struct snd_compr_tstamp
*tstamp
, struct snd_soc_dai
*dai
)
113 struct snd_sof_dev
*sdev
=
114 snd_soc_component_get_drvdata(dai
->component
);
116 return snd_sof_probe_compr_pointer(sdev
, cstream
, tstamp
, dai
);
118 EXPORT_SYMBOL(sof_probe_compr_pointer
);
120 int sof_probe_compr_copy(struct snd_soc_component
*component
,
121 struct snd_compr_stream
*cstream
,
122 char __user
*buf
, size_t count
)
124 struct snd_compr_runtime
*rtd
= cstream
->runtime
;
125 unsigned int offset
, n
;
129 if (count
> rtd
->buffer_size
)
130 count
= rtd
->buffer_size
;
132 div_u64_rem(rtd
->total_bytes_transferred
, rtd
->buffer_size
, &offset
);
133 ptr
= rtd
->dma_area
+ offset
;
134 n
= rtd
->buffer_size
- offset
;
137 ret
= copy_to_user(buf
, ptr
, count
);
139 ret
= copy_to_user(buf
, ptr
, n
);
140 ret
+= copy_to_user(buf
+ n
, rtd
->dma_area
, count
- n
);
147 EXPORT_SYMBOL(sof_probe_compr_copy
);