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

📄 gspca_core.c

📁 Linux下很强大的万能USB摄像头驱动。解压后
💻 C
📖 第 1 页 / 共 5 页
字号:
	{USB_DEVICE(0x046d, 0x092d)},	/* Logitech QC  Elch2 */	{USB_DEVICE(0x046d, 0x092e)},	/* Logitech QC  Elch2 */	{USB_DEVICE(0x046d, 0x092f)},	/* Logitech QC  Elch2 */	{USB_DEVICE(0x041e, 0x4051)},	/* Creative Live!Cam Notebook Pro (VF0250) */	{USB_DEVICE(0x041E, 0x4029)},	/* Creative WebCam Vista Pro */	{USB_DEVICE(0x041E, 0x041E)},	/* Creative WebCam Live! */	{USB_DEVICE(0x041e, 0x4053)},	/* Creative Live!Cam Video IM */	{USB_DEVICE(0x046d, 0x08d7)},	/* Logitech QCam STX */	{USB_DEVICE(0x046d, 0x08d8)},	/* Logitech Notebook Deluxe */	{USB_DEVICE(0x08ca, 0x2040)},	/* Aiptek PocketDV4100M */	{USB_DEVICE(0x0c45, 0x612c)},	/* Typhoon Rasy Cam 1.3MPix */	{USB_DEVICE(0x0c45, 0x613b)},	/* Surfer SN-206 */	{USB_DEVICE(0x0c45, 0x60fb)},	/* Surfer NoName */	{USB_DEVICE(0x0ac8, 0xc002)},	/* Sony embedded vimicro */	{USB_DEVICE(0x0ac8, 0x0321)},	/* Vimicro generic vc0321 */	{USB_DEVICE(0x046d, 0x0892)},	/* Logitech Orbicam */	{USB_DEVICE(0x046d, 0x0896)},	/* Logitech Orbicam */	{USB_DEVICE(0x045e, 0x00f7)},	/* MicroSoft VX1000 */	{USB_DEVICE(0x045e, 0x00f5)},	/* MicroSoft VX3000 */	{USB_DEVICE(0x0471, 0x032d)},	/* Philips spc210nc */	{USB_DEVICE(0x06d6, 0x0031)},	/* Trust 610 LCD PowerC@m Zoom (webcam mode) */	{USB_DEVICE(0x0ac8, 0xc001)},	/* Sony embedded vimicro */	{USB_DEVICE(0x0471, 0x032e)},	/* Philips spc315nc */	{USB_DEVICE(0x0c45, 0x6138)},	/* Sn9c120 Mo4000 */	{USB_DEVICE(0x041E, 0x401a)},	/* Creative Webcam Vista (PD1100) */	{USB_DEVICE(0x0458, 0x7025)},	/* Genius Eye 311Q sn9c120+Mi360 */	{USB_DEVICE(0x093a, 0x2600)},	/* PAC7311 Typhoon */	{USB_DEVICE(0x093a, 0x2601)},	/* PAC7311 Phillips SPC610NC */	{USB_DEVICE(0x093a, 0x2603)},	/* PAC7312  */	{USB_DEVICE(0x093a, 0x2608)},	/* PAC7311 Trust WB-3300p */	{USB_DEVICE(0x093a, 0x260e)},	/* PAC7311 Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350 */	{USB_DEVICE(0x093a, 0x260f)},	/* PAC7311 SnakeCam */	{USB_DEVICE(0x0471, 0x0322)},	/* Philips DMVC1300K */	{USB_DEVICE(0x0d64, 0x0303)},	/* Sunplus FashionCam DXG */	{USB_DEVICE(0x0ac8, 0x307b)},	/* Ldlc VC302+Ov7620 */	{USB_DEVICE(0x0ac8, 0x0328)},	/* A4Tech PK-130MG */	{USB_DEVICE(0x0c45, 0x60ec)},	/* SN9C105+MO4000 */	{USB_DEVICE(0x0471, 0x0330)},	/* Philips SPC 710NC */	{USB_DEVICE(0x0ac8, 0x0323)},	/* Vimicro Vc0323 */	{USB_DEVICE(0x17ef, 0x4802)},	/* Lenovo Vc0323+MI1310_SOC */	{USB_DEVICE(0x046d, 0x08dd)},	/* Logitech QuickCam for Notebooks */	{USB_DEVICE(0x046d, 0x08af)},	/* Logitech QuickCam Cool */	{USB_DEVICE(0x093a, 0x2472)},	/* PAC207 Genius VideoCam ge110 */	{USB_DEVICE(0x093a, 0x2463)},	/* Philips spc200nc pac207 */	{USB_DEVICE(0x0000, 0x0000)},	/* MystFromOri Unknow Camera */	{}			/* Terminating entry */};MODULE_DEVICE_TABLE(usb, device_table);/*Let's include the initialization data for each camera type*/#include "utils/spcausb.h"#include "Sunplus/spca501_init.h"#include "Sunplus/spca505_init.h"#include "Sunplus/spca506.h"#include "Sunplus/spca508_init.h"#include "Sunplus/spca561.h"#include "Sunplus-jpeg/jpeg_qtables.h"#include "Sunplus-jpeg/spca500_init.h"#include "Sunplus-jpeg/sp5xxfw2.h"#include "Sonix/sonix.h"#include "Vimicro/zc3xx.h"#include "Conexant/cx11646.h"#include "Transvision/tv8532.h"#include "Etoms/et61xx51.h"#include "Mars-Semi/mr97311.h"#include "Pixart/pac207.h"#include "Pixart/pac7311.h"#include "Vimicro/vc032x.h"/* function for the tasklet */void outpict_do_tasklet(unsigned long ptr);/************************************************************************ Memory management**********************************************************************/static inline unsigned longkvirt_to_pa(unsigned long adr){	unsigned long kva, ret;	kva = (unsigned long) page_address(vmalloc_to_page((void *) adr));	kva |= adr & (PAGE_SIZE - 1);	ret = __pa(kva);	return ret;}static void *rvmalloc(unsigned long size){	void *mem;	unsigned long adr;	size = PAGE_ALIGN(size);	mem = vmalloc_32(size);	if (!mem)		return NULL;	memset(mem, 0, size);	/* Clear the ram out, no junk to the user */	adr = (unsigned long) mem;	while ((long) size > 0) {		SetPageReserved(vmalloc_to_page((void *) adr));		adr += PAGE_SIZE;		size -= PAGE_SIZE;	}	return mem;}static voidrvfree(void *mem, unsigned long size){	unsigned long adr;	if (!mem)		return;	adr = (unsigned long) mem;	while ((long) size > 0) {		ClearPageReserved(vmalloc_to_page((void *) adr));		adr += PAGE_SIZE;		size -= PAGE_SIZE;	}	vfree(mem);}/* ------------------------------------------------------------------------ *//*** Endpoint management we assume one isoc endpoint per device* that is not true some Zoran 0x0572:0x0001 have two* assume ep adresse is static know * FIXME as I don't know how to set the bandwith budget* we allow the maximum**/static struct usb_host_endpoint *gspca_set_isoc_ep(struct usb_spca50x *spca50x, int nbalt){	int i, j;	struct usb_interface *intf;	struct usb_host_endpoint *ep;	struct usb_device *dev = spca50x->dev;	struct usb_host_interface *altsetting = NULL;	int error = 0;	PDEBUG(3, "enter get iso ep ");	intf = usb_ifnum_to_if(dev, spca50x->iface);/* bandwith budget can be set here */	for (i = nbalt; i; i--) {		altsetting = &intf->altsetting[i];		for (j = 0; j < altsetting->desc.bNumEndpoints; ++j) {			ep = &altsetting->endpoint[j];			PDEBUG(3, "test ISO EndPoint  %d",			       ep->desc.bEndpointAddress);			if ((ep->desc.bEndpointAddress ==			     (spca50x->epadr | USB_DIR_IN))			    &&			    ((ep->desc.			      bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==			     USB_ENDPOINT_XFER_ISOC)) {				PDEBUG(0,				       "ISO EndPoint found 0x%02X AlternateSet %d",				       ep->desc.bEndpointAddress, i);				if ((error =				     usb_set_interface(dev, spca50x->iface,						       i)) < 0) {					PDEBUG(0, "Set interface err %d",					       error);					return NULL;				}				spca50x->alt = i;				return ep;			}		}	}	PDEBUG(0, "FATAL ISO EndPoint not found ");	return NULL;}static intgspca_set_alt0(struct usb_spca50x *spca50x){	int error = 0;	if ((error = usb_set_interface(spca50x->dev, spca50x->iface, 0)) < 0) {		PDEBUG(0, "Set interface err %d", error);	}	spca50x->alt = 0;	return error;}static intgspca_kill_transfert(struct usb_spca50x *spca50x){	struct urb *urb;	unsigned int i;	spca50x->streaming = 0;	for (i = 0; i < SPCA50X_NUMSBUF; ++i) {		if ((urb = spca50x->sbuf[i].urb) == NULL)			continue;		usb_kill_urb(urb);/* urb->transfer_buffer_length is not touched by USB core, so* we can use it here as the buffer length.*/		if (spca50x->sbuf[i].data) {// kfree(gspca_dev->sbuf[i].data);			usb_buffer_free(spca50x->dev,					urb->transfer_buffer_length,					spca50x->sbuf[i].data,					urb->transfer_dma);			spca50x->sbuf[i].data = NULL;		}		usb_free_urb(urb);		spca50x->sbuf[i].urb = NULL;	}	return 0;}static intgspca_init_transfert(struct usb_spca50x *spca50x){	struct usb_host_endpoint *ep;	struct usb_interface *intf;	struct urb *urb;	__u16 psize;	int n, fx;	struct usb_device *dev = spca50x->dev;// struct usb_host_interface *altsetting = NULL;	int error = -ENOSPC;	int nbalt = 0;	if (spca50x->streaming)		return -EBUSY;	intf = usb_ifnum_to_if(dev, spca50x->iface);	nbalt = intf->num_altsetting - 1;/* Damned Sunplus fault */	if (spca50x->bridge == BRIDGE_SPCA561)		nbalt = 7;	PDEBUG(3, "get iso nbalt %d", nbalt);	spca50x->curframe = 0;	while (nbalt && (error == -ENOSPC)) {		if ((ep = gspca_set_isoc_ep(spca50x, nbalt--)) == NULL)			return -EIO;		psize = le16_to_cpu(ep->desc.wMaxPacketSize);		psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));		PDEBUG(3, "packet size %d", psize);		for (n = 0; n < SPCA50X_NUMSBUF; n++) {			urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);			if (!urb) {				err("init isoc: usb_alloc_urb ret. NULL");				return -ENOMEM;			}			spca50x->sbuf[n].data = usb_buffer_alloc(spca50x->dev,								 psize *								 FRAMES_PER_DESC,								 GFP_KERNEL,								 &urb->								 transfer_dma);//gspca_dev->sbuf[n].data = kmalloc((psize+1)* FRAMES_PER_DESC,GFP_KERNEL);			if (spca50x->sbuf[n].data == NULL) {				usb_free_urb(urb);				gspca_kill_transfert(spca50x);				return -ENOMEM;			}			spca50x->sbuf[n].urb = urb;			urb->dev = spca50x->dev;			urb->context = spca50x;			urb->pipe =			    usb_rcvisocpipe(spca50x->dev,					    ep->desc.bEndpointAddress);			urb->transfer_flags =			    URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;			urb->interval = ep->desc.bInterval;			urb->transfer_buffer = spca50x->sbuf[n].data;			urb->complete = spca50x_isoc_irq;			urb->number_of_packets = FRAMES_PER_DESC;			urb->transfer_buffer_length = psize * FRAMES_PER_DESC;			for (fx = 0; fx < FRAMES_PER_DESC; fx++) {				urb->iso_frame_desc[fx].offset = psize * fx;				urb->iso_frame_desc[fx].length = psize;			}		}/* mark all frame unused */		for (n = 0; n < SPCA50X_NUMFRAMES; n++) {			spca50x->frame[n].grabstate = FRAME_UNUSED;			spca50x->frame[n].scanstate = STATE_SCANNING;		}/* start the cam and initialize the tasklet lock */		spca50x->funct.start(spca50x);		spca50x->streaming = 1;		atomic_set(&spca50x->in_use, 0);		PDEBUG(3, "Submit URB Now");/* Submit the URBs. */		for (n = 0; n < SPCA50X_NUMSBUF; ++n) {			if ((error =			     usb_submit_urb(spca50x->sbuf[n].urb,					    GFP_KERNEL)) < 0) {				err("init isoc: usb_submit_urb(%d) ret %d", n,				    error);				gspca_kill_transfert(spca50x);				break;			}		}	}	return error;}/* Returns number of bits per pixel (regardless of where they are located; planar or* not), or zero for unsupported format.*/static intspca5xx_get_depth(struct usb_spca50x *spca50x, int palette){	switch (palette) {//      case VIDEO_PALETTE_GREY:     return 8;	case VIDEO_PALETTE_RGB565:		return 16;	case VIDEO_PALETTE_RGB24:		return 24;//      case VIDEO_PALETTE_YUV422:   return 16;//      case VIDEO_PALETTE_YUYV:// return 16;//      case VIDEO_PALETTE_YUV420:   return 24;	case VIDEO_PALETTE_YUV420P:		return 12;	/* strange need 12 this break the read method for this planar mode (6*8/4) *///      case VIDEO_PALETTE_YUV422P:  return 24; /* Planar */	case VIDEO_PALETTE_RGB32:		return 32;	case VIDEO_PALETTE_RAW_JPEG:		return 24;	/* raw jpeg. what should we return ?? */	case VIDEO_PALETTE_JPEG:		if (spca50x->cameratype == JPEG ||		    spca50x->cameratype == JPGH ||		    spca50x->cameratype == JPGC ||		    spca50x->cameratype == JPGS ||		    spca50x->cameratype == JPGM ||		    spca50x->cameratype == PJPG ||		    spca50x->cameratype == JPGV ) {			return 8;		} else			return 0;	default:		return 0;	/* Invalid format */	}}/*********************************************************************** spca50x_isoc_irq* Function processes the finish of the USB transfer by calling * spca50x_move_data function to move data from USB buffer to internal* driver structures ***********************************************************************/#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)static voidspca50x_isoc_irq(struct urb *urb, struct pt_regs *regs)#elsestatic voidspca50x_isoc_irq(struct urb *urb)#endif{	int i;	struct usb_spca50x *spca50x = (struct usb_spca50x *) urb->context;	int len;	switch (urb->status) {	case 0:		break;	default:		PDEBUG(0, "Non-zero status (%d) in isoc "		       "completion handler.", urb->status);	case -ENOENT:		/* usb_kill_urb() called. */	case -ECONNRESET:	/* usb_unlink_urb() called. */	case -ESHUTDOWN:	/* The endpoint is being disabled. */		return;	}	if (!spca50x->dev) {		PDEBUG(4, "no device ");		return;	}	if (!spca50x->user) {		PDEBUG(4, "device not open");		return;	}	if (!spca50x->streaming) {/* Always get some of these after close but before packet engine stops */		PDEBUG(4, "hmmm... not streaming, but got interrupt");		return;	}	if (!spca50x->present) {/*  */		PDEBUG(4, "device disconnected ..., but got interrupt !!");		return;	}/* Copy the data received into our scratch buffer */	if (spca50x->curframe >= 0) {		len = spca50x_move_data(spca50x, urb);	} else if (waitqueue_active(&spca50x->wq)) {		wake_up_interruptible(&spca50x->wq);	}/* Move to the next sbuf */	urb->dev = spca50x->dev;	urb->status = 0;	if ((i = usb_submit_urb(urb, GFP_ATOMIC)) != 0)		err("usb_submit_urb() ret %d", i);	return;}static voidspca50x_stop_isoc(struct usb_spca50x *spca50x){	if (!spca50x->streaming || !spca50x->dev)		return;	PDEBUG(3, "*** Stopping capture ***");

⌨️ 快捷键说明

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