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

📄 w9968cf.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		    value, index, res, symbolic(urb_errlist, res))	return (res >= 0) ? 0 : -1;}/*--------------------------------------------------------------------------  Read a W9968CF register.   Return the register value on success, -1 otherwise.  --------------------------------------------------------------------------*/static int w9968cf_read_reg(struct w9968cf_device* cam, u16 index){	struct usb_device* udev = cam->usbdev;	u16* buff = cam->control_buffer;	int res;	res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 1,	                      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,	                      0, index, buff, 2, W9968CF_USB_CTRL_TIMEOUT);	if (res < 0)		DBG(4, "Failed to read a register "		       "(index 0x%02X, error #%d, %s)",		    index, res, symbolic(urb_errlist, res))	return (res >= 0) ? (int)(*buff) : -1;}/*--------------------------------------------------------------------------  Write 64-bit data to the fast serial bus registers.  Return 0 on success, -1 otherwise.  --------------------------------------------------------------------------*/static int w9968cf_write_fsb(struct w9968cf_device* cam, u16* data){	struct usb_device* udev = cam->usbdev;	u16 value;	int res;	value = *data++;	res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,	                      USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,	                      value, 0x06, data, 6, W9968CF_USB_CTRL_TIMEOUT);	if (res < 0)		DBG(4, "Failed to write the FSB registers "		       "(error #%d, %s)", res, symbolic(urb_errlist, res))	return (res >= 0) ? 0 : -1;}/*--------------------------------------------------------------------------  Write data to the serial bus control register.  Return 0 on success, a negative number otherwise.  --------------------------------------------------------------------------*/static int w9968cf_write_sb(struct w9968cf_device* cam, u16 value){	int err = 0;	err = w9968cf_write_reg(cam, value, 0x01);	udelay(W9968CF_I2C_BUS_DELAY);	return err;}/*--------------------------------------------------------------------------  Read data from the serial bus control register.  Return 0 on success, a negative number otherwise.  --------------------------------------------------------------------------*/static int w9968cf_read_sb(struct w9968cf_device* cam){	int v = 0;	v = w9968cf_read_reg(cam, 0x01);	udelay(W9968CF_I2C_BUS_DELAY);	return v;}/*--------------------------------------------------------------------------  Upload quantization tables for the JPEG compression.  This function is called by w9968cf_start_transfer().  Return 0 on success, a negative number otherwise.  --------------------------------------------------------------------------*/static int w9968cf_upload_quantizationtables(struct w9968cf_device* cam){	u16 a, b;	int err = 0, i, j;	err += w9968cf_write_reg(cam, 0x0010, 0x39); /* JPEG clock enable */	for (i = 0, j = 0; i < 32; i++, j += 2) {		a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8);		b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8);		err += w9968cf_write_reg(cam, a, 0x40+i);		err += w9968cf_write_reg(cam, b, 0x60+i);	}	err += w9968cf_write_reg(cam, 0x0012, 0x39); /* JPEG encoder enable */	return err;}/**************************************************************************** * Low-level I2C I/O functions.                                             * * The adapter supports the following I2C transfer functions:               * * i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only)           * * i2c_adap_read_byte_data()                                                * * i2c_adap_read_byte()                                                     * ****************************************************************************/static int w9968cf_smbus_start(struct w9968cf_device* cam){	int err = 0;	err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */	err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */	return err;}static int w9968cf_smbus_stop(struct w9968cf_device* cam){	int err = 0;	err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */	err += w9968cf_write_sb(cam, 0x0013); /* SDE=1, SDA=1, SCL=1 */	return err;}static int w9968cf_smbus_write_byte(struct w9968cf_device* cam, u8 v){	u8 bit;	int err = 0, sda;	for (bit = 0 ; bit < 8 ; bit++) {		sda = (v & 0x80) ? 2 : 0;		v <<= 1;		/* SDE=1, SDA=sda, SCL=0 */		err += w9968cf_write_sb(cam, 0x10 | sda);		/* SDE=1, SDA=sda, SCL=1 */		err += w9968cf_write_sb(cam, 0x11 | sda);		/* SDE=1, SDA=sda, SCL=0 */		err += w9968cf_write_sb(cam, 0x10 | sda);	}	return err;}static int w9968cf_smbus_read_byte(struct w9968cf_device* cam, u8* v){	u8 bit;	int err = 0;	*v = 0;	for (bit = 0 ; bit < 8 ; bit++) {		*v <<= 1;		err += w9968cf_write_sb(cam, 0x0013);		*v |= (w9968cf_read_sb(cam) & 0x0008) ? 1 : 0;		err += w9968cf_write_sb(cam, 0x0012);	}	return err;}static int w9968cf_smbus_write_ack(struct w9968cf_device* cam){	int err = 0;	err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */	err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */	err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */	return err;}static int w9968cf_smbus_read_ack(struct w9968cf_device* cam){	int err = 0, sda;	err += w9968cf_write_sb(cam, 0x0013); /* SDE=1, SDA=1, SCL=1 */	sda = (w9968cf_read_sb(cam) & 0x08) ? 1 : 0; /* sda = SDA */	err += w9968cf_write_sb(cam, 0x0012); /* SDE=1, SDA=1, SCL=0 */	if (sda < 0)		err += sda;	if (sda == 1) {		DBG(6, "Couldn't receive the ACK")		err += -1;	}	return err;}/* This seems to refresh the communication through the serial bus */static int w9968cf_smbus_refresh_bus(struct w9968cf_device* cam){	int err = 0, j;	for (j = 1; j <= 10; j++) {		err = w9968cf_write_reg(cam, 0x0020, 0x01);		err += w9968cf_write_reg(cam, 0x0000, 0x01);		if (err)			break;	}	return err;}/* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */static int w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device* cam,                                      u16 address, u8 subaddress,u8 value){	u16* data = cam->data_buffer;	int err = 0;	err += w9968cf_smbus_refresh_bus(cam);	/* Enable SBUS outputs */	err += w9968cf_write_sb(cam, 0x0020);	data[0] = 0x082f | ((address & 0x80) ? 0x1500 : 0x0);	data[0] |= (address & 0x40) ? 0x4000 : 0x0;	data[1] = 0x2082 | ((address & 0x40) ? 0x0005 : 0x0);	data[1] |= (address & 0x20) ? 0x0150 : 0x0;	data[1] |= (address & 0x10) ? 0x5400 : 0x0;	data[2] = 0x8208 | ((address & 0x08) ? 0x0015 : 0x0);	data[2] |= (address & 0x04) ? 0x0540 : 0x0;	data[2] |= (address & 0x02) ? 0x5000 : 0x0;	data[3] = 0x1d20 | ((address & 0x02) ? 0x0001 : 0x0);	data[3] |= (address & 0x01) ? 0x0054 : 0x0;	err += w9968cf_write_fsb(cam, data);	data[0] = 0x8208 | ((subaddress & 0x80) ? 0x0015 : 0x0);	data[0] |= (subaddress & 0x40) ? 0x0540 : 0x0;	data[0] |= (subaddress & 0x20) ? 0x5000 : 0x0;	data[1] = 0x0820 | ((subaddress & 0x20) ? 0x0001 : 0x0);	data[1] |= (subaddress & 0x10) ? 0x0054 : 0x0;	data[1] |= (subaddress & 0x08) ? 0x1500 : 0x0;	data[1] |= (subaddress & 0x04) ? 0x4000 : 0x0;	data[2] = 0x2082 | ((subaddress & 0x04) ? 0x0005 : 0x0);	data[2] |= (subaddress & 0x02) ? 0x0150 : 0x0;	data[2] |= (subaddress & 0x01) ? 0x5400 : 0x0;	data[3] = 0x001d;	err += w9968cf_write_fsb(cam, data);	data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);	data[0] |= (value & 0x40) ? 0x0540 : 0x0;	data[0] |= (value & 0x20) ? 0x5000 : 0x0;	data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0);	data[1] |= (value & 0x10) ? 0x0054 : 0x0;	data[1] |= (value & 0x08) ? 0x1500 : 0x0;	data[1] |= (value & 0x04) ? 0x4000 : 0x0;	data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0);	data[2] |= (value & 0x02) ? 0x0150 : 0x0;	data[2] |= (value & 0x01) ? 0x5400 : 0x0;	data[3] = 0xfe1d;	err += w9968cf_write_fsb(cam, data);	/* Disable SBUS outputs */	err += w9968cf_write_sb(cam, 0x0000);	if (!err)		DBG(5, "I2C write byte data done, addr.0x%04X, subaddr.0x%02X "		       "value 0x%02X", address, subaddress, value)	else		DBG(5, "I2C write byte data failed, addr.0x%04X, "		       "subaddr.0x%02X, value 0x%02X", 		    address, subaddress, value)	return err;}/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */static int w9968cf_i2c_adap_read_byte_data(struct w9968cf_device* cam,                                 u16 address, u8 subaddress,                                 u8* value){	int err = 0;	/* Serial data enable */	err += w9968cf_write_sb(cam, 0x0013); /* don't change ! */	err += w9968cf_smbus_start(cam);	err += w9968cf_smbus_write_byte(cam, address);	err += w9968cf_smbus_read_ack(cam);	err += w9968cf_smbus_write_byte(cam, subaddress);	err += w9968cf_smbus_read_ack(cam);	err += w9968cf_smbus_stop(cam);	err += w9968cf_smbus_start(cam);	err += w9968cf_smbus_write_byte(cam, address + 1);	err += w9968cf_smbus_read_ack(cam);	err += w9968cf_smbus_read_byte(cam, value);	err += w9968cf_smbus_write_ack(cam);	err += w9968cf_smbus_stop(cam);	/* Serial data disable */	err += w9968cf_write_sb(cam, 0x0000);	if (!err)		DBG(5, "I2C read byte data done, addr.0x%04X, "		       "subaddr.0x%02X, value 0x%02X", 		    address, subaddress, *value)	else		DBG(5, "I2C read byte data failed, addr.0x%04X, "		       "subaddr.0x%02X, wrong value 0x%02X",		    address, subaddress, *value)	return err;}/* SMBus protocol: S Addr+1 Rd [A] [Value] NA P */static int w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam,                           u16 address, u8* value){	int err = 0;	/* Serial data enable */	err += w9968cf_write_sb(cam, 0x0013);	err += w9968cf_smbus_start(cam);	err += w9968cf_smbus_write_byte(cam, address + 1);	err += w9968cf_smbus_read_ack(cam);	err += w9968cf_smbus_read_byte(cam, value);	err += w9968cf_smbus_write_ack(cam);	err += w9968cf_smbus_stop(cam); 	/* Serial data disable */	err += w9968cf_write_sb(cam, 0x0000);	if (!err)		DBG(5, "I2C read byte done, addr.0x%04X, "		       "value 0x%02X", address, *value)	else		DBG(5, "I2C read byte failed, addr.0x%04X, "		       "wrong value 0x%02X", address, *value)	return err;}/* SMBus protocol: S Addr Wr [A] Value [A] P */static int w9968cf_i2c_adap_write_byte(struct w9968cf_device* cam,                            u16 address, u8 value)

⌨️ 快捷键说明

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