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

📄 spca5xx.c

📁 凌阳SPCA5XX解码芯片USB驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
spca50x_write_proc (struct file *file, const char *buffer,		    unsigned long count, void *data){  return -EINVAL;}/* * Function services read requests to control proc entry * and prints all the static variables */static intspca50x_ctlread_proc (char *page, char **start, off_t off,		      int count, int *eof, void *data){  char *out = page;  int len = 0;  struct usb_spca50x *spca50x = data;  out += sprintf (out, "force_rgb = %d\n", spca50x->force_rgb);  out += sprintf (out, "min_bpp = %d\n", spca50x->min_bpp);  out += sprintf (out, "lum_level = %d\n", spca50x->lum_level);  out += sprintf (out, "debug = %d\n", debug);#ifdef SPCA50X_ENABLE_OSD  out += sprintf (out, "osd = %d\n", osd);#endif /* SPCA50X_ENABLE_OSD */  len = out - page;  len -= off;  if (len < count)    {      *eof = 1;      if (len <= 0)	return 0;    }  else    len = count;  *start = page + off;  return len;}/* * Function compares two strings. * Return offset in pussy where prick ends if "prick" may penetrate  * int "pussy" like prick into pussy, -1 otherwise. */static inline intmatch (const char *prick, const char *pussy, int len2){  int len1 = strlen (prick);	//length of male string  int i;			//just an index variable  const char *tmp;		//temporary pointer for my own pleasure  // We skip all spaces and tabs  for (i = 0; i < len2 && (pussy[i] == ' ' || pussy[i] == '\t'); i++)    {    }  tmp = pussy + i;		// pointer to pussy with skipped shit (spaces and tabs)  len2 = strlen (tmp);		//calculate length again  if (len1 > len2)    return -1;			//Fuck off, no fucking  if (!strncmp (prick, tmp, len1))    return i + len1;  return -1;}#ifdef SPCA50X_ENABLE_RAWPROCENTRYstatic intspca50x_rawread_proc (char *page,		      char **start,		      off_t off, int count, int *eof, void *data){  struct usb_spca50x *spca50x = data;  *start = page;  /* check whether the buffer exists */  if (spca50x->rawBuffer == NULL)    {      *eof = 1;      return 0;    }  /* check offset is valid */  if (off > spca50x->rawBufferSize)    {      *eof = 1;      return 0;    }  /* can't read more than exists in the buffer, either */  if ((count + off) > spca50x->rawBufferSize)    {      count = spca50x->rawBufferSize - off;    }  /* can't read more than is available in the output buffer */  if (count > PAGE_SIZE)    {      count = PAGE_SIZE;    }  if (count == 0)    {      *eof = 1;      return 0;    }  /* populate the output buffer */  memcpy (page, spca50x->rawBuffer + off, count);  /* return read count */  return count;}static intspca50x_rawwrite_proc (struct file *file,		       const char *buffer, unsigned long count, void *data){  struct usb_spca50x *spca50x = data;  /* if anything is written, flush the buffer */  PDEBUG (3, "flushed raw proc entry buffer");  spca50x->rawBufferSize = 0;  return count;}#endif /* SPCA50X_ENABLE_RAWPROCENTRY *//* * Try to calculate value from string (atoi). Converts   * decimal integer */static inline intatoi (const char *str){  int result = 0;		//result of the function  int i;			//just an index variable  for (i = 0; str[i] >= '0' && str[i] <= '9'; i++)    {      result *= 10;      result += str[i] - '0';    }  return result;}static intspca50x_ctlwrite_proc (struct file *file, const char *buffer,		       unsigned long count, void *data){  int off;			//where look for a value  struct usb_spca50x *spca50x = data;  if ((off = match ("lum_level=", buffer, count)) >= 0)    spca50x->lum_level = atoi (buffer + off);  if ((off = match ("min_bpp=", buffer, count)) >= 0)    spca50x->min_bpp = atoi (buffer + off);  if ((off = match ("force_rgb=", buffer, count)) >= 0)    spca50x->force_rgb = atoi (buffer + off);  if ((off = match ("debug=", buffer, count)) >= 0)    debug = atoi (buffer + off);  return count;}static voidcreate_proc_spca50x_cam (struct usb_spca50x *spca50x){  char name[PROC_NAME_LEN];  struct proc_dir_entry *ent;  if (!spca50x_proc_entry || !spca50x)    return;//Create videoxx proc entry  sprintf (name, "video%d", spca50x->vdev->minor);  PDEBUG (4, "creating /proc/video/spca50x/%s", name);  ent =    create_proc_entry (name, S_IFREG | S_IRUGO | S_IWUSR, spca50x_proc_entry);  if (!ent)    return;  ent->data = spca50x;  ent->read_proc = spca50x_read_proc;  ent->write_proc = spca50x_write_proc;  spca50x->proc_entry = ent;// Create the controlxx proc entry  sprintf (name, "control%d", spca50x->vdev->minor);  PDEBUG (4, "creating /proc/video/spca50x/%s", name);  ent = create_proc_entry (name, S_IFREG | S_IRUGO | S_IWUSR,			   spca50x_proc_entry);  if (!ent)    return;  ent->data = spca50x;  ent->read_proc = spca50x_ctlread_proc;  ent->write_proc = spca50x_ctlwrite_proc;  spca50x->ctl_proc_entry = ent;#ifdef SPCA50X_ENABLE_RAWPROCENTRY// Create the rawxx proc entry  sprintf (name, "raw%d", spca50x->vdev.minor);  PDEBUG (4, "creating /proc/video/spca50x/%s", name);  ent = create_proc_entry (name, S_IFREG | S_IRUGO | S_IWUSR,			   spca50x_proc_entry);  if (!ent)    return;  ent->data = spca50x;  ent->read_proc = spca50x_rawread_proc;  ent->write_proc = spca50x_rawwrite_proc;  spca50x->raw_proc_entry = ent;  spca50x->rawBufferSize = 0;  spca50x->rawBuffer = vmalloc (10 * 1024 * 1024);  if (spca50x->rawBuffer != NULL)    {      spca50x->rawBufferMax = 10 * 1024 * 1024;      PDEBUG (3, "allocated 10Mb raw proc entry buffer");    }  else    {      PDEBUG (3, "vmalloc of raw proc entry buffer failed");      spca50x->rawBufferMax = 0;    }#endif /* SPCA50X_ENABLE_RAWPROCENTRY */}static voiddestroy_proc_spca50x_cam (struct usb_spca50x *spca50x){  char name[PROC_NAME_LEN];  if (!spca50x || !spca50x_proc_entry)    return;  /* destroy videoxx proc entry */  if (spca50x->proc_entry != NULL)    {      sprintf (name, "video%d", spca50x->vdev->minor);      PDEBUG (4, "destroying %s", name);      remove_proc_entry (name, spca50x_proc_entry);      spca50x->proc_entry = NULL;    }  /* destroy controlxx proc entry */  if (spca50x->ctl_proc_entry != NULL)    {      sprintf (name, "control%d", spca50x->vdev->minor);      PDEBUG (4, "destroying %s", name);      remove_proc_entry (name, spca50x_proc_entry);      spca50x->ctl_proc_entry = NULL;    }#ifdef SPCA50X_ENABLE_RAWPROCENTRY  /* destroy rawxx proc entry */  if (spca50x->raw_proc_entry != NULL)    {      sprintf (name, "raw%d", spca50x->vdev.minor);      remove_proc_entry (name, spca50x_proc_entry);      spca50x->raw_proc_entry = NULL;      vfree (spca50x->rawBuffer);    }#endif /* SPCA50X_ENABLE_RAWPROCENTRY */}static voidproc_spca50x_create (void){  /* No current standard here. Alan prefers /proc/video/ as it keeps   * /proc "less cluttered than /proc/randomcardifoundintheshed/"   * -claudio   */#ifdef CONFIG_VIDEO_PROC_FS  if (video_proc_entry == NULL)    {      err ("Unable to initialise /proc/video/spca50x");      return;    }  spca50x_proc_entry =    create_proc_entry ("spca50x", S_IFDIR, video_proc_entry);#else /* CONFIG_VIDEO_PROC_FS */  spca50x_proc_entry = create_proc_entry ("spca50x", S_IFDIR, 0);#endif /* CONFIG_VIDEO_PROC_FS */#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0)  if (spca50x_proc_entry)    spca50x_proc_entry->owner = THIS_MODULE;  else#ifdef CONFIG_VIDEO_PROC_FS    err ("Unable to initialise /proc/video/spca50x");#else /* CONFIG_VIDEO_PROC_FS */    err ("Unable to initialise /proc/spca50x");#endif /* CONFIG_VIDEO_PROC_FS */#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) */}static voidproc_spca50x_destroy (void){#ifdef CONFIG_VIDEO_PROC_FS  PDEBUG (3, "removing /proc/video/spca50x");#else /* CONFIG_VIDEO_PROC_FS */  PDEBUG (3, "removing /proc/spca50x");#endif /* CONFIG_VIDEO_PROC_FS */  if (spca50x_proc_entry == NULL)    return;#ifdef CONFIG_VIDEO_PROC_FS  remove_proc_entry ("spca50x", video_proc_entry);#else /* CONFIG_VIDEO_PROC_FS */  remove_proc_entry ("spca50x", 0);#endif /* CONFIG_VIDEO_PROC_FS */}#endif /* CONFIG_PROC_FS *//********************************************************************** * * Camera interface * **********************************************************************//* Read a value from the I2C bus. Returns the value read */static intspca50x_read_i2c (struct usb_spca50x *spca50x, __u16 device, __u16 address){  struct usb_device *dev = spca50x->dev;  int err_code;  int retry;  int ctrl = spca50x->i2c_ctrl_reg;	//The I2C control register  int base = spca50x->i2c_base;	//The I2C base address  err_code = spca50x_reg_write (dev, ctrl, base + SPCA50X_I2C_DEVICE, device);  err_code =    spca50x_reg_write (dev, ctrl, base + SPCA50X_I2C_SUBADDR, address);  err_code =    spca50x_reg_write (dev, ctrl, base + SPCA50X_I2C_TRIGGER,		       SPCA50X_I2C_TRIGGER_BIT);  /* Hmm. 506 docs imply we should poll the ready register before reading the return value */  /* Poll the status register for a ready status */  /* Doesn't look like the windows driver does tho' */  retry = 60;  while (--retry)    {      err_code = spca50x_reg_read (dev, ctrl, base + SPCA50X_I2C_STATUS, 1);      if (err_code < 0)	PDEBUG (1, "Error reading I2C status register");      if (!err_code)	break;    }  if (!retry)    PDEBUG (1, "Too many retries polling I2C status after write to register");  err_code = spca50x_reg_read (dev, ctrl, base + SPCA50X_I2C_READ, 1);  if (err_code < 0)    PDEBUG (1, "Failed to read I2C register at %d:%d", device, address);  PDEBUG (3, "Read %d from %d:%d", err_code, device, address);  return err_code;}static intspca50x_read_SAA7113_status (struct usb_spca50x *spca50x){  int value = 0;  value =    spca50x_read_i2c (spca50x, SAA7113_I2C_BASE_READ, SAA7113_REG_STATUS);  if (value < 0)    PDEBUG (1, "Failed to read SAA7113 status");  PDEBUG (1, "7113 status : ");  PDEBUG (1, "  READY %s", (SAA7113_STATUS_READY (value) ? "YES" : "NO"));  PDEBUG (1, "  COPRO %s", (SAA7113_STATUS_COPRO (value) ? "YES" : "NO"));  /*PDEBUG(1,"  SLTCA %s",(SAA7113_STATUS_SLTCA(value)?"YES":"NO")); */  PDEBUG (1, "  WIPA  %s", (SAA7113_STATUS_WIPA (value) ? "YES" : "NO"));  PDEBUG (1, "  GLIMB %s", (SAA7113_STATUS_GLIMB (value) ? "YES" : "NO"));  PDEBUG (1, "  GLIMT %s", (SAA7113_STATUS_GLIMT (value) ? "YES" : "NO"));  PDEBUG (1, "  FIDT  %s", (SAA7113_STATUS_FIDT (value) ? "YES" : "NO"));  PDEBUG (1, "  HLVLN %s", (SAA7113_STATUS_HLVLN (value) ? "YES" : "NO"));  PDEBUG (1, "  INTL  %s", (SAA7113_STATUS_INTL (value) ? "YES" : "NO"));  return value;}static intspca50x_write_i2c (struct usb_spca50x *spca50x, __u16 device,		   __u16 subaddress, __u16 data){  struct usb_device *dev = spca50x->dev;  int err_code;  int retry;  int ctrl = spca50x->i2c_ctrl_reg;	//The I2C control register  int base = spca50x->i2c_base;	//The I2C base address  /* Tell the SPCA50x i2c subsystem the device address of the i2c device */  err_code = spca50x_reg_write (dev, ctrl, base + SPCA50X_I2C_DEVICE, device);  /* Poll the status register for a ready status */  retry = 60;			// Arbitrary  while (--retry)    {      err_code = spca50x_reg_read (dev, ctrl, base + SPCA50X_I2C_STATUS, 1);      if (err_code < 0)	PDEBUG (1, "Error reading I2C status register");      if (!err_code)	break;    }  if (!retry)    PDEBUG (1, "Too many retries polling I2C status");  err_code =    spca50x_reg_write (dev, ctrl, base + SPCA50X_I2C_SUBADDR, subaddress);  err_code = spca50x_reg_write (dev, ctrl, base + SPCA50X_I2C_VALUE, data);  if (spca50x->i2c_trigger_on_write)    err_code = spca50x_reg_write (dev, ctrl, base + SPCA50X_I2C_TRIGGER,				  SPCA50X_I2C_TRIGGER_BIT);

⌨️ 快捷键说明

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