Skip to content

Commit 0badb54

Browse files
Srinivas-Kandagatlabroonie
authored andcommitted
ASoC: q6apm: add q6apm_get_hw_pointer helper
Implement an helper function in q6apm to be able to read the current hardware pointer for both read and write buffers. This should help q6apm-dai to get the hardware pointer consistently without it doing manual calculation, which could go wrong in some race conditions. Fixes: 9b4fe0f ("ASoC: qdsp6: audioreach: add q6apm-dai support") Cc: stable@vger.kernel.org Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Tested-by: Johan Hovold <johan+linaro@kernel.org> Link: https://patch.msgid.link/20250314174800.10142-3-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 3d4a441 commit 0badb54

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

sound/soc/qcom/qdsp6/q6apm.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,19 @@ int q6apm_read(struct q6apm_graph *graph)
494494
}
495495
EXPORT_SYMBOL_GPL(q6apm_read);
496496

497+
int q6apm_get_hw_pointer(struct q6apm_graph *graph, int dir)
498+
{
499+
struct audioreach_graph_data *data;
500+
501+
if (dir == SNDRV_PCM_STREAM_PLAYBACK)
502+
data = &graph->rx_data;
503+
else
504+
data = &graph->tx_data;
505+
506+
return (int)atomic_read(&data->hw_ptr);
507+
}
508+
EXPORT_SYMBOL_GPL(q6apm_get_hw_pointer);
509+
497510
static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op)
498511
{
499512
struct data_cmd_rsp_rd_sh_mem_ep_data_buffer_done_v2 *rd_done;
@@ -520,7 +533,8 @@ static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op)
520533
done = data->payload;
521534
phys = graph->rx_data.buf[token].phys;
522535
mutex_unlock(&graph->lock);
523-
536+
/* token numbering starts at 0 */
537+
atomic_set(&graph->rx_data.hw_ptr, token + 1);
524538
if (lower_32_bits(phys) == done->buf_addr_lsw &&
525539
upper_32_bits(phys) == done->buf_addr_msw) {
526540
graph->result.opcode = hdr->opcode;
@@ -553,6 +567,8 @@ static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op)
553567
rd_done = data->payload;
554568
phys = graph->tx_data.buf[hdr->token].phys;
555569
mutex_unlock(&graph->lock);
570+
/* token numbering starts at 0 */
571+
atomic_set(&graph->tx_data.hw_ptr, hdr->token + 1);
556572

557573
if (upper_32_bits(phys) == rd_done->buf_addr_msw &&
558574
lower_32_bits(phys) == rd_done->buf_addr_lsw) {

sound/soc/qcom/qdsp6/q6apm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#ifndef __Q6APM_H__
33
#define __Q6APM_H__
44
#include <linux/types.h>
5+
#include <linux/atomic.h>
56
#include <linux/slab.h>
67
#include <linux/wait.h>
78
#include <linux/kernel.h>
@@ -77,6 +78,7 @@ struct audioreach_graph_data {
7778
uint32_t num_periods;
7879
uint32_t dsp_buf;
7980
uint32_t mem_map_handle;
81+
atomic_t hw_ptr;
8082
};
8183

8284
struct audioreach_graph {
@@ -150,4 +152,5 @@ int q6apm_enable_compress_module(struct device *dev, struct q6apm_graph *graph,
150152
int q6apm_remove_initial_silence(struct device *dev, struct q6apm_graph *graph, uint32_t samples);
151153
int q6apm_remove_trailing_silence(struct device *dev, struct q6apm_graph *graph, uint32_t samples);
152154
int q6apm_set_real_module_id(struct device *dev, struct q6apm_graph *graph, uint32_t codec_id);
155+
int q6apm_get_hw_pointer(struct q6apm_graph *graph, int dir);
153156
#endif /* __APM_GRAPH_ */

0 commit comments

Comments
 (0)