1
2
3
4
5
6
7#ifndef __SOUND_DMAENGINE_PCM_H__
8#define __SOUND_DMAENGINE_PCM_H__
9
10#include <sound/pcm.h>
11#include <sound/soc.h>
12#include <linux/dmaengine.h>
13
14
15
16
17
18
19static inline enum dma_transfer_direction
20snd_pcm_substream_to_dma_direction(const struct snd_pcm_substream *substream)
21{
22 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
23 return DMA_MEM_TO_DEV;
24 else
25 return DMA_DEV_TO_MEM;
26}
27
28int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
29 const struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config);
30int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
31snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream);
32snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream);
33
34int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
35 struct dma_chan *chan);
36int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream);
37
38int snd_dmaengine_pcm_open_request_chan(struct snd_pcm_substream *substream,
39 dma_filter_fn filter_fn, void *filter_data);
40int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream);
41
42struct dma_chan *snd_dmaengine_pcm_request_channel(dma_filter_fn filter_fn,
43 void *filter_data);
44struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream);
45
46
47
48
49
50
51
52
53
54#define SND_DMAENGINE_PCM_DAI_FLAG_PACK BIT(0)
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73struct snd_dmaengine_dai_dma_data {
74 dma_addr_t addr;
75 enum dma_slave_buswidth addr_width;
76 u32 maxburst;
77 unsigned int slave_id;
78 void *filter_data;
79 const char *chan_name;
80 unsigned int fifo_size;
81 unsigned int flags;
82 void *peripheral_config;
83 size_t peripheral_size;
84};
85
86void snd_dmaengine_pcm_set_config_from_dai_data(
87 const struct snd_pcm_substream *substream,
88 const struct snd_dmaengine_dai_dma_data *dma_data,
89 struct dma_slave_config *config);
90
91int snd_dmaengine_pcm_refine_runtime_hwparams(
92 struct snd_pcm_substream *substream,
93 struct snd_dmaengine_dai_dma_data *dma_data,
94 struct snd_pcm_hardware *hw,
95 struct dma_chan *chan);
96
97
98
99
100
101#define SND_DMAENGINE_PCM_FLAG_COMPAT BIT(0)
102
103
104
105
106#define SND_DMAENGINE_PCM_FLAG_NO_DT BIT(1)
107
108
109
110
111#define SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX BIT(3)
112
113
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 int (*process)(struct snd_pcm_substream *substream,
144 int channel, unsigned long hwoff,
145 void *buf, unsigned long bytes);
146 dma_filter_fn compat_filter_fn;
147 struct device *dma_dev;
148 const char *chan_names[SNDRV_PCM_STREAM_LAST + 1];
149
150 const struct snd_pcm_hardware *pcm_hardware;
151 unsigned int prealloc_buffer_size;
152};
153
154int snd_dmaengine_pcm_register(struct device *dev,
155 const struct snd_dmaengine_pcm_config *config,
156 unsigned int flags);
157void snd_dmaengine_pcm_unregister(struct device *dev);
158
159int devm_snd_dmaengine_pcm_register(struct device *dev,
160 const struct snd_dmaengine_pcm_config *config,
161 unsigned int flags);
162
163int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
164 struct snd_pcm_hw_params *params,
165 struct dma_slave_config *slave_config);
166
167#define SND_DMAENGINE_PCM_DRV_NAME "snd_dmaengine_pcm"
168
169struct dmaengine_pcm {
170 struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1];
171 const struct snd_dmaengine_pcm_config *config;
172 struct snd_soc_component component;
173 unsigned int flags;
174};
175
176static inline struct dmaengine_pcm *soc_component_to_pcm(struct snd_soc_component *p)
177{
178 return container_of(p, struct dmaengine_pcm, component);
179}
180#endif
181