.. | .. |
---|
25 | 25 | */ |
---|
26 | 26 | #define SND_DMAENGINE_PCM_FLAG_NO_RESIDUE BIT(31) |
---|
27 | 27 | |
---|
28 | | -struct dmaengine_pcm { |
---|
29 | | - struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1]; |
---|
30 | | - const struct snd_dmaengine_pcm_config *config; |
---|
31 | | - struct snd_soc_component component; |
---|
32 | | - unsigned int flags; |
---|
33 | | -}; |
---|
34 | | - |
---|
35 | | -static struct dmaengine_pcm *soc_component_to_pcm(struct snd_soc_component *p) |
---|
36 | | -{ |
---|
37 | | - return container_of(p, struct dmaengine_pcm, component); |
---|
38 | | -} |
---|
39 | | - |
---|
40 | 28 | static struct device *dmaengine_dma_dev(struct dmaengine_pcm *pcm, |
---|
41 | 29 | struct snd_pcm_substream *substream) |
---|
42 | 30 | { |
---|
.. | .. |
---|
62 | 50 | int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream, |
---|
63 | 51 | struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config) |
---|
64 | 52 | { |
---|
65 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
| 53 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
66 | 54 | struct snd_dmaengine_dai_dma_data *dma_data; |
---|
67 | 55 | int ret; |
---|
68 | 56 | |
---|
69 | | - dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
---|
| 57 | + if (rtd->num_cpus > 1) { |
---|
| 58 | + dev_err(rtd->dev, |
---|
| 59 | + "%s doesn't support Multi CPU yet\n", __func__); |
---|
| 60 | + return -EINVAL; |
---|
| 61 | + } |
---|
| 62 | + |
---|
| 63 | + dma_data = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); |
---|
70 | 64 | |
---|
71 | 65 | ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config); |
---|
72 | 66 | if (ret) |
---|
.. | .. |
---|
79 | 73 | } |
---|
80 | 74 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_prepare_slave_config); |
---|
81 | 75 | |
---|
82 | | -static int dmaengine_pcm_hw_params(struct snd_pcm_substream *substream, |
---|
83 | | - struct snd_pcm_hw_params *params) |
---|
| 76 | +static int dmaengine_pcm_hw_params(struct snd_soc_component *component, |
---|
| 77 | + struct snd_pcm_substream *substream, |
---|
| 78 | + struct snd_pcm_hw_params *params) |
---|
84 | 79 | { |
---|
85 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
86 | | - struct snd_soc_component *component = |
---|
87 | | - snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME); |
---|
88 | 80 | struct dmaengine_pcm *pcm = soc_component_to_pcm(component); |
---|
89 | 81 | struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream); |
---|
90 | 82 | int (*prepare_slave_config)(struct snd_pcm_substream *substream, |
---|
.. | .. |
---|
110 | 102 | return ret; |
---|
111 | 103 | } |
---|
112 | 104 | |
---|
113 | | - return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); |
---|
| 105 | + return 0; |
---|
114 | 106 | } |
---|
115 | 107 | |
---|
116 | | -static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substream) |
---|
| 108 | +static int |
---|
| 109 | +dmaengine_pcm_set_runtime_hwparams(struct snd_soc_component *component, |
---|
| 110 | + struct snd_pcm_substream *substream) |
---|
117 | 111 | { |
---|
118 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
119 | | - struct snd_soc_component *component = |
---|
120 | | - snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME); |
---|
| 112 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
121 | 113 | struct dmaengine_pcm *pcm = soc_component_to_pcm(component); |
---|
122 | 114 | struct device *dma_dev = dmaengine_dma_dev(pcm, substream); |
---|
123 | 115 | struct dma_chan *chan = pcm->chan[substream->stream]; |
---|
124 | 116 | struct snd_dmaengine_dai_dma_data *dma_data; |
---|
125 | | - struct dma_slave_caps dma_caps; |
---|
126 | 117 | struct snd_pcm_hardware hw; |
---|
127 | | - u32 addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
---|
128 | | - BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | |
---|
129 | | - BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); |
---|
130 | | - snd_pcm_format_t i; |
---|
131 | | - int ret; |
---|
| 118 | + |
---|
| 119 | + if (rtd->num_cpus > 1) { |
---|
| 120 | + dev_err(rtd->dev, |
---|
| 121 | + "%s doesn't support Multi CPU yet\n", __func__); |
---|
| 122 | + return -EINVAL; |
---|
| 123 | + } |
---|
132 | 124 | |
---|
133 | 125 | if (pcm->config && pcm->config->pcm_hardware) |
---|
134 | 126 | return snd_soc_set_runtime_hwparams(substream, |
---|
135 | 127 | pcm->config->pcm_hardware); |
---|
136 | 128 | |
---|
137 | | - dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
---|
| 129 | + dma_data = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); |
---|
138 | 130 | |
---|
139 | 131 | memset(&hw, 0, sizeof(hw)); |
---|
140 | 132 | hw.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | |
---|
.. | .. |
---|
149 | 141 | if (pcm->flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) |
---|
150 | 142 | hw.info |= SNDRV_PCM_INFO_BATCH; |
---|
151 | 143 | |
---|
152 | | - ret = dma_get_slave_caps(chan, &dma_caps); |
---|
153 | | - if (ret == 0) { |
---|
154 | | - if (dma_caps.cmd_pause && dma_caps.cmd_resume) |
---|
155 | | - hw.info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME; |
---|
156 | | - if (dma_caps.residue_granularity <= DMA_RESIDUE_GRANULARITY_SEGMENT) |
---|
157 | | - hw.info |= SNDRV_PCM_INFO_BATCH; |
---|
158 | | - |
---|
159 | | - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
---|
160 | | - addr_widths = dma_caps.dst_addr_widths; |
---|
161 | | - else |
---|
162 | | - addr_widths = dma_caps.src_addr_widths; |
---|
163 | | - } |
---|
164 | | - |
---|
165 | | - /* |
---|
166 | | - * If SND_DMAENGINE_PCM_DAI_FLAG_PACK is set keep |
---|
167 | | - * hw.formats set to 0, meaning no restrictions are in place. |
---|
168 | | - * In this case it's the responsibility of the DAI driver to |
---|
169 | | - * provide the supported format information. |
---|
| 144 | + /** |
---|
| 145 | + * FIXME: Remove the return value check to align with the code |
---|
| 146 | + * before adding snd_dmaengine_pcm_refine_runtime_hwparams |
---|
| 147 | + * function. |
---|
170 | 148 | */ |
---|
171 | | - if (!(dma_data->flags & SND_DMAENGINE_PCM_DAI_FLAG_PACK)) |
---|
172 | | - /* |
---|
173 | | - * Prepare formats mask for valid/allowed sample types. If the |
---|
174 | | - * dma does not have support for the given physical word size, |
---|
175 | | - * it needs to be masked out so user space can not use the |
---|
176 | | - * format which produces corrupted audio. |
---|
177 | | - * In case the dma driver does not implement the slave_caps the |
---|
178 | | - * default assumption is that it supports 1, 2 and 4 bytes |
---|
179 | | - * widths. |
---|
180 | | - */ |
---|
181 | | - for (i = SNDRV_PCM_FORMAT_FIRST; i <= SNDRV_PCM_FORMAT_LAST; i++) { |
---|
182 | | - int bits = snd_pcm_format_physical_width(i); |
---|
183 | | - |
---|
184 | | - /* |
---|
185 | | - * Enable only samples with DMA supported physical |
---|
186 | | - * widths |
---|
187 | | - */ |
---|
188 | | - switch (bits) { |
---|
189 | | - case 8: |
---|
190 | | - case 16: |
---|
191 | | - case 24: |
---|
192 | | - case 32: |
---|
193 | | - case 64: |
---|
194 | | - if (addr_widths & (1 << (bits / 8))) |
---|
195 | | - hw.formats |= pcm_format_to_bits(i); |
---|
196 | | - break; |
---|
197 | | - default: |
---|
198 | | - /* Unsupported types */ |
---|
199 | | - break; |
---|
200 | | - } |
---|
201 | | - } |
---|
| 149 | + snd_dmaengine_pcm_refine_runtime_hwparams(substream, |
---|
| 150 | + dma_data, |
---|
| 151 | + &hw, |
---|
| 152 | + chan); |
---|
202 | 153 | |
---|
203 | 154 | return snd_soc_set_runtime_hwparams(substream, &hw); |
---|
204 | 155 | } |
---|
205 | 156 | |
---|
206 | | -static int dmaengine_pcm_open(struct snd_pcm_substream *substream) |
---|
| 157 | +static int dmaengine_pcm_open(struct snd_soc_component *component, |
---|
| 158 | + struct snd_pcm_substream *substream) |
---|
207 | 159 | { |
---|
208 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
209 | | - struct snd_soc_component *component = |
---|
210 | | - snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME); |
---|
211 | 160 | struct dmaengine_pcm *pcm = soc_component_to_pcm(component); |
---|
212 | 161 | struct dma_chan *chan = pcm->chan[substream->stream]; |
---|
213 | 162 | int ret; |
---|
214 | 163 | |
---|
215 | | - ret = dmaengine_pcm_set_runtime_hwparams(substream); |
---|
| 164 | + ret = dmaengine_pcm_set_runtime_hwparams(component, substream); |
---|
216 | 165 | if (ret) |
---|
217 | 166 | return ret; |
---|
218 | 167 | |
---|
219 | 168 | return snd_dmaengine_pcm_open(substream, chan); |
---|
220 | 169 | } |
---|
221 | 170 | |
---|
| 171 | +static int dmaengine_pcm_close(struct snd_soc_component *component, |
---|
| 172 | + struct snd_pcm_substream *substream) |
---|
| 173 | +{ |
---|
| 174 | + return snd_dmaengine_pcm_close(substream); |
---|
| 175 | +} |
---|
| 176 | + |
---|
| 177 | +static int dmaengine_pcm_trigger(struct snd_soc_component *component, |
---|
| 178 | + struct snd_pcm_substream *substream, int cmd) |
---|
| 179 | +{ |
---|
| 180 | + return snd_dmaengine_pcm_trigger(substream, cmd); |
---|
| 181 | +} |
---|
| 182 | + |
---|
222 | 183 | static struct dma_chan *dmaengine_pcm_compat_request_channel( |
---|
| 184 | + struct snd_soc_component *component, |
---|
223 | 185 | struct snd_soc_pcm_runtime *rtd, |
---|
224 | 186 | struct snd_pcm_substream *substream) |
---|
225 | 187 | { |
---|
226 | | - struct snd_soc_component *component = |
---|
227 | | - snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME); |
---|
228 | 188 | struct dmaengine_pcm *pcm = soc_component_to_pcm(component); |
---|
229 | 189 | struct snd_dmaengine_dai_dma_data *dma_data; |
---|
230 | 190 | dma_filter_fn fn = NULL; |
---|
231 | 191 | |
---|
232 | | - dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
---|
| 192 | + if (rtd->num_cpus > 1) { |
---|
| 193 | + dev_err(rtd->dev, |
---|
| 194 | + "%s doesn't support Multi CPU yet\n", __func__); |
---|
| 195 | + return NULL; |
---|
| 196 | + } |
---|
| 197 | + |
---|
| 198 | + dma_data = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); |
---|
233 | 199 | |
---|
234 | 200 | if ((pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) && pcm->chan[0]) |
---|
235 | 201 | return pcm->chan[0]; |
---|
.. | .. |
---|
262 | 228 | return true; |
---|
263 | 229 | } |
---|
264 | 230 | |
---|
265 | | -static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd) |
---|
| 231 | +static int dmaengine_pcm_new(struct snd_soc_component *component, |
---|
| 232 | + struct snd_soc_pcm_runtime *rtd) |
---|
266 | 233 | { |
---|
267 | | - struct snd_soc_component *component = |
---|
268 | | - snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME); |
---|
269 | 234 | struct dmaengine_pcm *pcm = soc_component_to_pcm(component); |
---|
270 | 235 | const struct snd_dmaengine_pcm_config *config = pcm->config; |
---|
271 | 236 | struct device *dev = component->dev; |
---|
272 | | - struct snd_dmaengine_dai_dma_data *dma_data; |
---|
273 | 237 | struct snd_pcm_substream *substream; |
---|
274 | 238 | size_t prealloc_buffer_size; |
---|
275 | 239 | size_t max_buffer_size; |
---|
276 | 240 | unsigned int i; |
---|
277 | | - int ret; |
---|
278 | 241 | |
---|
279 | 242 | if (config && config->prealloc_buffer_size) { |
---|
280 | 243 | prealloc_buffer_size = config->prealloc_buffer_size; |
---|
.. | .. |
---|
284 | 247 | max_buffer_size = SIZE_MAX; |
---|
285 | 248 | } |
---|
286 | 249 | |
---|
287 | | - for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) { |
---|
| 250 | + for_each_pcm_streams(i) { |
---|
288 | 251 | substream = rtd->pcm->streams[i].substream; |
---|
289 | 252 | if (!substream) |
---|
290 | 253 | continue; |
---|
291 | 254 | |
---|
292 | | - dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
---|
293 | | - |
---|
294 | | - if (!pcm->chan[i] && |
---|
295 | | - (pcm->flags & SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME)) |
---|
| 255 | + if (!pcm->chan[i] && config && config->chan_names[i]) |
---|
296 | 256 | pcm->chan[i] = dma_request_slave_channel(dev, |
---|
297 | | - dma_data->chan_name); |
---|
| 257 | + config->chan_names[i]); |
---|
298 | 258 | |
---|
299 | 259 | if (!pcm->chan[i] && (pcm->flags & SND_DMAENGINE_PCM_FLAG_COMPAT)) { |
---|
300 | | - pcm->chan[i] = dmaengine_pcm_compat_request_channel(rtd, |
---|
301 | | - substream); |
---|
| 260 | + pcm->chan[i] = dmaengine_pcm_compat_request_channel( |
---|
| 261 | + component, rtd, substream); |
---|
302 | 262 | } |
---|
303 | 263 | |
---|
304 | 264 | if (!pcm->chan[i]) { |
---|
.. | .. |
---|
307 | 267 | return -EINVAL; |
---|
308 | 268 | } |
---|
309 | 269 | |
---|
310 | | - ret = snd_pcm_lib_preallocate_pages(substream, |
---|
| 270 | + snd_pcm_set_managed_buffer(substream, |
---|
311 | 271 | SNDRV_DMA_TYPE_DEV_IRAM, |
---|
312 | 272 | dmaengine_dma_dev(pcm, substream), |
---|
313 | 273 | prealloc_buffer_size, |
---|
314 | 274 | max_buffer_size); |
---|
315 | | - if (ret) |
---|
316 | | - return ret; |
---|
317 | 275 | |
---|
318 | 276 | if (!dmaengine_pcm_can_report_residue(dev, pcm->chan[i])) |
---|
319 | 277 | pcm->flags |= SND_DMAENGINE_PCM_FLAG_NO_RESIDUE; |
---|
320 | 278 | |
---|
321 | 279 | if (rtd->pcm->streams[i].pcm->name[0] == '\0') { |
---|
322 | | - strncpy(rtd->pcm->streams[i].pcm->name, |
---|
323 | | - rtd->pcm->streams[i].pcm->id, |
---|
324 | | - sizeof(rtd->pcm->streams[i].pcm->name)); |
---|
| 280 | + strscpy_pad(rtd->pcm->streams[i].pcm->name, |
---|
| 281 | + rtd->pcm->streams[i].pcm->id, |
---|
| 282 | + sizeof(rtd->pcm->streams[i].pcm->name)); |
---|
325 | 283 | } |
---|
326 | 284 | } |
---|
327 | 285 | |
---|
.. | .. |
---|
329 | 287 | } |
---|
330 | 288 | |
---|
331 | 289 | static snd_pcm_uframes_t dmaengine_pcm_pointer( |
---|
| 290 | + struct snd_soc_component *component, |
---|
332 | 291 | struct snd_pcm_substream *substream) |
---|
333 | 292 | { |
---|
334 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
335 | | - struct snd_soc_component *component = |
---|
336 | | - snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME); |
---|
337 | 293 | struct dmaengine_pcm *pcm = soc_component_to_pcm(component); |
---|
338 | 294 | |
---|
339 | 295 | if (pcm->flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) |
---|
.. | .. |
---|
342 | 298 | return snd_dmaengine_pcm_pointer(substream); |
---|
343 | 299 | } |
---|
344 | 300 | |
---|
345 | | -static int dmaengine_copy_user(struct snd_pcm_substream *substream, |
---|
| 301 | +static int dmaengine_copy_user(struct snd_soc_component *component, |
---|
| 302 | + struct snd_pcm_substream *substream, |
---|
346 | 303 | int channel, unsigned long hwoff, |
---|
347 | 304 | void __user *buf, unsigned long bytes) |
---|
348 | 305 | { |
---|
349 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
350 | | - struct snd_soc_component *component = |
---|
351 | | - snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME); |
---|
352 | 306 | struct snd_pcm_runtime *runtime = substream->runtime; |
---|
353 | 307 | struct dmaengine_pcm *pcm = soc_component_to_pcm(component); |
---|
354 | 308 | int (*process)(struct snd_pcm_substream *substream, |
---|
.. | .. |
---|
376 | 330 | return 0; |
---|
377 | 331 | } |
---|
378 | 332 | |
---|
379 | | -static const struct snd_pcm_ops dmaengine_pcm_ops = { |
---|
380 | | - .open = dmaengine_pcm_open, |
---|
381 | | - .close = snd_dmaengine_pcm_close, |
---|
382 | | - .ioctl = snd_pcm_lib_ioctl, |
---|
383 | | - .hw_params = dmaengine_pcm_hw_params, |
---|
384 | | - .hw_free = snd_pcm_lib_free_pages, |
---|
385 | | - .trigger = snd_dmaengine_pcm_trigger, |
---|
386 | | - .pointer = dmaengine_pcm_pointer, |
---|
387 | | -}; |
---|
388 | | - |
---|
389 | | -static const struct snd_pcm_ops dmaengine_pcm_process_ops = { |
---|
390 | | - .open = dmaengine_pcm_open, |
---|
391 | | - .close = snd_dmaengine_pcm_close, |
---|
392 | | - .ioctl = snd_pcm_lib_ioctl, |
---|
393 | | - .hw_params = dmaengine_pcm_hw_params, |
---|
394 | | - .hw_free = snd_pcm_lib_free_pages, |
---|
395 | | - .trigger = snd_dmaengine_pcm_trigger, |
---|
396 | | - .pointer = dmaengine_pcm_pointer, |
---|
397 | | - .copy_user = dmaengine_copy_user, |
---|
398 | | -}; |
---|
399 | | - |
---|
400 | 333 | static const struct snd_soc_component_driver dmaengine_pcm_component = { |
---|
401 | 334 | .name = SND_DMAENGINE_PCM_DRV_NAME, |
---|
402 | 335 | .probe_order = SND_SOC_COMP_ORDER_LATE, |
---|
403 | | - .ops = &dmaengine_pcm_ops, |
---|
404 | | - .pcm_new = dmaengine_pcm_new, |
---|
| 336 | + .open = dmaengine_pcm_open, |
---|
| 337 | + .close = dmaengine_pcm_close, |
---|
| 338 | + .hw_params = dmaengine_pcm_hw_params, |
---|
| 339 | + .trigger = dmaengine_pcm_trigger, |
---|
| 340 | + .pointer = dmaengine_pcm_pointer, |
---|
| 341 | + .pcm_construct = dmaengine_pcm_new, |
---|
405 | 342 | }; |
---|
406 | 343 | |
---|
407 | 344 | static const struct snd_soc_component_driver dmaengine_pcm_component_process = { |
---|
408 | 345 | .name = SND_DMAENGINE_PCM_DRV_NAME, |
---|
409 | 346 | .probe_order = SND_SOC_COMP_ORDER_LATE, |
---|
410 | | - .ops = &dmaengine_pcm_process_ops, |
---|
411 | | - .pcm_new = dmaengine_pcm_new, |
---|
| 347 | + .open = dmaengine_pcm_open, |
---|
| 348 | + .close = dmaengine_pcm_close, |
---|
| 349 | + .hw_params = dmaengine_pcm_hw_params, |
---|
| 350 | + .trigger = dmaengine_pcm_trigger, |
---|
| 351 | + .pointer = dmaengine_pcm_pointer, |
---|
| 352 | + .copy_user = dmaengine_copy_user, |
---|
| 353 | + .pcm_construct = dmaengine_pcm_new, |
---|
412 | 354 | }; |
---|
413 | 355 | |
---|
414 | 356 | static const char * const dmaengine_pcm_dma_channel_names[] = { |
---|
.. | .. |
---|
423 | 365 | const char *name; |
---|
424 | 366 | struct dma_chan *chan; |
---|
425 | 367 | |
---|
426 | | - if ((pcm->flags & (SND_DMAENGINE_PCM_FLAG_NO_DT | |
---|
427 | | - SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME)) || |
---|
428 | | - !dev->of_node) |
---|
| 368 | + if ((pcm->flags & SND_DMAENGINE_PCM_FLAG_NO_DT) || (!dev->of_node && |
---|
| 369 | + !(config && config->dma_dev && config->dma_dev->of_node))) |
---|
429 | 370 | return 0; |
---|
430 | 371 | |
---|
431 | 372 | if (config && config->dma_dev) { |
---|
.. | .. |
---|
440 | 381 | dev = config->dma_dev; |
---|
441 | 382 | } |
---|
442 | 383 | |
---|
443 | | - for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; |
---|
444 | | - i++) { |
---|
| 384 | + for_each_pcm_streams(i) { |
---|
445 | 385 | if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) |
---|
446 | 386 | name = "rx-tx"; |
---|
447 | 387 | else |
---|
448 | 388 | name = dmaengine_pcm_dma_channel_names[i]; |
---|
449 | 389 | if (config && config->chan_names[i]) |
---|
450 | 390 | name = config->chan_names[i]; |
---|
451 | | - chan = dma_request_slave_channel_reason(dev, name); |
---|
| 391 | + chan = dma_request_chan(dev, name); |
---|
452 | 392 | if (IS_ERR(chan)) { |
---|
| 393 | + /* |
---|
| 394 | + * Only report probe deferral errors, channels |
---|
| 395 | + * might not be present for devices that |
---|
| 396 | + * support only TX or only RX. |
---|
| 397 | + */ |
---|
453 | 398 | if (PTR_ERR(chan) == -EPROBE_DEFER) |
---|
454 | 399 | return -EPROBE_DEFER; |
---|
455 | 400 | pcm->chan[i] = NULL; |
---|
.. | .. |
---|
470 | 415 | { |
---|
471 | 416 | unsigned int i; |
---|
472 | 417 | |
---|
473 | | - for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; |
---|
474 | | - i++) { |
---|
| 418 | + for_each_pcm_streams(i) { |
---|
475 | 419 | if (!pcm->chan[i]) |
---|
476 | 420 | continue; |
---|
477 | 421 | dma_release_channel(pcm->chan[i]); |
---|
.. | .. |
---|
489 | 433 | int snd_dmaengine_pcm_register(struct device *dev, |
---|
490 | 434 | const struct snd_dmaengine_pcm_config *config, unsigned int flags) |
---|
491 | 435 | { |
---|
| 436 | + const struct snd_soc_component_driver *driver; |
---|
492 | 437 | struct dmaengine_pcm *pcm; |
---|
493 | 438 | int ret; |
---|
494 | 439 | |
---|
.. | .. |
---|
507 | 452 | goto err_free_dma; |
---|
508 | 453 | |
---|
509 | 454 | if (config && config->process) |
---|
510 | | - ret = snd_soc_add_component(dev, &pcm->component, |
---|
511 | | - &dmaengine_pcm_component_process, |
---|
512 | | - NULL, 0); |
---|
| 455 | + driver = &dmaengine_pcm_component_process; |
---|
513 | 456 | else |
---|
514 | | - ret = snd_soc_add_component(dev, &pcm->component, |
---|
515 | | - &dmaengine_pcm_component, NULL, 0); |
---|
| 457 | + driver = &dmaengine_pcm_component; |
---|
| 458 | + |
---|
| 459 | + ret = snd_soc_component_initialize(&pcm->component, driver, dev); |
---|
| 460 | + if (ret) |
---|
| 461 | + goto err_free_dma; |
---|
| 462 | + |
---|
| 463 | + ret = snd_soc_add_component(&pcm->component, NULL, 0); |
---|
516 | 464 | if (ret) |
---|
517 | 465 | goto err_free_dma; |
---|
518 | 466 | |
---|
.. | .. |
---|
543 | 491 | |
---|
544 | 492 | pcm = soc_component_to_pcm(component); |
---|
545 | 493 | |
---|
546 | | - snd_soc_unregister_component(dev); |
---|
| 494 | + snd_soc_unregister_component_by_driver(dev, component->driver); |
---|
547 | 495 | dmaengine_pcm_release_chan(pcm); |
---|
548 | 496 | kfree(pcm); |
---|
549 | 497 | } |
---|