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

📄 spca50x.c

📁 广州斯道2410普及版II的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	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 */	spca50x->cursbuf = (spca50x->cursbuf + 1) % SPCA50X_NUMSBUF;	urb->dev = spca50x->dev;	urb->status = 0;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 4)	if ((i = usb_submit_urb(urb, GFP_ATOMIC)) != 0)	err("usb_submit_urb() ret %d", i);#else/* If we use urb->next usb_submit_urb() is not need in 2.4.x */	//if ((i = usb_submit_urb(urb)) != 0)	//err("usb_submit_urb() ret %d", i);#endif			/* let's try to set up brightness for the next frame*/	if (autoadjust && !spca50x->bh_requested)	{		spca50x->task.data = spca50x;#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)		spca50x->task.func = auto_bh;		schedule_work(&spca50x->task);#else		spca50x->task.sync = 0;		spca50x->task.routine = auto_bh;		SCHEDULE_TASK(&spca50x->task);#endif		spca50x->bh_requested = 1;	}		return;}/*********************************************************************** spca50x_init_isoc* Function starts the ISO USB transfer by enabling this process* from USB side and enabling ISO machine from the chip side***********************************************************************/static inline void spcaCameraStart (struct usb_spca50x *spca50x){	int err_code;	struct usb_device *dev=spca50x->dev;	switch(spca50x->bridge)	{			case BRIDGE_CX11646:			cx11646_start(spca50x);			break;		case BRIDGE_ZC3XX:			zc3xx_start(spca50x );			break;		case BRIDGE_SONIX:			sonix_start(spca50x);			break;		case BRIDGE_SPCA500:		{			err_code = spca500_initialise(spca50x);			break;		}		case BRIDGE_SPCA501:		{			/* Enable ISO packet machine CTRL reg=2,			 * index=1 bitmask=0x2 (bit ordinal 1)			 */			err_code = spca50x_reg_write(dev, SPCA501_REG_CTLRL, 			                             (__u16)0x1, (__u16)0x2);			break;		}		case BRIDGE_SPCA504:			spca504_initialize(spca50x);			break;		case BRIDGE_SPCA504_PCCAM600:		{	/* specific code for clicsmart is in pccam600 */			spca504_pccam600_initialize(spca50x);			break;		}				case BRIDGE_SPCA536:		{			spca536_start(spca50x);			break;		}				case BRIDGE_SPCA533:			case BRIDGE_SPCA504B:		{			spca504B_start(spca50x);			break;		}		case BRIDGE_SPCA506:			spca506_start(spca50x);					break;		case BRIDGE_SPCA505:				{			//nessesary because without it we can see stream only once after loading module			//stopping usb registers Tomasz change			spca50x_reg_write(dev, 0x2, 0x0, 0x0);			/* Enable ISO packet machine - should we do this here or in ISOC init ? */			err_code = spca50x_reg_write(dev, SPCA50X_REG_USB,				SPCA50X_USB_CTRL, SPCA50X_CUSB_ENABLE);			//			spca50x_reg_write(dev, 0x5, 0x0, 0x0);//			spca50x_reg_write(dev, 0x5, 0x0, 0x1);//			spca50x_reg_write(dev, 0x5, 0x11, 0x2);			break;		}		case BRIDGE_SPCA508:			err_code = spca50x_reg_write(dev, 0, 0x8112, 0x10 | 0x20); 			break;		case BRIDGE_SPCA561:		{			/* Video ISO enable, Video Drop Packet enable: */			 spca561_start(spca50x); //spca50x_reg_write(dev, 0, 0x8112, 0x10 | 0x20); 			break;		}		case BRIDGE_TV8532:		{			tv8532_start(spca50x);			break;		}	}}static inline void spcaCameraStop (struct usb_spca50x *spca50x){			switch(spca50x->bridge)	{			case BRIDGE_CX11646:		/* deferred after set_alt(0,0) 			cx11646_stop(spca50x); 		*/		break;		case BRIDGE_ZC3XX:			zc3xx_stop(spca50x );		break;		case BRIDGE_SONIX:			sonix_stop(spca50x);			break;		case BRIDGE_SPCA500:		{			/* stop the transfer */			// Tha's the code need for familycam 300		 	//spca50x_reg_write(spca50x->dev, 0x00, 0x8000, 0x0000);		/*			spca50x_reg_write(spca50x->dev, 0xe1, 0x0001, 0x0000);			if (spca50x_reg_readwait(spca50x->dev, 0x06, 0, 0) != 0)			{				PDEBUG(2, "spca50x_reg_readwait() failed");			}			spca50x_reg_write(spca50x->dev, 0x0c, 0x0000, 0x0000);			spca50x_reg_write(spca50x->dev, 0x30, 0x0000, 0x0004);			if (spca500_full_reset(spca50x) < 0)			{				PDEBUG(2, "spca50x_full_reset() failed");			}		*/			break;		}		case BRIDGE_SPCA501:		{			/* Disable ISO packet machine CTRL reg=2, index=1 bitmask=0x0 (bit ordinal 1)*/			spca50x_reg_write(spca50x->dev, SPCA501_REG_CTLRL, 				(__u16)0x1, (__u16)0x0);			break;		}		case BRIDGE_SPCA504_PCCAM600:		case BRIDGE_SPCA504:			spca50x_reg_write(spca50x->dev, 0x00, 0x2000, 0x0000);						if (spca50x->desc == AiptekMiniPenCam13){					/* spca504a aiptek */						spca504A_acknowledged_command(spca50x, 0x08, 6, 0, 0x86, 1);			spca504A_acknowledged_command(spca50x, 0x24, 0x0000, 0x0000, 0x9d,1);			spca504A_acknowledged_command(spca50x, 0x01, 0x000f, 0x0000, 0xFF,1);			} else {			spca504_acknowledged_command(spca50x, 0x24, 0x0000, 0x0000);			spca50x_reg_write(spca50x->dev, 0x01, 0x000f, 0x0);			}			break;		case BRIDGE_SPCA536:		{			spca536_stop ( spca50x );		}			case BRIDGE_SPCA533:			case BRIDGE_SPCA504B:		{			spca504B_stop ( spca50x );			break;		}			case BRIDGE_SPCA505:		{			spca50x_reg_write(spca50x->dev,0x2,0x0,0x0); //Disable ISO packet machine			break;		}		case BRIDGE_SPCA506:			spca506_stop(spca50x);		break;		case BRIDGE_SPCA508:		{			// Video ISO disable, Video Drop Packet enable:			spca50x_reg_write(spca50x->dev, 0, 0x8112, 0x20); 			break;		}		case BRIDGE_SPCA561:		{			// Video ISO disable, Video Drop Packet enable:			spca561_stop(spca50x);//spca50x_reg_write(spca50x->dev, 0, 0x8112, 0x20); 			break;		}		case BRIDGE_TV8532:		{			tv8532_stop(spca50x);			break;			}	}}static int spca50x_init_isoc(struct usb_spca50x *spca50x){		struct urb *urb;	int fx, err, n;	int intpipe;	PDEBUG(3, "*** Initializing capture ***");	spca50x->compress = 0;	spca50x->curframe = 0;	spca50x->cursbuf = 0;	spca50x->scratchlen = 0;	spca50x_set_packet_size(spca50x, spca50x->pipe_size);	PDEBUG(2, "setpacketsize %d",spca50x->pipe_size);	for (n = 0; n < SPCA50X_NUMSBUF; n++) {#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)		urb = usb_alloc_urb(FRAMES_PER_DESC,GFP_KERNEL);#else		urb = usb_alloc_urb(FRAMES_PER_DESC);#endif		if (!urb) {			err("init isoc: usb_alloc_urb ret. NULL");			return -ENOMEM;		}		spca50x->sbuf[n].urb = urb;		urb->dev = spca50x->dev;		urb->context = spca50x;		urb->pipe = usb_rcvisocpipe(spca50x->dev, SPCA50X_ENDPOINT_ADDRESS);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)		urb->transfer_flags = URB_ISO_ASAP;		urb->interval = 1;#else		urb->transfer_flags = USB_ISO_ASAP;#endif		urb->transfer_buffer = spca50x->sbuf[n].data;		urb->complete = spca50x_isoc_irq;		urb->number_of_packets = FRAMES_PER_DESC;		urb->transfer_buffer_length = spca50x->packet_size * FRAMES_PER_DESC;		for (fx = 0; fx < FRAMES_PER_DESC; fx++) {			urb->iso_frame_desc[fx].offset = spca50x->packet_size * fx;			urb->iso_frame_desc[fx].length = spca50x->packet_size;		}	}#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,41)	spca50x->sbuf[SPCA50X_NUMSBUF - 1].urb->next = spca50x->sbuf[0].urb;	for (n = 0; n < SPCA50X_NUMSBUF - 1; n++)		spca50x->sbuf[n].urb->next = spca50x->sbuf[n + 1].urb;#endif	spcaCameraStart (spca50x);	if(spca50x->bridge == BRIDGE_SONIX){		intpipe= usb_rcvintpipe(spca50x->dev,3);		usb_clear_halt(spca50x->dev, intpipe);		}	PDEBUG(5, "init isoc int %d altsetting %d",spca50x->iface,spca50x->alt);	for (n = 0; n < SPCA50X_NUMSBUF; n++) {		spca50x->sbuf[n].urb->dev = spca50x->dev;#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)		err = usb_submit_urb(spca50x->sbuf[n].urb,GFP_KERNEL);#else		err = usb_submit_urb(spca50x->sbuf[n].urb);#endif		if (err)			err("init isoc: usb_submit_urb(%d) ret %d", n, err);	}	for (n = 0; n < SPCA50X_NUMFRAMES; n++)	{		spca50x->frame[n].grabstate = FRAME_UNUSED;		spca50x->frame[n].scanstate = STATE_SCANNING;	}		spca50x->streaming = 1;		return 0;}/*********************************************************************** spca50x_stop_isoc* Function stops the USB ISO pipe by stopping the chip ISO machine* and stopping USB transfer***********************************************************************/static void spca50x_stop_isoc(struct usb_spca50x *spca50x){	int n;	if (!spca50x->streaming || !spca50x->dev)		return;	PDEBUG (3, "*** Stopping capture ***");	spcaCameraStop ( spca50x );	spca50x->streaming = 0;	/* Unschedule all of the iso td's */	for (n = SPCA50X_NUMSBUF - 1; n >= 0; n--) {		if (spca50x->sbuf[n].urb) {#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)			usb_kill_urb(spca50x->sbuf[n].urb);#else			usb_unlink_urb(spca50x->sbuf[n].urb);#endif			usb_free_urb(spca50x->sbuf[n].urb);			spca50x->sbuf[n].urb = NULL;		}	}	spca50x_set_packet_size(spca50x, 0);	if (spca50x->bridge == BRIDGE_CX11646)		cx11646_stop(spca50x);		PDEBUG (3, "*** Capture stopped ***");}/*********************************************************************** spca50x_find_mode_index* Function finds the mode index in the modes table***********************************************************************/static inline int spca50x_find_mode_index(int   width,                                          int   height,                                           __u16 ext_modes [][6]){	int i = 0;	int j = 0;	/* search through the mode list until we hit one which has	 * a smaller or equal resolution, or we run out of modes.	 */	for (i = 0; ext_modes[i][0] && 		(ext_modes[i][0] >= width && ext_modes[i][1] >= height);		i++)	{ if (((ext_modes[i][2] & 0xF0) >> 4) == 0 ) j = (i & 0x0F) << 4;	}	/* search to found the first hardware available mode */	i--; /* FIXME */	PDEBUG(2, "find Hardware mode %d soft mode %d", j >> 4 ,i);	/* check whether we found the requested mode, or ran out of	 * modes in the list.	 */	if (!ext_modes[i][0]         ||	    ext_modes[i][0] != width ||	    ext_modes[i][1] != height )	{		PDEBUG(3, "Failed to find mode %d x %d", width, height);		return -EINVAL;	}	i = (i & 0x0F) | j;	PDEBUG(2, "Pass Hardware mode %d soft mode %d", (i >> 4) ,(i & 0x0F));	/* return the index of the requested mode */	return i;}/*********************************************************************** spca50x_smallest_mode_index* Function finds the mode index in the modes table of the smallest* available mode.***********************************************************************/static inline int spca50x_smallest_mode_index(__u16 ext_modes [][6],                                              int  *cols,                                              int  *rows,					      int  *pipe){	int i;	int width  = INT_MAX;	int height = INT_MAX;	int intpipe = 1023 ;	int index  = -EINVAL;	/* search through the mode list until we run out of modes */	/* and take the smallest hardware mode and pipe size*/	for (i = 0; ext_modes[i][0]; i++)	//i=0;	{		if (ext_modes[i][0] < width || ext_modes[i][1] < height)		{ if (!(ext_modes[i][2] & 0xF0)){			width  = 

⌨️ 快捷键说明

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