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
70struct snd_dmaengine_dai_dma_data {
71 dma_addr_t addr;
72 enum dma_slave_buswidth addr_width;
73 u32 maxburst;
74 unsigned int slave_id;
75 void *filter_data;
76 const char *chan_name;
77 unsigned int fifo_size;
78 unsigned int flags;
79};
80
81void snd_dmaengine_pcm_set_config_from_dai_data(
82 const struct snd_pcm_substream *substream,
83 const struct snd_dmaengine_dai_dma_data *dma_data,
84 struct dma_slave_config *config);
85
86int snd_dmaengine_pcm_refine_runtime_hwparams(
87 struct snd_pcm_substream *substream,
88 struct snd_dmaengine_dai_dma_data *dma_data,
89 struct snd_pcm_hardware *hw,
90 struct dma_chan *chan);
91
92
93
94
95
96#define SND_DMAENGINE_PCM_FLAG_COMPAT BIT(0)
97
98
99
100
101#define SND_DMAENGINE_PCM_FLAG_NO_DT BIT(1)
102
103
104
105
106#define SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX BIT(3)
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131struct snd_dmaengine_pcm_config {
132 int (*prepare_slave_config)(struct snd_pcm_substream *substream,
133 struct snd_pcm_hw_params *params,
134 struct dma_slave_config *slave_config);
135 struct dma_chan *(*compat_request_channel)(
136 struct snd_soc_pcm_runtime *rtd,
137 struct snd_pcm_substream *substream);
138 int (*process)(struct snd_pcm_substream *substream,
139 int channel, unsigned long hwoff,
140 void *buf, unsigned long bytes);
141 dma_filter_fn compat_filter_fn;
142 struct device *dma_dev;
143 const char *chan_names[SNDRV_PCM_STREAM_LAST + 1];
144
145 const struct snd_pcm_hardware *pcm_hardware;
146 unsigned int prealloc_buffer_size;
147};
148
149int snd_dmaengine_pcm_register(struct device *dev,
150 const struct snd_dmaengine_pcm_config *config,
151 unsigned int flags);
152void snd_dmaengine_pcm_unregister(struct device *dev);
153
154int devm_snd_dmaengine_pcm_register(struct device *dev,
155 const struct snd_dmaengine_pcm_config *config,
156 unsigned int flags);
157
158int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
159 struct snd_pcm_hw_params *params,
160 struct dma_slave_config *slave_config);
161
162#define SND_DMAENGINE_PCM_DRV_NAME "snd_dmaengine_pcm"
163
164struct dmaengine_pcm {
165 struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1];
166 const struct snd_dmaengine_pcm_config *config;
167 struct snd_soc_component component;
168 unsigned int flags;
169};
170
171static inline struct dmaengine_pcm *soc_component_to_pcm(struct snd_soc_component *p)
172{
173 return container_of(p, struct dmaengine_pcm, component);
174}
175#endif
176