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

📄 spca5xx.c

📁 LINUX下的万能摄象头驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
	} 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,5,0)static void spca50x_isoc_irq(struct urb *urb, struct pt_regs *regs){    int i;#elsestatic void spca50x_isoc_irq(struct urb *urb){#endif    int len;    struct usb_spca50x *spca50x;    if (!urb->context) {	PDEBUG(4, "no context");	return;    }    spca50x = (struct usb_spca50x *) urb->context;    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 */    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    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_SN9CXXX:	sn9cxxx_start(spca50x);	break;    case BRIDGE_ETOMS:	Et_startCamera(spca50x);	break;    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:    case BRIDGE_SPCA504C:    case BRIDGE_SPCA536:    case BRIDGE_SPCA533:    case BRIDGE_SPCA504B:	{	    sp5xxfw2_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);	    break;	}    case BRIDGE_TV8532:	{	    tv8532_start(spca50x);	    break;	}    case BRIDGE_MR97311:	{	    pcam_start(spca50x);	    break;	}    case BRIDGE_PAC207:	{	    pac207_start(spca50x);	    break;	}    }}static inline void spcaCameraStop2(struct usb_spca50x *spca50x){/* stop on alt 0 */switch (spca50x->bridge) {	case BRIDGE_CX11646:	cx11646_stop(spca50x);	break;    case BRIDGE_ZC3XX:	zc3xx_stop(spca50x);	break;}}static inline void spcaCameraStop(struct usb_spca50x *spca50x){/* stop on alt x */    switch (spca50x->bridge) {    case BRIDGE_SN9CXXX:	sn9cxxx_stop(spca50x);	break;    case BRIDGE_ETOMS:	Et_stopCamera(spca50x);	break;    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:	{	    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_SPCA504C:    case BRIDGE_SPCA504:    case BRIDGE_SPCA536:    case BRIDGE_SPCA533:    case BRIDGE_SPCA504B:	{	    sp5xxfw2_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);	    break;	}    case BRIDGE_TV8532:	{	    tv8532_stop(spca50x);	    break;	}    case BRIDGE_MR97311:	{	    pcam_stop(spca50x);	    break;	}    case BRIDGE_PAC207:	{	    pac207_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 ***");/* reset iso context */    spca50x->compress = compress;    spca50x->curframe = 0;    spca50x->cursbuf = 0;    spca50x->frame[0].seq = -1;    spca50x->lastFrameRead = -1;    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;	if (spca50x->bridge == BRIDGE_PAC207) {	    urb->pipe =		usb_rcvisocpipe(spca50x->dev, PAC207_ENDPOINT_ADDRESS);	} else {	    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);	    return 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 spca5xx_kill_isoc(struct usb_spca50x *spca50x){    int n;    if (!spca50x)	return;    PDEBUG(3, "*** killing capture ***");    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;	}    }    PDEBUG(3, "*** Isoc killed ***");}static void spca50x_stop_isoc(struct usb_spca50x *spca50x){    if (!spca50x->streaming || !spca50x->dev)	return;    PDEBUG(3, "*** Stopping capture ***");    spcaCameraStop(spca50x);    spca5xx_kill_isoc(spca50x);    spca50x_set_packet_size(spca50x, 0);    spcaCameraStop2(spca50x);    PDEBUG(3, "*** Capture stopped ***");}/*********************************************************************** spca50x_find_mode_index* Function finds the mode index in the modes table***********************************************************************/static inline intspca50x_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

⌨️ 快捷键说明

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