www.pudn.com > spca5xx-.rar > spcausb.h



#ifndef SPCAUSB_H
#define SPCAUSB_INIT_H

#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 6)
#define wait_ms(a) msleep((a))
#endif
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 11)
#define TimeOut 1000
#else
#define TimeOut HZ
#endif
/* Common functions prototype */
static int spca50x_reg_read(struct usb_device *dev,
                            __u16              reg,
                            __u16              index,
                            __u16              length);
static int spca50x_reg_write(struct usb_device *dev,
                             __u16              reg,
                             __u16              index,
                             __u16              value);
			     
static void spca5xxRegRead(struct usb_device *dev,
				__u16 reg,
				__u16 value,
				__u16 index,
				__u8 *buffer,
				__u16 length) ;	
static void spca5xxRegWrite(struct usb_device *dev,
				__u16 reg,
				__u16 value,
				__u16 index,
				__u8 *buffer,
				__u16 length) ;	
static void sonixRegRead(struct usb_device *dev,
				__u16 reg,
				__u16 value,
				__u16 index,
				__u8 *buffer,
				__u16 length) ;	
static void sonixRegWrite(struct usb_device *dev,
				__u16 reg,
				__u16 value,
				__u16 index,
				__u8 *buffer,
				__u16 length) ;	
static void Et_RegWrite(struct usb_device *dev,
				__u16 reg,
				__u16 value,
				__u16 index,
				__u8 *buffer,
				__u16 length);
static void Et_RegRead(struct usb_device *dev,
				__u16 reg,
				__u16 value,
				__u16 index,
				__u8 *buffer,
				__u16 length);
static int spca_set_interface(struct usb_device *dev,
				 int interface,
				 int alternate);
/*
static int spca_clear_feature(struct usb_device *dev,
				 int endpoint)
{
	int inpipe;
	inpipe = usb_rcvintpipe(dev,endpoint);
	usb_clear_halt(dev, inpipe);
	return 0;
}
*/

static int spca50x_setup_qtable(struct usb_spca50x *spca50x,
                                unsigned int        request,
                                unsigned int        ybase,
                                unsigned int        cbase,
                                unsigned char       qtable[2][64]);
/* Alias setting */				
#define pac207RegWrite(dev,req,value,index,buffer,length) sonixRegWrite(dev,req,value,index,buffer,length)
#define pac207RegRead(dev,req,value,index,buffer,length) sonixRegRead(dev,req,value,index,buffer,length)
/***************************** Implementation ****************************/
static void spca5xxRegRead(struct usb_device *dev,
				__u16 reg,
				__u16 value,
				__u16 index,
				__u8 *buffer,
				__u16 length) 
{	
	int rc;
	__u8 *kbuffer = NULL;
	__u16 RegType;
	if(length >0) {
		kbuffer = (__u8 *) kmalloc (length,GFP_KERNEL);
		memcpy (kbuffer, buffer, length);
	}
	RegType = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
	rc = usb_control_msg(dev,
		usb_rcvctrlpipe(dev,0),
		reg,
		RegType,
		(__u16)value, (__u16)index, kbuffer, length, TimeOut);
	if(length >0) {	
		memcpy (buffer, kbuffer, length);
		kfree (kbuffer);
	}
	if (buffer) { 
		PDEBUG(5, "reg read: 0x%02X, 0x%02X, 0x%02X, 0x%02X: 0x%04X",
		RegType ,reg ,value ,index ,(int) *buffer);
	} else { 
		PDEBUG(5, "reg read: 0x%02X, 0x%02X,0x%02X, 0x%02X ",RegType,reg,value,index );
	}
	return ;
}


static void spca5xxRegWrite(struct usb_device *dev,
				__u16 reg,
				__u16 value,
				__u16 index,
				__u8 *buffer,
				__u16 length) 
{	int rc;
	__u16 RegType;
	__u8 *kbuffer = NULL;
	if(length >0) {
		kbuffer = (__u8 *) kmalloc (length,GFP_KERNEL);
		memcpy (kbuffer, buffer, length);
	}
	RegType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
	rc = usb_control_msg(dev,
		usb_sndctrlpipe(dev,0),
		reg,
		RegType,
		(__u16)value, (__u16)index, kbuffer, length, TimeOut);
	if(length >0) {	
		memcpy (buffer, kbuffer, length);
		kfree (kbuffer);
	}
	if (buffer) { 
		PDEBUG(5, "reg write: 0x%02X, 0x%02X, 0x%02X, 0x%02X: 0x%04X",
		RegType ,reg ,value ,index ,(int) *buffer);
	} else { 
		PDEBUG(5, "reg write: 0x%02X, 0x%02X,0x%02X, 0x%02X ",RegType,reg,value,index );
	}
	return ;
}
static void sonixRegRead(struct usb_device *dev,
				__u16 reg,
				__u16 value,
				__u16 index,
				__u8 *buffer,
				__u16 length)
{
	int rc;
	__u8 *kbuffer = NULL;
	__u16 RegType;
	if(length >0) {
		kbuffer = (__u8 *) kmalloc (length,GFP_KERNEL);
		memcpy (kbuffer, buffer, length);
	}
	RegType = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE;
	rc = usb_control_msg(dev,
		usb_rcvctrlpipe(dev,0),
		reg,
		RegType,
		(__u16)value, (__u16)index, kbuffer, length, TimeOut);
	if(length >0) {
		memcpy (buffer, kbuffer, length);
		kfree (kbuffer);
	}
	if (buffer) {
		PDEBUG(5, "reg read: 0x%02X, 0x%02X, 0x%02X, 0x%02X: 0x%04X",
		RegType ,reg ,value ,index ,(int) *buffer);
	} else {
		PDEBUG(5, "reg read: 0x%02X, 0x%02X,0x%02X, 0x%02X ",RegType,reg,value,index );
	}
	return ;
}

static void sonixRegWrite(struct usb_device *dev,
				__u16 reg,
				__u16 value,
				__u16 index,
				__u8 *buffer,
				__u16 length)
{	int rc;
	__u16 RegType;
	__u8 *kbuffer = NULL;
	if(length >0) {
		kbuffer = (__u8 *) kmalloc (length,GFP_KERNEL);
		memcpy (kbuffer, buffer, length);
	}
	RegType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE;
	rc = usb_control_msg(dev,
		usb_sndctrlpipe(dev,0),
		reg,
		RegType,
		(__u16)value, (__u16)index, kbuffer, length, TimeOut);
	if(length >0) {
		memcpy (buffer, kbuffer, length);
		kfree (kbuffer);
	}
	if (buffer) {
		PDEBUG(5, "reg write: 0x%02X, 0x%02X, 0x%02X, 0x%02X: 0x%04X",
		RegType ,reg ,value ,index ,(int) *buffer);
	} else {
		PDEBUG(5, "reg write: 0x%02X, 0x%02X,0x%02X, 0x%02X ",RegType,reg,value,index );
	}
	return ;
}
static void Et_RegRead(struct usb_device *dev,
				__u16 reg,
				__u16 value,
				__u16 index,
				__u8 *buffer,
				__u16 length)
{
	int rc;
	__u8 *kbuffer = NULL;
	__u16 RegType;
	if(length >0) {
		kbuffer = (__u8 *) kmalloc (length,GFP_KERNEL);
		memcpy (kbuffer, buffer, length);
	}
	RegType = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE;
	rc = usb_control_msg(dev,
		usb_rcvctrlpipe(dev,0),
		reg,
		RegType,
		(__u16)value, (__u16)index, kbuffer, length, TimeOut);
	if(length >0) {
		memcpy (buffer, kbuffer, length);
		kfree (kbuffer);
	}
	if (buffer) {
		PDEBUG(5, "reg read: 0x%02X, 0x%02X, 0x%02X, 0x%02X: 0x%04X",
		RegType ,reg ,value ,index ,(int) *buffer);
	} else {
		PDEBUG(5, "reg read: 0x%02X, 0x%02X,0x%02X, 0x%02X ",RegType,reg,value,index );
	}
	return ;
}

static void Et_RegWrite(struct usb_device *dev,
				__u16 reg,
				__u16 value,
				__u16 index,
				__u8 *buffer,
				__u16 length)
{	int rc;
	__u16 RegType;
	__u8 *kbuffer = NULL;
	if(length >0) {
		kbuffer = (__u8 *) kmalloc (length,GFP_KERNEL);
		memcpy (kbuffer, buffer, length);
	}
	RegType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE;
	rc = usb_control_msg(dev,
		usb_sndctrlpipe(dev,0),
		reg,
		RegType,
		(__u16)value, (__u16)index, kbuffer, length, TimeOut);
	if(length >0) {
		memcpy (buffer, kbuffer, length);
		kfree (kbuffer);
	}
	if (buffer) {
		PDEBUG(5, "reg write: 0x%02X, 0x%02X, 0x%02X, 0x%02X: 0x%04X",
		RegType ,reg ,value ,index ,(int) *buffer);
	} else {
		PDEBUG(5, "reg write: 0x%02X, 0x%02X,0x%02X, 0x%02X ",RegType,reg,value,index );
	}
	return ;
}
static int spca_set_interface(struct usb_device *dev, int interface, int alternate)
{
	struct usb_interface *iface;
	int ret;

	iface = usb_ifnum_to_if(dev, interface);
	if (!iface) {
		warn("selecting invalid interface %d", interface);
		return -EINVAL;
	}

	/* 9.4.10 says devices don't need this, if the interface
	   only has one alternate setting */
	if (iface->num_altsetting == 1) {
		dbg("ignoring set_interface for dev %d, iface %d, alt %d",
			dev->devnum, interface, alternate);
		return 0;
	}

	if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
	    USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, alternate,
	    interface, NULL, 0, TimeOut * 5)) < 0)
		return ret;

	
	return 0;

}
 
static int spca50x_reg_write(struct usb_device *dev,
			   __u16 reg,
			   __u16 index,
			   __u16 value)
{
	int rc;

	rc = usb_control_msg(dev,
		usb_sndctrlpipe(dev, 0),
		reg,
		USB_TYPE_VENDOR | USB_RECIP_DEVICE,
		value, index, NULL, 0, TimeOut);

	PDEBUG(5, "reg write: 0x%02X,0x%02X:0x%02X, 0x%x", reg, index, value, rc);

	if (rc < 0)
		err("reg write: error %d", rc);

	return rc;
}

static int spca50x_reg_read_with_value(struct usb_device *dev,
                                       __u16              reg, // bRequest
                                       __u16              value, // wValue
                                       __u16              index, // wIndex
                                       __u16              length) // wLength
{
	int rc;
	unsigned char buffer[4]={0,0,0,0};
	/* Hope plp didn't ask for more */
	rc = usb_control_msg(dev,
		usb_rcvctrlpipe(dev, 0),
		reg,
		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
		(__u16)value, (__u16)index, buffer, length, TimeOut);
		
	PDEBUG(5, "reg read: 0x%02X,0x%02X:0x%04X", reg, index, *(int *)&buffer[0]);

	if (rc < 0) {
		err("reg read: error %d", rc);
		return rc;
	} else {
		return *(int *)&buffer[0];
	}
}

/* returns: negative is error, pos or zero is data */
static int spca50x_reg_read(struct usb_device *dev, 
                            __u16              reg, // bRequest
                            __u16              index, // wIndex
                            __u16              length) // wLength
{
	return spca50x_reg_read_with_value(dev, reg, 0, index, length);
}
/*
 * Simple function to wait for a given 8-bit value to be returned from
 * a spca50x_reg_read call.
 * Returns: negative is error or timeout, zero is success.
 */
static int spca50x_reg_readwait(struct usb_device *dev,
                                __u16              reg,
                                __u16              index,
                                __u16              value)
{
	int count = 0;
	int result = 0;

	while (count < 20)
	{
		result = spca50x_reg_read(dev, reg, index, 1);
		if (result == value) return 0;

		wait_ms(50);

		count++;
	}

	PDEBUG(2, "spca50x_reg_readwait failed");

	return -EIO;
}
static int spca50x_write_vector(struct usb_spca50x *spca50x,__u16 data[][3])
{
	struct usb_device *dev=spca50x->dev;
	int err_code;

	int I=0;
	while((data[I][0])!=(__u16)0 || (data[I][1])!=(__u16)0 || (data[I][2])!=(__u16)0)
	{
		err_code = spca50x_reg_write(dev, data[I][0], (__u16)(data[I][2]), 
			(__u16)(data[I][1]));
		if(err_code < 0) 
		{ 
			PDEBUG(1, "Register write failed for 0x%x,0x%x,0x%x", 
				data[I][0],data[I][1], data[I][2]); 
			return -1; 
		}
		I++;
	}
	return 0;
}

static int spca50x_setup_qtable(struct usb_spca50x *spca50x,
                                unsigned int        request,
                                unsigned int        ybase,
                                unsigned int        cbase,
                                unsigned char       qtable[2][64])
{
	int i;
	int err;

	/* loop over y components */
	for (i = 0; i < 64; i++)
	{
		err = spca50x_reg_write(spca50x->dev, request, ybase + i, qtable[0][i]);
		if (err < 0)
		{
			PDEBUG(2, "spca50x_reg_write failed");
			return err;
		}
	}

	/* loop over c components */
	for (i = 0; i < 64; i++)
	{
		err = spca50x_reg_write(spca50x->dev, request, cbase + i, qtable[1][i]);
		if (err < 0)
		{
			PDEBUG(2, "spca50x_reg_write failed");
			return err;
		}
	}

	/* all ok */
	return 0;
}

	 
#endif /* SPCAUSB_H */