| .. | .. |
|---|
| 30 | 30 | #include <linux/spinlock.h> |
|---|
| 31 | 31 | #include <linux/soundcard.h> |
|---|
| 32 | 32 | #include <linux/slab.h> |
|---|
| 33 | | -#include <linux/vmalloc.h> |
|---|
| 34 | | -#include <linux/proc_fs.h> |
|---|
| 35 | 33 | #include <linux/module.h> |
|---|
| 36 | 34 | #include <sound/core.h> |
|---|
| 37 | 35 | #include <sound/pcm.h> |
|---|
| .. | .. |
|---|
| 116 | 114 | stride = runtime->frame_bits >> 3; |
|---|
| 117 | 115 | |
|---|
| 118 | 116 | for (i = 0; i < urb->number_of_packets; i++) { |
|---|
| 117 | + unsigned long flags; |
|---|
| 119 | 118 | int length = |
|---|
| 120 | 119 | urb->iso_frame_desc[i].actual_length / stride; |
|---|
| 121 | 120 | cp = (unsigned char *)urb->transfer_buffer + |
|---|
| .. | .. |
|---|
| 137 | 136 | length * stride); |
|---|
| 138 | 137 | } |
|---|
| 139 | 138 | |
|---|
| 140 | | - snd_pcm_stream_lock(substream); |
|---|
| 139 | + snd_pcm_stream_lock_irqsave(substream, flags); |
|---|
| 141 | 140 | |
|---|
| 142 | 141 | dev->adev.hwptr_done_capture += length; |
|---|
| 143 | 142 | if (dev->adev.hwptr_done_capture >= |
|---|
| .. | .. |
|---|
| 153 | 152 | period_elapsed = 1; |
|---|
| 154 | 153 | } |
|---|
| 155 | 154 | |
|---|
| 156 | | - snd_pcm_stream_unlock(substream); |
|---|
| 155 | + snd_pcm_stream_unlock_irqrestore(substream, flags); |
|---|
| 157 | 156 | } |
|---|
| 158 | 157 | if (period_elapsed) |
|---|
| 159 | 158 | snd_pcm_period_elapsed(substream); |
|---|
| .. | .. |
|---|
| 188 | 187 | return err; |
|---|
| 189 | 188 | } |
|---|
| 190 | 189 | } |
|---|
| 191 | | - |
|---|
| 192 | | - return 0; |
|---|
| 193 | | -} |
|---|
| 194 | | - |
|---|
| 195 | | -static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, |
|---|
| 196 | | - size_t size) |
|---|
| 197 | | -{ |
|---|
| 198 | | - struct em28xx *dev = snd_pcm_substream_chip(subs); |
|---|
| 199 | | - struct snd_pcm_runtime *runtime = subs->runtime; |
|---|
| 200 | | - |
|---|
| 201 | | - dprintk("Allocating vbuffer\n"); |
|---|
| 202 | | - if (runtime->dma_area) { |
|---|
| 203 | | - if (runtime->dma_bytes > size) |
|---|
| 204 | | - return 0; |
|---|
| 205 | | - |
|---|
| 206 | | - vfree(runtime->dma_area); |
|---|
| 207 | | - } |
|---|
| 208 | | - runtime->dma_area = vmalloc(size); |
|---|
| 209 | | - if (!runtime->dma_area) |
|---|
| 210 | | - return -ENOMEM; |
|---|
| 211 | | - |
|---|
| 212 | | - runtime->dma_bytes = size; |
|---|
| 213 | 190 | |
|---|
| 214 | 191 | return 0; |
|---|
| 215 | 192 | } |
|---|
| .. | .. |
|---|
| 341 | 318 | } |
|---|
| 342 | 319 | |
|---|
| 343 | 320 | em28xx_audio_analog_set(dev); |
|---|
| 344 | | - if (substream->runtime->dma_area) { |
|---|
| 345 | | - dprintk("freeing\n"); |
|---|
| 346 | | - vfree(substream->runtime->dma_area); |
|---|
| 347 | | - substream->runtime->dma_area = NULL; |
|---|
| 348 | | - } |
|---|
| 349 | 321 | mutex_unlock(&dev->lock); |
|---|
| 350 | 322 | kref_put(&dev->ref, em28xx_free_device); |
|---|
| 351 | | - |
|---|
| 352 | | - return 0; |
|---|
| 353 | | -} |
|---|
| 354 | | - |
|---|
| 355 | | -static int snd_em28xx_hw_capture_params(struct snd_pcm_substream *substream, |
|---|
| 356 | | - struct snd_pcm_hw_params *hw_params) |
|---|
| 357 | | -{ |
|---|
| 358 | | - int ret; |
|---|
| 359 | | - struct em28xx *dev = snd_pcm_substream_chip(substream); |
|---|
| 360 | | - |
|---|
| 361 | | - if (dev->disconnected) |
|---|
| 362 | | - return -ENODEV; |
|---|
| 363 | | - |
|---|
| 364 | | - dprintk("Setting capture parameters\n"); |
|---|
| 365 | | - |
|---|
| 366 | | - ret = snd_pcm_alloc_vmalloc_buffer(substream, |
|---|
| 367 | | - params_buffer_bytes(hw_params)); |
|---|
| 368 | | - if (ret < 0) |
|---|
| 369 | | - return ret; |
|---|
| 370 | | -#if 0 |
|---|
| 371 | | - /* |
|---|
| 372 | | - * TODO: set up em28xx audio chip to deliver the correct audio format, |
|---|
| 373 | | - * current default is 48000hz multiplexed => 96000hz mono |
|---|
| 374 | | - * which shouldn't matter since analogue TV only supports mono |
|---|
| 375 | | - */ |
|---|
| 376 | | - unsigned int channels, rate, format; |
|---|
| 377 | | - |
|---|
| 378 | | - format = params_format(hw_params); |
|---|
| 379 | | - rate = params_rate(hw_params); |
|---|
| 380 | | - channels = params_channels(hw_params); |
|---|
| 381 | | -#endif |
|---|
| 382 | | - |
|---|
| 383 | | - return 0; |
|---|
| 384 | | -} |
|---|
| 385 | | - |
|---|
| 386 | | -static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream) |
|---|
| 387 | | -{ |
|---|
| 388 | | - struct em28xx *dev = snd_pcm_substream_chip(substream); |
|---|
| 389 | | - struct em28xx_audio *adev = &dev->adev; |
|---|
| 390 | | - |
|---|
| 391 | | - dprintk("Stop capture, if needed\n"); |
|---|
| 392 | | - |
|---|
| 393 | | - if (atomic_read(&adev->stream_started) > 0) { |
|---|
| 394 | | - atomic_set(&adev->stream_started, 0); |
|---|
| 395 | | - schedule_work(&adev->wq_trigger); |
|---|
| 396 | | - } |
|---|
| 397 | 323 | |
|---|
| 398 | 324 | return 0; |
|---|
| 399 | 325 | } |
|---|
| .. | .. |
|---|
| 436 | 362 | return -ENODEV; |
|---|
| 437 | 363 | |
|---|
| 438 | 364 | switch (cmd) { |
|---|
| 439 | | - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ |
|---|
| 440 | | - case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ |
|---|
| 365 | + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
|---|
| 366 | + case SNDRV_PCM_TRIGGER_RESUME: |
|---|
| 441 | 367 | case SNDRV_PCM_TRIGGER_START: |
|---|
| 442 | 368 | atomic_set(&dev->adev.stream_started, 1); |
|---|
| 443 | 369 | break; |
|---|
| 444 | | - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ |
|---|
| 445 | | - case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ |
|---|
| 370 | + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
|---|
| 371 | + case SNDRV_PCM_TRIGGER_SUSPEND: |
|---|
| 446 | 372 | case SNDRV_PCM_TRIGGER_STOP: |
|---|
| 447 | 373 | atomic_set(&dev->adev.stream_started, 0); |
|---|
| 448 | 374 | break; |
|---|
| .. | .. |
|---|
| 469 | 395 | spin_unlock_irqrestore(&dev->adev.slock, flags); |
|---|
| 470 | 396 | |
|---|
| 471 | 397 | return hwptr_done; |
|---|
| 472 | | -} |
|---|
| 473 | | - |
|---|
| 474 | | -static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs, |
|---|
| 475 | | - unsigned long offset) |
|---|
| 476 | | -{ |
|---|
| 477 | | - void *pageptr = subs->runtime->dma_area + offset; |
|---|
| 478 | | - |
|---|
| 479 | | - return vmalloc_to_page(pageptr); |
|---|
| 480 | 398 | } |
|---|
| 481 | 399 | |
|---|
| 482 | 400 | /* |
|---|
| .. | .. |
|---|
| 708 | 626 | static const struct snd_pcm_ops snd_em28xx_pcm_capture = { |
|---|
| 709 | 627 | .open = snd_em28xx_capture_open, |
|---|
| 710 | 628 | .close = snd_em28xx_pcm_close, |
|---|
| 711 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 712 | | - .hw_params = snd_em28xx_hw_capture_params, |
|---|
| 713 | | - .hw_free = snd_em28xx_hw_capture_free, |
|---|
| 714 | 629 | .prepare = snd_em28xx_prepare, |
|---|
| 715 | 630 | .trigger = snd_em28xx_capture_trigger, |
|---|
| 716 | 631 | .pointer = snd_em28xx_capture_pointer, |
|---|
| 717 | | - .page = snd_pcm_get_vmalloc_page, |
|---|
| 718 | 632 | }; |
|---|
| 719 | 633 | |
|---|
| 720 | 634 | static void em28xx_audio_free_urb(struct em28xx *dev) |
|---|
| .. | .. |
|---|
| 842 | 756 | |
|---|
| 843 | 757 | dev->adev.transfer_buffer = kcalloc(num_urb, |
|---|
| 844 | 758 | sizeof(*dev->adev.transfer_buffer), |
|---|
| 845 | | - GFP_ATOMIC); |
|---|
| 759 | + GFP_KERNEL); |
|---|
| 846 | 760 | if (!dev->adev.transfer_buffer) |
|---|
| 847 | 761 | return -ENOMEM; |
|---|
| 848 | 762 | |
|---|
| 849 | | - dev->adev.urb = kcalloc(num_urb, sizeof(*dev->adev.urb), GFP_ATOMIC); |
|---|
| 763 | + dev->adev.urb = kcalloc(num_urb, sizeof(*dev->adev.urb), GFP_KERNEL); |
|---|
| 850 | 764 | if (!dev->adev.urb) { |
|---|
| 851 | 765 | kfree(dev->adev.transfer_buffer); |
|---|
| 852 | 766 | return -ENOMEM; |
|---|
| .. | .. |
|---|
| 859 | 773 | int j, k; |
|---|
| 860 | 774 | void *buf; |
|---|
| 861 | 775 | |
|---|
| 862 | | - urb = usb_alloc_urb(npackets, GFP_ATOMIC); |
|---|
| 776 | + urb = usb_alloc_urb(npackets, GFP_KERNEL); |
|---|
| 863 | 777 | if (!urb) { |
|---|
| 864 | 778 | em28xx_audio_free_urb(dev); |
|---|
| 865 | 779 | return -ENOMEM; |
|---|
| 866 | 780 | } |
|---|
| 867 | 781 | dev->adev.urb[i] = urb; |
|---|
| 868 | 782 | |
|---|
| 869 | | - buf = usb_alloc_coherent(udev, npackets * ep_size, GFP_ATOMIC, |
|---|
| 783 | + buf = usb_alloc_coherent(udev, npackets * ep_size, GFP_KERNEL, |
|---|
| 870 | 784 | &urb->transfer_dma); |
|---|
| 871 | 785 | if (!buf) { |
|---|
| 872 | 786 | dev_err(&dev->intf->dev, |
|---|
| .. | .. |
|---|
| 936 | 850 | goto card_free; |
|---|
| 937 | 851 | |
|---|
| 938 | 852 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_em28xx_pcm_capture); |
|---|
| 853 | + snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0); |
|---|
| 939 | 854 | pcm->info_flags = 0; |
|---|
| 940 | 855 | pcm->private_data = dev; |
|---|
| 941 | | - strcpy(pcm->name, "Empia 28xx Capture"); |
|---|
| 856 | + strscpy(pcm->name, "Empia 28xx Capture", sizeof(pcm->name)); |
|---|
| 942 | 857 | |
|---|
| 943 | | - strcpy(card->driver, "Em28xx-Audio"); |
|---|
| 944 | | - strcpy(card->shortname, "Em28xx Audio"); |
|---|
| 945 | | - strcpy(card->longname, "Empia Em28xx Audio"); |
|---|
| 858 | + strscpy(card->driver, "Em28xx-Audio", sizeof(card->driver)); |
|---|
| 859 | + strscpy(card->shortname, "Em28xx Audio", sizeof(card->shortname)); |
|---|
| 860 | + strscpy(card->longname, "Empia Em28xx Audio", sizeof(card->longname)); |
|---|
| 946 | 861 | |
|---|
| 947 | 862 | INIT_WORK(&adev->wq_trigger, audio_trigger); |
|---|
| 948 | 863 | |
|---|