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

📄 stv680.c

📁 是关于linux2.5.1的完全源码
💻 C
📖 第 1 页 / 共 3 页
字号:
				else					*(output + x) -= (unsigned char) p;			}	/* for */		}		/* else */	}	/* if */	frame->curpix = 0;	frame->curlinepix = 0;	frame->grabstate = FRAME_DONE;	stv680->framecount++;	stv680->readcount++;	if (stv680->frame[(stv680->curframe + 1) & (STV680_NUMFRAMES - 1)].grabstate == FRAME_READY) {		stv680->curframe = (stv680->curframe + 1) & (STV680_NUMFRAMES - 1);	}}				/* bayer_unshuffle *//*******  end routines from the pencam program  *********/static int stv680_newframe (struct usb_stv *stv680, int framenr){	int errors = 0;	while (stv680->streaming && (stv680->frame[framenr].grabstate == FRAME_READY || stv680->frame[framenr].grabstate == FRAME_GRABBING)) {		if (!stv680->frame[framenr].curpix) {			errors++;		}		wait_event_interruptible (stv680->wq, (stv680->scratch[stv680->scratch_use].state == BUFFER_READY));		if (stv680->nullpackets > STV680_MAX_NULLPACKETS) {			stv680->nullpackets = 0;			PDEBUG (2, "STV(i): too many null length packets, restarting capture");			stv680_stop_stream (stv680);			stv680_start_stream (stv680);		} else {			if (stv680->scratch[stv680->scratch_use].state != BUFFER_READY) {				stv680->frame[framenr].grabstate = FRAME_ERROR;				PDEBUG (2, "STV(e): FRAME_ERROR in _newframe");				return -EIO;			}			stv680->scratch[stv680->scratch_use].state = BUFFER_BUSY;			bayer_unshuffle (stv680, &stv680->scratch[stv680->scratch_use]);			stv680->scratch[stv680->scratch_use].state = BUFFER_UNUSED;			stv680->scratch_use++;			if (stv680->scratch_use >= STV680_NUMSCRATCH)				stv680->scratch_use = 0;			if (errors > STV680_MAX_ERRORS) {				errors = 0;				PDEBUG (2, "STV(i): too many errors, restarting capture");				stv680_stop_stream (stv680);				stv680_start_stream (stv680);			}		}		/* else */	}			/* while */	return 0;}/********************************************************************* * Video4Linux *********************************************************************/static int stv_open (struct inode *inode, struct file *file){	struct video_device *dev = video_devdata(file);	struct usb_stv *stv680 = (struct usb_stv *) dev;	int err = 0;	/* we are called with the BKL held */	stv680->user = 1;	err = stv_init (stv680);	/* main initialization routine for camera */	if (err >= 0) {		stv680->fbuf = rvmalloc (stv680->maxframesize * STV680_NUMFRAMES);		if (!stv680->fbuf) {			PDEBUG (0, "STV(e): Could not rvmalloc frame bufer");			err = -ENOMEM;		}		file->private_data = dev;	}	if (err)		stv680->user = 0;	return err;}static int stv_close (struct inode *inode, struct file *file){	struct video_device *dev = file->private_data;	struct usb_stv *stv680 = (struct usb_stv *) dev;	int i;	for (i = 0; i < STV680_NUMFRAMES; i++)		stv680->frame[i].grabstate = FRAME_UNUSED;	if (stv680->streaming)		stv680_stop_stream (stv680);	if ((i = stv_stop_video (stv680)) < 0)		PDEBUG (1, "STV(e): stop_video failed in stv_close");	rvfree (stv680->fbuf, stv680->maxframesize * STV680_NUMFRAMES);	stv680->user = 0;	if (stv680->removed) {		kfree (stv680);		stv680 = NULL;		PDEBUG (0, "STV(i): device unregistered");	}	file->private_data = NULL;	return 0;}static int stv680_do_ioctl (struct inode *inode, struct file *file,			    unsigned int cmd, void *arg){	struct video_device *vdev = file->private_data;	struct usb_stv *stv680 = (struct usb_stv *) vdev;	if (!stv680->udev)		return -EIO;	switch (cmd) {	case VIDIOCGCAP:{			struct video_capability *b = arg;			strcpy (b->name, stv680->camera_name);			b->type = VID_TYPE_CAPTURE;			b->channels = 1;			b->audios = 0;			b->maxwidth = stv680->maxwidth;			b->maxheight = stv680->maxheight;			b->minwidth = stv680->maxwidth / 2;			b->minheight = stv680->maxheight / 2;			return 0;		}	case VIDIOCGCHAN:{			struct video_channel *v = arg;			if (v->channel != 0)				return -EINVAL;			v->flags = 0;			v->tuners = 0;			v->type = VIDEO_TYPE_CAMERA;			strcpy (v->name, "STV Camera");			return 0;		}	case VIDIOCSCHAN:{			struct video_channel *v = arg;			if (v->channel != 0)				return -EINVAL;			return 0;		}	case VIDIOCGPICT:{			struct video_picture *p = arg;			stv680_get_pict (stv680, p);			return 0;		}	case VIDIOCSPICT:{			struct video_picture *p = arg;			if (stv680_set_pict (stv680, p))				return -EINVAL;			return 0;		}	case VIDIOCSWIN:{			struct video_window *vw = arg;			if (vw->flags)				return -EINVAL;			if (vw->clipcount)				return -EINVAL;			if (vw->width != stv680->vwidth) {				if (stv680_set_size (stv680, vw->width, vw->height)) {					PDEBUG (2, "STV(e): failed (from user) set size in VIDIOCSWIN");					return -EINVAL;				}			}			return 0;		}	case VIDIOCGWIN:{			struct video_window *vw = arg;			vw->x = 0;	/* FIXME */			vw->y = 0;			vw->chromakey = 0;			vw->flags = 0;			vw->clipcount = 0;			vw->width = stv680->vwidth;			vw->height = stv680->vheight;			return 0;		}	case VIDIOCGMBUF:{			struct video_mbuf *vm = arg;			int i;			memset (vm, 0, sizeof (*vm));			vm->size = STV680_NUMFRAMES * stv680->maxframesize;			vm->frames = STV680_NUMFRAMES;			for (i = 0; i < STV680_NUMFRAMES; i++)				vm->offsets[i] = stv680->maxframesize * i;			return 0;		}	case VIDIOCMCAPTURE:{			struct video_mmap *vm = arg;			if (vm->format != STV_VIDEO_PALETTE) {				PDEBUG (2, "STV(i): VIDIOCMCAPTURE vm.format (%i) != VIDEO_PALETTE (%i)",					vm->format, STV_VIDEO_PALETTE);				if ((vm->format == 3) && (swapRGB_on == 0))  {					PDEBUG (2, "STV(i): VIDIOCMCAPTURE swapRGB is (auto) ON");					/* this may fix those apps (e.g., xawtv) that want BGR */					swapRGB = 1;				}				return -EINVAL;			}			if (vm->frame >= STV680_NUMFRAMES) {				PDEBUG (2, "STV(e): VIDIOCMCAPTURE vm.frame > NUMFRAMES");				return -EINVAL;			}			if ((stv680->frame[vm->frame].grabstate == FRAME_ERROR)			    || (stv680->frame[vm->frame].grabstate == FRAME_GRABBING)) {				PDEBUG (2, "STV(e): VIDIOCMCAPTURE grabstate (%i) error",					stv680->frame[vm->frame].grabstate);				return -EBUSY;			}			/* Is this according to the v4l spec??? */			if (stv680->vwidth != vm->width) {				if (stv680_set_size (stv680, vm->width, vm->height)) {					PDEBUG (2, "STV(e): VIDIOCMCAPTURE set_size failed");					return -EINVAL;				}			}			stv680->frame[vm->frame].grabstate = FRAME_READY;			if (!stv680->streaming)				stv680_start_stream (stv680);			return 0;		}	case VIDIOCSYNC:{			int *frame = arg;			int ret = 0;			if (*frame < 0 || *frame >= STV680_NUMFRAMES) {				PDEBUG (2, "STV(e): Bad frame # in VIDIOCSYNC");				return -EINVAL;			}			ret = stv680_newframe (stv680, *frame);			stv680->frame[*frame].grabstate = FRAME_UNUSED;			return ret;		}	case VIDIOCGFBUF:{			struct video_buffer *vb = arg;			memset (vb, 0, sizeof (*vb));			return 0;		}	case VIDIOCKEY:		return 0;	case VIDIOCCAPTURE:		{			PDEBUG (2, "STV(e): VIDIOCCAPTURE failed");			return -EINVAL;		}	case VIDIOCSFBUF:		return -EINVAL;	case VIDIOCGTUNER:	case VIDIOCSTUNER:		return -EINVAL;	case VIDIOCGFREQ:	case VIDIOCSFREQ:		return -EINVAL;	case VIDIOCGAUDIO:	case VIDIOCSAUDIO:		return -EINVAL;	default:		return -ENOIOCTLCMD;	}			/* end switch */	return 0;}static int stv680_ioctl(struct inode *inode, struct file *file,			unsigned int cmd, unsigned long arg){	return video_usercopy(inode, file, cmd, arg, stv680_do_ioctl);}static int stv680_mmap (struct file *file, struct vm_area_struct *vma){	struct video_device *dev = file->private_data;	struct usb_stv *stv680 = (struct usb_stv *) dev;	unsigned long start = vma->vm_start;	unsigned long size  = vma->vm_end-vma->vm_start;	unsigned long page, pos;	down (&stv680->lock);	if (stv680->udev == NULL) {		up (&stv680->lock);		return -EIO;	}	if (size > (((STV680_NUMFRAMES * stv680->maxframesize) + PAGE_SIZE - 1)		    & ~(PAGE_SIZE - 1))) {		up (&stv680->lock);		return -EINVAL;	}	pos = (unsigned long) stv680->fbuf;	while (size > 0) {		page = kvirt_to_pa (pos);		if (remap_page_range (vma, start, page, PAGE_SIZE, PAGE_SHARED)) {			up (&stv680->lock);			return -EAGAIN;		}		start += PAGE_SIZE;		pos += PAGE_SIZE;		if (size > PAGE_SIZE)			size -= PAGE_SIZE;		else			size = 0;	}	up (&stv680->lock);	return 0;}static int stv680_read (struct file *file, char *buf,			size_t count, loff_t *ppos){	struct video_device *dev = file->private_data;	unsigned long int realcount = count;	int ret = 0;	struct usb_stv *stv680 = (struct usb_stv *) dev;	unsigned long int i;	if (STV680_NUMFRAMES != 2) {		PDEBUG (0, "STV(e): STV680_NUMFRAMES needs to be 2!");		return -1;	}	if (stv680->udev == NULL)		return -EIO;	if (realcount > (stv680->vwidth * stv680->vheight * 3))		realcount = stv680->vwidth * stv680->vheight * 3;	/* Shouldn't happen: */	if (stv680->frame[0].grabstate == FRAME_GRABBING) {		PDEBUG (2, "STV(e): FRAME_GRABBING in stv680_read");		return -EBUSY;	}	stv680->frame[0].grabstate = FRAME_READY;	stv680->frame[1].grabstate = FRAME_UNUSED;	stv680->curframe = 0;	if (!stv680->streaming)		stv680_start_stream (stv680);	if (!stv680->streaming) {		ret = stv680_newframe (stv680, 0);	/* ret should = 0 */	}	ret = stv680_newframe (stv680, 0);	if (!ret) {		if ((i = copy_to_user (buf, stv680->frame[0].data, realcount)) != 0) {			PDEBUG (2, "STV(e): copy_to_user frame 0 failed, ret count = %li", i);			return -EFAULT;		}	} else {		realcount = ret;	}	stv680->frame[0].grabstate = FRAME_UNUSED;	return realcount;}				/* stv680_read */static struct file_operations stv680_fops = {	owner:		THIS_MODULE,	open:		stv_open,	release:       	stv_close,	read:		stv680_read,	mmap:		stv680_mmap,	ioctl:          stv680_ioctl,	llseek:         no_llseek,};static struct video_device stv680_template = {	owner:		THIS_MODULE,	name:		"STV0680 USB camera",	type:		VID_TYPE_CAPTURE,	hardware:	VID_HARDWARE_SE401,	fops:           &stv680_fops,};static void *__devinit stv680_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id){	struct usb_interface_descriptor *interface;	struct usb_stv *stv680;	char *camera_name = NULL;	/* We don't handle multi-config cameras */	if (dev->descriptor.bNumConfigurations != 1) {		PDEBUG (0, "STV(e): Number of Configurations != 1");		return NULL;	}	interface = &dev->actconfig->interface[ifnum].altsetting[0];	/* Is it a STV680? */	if ((dev->descriptor.idVendor == USB_PENCAM_VENDOR_ID) && (dev->descriptor.idProduct == USB_PENCAM_PRODUCT_ID)) {		camera_name = "STV0680";		PDEBUG (0, "STV(i): STV0680 camera found.");	} else {		PDEBUG (0, "STV(e): Vendor/Product ID do not match STV0680 values.");		PDEBUG (0, "STV(e): Check that the STV0680 camera is connected to the computer.");		return NULL;	}	/* We found one */	if ((stv680 = kmalloc (sizeof (*stv680), GFP_KERNEL)) == NULL) {		PDEBUG (0, "STV(e): couldn't kmalloc stv680 struct.");		return NULL;	}	memset (stv680, 0, sizeof (*stv680));	stv680->udev = dev;	stv680->camera_name = camera_name;	memcpy (&stv680->vdev, &stv680_template, sizeof (stv680_template));	memcpy (stv680->vdev.name, stv680->camera_name, strlen (stv680->camera_name));	init_waitqueue_head (&stv680->wq);	init_MUTEX (&stv680->lock);	wmb ();	if (video_register_device (&stv680->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {		kfree (stv680);		PDEBUG (0, "STV(e): video_register_device failed");		return NULL;	}#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)	create_proc_stv680_cam (stv680);#endif	PDEBUG (0, "STV(i): registered new video device: video%d", stv680->vdev.minor);	return stv680;}static inline void usb_stv680_remove_disconnected (struct usb_stv *stv680){	int i;	stv680->udev = NULL;	stv680->frame[0].grabstate = FRAME_ERROR;	stv680->frame[1].grabstate = FRAME_ERROR;	stv680->streaming = 0;	wake_up_interruptible (&stv680->wq);	for (i = 0; i < STV680_NUMSBUF; i++)		if (stv680->urb[i]) {			stv680->urb[i]->next = NULL;			usb_unlink_urb (stv680->urb[i]);			usb_free_urb (stv680->urb[i]);			stv680->urb[i] = NULL;			kfree (stv680->sbuf[i].data);		}	for (i = 0; i < STV680_NUMSCRATCH; i++)		if (stv680->scratch[i].data) {			kfree (stv680->scratch[i].data);		}	PDEBUG (0, "STV(i): %s disconnected", stv680->camera_name);#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)	destroy_proc_stv680_cam (stv680);#endif	/* Free the memory */	kfree (stv680);}static void stv680_disconnect (struct usb_device *dev, void *ptr){	struct usb_stv *stv680 = (struct usb_stv *) ptr;	/* We don't want people trying to open up the device */	video_unregister_device (&stv680->vdev);	if (!stv680->user) {		usb_stv680_remove_disconnected (stv680);	} else {		stv680->removed = 1;	}}static struct usb_driver stv680_driver = {	name:		"stv680",	probe:		stv680_probe,	disconnect:	stv680_disconnect,	id_table:	device_table};/******************************************************************** *  Module routines ********************************************************************/static int __init usb_stv680_init (void){#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)	if (proc_stv680_create () < 0)		return -1;#endif	if (usb_register (&stv680_driver) < 0) {		PDEBUG (0, "STV(e): Could not setup STV0680 driver");		return -1;	}	PDEBUG (0, "STV(i): usb camera driver version %s registering", DRIVER_VERSION);	info(DRIVER_DESC " " DRIVER_VERSION);	return 0;}static void __exit usb_stv680_exit (void){	usb_deregister (&stv680_driver);	PDEBUG (0, "STV(i): driver deregistered");#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)	proc_stv680_destroy ();#endif}module_init (usb_stv680_init);module_exit (usb_stv680_exit);

⌨️ 快捷键说明

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