| .. | .. | 
|---|
| 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 |  | 
|---|