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

📄 usbvision-video.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
{	.fops		= &usbvision_vbi_fops,	.release	= video_device_release,	.name           = "usbvision-vbi",	.minor		= -1,};static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision,					struct video_device *vdev_template,					char *name){	struct usb_device *usb_dev = usbvision->dev;	struct video_device *vdev;	if (usb_dev == NULL) {		err("%s: usbvision->dev is not set", __func__);		return NULL;	}	vdev = video_device_alloc();	if (NULL == vdev) {		return NULL;	}	*vdev = *vdev_template;//	vdev->minor   = -1;	vdev->parent  = &usb_dev->dev;	snprintf(vdev->name, sizeof(vdev->name), "%s", name);	video_set_drvdata(vdev, usbvision);	return vdev;}// unregister video4linux devicesstatic void usbvision_unregister_video(struct usb_usbvision *usbvision){	// vbi Device:	if (usbvision->vbi) {		PDEBUG(DBG_PROBE, "unregister /dev/vbi%d [v4l2]",		       usbvision->vbi->num);		if (usbvision->vbi->minor != -1) {			video_unregister_device(usbvision->vbi);		} else {			video_device_release(usbvision->vbi);		}		usbvision->vbi = NULL;	}	// Radio Device:	if (usbvision->rdev) {		PDEBUG(DBG_PROBE, "unregister /dev/radio%d [v4l2]",		       usbvision->rdev->num);		if (usbvision->rdev->minor != -1) {			video_unregister_device(usbvision->rdev);		} else {			video_device_release(usbvision->rdev);		}		usbvision->rdev = NULL;	}	// Video Device:	if (usbvision->vdev) {		PDEBUG(DBG_PROBE, "unregister /dev/video%d [v4l2]",		       usbvision->vdev->num);		if (usbvision->vdev->minor != -1) {			video_unregister_device(usbvision->vdev);		} else {			video_device_release(usbvision->vdev);		}		usbvision->vdev = NULL;	}}// register video4linux devicesstatic int __devinit usbvision_register_video(struct usb_usbvision *usbvision){	// Video Device:	usbvision->vdev = usbvision_vdev_init(usbvision,					      &usbvision_video_template,					      "USBVision Video");	if (usbvision->vdev == NULL) {		goto err_exit;	}	if (video_register_device(usbvision->vdev,				  VFL_TYPE_GRABBER,				  video_nr)<0) {		goto err_exit;	}	printk(KERN_INFO "USBVision[%d]: registered USBVision Video device /dev/video%d [v4l2]\n",	       usbvision->nr, usbvision->vdev->num);	// Radio Device:	if (usbvision_device_data[usbvision->DevModel].Radio) {		// usbvision has radio		usbvision->rdev = usbvision_vdev_init(usbvision,						      &usbvision_radio_template,						      "USBVision Radio");		if (usbvision->rdev == NULL) {			goto err_exit;		}		if (video_register_device(usbvision->rdev,					  VFL_TYPE_RADIO,					  radio_nr)<0) {			goto err_exit;		}		printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device /dev/radio%d [v4l2]\n",		       usbvision->nr, usbvision->rdev->num);	}	// vbi Device:	if (usbvision_device_data[usbvision->DevModel].vbi) {		usbvision->vbi = usbvision_vdev_init(usbvision,						     &usbvision_vbi_template,						     "USBVision VBI");		if (usbvision->vdev == NULL) {			goto err_exit;		}		if (video_register_device(usbvision->vbi,					  VFL_TYPE_VBI,					  vbi_nr)<0) {			goto err_exit;		}		printk(KERN_INFO "USBVision[%d]: registered USBVision VBI device /dev/vbi%d [v4l2] (Not Working Yet!)\n",		       usbvision->nr, usbvision->vbi->num);	}	// all done	return 0; err_exit:	err("USBVision[%d]: video_register_device() failed", usbvision->nr);	usbvision_unregister_video(usbvision);	return -1;}/* * usbvision_alloc() * * This code allocates the struct usb_usbvision. * It is filled with default values. * * Returns NULL on error, a pointer to usb_usbvision else. * */static struct usb_usbvision *usbvision_alloc(struct usb_device *dev){	struct usb_usbvision *usbvision;	if ((usbvision = kzalloc(sizeof(struct usb_usbvision), GFP_KERNEL)) ==	    NULL) {		goto err_exit;	}	usbvision->dev = dev;	mutex_init(&usbvision->lock);	/* available */	// prepare control urb for control messages during interrupts	usbvision->ctrlUrb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL);	if (usbvision->ctrlUrb == NULL) {		goto err_exit;	}	init_waitqueue_head(&usbvision->ctrlUrb_wq);	usbvision_init_powerOffTimer(usbvision);	return usbvision;err_exit:	if (usbvision && usbvision->ctrlUrb) {		usb_free_urb(usbvision->ctrlUrb);	}	if (usbvision) {		kfree(usbvision);	}	return NULL;}/* * usbvision_release() * * This code does final release of struct usb_usbvision. This happens * after the device is disconnected -and- all clients closed their files. * */static void usbvision_release(struct usb_usbvision *usbvision){	PDEBUG(DBG_PROBE, "");	mutex_lock(&usbvision->lock);	usbvision_reset_powerOffTimer(usbvision);	usbvision->initialized = 0;	mutex_unlock(&usbvision->lock);	usbvision_remove_sysfs(usbvision->vdev);	usbvision_unregister_video(usbvision);	if (usbvision->ctrlUrb) {		usb_free_urb(usbvision->ctrlUrb);	}	kfree(usbvision);	PDEBUG(DBG_PROBE, "success");}/*********************** usb interface **********************************/static void usbvision_configure_video(struct usb_usbvision *usbvision){	int model;	if (usbvision == NULL)		return;	model = usbvision->DevModel;	usbvision->palette = usbvision_v4l2_format[2]; // V4L2_PIX_FMT_RGB24;	if (usbvision_device_data[usbvision->DevModel].Vin_Reg2_override) {		usbvision->Vin_Reg2_Preset =			usbvision_device_data[usbvision->DevModel].Vin_Reg2;	} else {		usbvision->Vin_Reg2_Preset = 0;	}	usbvision->tvnormId = usbvision_device_data[model].VideoNorm;	usbvision->video_inputs = usbvision_device_data[model].VideoChannels;	usbvision->ctl_input = 0;	/* This should be here to make i2c clients to be able to register */	/* first switch off audio */	usbvision_audio_off(usbvision);	if (!PowerOnAtOpen) {		/* and then power up the noisy tuner */		usbvision_power_on(usbvision);		usbvision_i2c_register(usbvision);	}}/* * usbvision_probe() * * This procedure queries device descriptor and accepts the interface * if it looks like USBVISION video device * */static int __devinit usbvision_probe(struct usb_interface *intf,				     const struct usb_device_id *devid){	struct usb_device *dev = usb_get_dev(interface_to_usbdev(intf));	struct usb_interface *uif;	__u8 ifnum = intf->altsetting->desc.bInterfaceNumber;	const struct usb_host_interface *interface;	struct usb_usbvision *usbvision = NULL;	const struct usb_endpoint_descriptor *endpoint;	int model,i;	PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u",				dev->descriptor.idVendor,				dev->descriptor.idProduct, ifnum);	model = devid->driver_info;	if ( (model<0) || (model>=usbvision_device_data_size) ) {		PDEBUG(DBG_PROBE, "model out of bounds %d",model);		return -ENODEV;	}	printk(KERN_INFO "%s: %s found\n", __func__,				usbvision_device_data[model].ModelString);	if (usbvision_device_data[model].Interface >= 0) {		interface = &dev->actconfig->interface[usbvision_device_data[model].Interface]->altsetting[0];	} else {		interface = &dev->actconfig->interface[ifnum]->altsetting[0];	}	endpoint = &interface->endpoint[1].desc;	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=	    USB_ENDPOINT_XFER_ISOC) {		err("%s: interface %d. has non-ISO endpoint!",		    __func__, ifnum);		err("%s: Endpoint attributes %d",		    __func__, endpoint->bmAttributes);		return -ENODEV;	}	if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==	    USB_DIR_OUT) {		err("%s: interface %d. has ISO OUT endpoint!",		    __func__, ifnum);		return -ENODEV;	}	if ((usbvision = usbvision_alloc(dev)) == NULL) {		err("%s: couldn't allocate USBVision struct", __func__);		return -ENOMEM;	}	if (dev->descriptor.bNumConfigurations > 1) {		usbvision->bridgeType = BRIDGE_NT1004;	} else if (model == DAZZLE_DVC_90_REV_1_SECAM) {		usbvision->bridgeType = BRIDGE_NT1005;	} else {		usbvision->bridgeType = BRIDGE_NT1003;	}	PDEBUG(DBG_PROBE, "bridgeType %d", usbvision->bridgeType);	mutex_lock(&usbvision->lock);	/* compute alternate max packet sizes */	uif = dev->actconfig->interface[0];	usbvision->num_alt=uif->num_altsetting;	PDEBUG(DBG_PROBE, "Alternate settings: %i",usbvision->num_alt);	usbvision->alt_max_pkt_size = kmalloc(32*					      usbvision->num_alt,GFP_KERNEL);	if (usbvision->alt_max_pkt_size == NULL) {		err("usbvision: out of memory!\n");		mutex_unlock(&usbvision->lock);		return -ENOMEM;	}	for (i = 0; i < usbvision->num_alt ; i++) {		u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc.				      wMaxPacketSize);		usbvision->alt_max_pkt_size[i] =			(tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);		PDEBUG(DBG_PROBE, "Alternate setting %i, max size= %i",i,		       usbvision->alt_max_pkt_size[i]);	}	usbvision->nr = usbvision_nr++;	usbvision->have_tuner = usbvision_device_data[model].Tuner;	if (usbvision->have_tuner) {		usbvision->tuner_type = usbvision_device_data[model].TunerType;	}	usbvision->tuner_addr = ADDR_UNSET;	usbvision->DevModel = model;	usbvision->remove_pending = 0;	usbvision->iface = ifnum;	usbvision->ifaceAlt = 0;	usbvision->video_endp = endpoint->bEndpointAddress;	usbvision->isocPacketSize = 0;	usbvision->usb_bandwidth = 0;	usbvision->user = 0;	usbvision->streaming = Stream_Off;	usbvision_register_video(usbvision);	usbvision_configure_video(usbvision);	mutex_unlock(&usbvision->lock);	usb_set_intfdata (intf, usbvision);	usbvision_create_sysfs(usbvision->vdev);	PDEBUG(DBG_PROBE, "success");	return 0;}/* * usbvision_disconnect() * * This procedure stops all driver activity, deallocates interface-private * structure (pointed by 'ptr') and after that driver should be removable * with no ill consequences. * */static void __devexit usbvision_disconnect(struct usb_interface *intf){	struct usb_usbvision *usbvision = usb_get_intfdata(intf);	PDEBUG(DBG_PROBE, "");	if (usbvision == NULL) {		err("%s: usb_get_intfdata() failed", __func__);		return;	}	usb_set_intfdata (intf, NULL);	mutex_lock(&usbvision->lock);	// At this time we ask to cancel outstanding URBs	usbvision_stop_isoc(usbvision);	if (usbvision->power) {		usbvision_i2c_unregister(usbvision);		usbvision_power_off(usbvision);	}	usbvision->remove_pending = 1;	// Now all ISO data will be ignored	usb_put_dev(usbvision->dev);	usbvision->dev = NULL;	// USB device is no more	mutex_unlock(&usbvision->lock);	if (usbvision->user) {		printk(KERN_INFO "%s: In use, disconnect pending\n",		       __func__);		wake_up_interruptible(&usbvision->wait_frame);		wake_up_interruptible(&usbvision->wait_stream);	} else {		usbvision_release(usbvision);	}	PDEBUG(DBG_PROBE, "success");}static struct usb_driver usbvision_driver = {	.name		= "usbvision",	.id_table	= usbvision_table,	.probe		= usbvision_probe,	.disconnect	= usbvision_disconnect};/* * usbvision_init() * * This code is run to initialize the driver. * */static int __init usbvision_init(void){	int errCode;	PDEBUG(DBG_PROBE, "");	PDEBUG(DBG_IO,  "IO      debugging is enabled [video]");	PDEBUG(DBG_PROBE, "PROBE   debugging is enabled [video]");	PDEBUG(DBG_MMAP, "MMAP    debugging is enabled [video]");	/* disable planar mode support unless compression enabled */	if (isocMode != ISOC_MODE_COMPRESS ) {		// FIXME : not the right way to set supported flag		usbvision_v4l2_format[6].supported = 0; // V4L2_PIX_FMT_YVU420		usbvision_v4l2_format[7].supported = 0; // V4L2_PIX_FMT_YUV422P	}	errCode = usb_register(&usbvision_driver);	if (errCode == 0) {		printk(KERN_INFO DRIVER_DESC " : " USBVISION_VERSION_STRING "\n");		PDEBUG(DBG_PROBE, "success");	}	return errCode;}static void __exit usbvision_exit(void){ PDEBUG(DBG_PROBE, ""); usb_deregister(&usbvision_driver); PDEBUG(DBG_PROBE, "success");}module_init(usbvision_init);module_exit(usbvision_exit);/* * Overrides for Emacs so that we follow Linus's tabbing style. * --------------------------------------------------------------------------- * Local variables: * c-basic-offset: 8 * End: */

⌨️ 快捷键说明

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