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

📄 spca50x.c

📁 广州斯道2410普及版II的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	for (i = 0; str[i] >= '0' && str[i] <= '9'; i++)	{		result *= 10;		result += str[i] - '0';	}	return result;}static int spca50x_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 void create_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 void destroy_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 void proc_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 void proc_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 int spca50x_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 int spca50x_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 int spca50x_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);	/* Poll the status register for a ready status*/	retry = 60;	while(--retry)	{		err_code=spca50x_reg_read(dev, ctrl, SPCA50X_I2C_STATUS, 2);		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");	if (debug > 2)	{		err_code = spca50x_read_i2c(spca50x, device, subaddress);		if (err_code < 0) 		{			PDEBUG(3, "Can't read back I2C register value for %d:%d",				device, subaddress); 		}		else if ((err_code & 0xff) != (data & 0xff)) 			PDEBUG(3, "Read back %x should be %x at subaddr %x",				err_code, data, subaddress);	}	return 0;}static int spca50x_write_i2c_vector(struct usb_spca50x *spca50x,__u16 device,__u16 data[][2]){	int I=0;	while(data[I][0])	{		spca50x_write_i2c(spca50x,device,data[I][0],data[I][1]);		I++;	}	return 0;}static int spca50x_set_packet_size(struct usb_spca50x *spca50x, int size){	int alt ;	/**********************************************************************/	/******** Try to find real Packet size from usb struct ****************/	struct usb_device *dev= spca50x->dev;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	struct usb_interface_descriptor *interface = NULL;		struct usb_config_descriptor *config = dev->actconfig;#else	struct usb_host_interface *interface = NULL;	struct usb_interface *intf;#endif	int mysize = 0;		/**********************************************************************/		if      (size == 0)    alt = SPCA50X_ALT_SIZE_0;	else if (size == 128)  alt = SPCA50X_ALT_SIZE_128;	else if (size == 256)  alt = SPCA50X_ALT_SIZE_256;	else if (size == 384)  alt = SPCA50X_ALT_SIZE_384;	else if (size == 512)  alt = SPCA50X_ALT_SIZE_512;	else if (size == 640)  alt = SPCA50X_ALT_SIZE_640;	else if (size == 768)  alt = SPCA50X_ALT_SIZE_768;	else if (size == 896)  alt = SPCA50X_ALT_SIZE_896;	else if (size == 1023) 		if (spca50x->bridge == BRIDGE_SONIX){			alt = 8;		} else {		 alt = SPCA50X_ALT_SIZE_1023;		 }	else	{		/* if an unrecognised size, default to the minimum */		PDEBUG(5,"Set packet size: invalid size (%d), defaulting to %d",		         size, SPCA50X_ALT_SIZE_128);		alt = SPCA50X_ALT_SIZE_128;	}			PDEBUG(5,"iface alt: %d %d ",spca50x->iface, alt);	if (usb_set_interface(spca50x->dev, spca50x->iface, alt) < 0) {		err("Set packet size: set interface error");		return -EBUSY;	}	#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,3)	intf = usb_ifnum_to_if(dev,spca50x->iface);	if (intf) {		interface = usb_altnum_to_altsetting(intf,alt);		} else {		PDEBUG(0,"intf not found");		return -ENXIO;		}	mysize = interface->endpoint[0].desc.wMaxPacketSize;	#else	interface = &config->interface[spca50x->iface].altsetting[alt];	mysize = interface->endpoint[0].wMaxPacketSize;#endif	PDEBUG(1, "set real packet size: %d, alt=%d", mysize, alt);	spca50x->packet_size = mysize;	spca50x->alt = alt;	return 0;}/* Returns number of bits per pixel (regardless of where they are located; planar or * not), or zero for unsupported format. */static int spca50x_get_depth(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: return 8;	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;	}

⌨️ 快捷键说明

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