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

📄 spca5xx.c

📁 摄像头驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
      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 voidspcaCameraStart (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 voidspcaCameraStop (struct usb_spca50x *spca50x){  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 intspca50x_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 voidspca5xx_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 voidspca50x_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);  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 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_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 int spca5xx_getDefaultMode(struct usb_spca50x *spca50x){  int i;  for (i = QCIF;i < TOTMODE; i++){  if(spca50x->mode_cam[i].method == 0 && spca50x->mode_cam[i].width){		spca50x->width = spca50x->mode_cam[i].width;		spca50x->height = spca50x->mode_cam[i].height;		spca50x->method = 0;		spca50x->pipe_size = spca50x->mode_cam[i].pipe ;		spca50x->mode = spca50x->mode_cam[i].mode;		return 0;		}  }return -EINVAL;}static inline intspca50x_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++)    {      if (ext_modes[i][0] < width || ext_modes[i][1] < height)	{	  if (!(ext_modes[i][2] & 0xF0))	    {	      width = ext_modes[i][0];	      height = ext_modes[i][1];	      intpipe = ext_modes[i][5];	      index = i;	    }	}    }  /* return the index of the smallest mode */  if (index != -EINVAL

⌨️ 快捷键说明

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