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

📄 cpia2_v4l.c

📁 V4l driver for DVB HD
💻 C
📖 第 1 页 / 共 4 页
字号:
/**************************************************************************** * *  Filename: cpia2_v4l.c * *  Copyright 2001, STMicrolectronics, Inc. *      Contact:  steve.miller@st.com *  Copyright 2001,2005, Scott J. Bertin <scottbertin@yahoo.com> * *  Description: *     This is a USB driver for CPia2 based video cameras. *     The infrastructure of this driver is based on the cpia usb driver by *     Jochen Scharrlach and Johannes Erdfeldt. * *  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. * *  Stripped of 2.4 stuff ready for main kernel submit by *		Alan Cox <alan@redhat.com> ****************************************************************************/#include <linux/version.h>#include <linux/config.h>#include <linux/module.h>#include <linux/time.h>#include <linux/sched.h>#include <linux/slab.h>#include <linux/init.h>#include <linux/moduleparam.h>#include "cpia2.h"#include "cpia2dev.h"//#define _CPIA2_DEBUG_#define MAKE_STRING_1(x)	#x#define MAKE_STRING(x)	MAKE_STRING_1(x)static int video_nr = -1;module_param(video_nr, int, 0);MODULE_PARM_DESC(video_nr,"video device to register (0=/dev/video0, etc)");static int buffer_size = 68*1024;module_param(buffer_size, int, 0);MODULE_PARM_DESC(buffer_size, "Size for each frame buffer in bytes (default 68k)");static int num_buffers = 3;module_param(num_buffers, int, 0);MODULE_PARM_DESC(num_buffers, "Number of frame buffers (1-"		 MAKE_STRING(VIDEO_MAX_FRAME) ", default 3)");static int alternate = DEFAULT_ALT;module_param(alternate, int, 0);MODULE_PARM_DESC(alternate, "USB Alternate (" MAKE_STRING(USBIF_ISO_1) "-"		 MAKE_STRING(USBIF_ISO_6) ", default "		 MAKE_STRING(DEFAULT_ALT) ")");static int flicker_freq = 60;module_param(flicker_freq, int, 0);MODULE_PARM_DESC(flicker_freq, "Flicker frequency (" MAKE_STRING(50) "or"		 MAKE_STRING(60) ", default "		 MAKE_STRING(60) ")");static int flicker_mode = NEVER_FLICKER;module_param(flicker_mode, int, 0);MODULE_PARM_DESC(flicker_mode,		 "Flicker supression (" MAKE_STRING(NEVER_FLICKER) "or"		 MAKE_STRING(ANTI_FLICKER_ON) ", default "		 MAKE_STRING(NEVER_FLICKER) ")");MODULE_AUTHOR("Steve Miller (STMicroelectronics) <steve.miller@st.com>");MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras");MODULE_SUPPORTED_DEVICE("video");MODULE_LICENSE("GPL");#define ABOUT "V4L-Driver for Vision CPiA2 based cameras"#ifndef VID_HARDWARE_CPIA2#error "VID_HARDWARE_CPIA2 should have been defined in linux/videodev.h"#endifstruct control_menu_info {	int value;	char name[32];};static struct control_menu_info framerate_controls[] ={	{ CPIA2_VP_FRAMERATE_6_25, "6.25 fps" },	{ CPIA2_VP_FRAMERATE_7_5,  "7.5 fps"  },	{ CPIA2_VP_FRAMERATE_12_5, "12.5 fps" },	{ CPIA2_VP_FRAMERATE_15,   "15 fps"   },	{ CPIA2_VP_FRAMERATE_25,   "25 fps"   },	{ CPIA2_VP_FRAMERATE_30,   "30 fps"   },};#define NUM_FRAMERATE_CONTROLS (sizeof(framerate_controls)/sizeof(framerate_controls[0]))static struct control_menu_info flicker_controls[] ={	{ NEVER_FLICKER, "Off" },	{ FLICKER_50,    "50 Hz" },	{ FLICKER_60,    "60 Hz"  },};#define NUM_FLICKER_CONTROLS (sizeof(flicker_controls)/sizeof(flicker_controls[0]))static struct control_menu_info lights_controls[] ={	{ 0,   "Off" },	{ 64,  "Top" },	{ 128, "Bottom"  },	{ 192, "Both"  },};#define NUM_LIGHTS_CONTROLS (sizeof(lights_controls)/sizeof(lights_controls[0]))#define GPIO_LIGHTS_MASK 192static struct v4l2_queryctrl controls[] = {	{		.id            = V4L2_CID_BRIGHTNESS,		.type          = V4L2_CTRL_TYPE_INTEGER,		.name          = "Brightness",		.minimum       = 0,		.maximum       = 255,		.step          = 1,		.default_value = DEFAULT_BRIGHTNESS,	},	{		.id            = V4L2_CID_CONTRAST,		.type          = V4L2_CTRL_TYPE_INTEGER,		.name          = "Contrast",		.minimum       = 0,		.maximum       = 255,		.step          = 1,		.default_value = DEFAULT_CONTRAST,	},	{		.id            = V4L2_CID_SATURATION,		.type          = V4L2_CTRL_TYPE_INTEGER,		.name          = "Saturation",		.minimum       = 0,		.maximum       = 255,		.step          = 1,		.default_value = DEFAULT_SATURATION,	},	{		.id            = V4L2_CID_HFLIP,		.type          = V4L2_CTRL_TYPE_BOOLEAN,		.name          = "Mirror Horizontally",		.minimum       = 0,		.maximum       = 1,		.step          = 1,		.default_value = 0,	},	{		.id            = V4L2_CID_VFLIP,		.type          = V4L2_CTRL_TYPE_BOOLEAN,		.name          = "Flip Vertically",		.minimum       = 0,		.maximum       = 1,		.step          = 1,		.default_value = 0,	},	{		.id            = CPIA2_CID_TARGET_KB,		.type          = V4L2_CTRL_TYPE_INTEGER,		.name          = "Target KB",		.minimum       = 0,		.maximum       = 255,		.step          = 1,		.default_value = DEFAULT_TARGET_KB,	},	{		.id            = CPIA2_CID_GPIO,		.type          = V4L2_CTRL_TYPE_INTEGER,		.name          = "GPIO",		.minimum       = 0,		.maximum       = 255,		.step          = 1,		.default_value = 0,	},	{		.id            = CPIA2_CID_FLICKER_MODE,		.type          = V4L2_CTRL_TYPE_MENU,		.name          = "Flicker Reduction",		.minimum       = 0,		.maximum       = NUM_FLICKER_CONTROLS-1,		.step          = 1,		.default_value = 0,	},	{		.id            = CPIA2_CID_FRAMERATE,		.type          = V4L2_CTRL_TYPE_MENU,		.name          = "Framerate",		.minimum       = 0,		.maximum       = NUM_FRAMERATE_CONTROLS-1,		.step          = 1,		.default_value = NUM_FRAMERATE_CONTROLS-1,	},	{		.id            = CPIA2_CID_USB_ALT,		.type          = V4L2_CTRL_TYPE_INTEGER,		.name          = "USB Alternate",		.minimum       = USBIF_ISO_1,		.maximum       = USBIF_ISO_6,		.step          = 1,		.default_value = DEFAULT_ALT,	},	{		.id            = CPIA2_CID_LIGHTS,		.type          = V4L2_CTRL_TYPE_MENU,		.name          = "Lights",		.minimum       = 0,		.maximum       = NUM_LIGHTS_CONTROLS-1,		.step          = 1,		.default_value = 0,	},	{		.id            = CPIA2_CID_RESET_CAMERA,		.type          = V4L2_CTRL_TYPE_BUTTON,		.name          = "Reset Camera",		.minimum       = 0,		.maximum       = 0,		.step          = 0,		.default_value = 0,	},};#define NUM_CONTROLS (sizeof(controls)/sizeof(controls[0]))/****************************************************************************** * *  cpia2_open * *****************************************************************************/static int cpia2_open(struct inode *inode, struct file *file){	struct video_device *dev = video_devdata(file);	struct camera_data *cam = video_get_drvdata(dev);	int retval = 0;	if (!cam) {		ERR("Internal error, camera_data not found!\n");		return -ENODEV;	}	if(mutex_lock_interruptible(&cam->busy_lock))		return -ERESTARTSYS;	if(!cam->present) {		retval = -ENODEV;		goto err_return;	}	if (cam->open_count > 0) {		goto skip_init;	}	if (cpia2_allocate_buffers(cam)) {		retval = -ENOMEM;		goto err_return;	}	/* reset the camera */	if (cpia2_reset_camera(cam) < 0) {		retval = -EIO;		goto err_return;	}	cam->APP_len = 0;	cam->COM_len = 0;skip_init:	{		struct cpia2_fh *fh = kmalloc(sizeof(*fh),GFP_KERNEL);		if(!fh) {			retval = -ENOMEM;			goto err_return;		}		file->private_data = fh;		fh->prio = V4L2_PRIORITY_UNSET;		v4l2_prio_open(&cam->prio, &fh->prio);		fh->mmapped = 0;	}	++cam->open_count;	cpia2_dbg_dump_registers(cam);err_return:	mutex_unlock(&cam->busy_lock);	return retval;}/****************************************************************************** * *  cpia2_close * *****************************************************************************/static int cpia2_close(struct inode *inode, struct file *file){	struct video_device *dev = video_devdata(file);	struct camera_data *cam = video_get_drvdata(dev);	struct cpia2_fh *fh = file->private_data;	mutex_lock(&cam->busy_lock);	if (cam->present &&	    (cam->open_count == 1	     || fh->prio == V4L2_PRIORITY_RECORD	    )) {		cpia2_usb_stream_stop(cam);		if(cam->open_count == 1) {			/* save camera state for later open */			cpia2_save_camera_state(cam);			cpia2_set_low_power(cam);			cpia2_free_buffers(cam);		}	}	{		if(fh->mmapped)			cam->mmapped = 0;		v4l2_prio_close(&cam->prio,&fh->prio);		file->private_data = NULL;		kfree(fh);	}	if (--cam->open_count == 0) {		cpia2_free_buffers(cam);		if (!cam->present) {			video_unregister_device(dev);			kfree(cam);		}	}	mutex_unlock(&cam->busy_lock);	return 0;}/****************************************************************************** * *  cpia2_v4l_read * *****************************************************************************/static ssize_t cpia2_v4l_read(struct file *file, char __user *buf, size_t count,			      loff_t *off){	struct video_device *dev = video_devdata(file);	struct camera_data *cam = video_get_drvdata(dev);	int noblock = file->f_flags&O_NONBLOCK;	struct cpia2_fh *fh = file->private_data;	if(!cam)		return -EINVAL;	/* Priority check */	if(fh->prio != V4L2_PRIORITY_RECORD) {		return -EBUSY;	}	return cpia2_read(cam, buf, count, noblock);}/****************************************************************************** * *  cpia2_v4l_poll * *****************************************************************************/static unsigned int cpia2_v4l_poll(struct file *filp, struct poll_table_struct *wait){	struct video_device *dev = video_devdata(filp);	struct camera_data *cam = video_get_drvdata(dev);	struct cpia2_fh *fh = filp->private_data;	if(!cam)		return POLLERR;	/* Priority check */	if(fh->prio != V4L2_PRIORITY_RECORD) {		return POLLERR;	}	return cpia2_poll(cam, filp, wait);}/****************************************************************************** * *  ioctl_cap_query * *****************************************************************************/static int ioctl_cap_query(void *arg, struct camera_data *cam){	struct video_capability *vc;	int retval = 0;	vc = arg;	if (cam->params.pnp_id.product == 0x151)		strcpy(vc->name, "QX5 Microscope");	else		strcpy(vc->name, "CPiA2 Camera");	vc->type = VID_TYPE_CAPTURE | VID_TYPE_MJPEG_ENCODER;	vc->channels = 1;	vc->audios = 0;	vc->minwidth = 176;	/* VIDEOSIZE_QCIF */	vc->minheight = 144;	switch (cam->params.version.sensor_flags) {	case CPIA2_VP_SENSOR_FLAGS_500:		vc->maxwidth = STV_IMAGE_VGA_COLS;		vc->maxheight = STV_IMAGE_VGA_ROWS;		break;	case CPIA2_VP_SENSOR_FLAGS_410:		vc->maxwidth = STV_IMAGE_CIF_COLS;		vc->maxheight = STV_IMAGE_CIF_ROWS;		break;	default:		return -EINVAL;	}	return retval;}/****************************************************************************** * *  ioctl_get_channel * *****************************************************************************/static int ioctl_get_channel(void *arg){	int retval = 0;	struct video_channel *v;	v = arg;	if (v->channel != 0)		return -EINVAL;	v->channel = 0;	strcpy(v->name, "Camera");	v->tuners = 0;	v->flags = 0;	v->type = VIDEO_TYPE_CAMERA;	v->norm = 0;	return retval;}/****************************************************************************** * *  ioctl_set_channel * *****************************************************************************/static int ioctl_set_channel(void *arg){	struct video_channel *v;	int retval = 0;	v = arg;	if (retval == 0 && v->channel != 0)		retval = -EINVAL;	return retval;}/****************************************************************************** * *  ioctl_set_image_prop * *****************************************************************************/static int ioctl_set_image_prop(void *arg, struct camera_data *cam){	struct video_picture *vp;	int retval = 0;	vp = arg;	/* brightness, color, contrast need no check 0-65535 */	memcpy(&cam->vp, vp, sizeof(*vp));	/* update cam->params.colorParams */	cam->params.color_params.brightness = vp->brightness / 256;	cam->params.color_params.saturation = vp->colour / 256;	cam->params.color_params.contrast = vp->contrast / 256;	DBG("Requested params: bright 0x%X, sat 0x%X, contrast 0x%X\n",	    cam->params.color_params.brightness,	    cam->params.color_params.saturation,	    cam->params.color_params.contrast);	cpia2_set_color_params(cam);	return retval;}static int sync(struct camera_data *cam, int frame_nr){	struct framebuf *frame = &cam->buffers[frame_nr];	while (1) {		if (frame->status == FRAME_READY)			return 0;		if (!cam->streaming) {			frame->status = FRAME_READY;

⌨️ 快捷键说明

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