⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 em28xx-audio.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
#endif{	struct em28xx *dev = snd_pcm_substream_chip(substream);#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 16)	snd_pcm_runtime_t *runtime = substream->runtime;#else	struct snd_pcm_runtime *runtime = substream->runtime;#endif	int ret = 0;	dprintk("opening device and trying to acquire exclusive lock\n");	if (!dev) {		printk(KERN_ERR "BUG: em28xx can't find device struct."				" Can't proceed with open\n");		return -ENODEV;	}	/* Sets volume, mute, etc */	dev->mute = 0;	mutex_lock(&dev->lock);	ret = em28xx_audio_analog_set(dev);	mutex_unlock(&dev->lock);	if (ret < 0)		goto err;	runtime->hw = snd_em28xx_hw_capture;	if (dev->alt == 0 && dev->adev->users == 0) {		int errCode;		dev->alt = 7;		errCode = usb_set_interface(dev->udev, 0, 7);		dprintk("changing alternate number to 7\n");	}	dev->adev->users++;	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);	dev->adev->capture_pcm_substream = substream;	runtime->private_data = dev;	return 0;err:	printk(KERN_ERR "Error while configuring em28xx mixer\n");	return ret;}#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 16)static int snd_em28xx_pcm_close(snd_pcm_substream_t *substream)#elsestatic int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)#endif{	struct em28xx *dev = snd_pcm_substream_chip(substream);	dev->adev->users--;	dprintk("closing device\n");	dev->mute = 1;	mutex_lock(&dev->lock);	em28xx_audio_analog_set(dev);	mutex_unlock(&dev->lock);	if (dev->adev->users == 0 && dev->adev->shutdown == 1) {		dprintk("audio users: %d\n", dev->adev->users);		dprintk("disabling audio stream!\n");		dev->adev->shutdown = 0;		dprintk("released lock\n");		em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0);	}	return 0;}#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 16)static int snd_em28xx_hw_capture_params(snd_pcm_substream_t *substream,					snd_pcm_hw_params_t *hw_params)#elsestatic int snd_em28xx_hw_capture_params(struct snd_pcm_substream *substream,					struct snd_pcm_hw_params *hw_params)#endif{	unsigned int channels, rate, format;	int ret;	dprintk("Setting capture parameters\n");	ret = snd_pcm_alloc_vmalloc_buffer(substream,				params_buffer_bytes(hw_params));	format = params_format(hw_params);	rate = params_rate(hw_params);	channels = params_channels(hw_params);	/* TODO: set up em28xx audio chip to deliver the correct audio format,	   current default is 48000hz multiplexed => 96000hz mono	   which shouldn't matter since analogue TV only supports mono */	return 0;}#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 16)static int snd_em28xx_hw_capture_free(snd_pcm_substream_t *substream)#elsestatic int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream)#endif{	struct em28xx *dev = snd_pcm_substream_chip(substream);	dprintk("Stop capture, if needed\n");	if (dev->adev->capture_stream == STREAM_ON)		em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0);	return 0;}#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 16)static int snd_em28xx_prepare(snd_pcm_substream_t *substream)#elsestatic int snd_em28xx_prepare(struct snd_pcm_substream *substream)#endif{	return 0;}#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 16)static int snd_em28xx_capture_trigger(snd_pcm_substream_t *substream, int cmd)#elsestatic int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream,				      int cmd)#endif{	struct em28xx *dev = snd_pcm_substream_chip(substream);	dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START)?				       "start": "stop");	switch (cmd) {	case SNDRV_PCM_TRIGGER_START:		em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 1);		return 0;	case SNDRV_PCM_TRIGGER_STOP:		dev->adev->shutdown = 1;		return 0;	default:		return -EINVAL;	}}#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 16)static snd_pcm_uframes_t snd_em28xx_capture_pointer(snd_pcm_substream_t						    *substream)#elsestatic snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream						    *substream)#endif{	struct em28xx *dev;	snd_pcm_uframes_t hwptr_done;	dev = snd_pcm_substream_chip(substream);	hwptr_done = dev->adev->hwptr_done_capture;	return hwptr_done;}#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 16)static struct page *snd_pcm_get_vmalloc_page(snd_pcm_substream_t *subs,					     unsigned long offset)#elsestatic struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,					     unsigned long offset)#endif{	void *pageptr = subs->runtime->dma_area + offset;	return vmalloc_to_page(pageptr);}#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 16)static snd_pcm_ops_t snd_em28xx_pcm_capture = {#elsestatic struct snd_pcm_ops snd_em28xx_pcm_capture = {#endif	.open      = snd_em28xx_capture_open,	.close     = snd_em28xx_pcm_close,	.ioctl     = snd_pcm_lib_ioctl,	.hw_params = snd_em28xx_hw_capture_params,	.hw_free   = snd_em28xx_hw_capture_free,	.prepare   = snd_em28xx_prepare,	.trigger   = snd_em28xx_capture_trigger,	.pointer   = snd_em28xx_capture_pointer,	.page      = snd_pcm_get_vmalloc_page,};static int em28xx_audio_init(struct em28xx *dev){	struct em28xx_audio *adev;#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 16)	snd_pcm_t           *pcm;	snd_card_t          *card;#else	struct snd_pcm      *pcm;	struct snd_card     *card;#endif	static int          devnr;	int                 ret, err;	if (dev->has_audio_class) {		/* This device does not support the extension (in this case		   the device is expecting the snd-usb-audio module */		return 0;	}	printk(KERN_INFO "em28xx-audio.c: probing for em28x1 "			 "non standard usbaudio\n");	printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus "			 "Rechberger\n");	adev = kzalloc(sizeof(*adev), GFP_KERNEL);	if (!adev) {		printk(KERN_ERR "em28xx-audio.c: out of memory\n");		return -1;	}	card = snd_card_new(index[devnr], "Em28xx Audio", THIS_MODULE, 0);	if (card == NULL) {		kfree(adev);		return -ENOMEM;	}	spin_lock_init(&adev->slock);	ret = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm);	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_em28xx_pcm_capture);	pcm->info_flags = 0;	pcm->private_data = dev;	strcpy(pcm->name, "Empia 28xx Capture");	strcpy(card->driver, "Empia Em28xx Audio");	strcpy(card->shortname, "Em28xx Audio");	strcpy(card->longname, "Empia Em28xx Audio");	err = snd_card_register(card);	if (err < 0) {		snd_card_free(card);		return -ENOMEM;	}	adev->sndcard = card;	adev->udev = dev->udev;	dev->adev = adev;	return 0;}static int em28xx_audio_fini(struct em28xx *dev){	if (dev == NULL)		return 0;	if (dev->has_audio_class) {		/* This device does not support the extension (in this case		   the device is expecting the snd-usb-audio module */		return 0;	}	if (dev->adev) {		snd_card_free(dev->adev->sndcard);		kfree(dev->adev);		dev->adev = NULL;	}	return 0;}static struct em28xx_ops audio_ops = {	.id   = EM28XX_AUDIO,	.name = "Em28xx Audio Extension",	.init = em28xx_audio_init,	.fini = em28xx_audio_fini,};static int __init em28xx_alsa_register(void){	return em28xx_register_extension(&audio_ops);}static void __exit em28xx_alsa_unregister(void){	em28xx_unregister_extension(&audio_ops);}MODULE_LICENSE("GPL");MODULE_AUTHOR("Markus Rechberger <mrechberger@gmail.com>");MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");MODULE_DESCRIPTION("Em28xx Audio driver");module_init(em28xx_alsa_register);module_exit(em28xx_alsa_unregister);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -