.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * ALSA PCM device for the |
---|
3 | 4 | * ALSA interface to cx18 PCM capture streams |
---|
.. | .. |
---|
6 | 7 | * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com> |
---|
7 | 8 | * |
---|
8 | 9 | * Portions of this work were sponsored by ONELAN Limited. |
---|
9 | | - * |
---|
10 | | - * This program is free software; you can redistribute it and/or modify |
---|
11 | | - * it under the terms of the GNU General Public License as published by |
---|
12 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
13 | | - * (at your option) any later version. |
---|
14 | | - * |
---|
15 | | - * This program is distributed in the hope that it will be useful, |
---|
16 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
17 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
18 | | - * GNU General Public License for more details. |
---|
19 | 10 | */ |
---|
20 | 11 | |
---|
21 | 12 | #include <linux/init.h> |
---|
22 | 13 | #include <linux/kernel.h> |
---|
23 | | -#include <linux/vmalloc.h> |
---|
24 | 14 | |
---|
25 | 15 | #include <media/v4l2-device.h> |
---|
26 | 16 | |
---|
.. | .. |
---|
210 | 200 | return 0; |
---|
211 | 201 | } |
---|
212 | 202 | |
---|
213 | | -static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream, |
---|
214 | | - unsigned int cmd, void *arg) |
---|
215 | | -{ |
---|
216 | | - struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream); |
---|
217 | | - int ret; |
---|
218 | | - |
---|
219 | | - snd_cx18_lock(cxsc); |
---|
220 | | - ret = snd_pcm_lib_ioctl(substream, cmd, arg); |
---|
221 | | - snd_cx18_unlock(cxsc); |
---|
222 | | - return ret; |
---|
223 | | -} |
---|
224 | | - |
---|
225 | | - |
---|
226 | | -static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, |
---|
227 | | - size_t size) |
---|
228 | | -{ |
---|
229 | | - struct snd_pcm_runtime *runtime = subs->runtime; |
---|
230 | | - |
---|
231 | | - dprintk("Allocating vbuffer\n"); |
---|
232 | | - if (runtime->dma_area) { |
---|
233 | | - if (runtime->dma_bytes > size) |
---|
234 | | - return 0; |
---|
235 | | - |
---|
236 | | - vfree(runtime->dma_area); |
---|
237 | | - } |
---|
238 | | - runtime->dma_area = vmalloc(size); |
---|
239 | | - if (!runtime->dma_area) |
---|
240 | | - return -ENOMEM; |
---|
241 | | - |
---|
242 | | - runtime->dma_bytes = size; |
---|
243 | | - |
---|
244 | | - return 0; |
---|
245 | | -} |
---|
246 | | - |
---|
247 | | -static int snd_cx18_pcm_hw_params(struct snd_pcm_substream *substream, |
---|
248 | | - struct snd_pcm_hw_params *params) |
---|
249 | | -{ |
---|
250 | | - dprintk("%s called\n", __func__); |
---|
251 | | - |
---|
252 | | - return snd_pcm_alloc_vmalloc_buffer(substream, |
---|
253 | | - params_buffer_bytes(params)); |
---|
254 | | -} |
---|
255 | | - |
---|
256 | | -static int snd_cx18_pcm_hw_free(struct snd_pcm_substream *substream) |
---|
257 | | -{ |
---|
258 | | - struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream); |
---|
259 | | - unsigned long flags; |
---|
260 | | - unsigned char *dma_area = NULL; |
---|
261 | | - |
---|
262 | | - spin_lock_irqsave(&cxsc->slock, flags); |
---|
263 | | - if (substream->runtime->dma_area) { |
---|
264 | | - dprintk("freeing pcm capture region\n"); |
---|
265 | | - dma_area = substream->runtime->dma_area; |
---|
266 | | - substream->runtime->dma_area = NULL; |
---|
267 | | - } |
---|
268 | | - spin_unlock_irqrestore(&cxsc->slock, flags); |
---|
269 | | - vfree(dma_area); |
---|
270 | | - |
---|
271 | | - return 0; |
---|
272 | | -} |
---|
273 | | - |
---|
274 | 203 | static int snd_cx18_pcm_prepare(struct snd_pcm_substream *substream) |
---|
275 | 204 | { |
---|
276 | 205 | struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream); |
---|
.. | .. |
---|
300 | 229 | return hwptr_done; |
---|
301 | 230 | } |
---|
302 | 231 | |
---|
303 | | -static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs, |
---|
304 | | - unsigned long offset) |
---|
305 | | -{ |
---|
306 | | - void *pageptr = subs->runtime->dma_area + offset; |
---|
307 | | - |
---|
308 | | - return vmalloc_to_page(pageptr); |
---|
309 | | -} |
---|
310 | | - |
---|
311 | 232 | static const struct snd_pcm_ops snd_cx18_pcm_capture_ops = { |
---|
312 | 233 | .open = snd_cx18_pcm_capture_open, |
---|
313 | 234 | .close = snd_cx18_pcm_capture_close, |
---|
314 | | - .ioctl = snd_cx18_pcm_ioctl, |
---|
315 | | - .hw_params = snd_cx18_pcm_hw_params, |
---|
316 | | - .hw_free = snd_cx18_pcm_hw_free, |
---|
317 | 235 | .prepare = snd_cx18_pcm_prepare, |
---|
318 | 236 | .trigger = snd_cx18_pcm_trigger, |
---|
319 | 237 | .pointer = snd_cx18_pcm_pointer, |
---|
320 | | - .page = snd_pcm_get_vmalloc_page, |
---|
321 | 238 | }; |
---|
322 | 239 | |
---|
323 | 240 | int snd_cx18_pcm_create(struct snd_cx18_card *cxsc) |
---|
.. | .. |
---|
343 | 260 | |
---|
344 | 261 | snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE, |
---|
345 | 262 | &snd_cx18_pcm_capture_ops); |
---|
| 263 | + snd_pcm_set_managed_buffer_all(sp, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0); |
---|
346 | 264 | sp->info_flags = 0; |
---|
347 | 265 | sp->private_data = cxsc; |
---|
348 | | - strlcpy(sp->name, cx->card_name, sizeof(sp->name)); |
---|
| 266 | + strscpy(sp->name, cx->card_name, sizeof(sp->name)); |
---|
349 | 267 | |
---|
350 | 268 | return 0; |
---|
351 | 269 | |
---|