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

📄 usbvision-video.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * USB USBVISION Video device driver 0.9.9 * * * * Copyright (c) 1999-2005 Joerg Heckenbach <joerg@heckenbach-aw.de> * * This module is part of usbvision driver project. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Let's call the version 0.... until compression decoding is completely * implemented. * * This driver is written by Jose Ignacio Gijon and Joerg Heckenbach. * It was based on USB CPiA driver written by Peter Pregler, * Scott J. Bertin and Johannes Erdfelt * Ideas are taken from bttv driver by Ralph Metzler, Marcus Metzler & * Gerd Knorr and zoran 36120/36125 driver by Pauline Middelink * Updates to driver completed by Dwaine P. Garden * * * TODO: *     - use submit_urb for all setup packets *     - Fix memory settings for nt1004. It is 4 times as big as the *       nt1003 memory. *     - Add audio on endpoint 3 for nt1004 chip. *         Seems impossible, needs a codec interface.  Which one? *     - Clean up the driver. *     - optimization for performance. *     - Add Videotext capability (VBI).  Working on it..... *     - Check audio for other devices * */#include <linux/version.h>#include <linux/kernel.h>#include <linux/list.h>#include <linux/timer.h>#include <linux/slab.h>#include <linux/mm.h>#include <linux/utsname.h>#include <linux/highmem.h>#include <linux/vmalloc.h>#include <linux/module.h>#include <linux/init.h>#include <linux/spinlock.h>#include <asm/io.h>#include <linux/videodev2.h>#include <linux/video_decoder.h>#include <linux/i2c.h>#include <media/saa7115.h>#include <media/v4l2-common.h>#include <media/v4l2-ioctl.h>#include <media/tuner.h>#include <linux/workqueue.h>#include "usbvision.h"#include "usbvision-cards.h"#define DRIVER_AUTHOR "Joerg Heckenbach <joerg@heckenbach-aw.de>,\ Dwaine Garden <DwaineGarden@rogers.com>"#define DRIVER_NAME "usbvision"#define DRIVER_ALIAS "USBVision"#define DRIVER_DESC "USBVision USB Video Device Driver for Linux"#define DRIVER_LICENSE "GPL"#define USBVISION_DRIVER_VERSION_MAJOR 0#define USBVISION_DRIVER_VERSION_MINOR 9#define USBVISION_DRIVER_VERSION_PATCHLEVEL 9#define USBVISION_DRIVER_VERSION KERNEL_VERSION(USBVISION_DRIVER_VERSION_MAJOR,\USBVISION_DRIVER_VERSION_MINOR,\USBVISION_DRIVER_VERSION_PATCHLEVEL)#define USBVISION_VERSION_STRING __stringify(USBVISION_DRIVER_VERSION_MAJOR)\ "." __stringify(USBVISION_DRIVER_VERSION_MINOR)\ "." __stringify(USBVISION_DRIVER_VERSION_PATCHLEVEL)#define	ENABLE_HEXDUMP	0	/* Enable if you need it */#ifdef USBVISION_DEBUG	#define PDEBUG(level, fmt, args...) { \		if (video_debug & (level)) \			printk(KERN_INFO KBUILD_MODNAME ":[%s:%d] " fmt, \				__func__, __LINE__ , ## args); \	}#else	#define PDEBUG(level, fmt, args...) do {} while(0)#endif#define DBG_IO		1<<1#define DBG_PROBE	1<<2#define DBG_MMAP	1<<3//String operations#define rmspace(str)	while(*str==' ') str++;#define goto2next(str)	while(*str!=' ') str++; while(*str==' ') str++;/* sequential number of usbvision device */static int usbvision_nr;static struct usbvision_v4l2_format_st usbvision_v4l2_format[] = {	{ 1, 1,  8, V4L2_PIX_FMT_GREY    , "GREY" },	{ 1, 2, 16, V4L2_PIX_FMT_RGB565  , "RGB565" },	{ 1, 3, 24, V4L2_PIX_FMT_RGB24   , "RGB24" },	{ 1, 4, 32, V4L2_PIX_FMT_RGB32   , "RGB32" },	{ 1, 2, 16, V4L2_PIX_FMT_RGB555  , "RGB555" },	{ 1, 2, 16, V4L2_PIX_FMT_YUYV    , "YUV422" },	{ 1, 2, 12, V4L2_PIX_FMT_YVU420  , "YUV420P" }, // 1.5 !	{ 1, 2, 16, V4L2_PIX_FMT_YUV422P , "YUV422P" }};/* Function prototypes */static void usbvision_release(struct usb_usbvision *usbvision);/* Default initialization of device driver parameters *//* Set the default format for ISOC endpoint */static int isocMode = ISOC_MODE_COMPRESS;/* Set the default Debug Mode of the device driver */static int video_debug;/* Set the default device to power on at startup */static int PowerOnAtOpen = 1;/* Sequential Number of Video Device */static int video_nr = -1;/* Sequential Number of Radio Device */static int radio_nr = -1;/* Sequential Number of VBI Device */static int vbi_nr = -1;/* Grab parameters for the device driver *//* Showing parameters under SYSFS */module_param(isocMode, int, 0444);module_param(video_debug, int, 0444);module_param(PowerOnAtOpen, int, 0444);module_param(video_nr, int, 0444);module_param(radio_nr, int, 0444);module_param(vbi_nr, int, 0444);MODULE_PARM_DESC(isocMode, " Set the default format for ISOC endpoint.  Default: 0x60 (Compression On)");MODULE_PARM_DESC(video_debug, " Set the default Debug Mode of the device driver.  Default: 0 (Off)");MODULE_PARM_DESC(PowerOnAtOpen, " Set the default device to power on when device is opened.  Default: 1 (On)");MODULE_PARM_DESC(video_nr, "Set video device number (/dev/videoX).  Default: -1 (autodetect)");MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX).  Default: -1 (autodetect)");MODULE_PARM_DESC(vbi_nr, "Set vbi device number (/dev/vbiX).  Default: -1 (autodetect)");// Misc stuffMODULE_AUTHOR(DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_LICENSE(DRIVER_LICENSE);MODULE_VERSION(USBVISION_VERSION_STRING);MODULE_ALIAS(DRIVER_ALIAS);/*****************************************************************************//* SYSFS Code - Copied from the stv680.c usb module.			     *//* Device information is located at /sys/class/video4linux/video0            *//* Device parameters information is located at /sys/module/usbvision         *//* Device USB Information is located at                                      *//*   /sys/bus/usb/drivers/USBVision Video Grabber                            *//*****************************************************************************/#define YES_NO(x) ((x) ? "Yes" : "No")static inline struct usb_usbvision *cd_to_usbvision(struct device *cd){	struct video_device *vdev =		container_of(cd, struct video_device, dev);	return video_get_drvdata(vdev);}static ssize_t show_version(struct device *cd,			    struct device_attribute *attr, char *buf){	return sprintf(buf, "%s\n", USBVISION_VERSION_STRING);}static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);static ssize_t show_model(struct device *cd,			  struct device_attribute *attr, char *buf){	struct video_device *vdev =		container_of(cd, struct video_device, dev);	struct usb_usbvision *usbvision = video_get_drvdata(vdev);	return sprintf(buf, "%s\n",		       usbvision_device_data[usbvision->DevModel].ModelString);}static DEVICE_ATTR(model, S_IRUGO, show_model, NULL);static ssize_t show_hue(struct device *cd,			struct device_attribute *attr, char *buf){	struct video_device *vdev =		container_of(cd, struct video_device, dev);	struct usb_usbvision *usbvision = video_get_drvdata(vdev);	struct v4l2_control ctrl;	ctrl.id = V4L2_CID_HUE;	ctrl.value = 0;	if(usbvision->user)		call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);	return sprintf(buf, "%d\n", ctrl.value);}static DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);static ssize_t show_contrast(struct device *cd,			     struct device_attribute *attr, char *buf){	struct video_device *vdev =		container_of(cd, struct video_device, dev);	struct usb_usbvision *usbvision = video_get_drvdata(vdev);	struct v4l2_control ctrl;	ctrl.id = V4L2_CID_CONTRAST;	ctrl.value = 0;	if(usbvision->user)		call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);	return sprintf(buf, "%d\n", ctrl.value);}static DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);static ssize_t show_brightness(struct device *cd,			       struct device_attribute *attr, char *buf){	struct video_device *vdev =		container_of(cd, struct video_device, dev);	struct usb_usbvision *usbvision = video_get_drvdata(vdev);	struct v4l2_control ctrl;	ctrl.id = V4L2_CID_BRIGHTNESS;	ctrl.value = 0;	if(usbvision->user)		call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);	return sprintf(buf, "%d\n", ctrl.value);}static DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);static ssize_t show_saturation(struct device *cd,			       struct device_attribute *attr, char *buf){	struct video_device *vdev =		container_of(cd, struct video_device, dev);	struct usb_usbvision *usbvision = video_get_drvdata(vdev);	struct v4l2_control ctrl;	ctrl.id = V4L2_CID_SATURATION;	ctrl.value = 0;	if(usbvision->user)		call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);	return sprintf(buf, "%d\n", ctrl.value);}static DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);static ssize_t show_streaming(struct device *cd,			      struct device_attribute *attr, char *buf){	struct video_device *vdev =		container_of(cd, struct video_device, dev);	struct usb_usbvision *usbvision = video_get_drvdata(vdev);	return sprintf(buf, "%s\n",		       YES_NO(usbvision->streaming==Stream_On?1:0));}static DEVICE_ATTR(streaming, S_IRUGO, show_streaming, NULL);static ssize_t show_compression(struct device *cd,				struct device_attribute *attr, char *buf){	struct video_device *vdev =		container_of(cd, struct video_device, dev);	struct usb_usbvision *usbvision = video_get_drvdata(vdev);	return sprintf(buf, "%s\n",		       YES_NO(usbvision->isocMode==ISOC_MODE_COMPRESS));}static DEVICE_ATTR(compression, S_IRUGO, show_compression, NULL);static ssize_t show_device_bridge(struct device *cd,				  struct device_attribute *attr, char *buf){	struct video_device *vdev =		container_of(cd, struct video_device, dev);	struct usb_usbvision *usbvision = video_get_drvdata(vdev);	return sprintf(buf, "%d\n", usbvision->bridgeType);}static DEVICE_ATTR(bridge, S_IRUGO, show_device_bridge, NULL);static void usbvision_create_sysfs(struct video_device *vdev){	int res;	if (!vdev)		return;	do {		res = device_create_file(&vdev->dev, &dev_attr_version);		if (res<0)			break;		res = device_create_file(&vdev->dev, &dev_attr_model);		if (res<0)			break;		res = device_create_file(&vdev->dev, &dev_attr_hue);		if (res<0)			break;		res = device_create_file(&vdev->dev, &dev_attr_contrast);		if (res<0)			break;		res = device_create_file(&vdev->dev, &dev_attr_brightness);		if (res<0)			break;		res = device_create_file(&vdev->dev, &dev_attr_saturation);		if (res<0)			break;		res = device_create_file(&vdev->dev, &dev_attr_streaming);		if (res<0)			break;		res = device_create_file(&vdev->dev, &dev_attr_compression);		if (res<0)			break;		res = device_create_file(&vdev->dev, &dev_attr_bridge);		if (res>=0)			return;	} while (0);	err("%s error: %d\n", __func__, res);}static void usbvision_remove_sysfs(struct video_device *vdev){	if (vdev) {		device_remove_file(&vdev->dev, &dev_attr_version);		device_remove_file(&vdev->dev, &dev_attr_model);		device_remove_file(&vdev->dev, &dev_attr_hue);		device_remove_file(&vdev->dev, &dev_attr_contrast);		device_remove_file(&vdev->dev, &dev_attr_brightness);		device_remove_file(&vdev->dev, &dev_attr_saturation);		device_remove_file(&vdev->dev, &dev_attr_streaming);		device_remove_file(&vdev->dev, &dev_attr_compression);		device_remove_file(&vdev->dev, &dev_attr_bridge);	}}/* * usbvision_open() * * This is part of Video 4 Linux API. The driver can be opened by one * client only (checks internal counter 'usbvision->user'). The procedure * then allocates buffers needed for video processing. * */static int usbvision_v4l2_open(struct inode *inode, struct file *file){	struct usb_usbvision *usbvision = video_drvdata(file);	int errCode = 0;	PDEBUG(DBG_IO, "open");	lock_kernel();	usbvision_reset_powerOffTimer(usbvision);	if (usbvision->user)		errCode = -EBUSY;	else {		/* Allocate memory for the scratch ring buffer */		errCode = usbvision_scratch_alloc(usbvision);		if (isocMode==ISOC_MODE_COMPRESS) {			/* Allocate intermediate decompression buffers			   only if needed */			errCode = usbvision_decompress_alloc(usbvision);		}		if (errCode) {			/* Deallocate all buffers if trouble */			usbvision_scratch_free(usbvision);			usbvision_decompress_free(usbvision);		}	}	/* If so far no errors then we shall start the camera */	if (!errCode) {		mutex_lock(&usbvision->lock);		if (usbvision->power == 0) {			usbvision_power_on(usbvision);			usbvision_i2c_register(usbvision);		}		/* Send init sequence only once, it's large! */		if (!usbvision->initialized) {			int setup_ok = 0;			setup_ok = usbvision_setup(usbvision,isocMode);			if (setup_ok)				usbvision->initialized = 1;			else				errCode = -EBUSY;		}		if (!errCode) {			usbvision_begin_streaming(usbvision);			errCode = usbvision_init_isoc(usbvision);			/* device must be initialized before isoc transfer */			usbvision_muxsel(usbvision,0);			usbvision->user++;		} else {			if (PowerOnAtOpen) {				usbvision_i2c_unregister(usbvision);				usbvision_power_off(usbvision);				usbvision->initialized = 0;			}		}		mutex_unlock(&usbvision->lock);	}	/* prepare queues */	usbvision_empty_framequeues(usbvision);	PDEBUG(DBG_IO, "success");	unlock_kernel();	return errCode;}/* * usbvision_v4l2_close() * * This is part of Video 4 Linux API. The procedure * stops streaming and deallocates all buffers that were earlier * allocated in usbvision_v4l2_open(). * */static int usbvision_v4l2_close(struct inode *inode, struct file *file){	struct usb_usbvision *usbvision = video_drvdata(file);	PDEBUG(DBG_IO, "close");	mutex_lock(&usbvision->lock);	usbvision_audio_off(usbvision);	usbvision_restart_isoc(usbvision);	usbvision_stop_isoc(usbvision);	usbvision_decompress_free(usbvision);	usbvision_frames_free(usbvision);	usbvision_empty_framequeues(usbvision);	usbvision_scratch_free(usbvision);	usbvision->user--;	if (PowerOnAtOpen) {		/* power off in a little while		   to avoid off/on every close/open short sequences */		usbvision_set_powerOffTimer(usbvision);		usbvision->initialized = 0;	}	mutex_unlock(&usbvision->lock);	if (usbvision->remove_pending) {		printk(KERN_INFO "%s: Final disconnect\n", __func__);		usbvision_release(usbvision);	}	PDEBUG(DBG_IO, "success");	return 0;

⌨️ 快捷键说明

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