1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#ifndef __SOUND_DMAENGINE_PCM_H__
16#define __SOUND_DMAENGINE_PCM_H__
17
18#include <sound/pcm.h>
19#include <sound/soc.h>
20#include <linux/dmaengine.h>
21
22
23
24
25
26
27static inline enum dma_transfer_direction
28snd_pcm_substream_to_dma_direction(const struct snd_pcm_substream *substream)
29{
30 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
31 return DMA_MEM_TO_DEV;
32 else
33 return DMA_DEV_TO_MEM;
34}
35
36int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
37 const struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config);
38int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
39snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream);
40snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream);
41
42int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
43 struct dma_chan *chan);
44int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream);
45
46int snd_dmaengine_pcm_open_request_chan(struct snd_pcm_substream *substream,
47 dma_filter_fn filter_fn, void *filter_data);
48int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream);
49
50struct dma_chan *snd_dmaengine_pcm_request_channel(dma_filter_fn filter_fn,
51 void *filter_data);
52struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream);
53
54
55
56
57
58
59
60
61
62#define SND_DMAENGINE_PCM_DAI_FLAG_PACK BIT(0)
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78struct snd_dmaengine_dai_dma_data {
79 dma_addr_t addr;
80 enum dma_slave_buswidth addr_width;
81 u32 maxburst;
82 unsigned int slave_id;
83 void *filter_data;
84 const char *chan_name;
85 unsigned int fifo_size;
86 unsigned int flags;
87};
88
89void snd_dmaengine_pcm_set_config_from_dai_data(
90 const struct snd_pcm_substream *substream,
91 const struct snd_dmaengine_dai_dma_data *dma_data,
92 struct dma_slave_config *config);
93
94
95
96
97
98
99#define SND_DMAENGINE_PCM_FLAG_COMPAT BIT(0)
100
101
102
103
104#define SND_DMAENGINE_PCM_FLAG_NO_DT BIT(1)
105
106
107
108
109#define SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX BIT(3)
110
111
112
113#define SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME BIT(4)
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136struct snd_dmaengine_pcm_config {
137 int (*prepare_slave_config)(struct snd_pcm_substream *substream,
138 struct snd_pcm_hw_params *params,
139 struct dma_slave_config *slave_config);
140 struct dma_chan *(*compat_request_channel)(
141 struct snd_soc_pcm_runtime *rtd,
142 struct snd_pcm_substream *substream);
143 dma_filter_fn compat_filter_fn;
144 struct device *dma_dev;
145 const char *chan_names[SNDRV_PCM_STREAM_LAST + 1];
146
147 const struct snd_pcm_hardware *pcm_hardware;
148 unsigned int prealloc_buffer_size;
149};
150
151int snd_dmaengine_pcm_register(struct device *dev,
152 const struct snd_dmaengine_pcm_config *config,
153 unsigned int flags);
154void snd_dmaengine_pcm_unregister(struct device *dev);
155
156int devm_snd_dmaengine_pcm_register(struct device *dev,
157 const struct snd_dmaengine_pcm_config *config,
158 unsigned int flags);
159
160int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
161 struct snd_pcm_hw_params *params,
162 struct dma_slave_config *slave_config);
163
164#endif
165