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

📄 qc-hdcs.c

📁 在Linux下用于webeye的摄像头的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Start of file *//* {{{ [fold] Comments *//* * qc-usb, linux V4L driver for the Logitech QuickCam USB camera family * * qc-hdcs.c - HDCS Sensor Implementation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * *//* }}} */#ifdef NOKERNEL#include "quickcam.h"#else#include <linux/quickcam.h>#endif/* LSB bit of I2C or register address signifies write (0) or read (1) *//* I2C Address */#define HDCS_ADDR 	(0x55<<1) /* {{{ [fold] I2C registers *//* I2C Registers common for both HDCS-1000/1100 and HDCS-1020 */#define HDCS_IDENT	(0x00<<1)	/* Identifications Register */#define HDCS_STATUS	(0x01<<1)	/* Status Register */#define HDCS_IMASK	(0x02<<1)	/* Interrupt Mask Register */#define HDCS_PCTRL	(0x03<<1)	/* Pad Control Register */#define HDCS_PDRV	(0x04<<1)	/* Pad Drive Control Register */#define HDCS_ICTRL	(0x05<<1)	/* Interface Control Register */#define HDCS_ITMG	(0x06<<1)	/* Interface Timing Register */#define HDCS_BFRAC	(0x07<<1)	/* Baud Fraction Register */#define HDCS_BRATE	(0x08<<1)	/* Baud Rate Register */#define HDCS_ADCCTRL	(0x09<<1)	/* ADC Control Register */#define HDCS_FWROW	(0x0A<<1)	/* First Window Row Register */#define HDCS_FWCOL	(0x0B<<1)	/* First Window Column Register */#define HDCS_LWROW	(0x0C<<1)	/* Last Window Row Register */#define HDCS_LWCOL	(0x0D<<1)	/* Last Window Column Register */#define HDCS_TCTRL	(0x0E<<1)	/* Timing Control Register */#define HDCS_ERECPGA	(0x0F<<1)	/* PGA Gain Register: Even Row, Even Column */#define HDCS_EROCPGA	(0x10<<1)	/* PGA Gain Register: Even Row, Odd Column */#define HDCS_ORECPGA	(0x11<<1)	/* PGA Gain Register: Odd Row, Even Column */#define HDCS_OROCPGA	(0x12<<1)	/* PGA Gain Register: Odd Row, Odd Column */#define HDCS_ROWEXPL	(0x13<<1)	/* Row Exposure Low Register */#define HDCS_ROWEXPH	(0x14<<1)	/* Row Exposure High Register *//* I2C Registers only for HDCS-1000/1100 */#define HDCS00_SROWEXPL	(0x15<<1)	/* Sub-Row Exposure Low Register */#define HDCS00_SROWEXPH	(0x16<<1)	/* Sub-Row Exposure High Register */#define HDCS00_CONFIG	(0x17<<1)	/* Configuration Register */#define HDCS00_CONTROL	(0x18<<1)	/* Control Register *//* I2C Registers only for HDCS-1020 */#define HDCS20_SROWEXP	(0x15<<1)	/* Sub-Row Exposure Register	*/#define HDCS20_ERROR	(0x16<<1)	/* Error Control Register 	*/#define HDCS20_ITMG2	(0x17<<1)	/* Interface Timing 2 Register	*/#define HDCS20_ICTRL2	(0x18<<1)	/* Interface Control 2 Register	*/#define HDCS20_HBLANK	(0x19<<1)	/* Horizontal Blank Register	*/#define HDCS20_VBLANK	(0x1A<<1)	/* Vertical Blank Register	*/#define HDCS20_CONFIG	(0x1B<<1)	/* Configuration Register 	*/#define HDCS20_CONTROL	(0x1C<<1)	/* Control Register		*//* }}} */#define IS_870(qc)	(GET_PRODUCTID(qc)==0x870)#define IS_1020(qc)	((qc)->sensor_data.sensor->flag != 0)#define GET_CONTROL	(IS_1020(qc) ? HDCS20_CONTROL : HDCS00_CONTROL)#define GET_CONFIG	(IS_1020(qc) ? HDCS20_CONFIG : HDCS00_CONFIG)#define I2C_SET_CHECK(reg,val)	if ((r = qc_i2c_set(qc,(reg),(val)))<0) goto fail#define STV_SET_CHECK(reg,val)	if ((r = qc_stv_set(qc,(reg),(val)))<0) goto fail#define STV_SETW_CHECK(reg,val)	if ((r = qc_stv_setw(qc,(reg),(val)))<0) goto fail/* Enables experimental compressed mode, works with HDCS-1000/0x840,   mode derived from USB logs obtained from HDCS-1020/0x870   (should give 640x480), not tested with HDCS-1020.   On HDCS-1000, gives 30 fps but data is in unknown format,   observed image width 163 bytes (how many pixels?).   Frame length appears to vary, typically 3300-4550 bytes.   (apparently quite simple, however).    Use this with DUMPDATA mode. */#define HDCS_COMPRESS 0#if HDCS_COMPRESS/* {{{ [fold] hdcs_compress_init(struct quickcam *qc, int flags) */static int hdcs_compress_init(struct quickcam *qc, int flags){	int r;	if (flags & 1) {	/************************************** Plugin camera **************************************/	STV_SET_CHECK(0x1440, 0x00);							/* Turn on/off isochronous stream */	// if ((r = qc_stv_getw(qc, 0xE00A)) != 0x0870)					/* ProductId */	//	PDEBUG("Bad value 0x%02X in reg 0xE00A, should be 0x0870", r);	STV_SET_CHECK(0x0423, 0x05);							/* Unknown (sometimes 4, sometimes 5) */	// Warning: I2C address 0xBA is invalid	// if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0)		/* Identifications Register */	//	PDEBUG("error reading sensor reg HDCS_IDENT");	// if ((r = qc_stv_get(qc, 0x0424)) != 0x0a)					/* Successfully transmitted I2C commands */	//	PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x0a", r);	STV_SET_CHECK(0x0423, 0x04);							/* Unknown (sometimes 4, sometimes 5) */	if ((r = qc_stv_get(qc, 0x1444)) != 0x10)					/* ? */		PDEBUG("Bad value 0x%02X in reg 0x1444, should be 0x10", r);	if ((r = qc_stv_get(qc, 0x1444)) != 0x10)					/* ? */		PDEBUG("Bad value 0x%02X in reg 0x1444, should be 0x10", r);	if ((r = qc_stv_get(qc, 0x1444)) != 0x10)					/* ? */		PDEBUG("Bad value 0x%02X in reg 0x1444, should be 0x10", r);	STV_SET_CHECK(0x0423, 0x05);							/* Unknown (sometimes 4, sometimes 5) */	// Warning: I2C address 0x20 is invalid	// if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0)		/* Identifications Register */	//	PDEBUG("error reading sensor reg HDCS_IDENT");	// if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0)		/* Identifications Register */	//	PDEBUG("error reading sensor reg HDCS_IDENT");	// if ((r = qc_stv_get(qc, 0x0424)) != 0x0a)					/* Successfully transmitted I2C commands */	//	PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x0a", r);	// Warning: I2C address 0x20 is invalid	// if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0)		/* Identifications Register */	//	PDEBUG("error reading sensor reg HDCS_IDENT");	// if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0)		/* Identifications Register */	//	PDEBUG("error reading sensor reg HDCS_IDENT");	// if ((r = qc_stv_get(qc, 0x0424)) != 0x0a)					/* Successfully transmitted I2C commands */	//	PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x0a", r);	// Warning: I2C address 0x20 is invalid	// if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0)		/* Identifications Register */	//	PDEBUG("error reading sensor reg HDCS_IDENT");	// if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0)		/* Identifications Register */	//	PDEBUG("error reading sensor reg HDCS_IDENT");	// if ((r = qc_stv_get(qc, 0x0424)) != 0x0a)					/* Successfully transmitted I2C commands */	//	PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x0a", r);	STV_SET_CHECK(0x0423, 0x04);							/* Unknown (sometimes 4, sometimes 5) */	STV_SET_CHECK(0x0423, 0x04);							/* Unknown (sometimes 4, sometimes 5) */	// if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0)		/* Identifications Register */	//	PDEBUG("error reading sensor reg HDCS_IDENT");	// if ((r = qc_stv_get(qc, 0x0424)) != 0x02)					/* Successfully transmitted I2C commands */	//	PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x02", r);	// if ((r = qc_stv_get(qc, 0x1410)) != 0x10)					/* I2C area, first reg value */	//	PDEBUG("Bad value 0x%02X in reg 0x1410, should be 0x10", r);	// if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0)		/* Identifications Register */	//	PDEBUG("error reading sensor reg HDCS_IDENT");	// if ((r = qc_stv_get(qc, 0x0424)) != 0x02)					/* Successfully transmitted I2C commands */	//	PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x02", r);	// if ((r = qc_stv_get(qc, 0x1410)) != 0x10)					/* I2C area, first reg value */	//	PDEBUG("Bad value 0x%02X in reg 0x1410, should be 0x10", r);	STV_SET_CHECK(0x0423, 0x04);							/* Unknown (sometimes 4, sometimes 5) */	if ((r = qc_stv_get(qc, 0x0424)) != 0x02)					/* Successfully transmitted I2C commands */		PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x02", r);	STV_SET_CHECK(0x0423, 0x04);							/* Unknown (sometimes 4, sometimes 5) */	// if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0)		/* Identifications Register */	//	PDEBUG("error reading sensor reg HDCS_IDENT");	// if ((r = qc_stv_get(qc, 0x0424)) != 0x02)					/* Successfully transmitted I2C commands */	//	PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x02", r);	// if ((r = qc_stv_get(qc, 0x1410)) != 0x10)					/* I2C area, first reg value */	//	PDEBUG("Bad value 0x%02X in reg 0x1410, should be 0x10", r);	// if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0)		/* Identifications Register */	//	PDEBUG("error reading sensor reg HDCS_IDENT");	// if ((r = qc_stv_get(qc, 0x0424)) != 0x02)					/* Successfully transmitted I2C commands */	//	PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x02", r);	// if ((r = qc_stv_get(qc, 0x1410)) != 0x10)					/* I2C area, first reg value */	//	PDEBUG("Bad value 0x%02X in reg 0x1410, should be 0x10", r);	STV_SET_CHECK(0x1500, 0x1D);							/* ? */	if ((r = qc_stv_get(qc, 0x1443)) != 0x00)					/* Scan rate? */		PDEBUG("Bad value 0x%02X in reg 0x1443, should be 0x00", r);	STV_SET_CHECK(0x1443, 0x01);							/* Scan rate? */	if ((r = qc_stv_get(qc, 0x1443)) != 0x01)					/* Scan rate? */		PDEBUG("Bad value 0x%02X in reg 0x1443, should be 0x01", r);	STV_SET_CHECK(0x1443, 0x00);							/* Scan rate? */	I2C_SET_CHECK(HDCS_PCTRL, 0x63);						/* Pad Control Register */	I2C_SET_CHECK(HDCS_PDRV, 0x00);							/* Pad Drive Control Register */	I2C_SET_CHECK(GET_CONFIG, 0x08);						/* Configuration Register */	if ((r = qc_i2c_wait(qc))<0) goto fail;	I2C_SET_CHECK(GET_CONTROL, 0x04);						/* Control Register */	if ((r = qc_i2c_wait(qc))<0) goto fail;	I2C_SET_CHECK(GET_CONTROL, 0x00);						/* Control Register */	if ((r = qc_i2c_wait(qc))<0) goto fail;	STV_SET_CHECK(0x1446, 0x00);							/* ? */	I2C_SET_CHECK(HDCS_PCTRL, 0x63);						/* Pad Control Register */	I2C_SET_CHECK(HDCS_PDRV, 0x00);							/* Pad Drive Control Register */	I2C_SET_CHECK(GET_CONFIG, 0x08);						/* Configuration Register */	if ((r = qc_i2c_wait(qc))<0) goto fail;	if ((r = qc_stv_get(qc, 0x1445)) != 0x04)					/* Turn LED on/off? */		PDEBUG("Bad value 0x%02X in reg 0x1445, should be 0x04", r);	I2C_SET_CHECK(HDCS_ERECPGA, 0x3B);						/* PGA Gain Register: Even Row, Even Column */	I2C_SET_CHECK(HDCS_EROCPGA, 0x3B);						/* PGA Gain Register: Even Row, Odd Column */	I2C_SET_CHECK(HDCS_ORECPGA, 0x3B);						/* PGA Gain Register: Odd Row, Even Column */	I2C_SET_CHECK(HDCS_OROCPGA, 0x3B);						/* PGA Gain Register: Odd Row, Odd Column */	if ((r = qc_i2c_wait(qc))<0) goto fail;	STV_SET_CHECK(0x1504, 0x07);							/* ? */	STV_SET_CHECK(0x1503, 0x45);							/* ? */	if ((r = qc_stv_get(qc, 0x1500)) != 0x1d)					/* ? */		PDEBUG("Bad value 0x%02X in reg 0x1500, should be 0x1d", r);	STV_SET_CHECK(0x1500, 0x1D);							/* ? */	// if ((r = qc_stv_getw(qc, 0xE00A)) != 0x0870)					/* ProductId */	//	PDEBUG("Bad value 0x%02X in reg 0xE00A, should be 0x0870", r);	}		if (flags & 2) {	/************************************** Start grabbing **************************************/	// if ((r = qc_stv_getw(qc, 0xE00A)) != 0x0870)					/* ProductId */	//	PDEBUG("Bad value 0x%02X in reg 0xE00A, should be 0x0870", r);	STV_SET_CHECK(0x0423, 0x04);							/* Unknown (sometimes 4, sometimes 5) */	STV_SET_CHECK(0x1500, 0x1D);							/* ? */	I2C_SET_CHECK(HDCS_PCTRL, 0x63);						/* Pad Control Register */	I2C_SET_CHECK(HDCS_PDRV, 0x00);							/* Pad Drive Control Register */	I2C_SET_CHECK(GET_CONFIG, 0x08);						/* Configuration Register */	if ((r = qc_i2c_wait(qc))<0) goto fail;	STV_SET_CHECK(0x15C3, 0x02);							/* Y-Control, 1: 288 lines, 2: 144 lines */	STV_SETW_CHECK(0x15C1, 0x027B);							/* Max. ISO packet size */	I2C_SET_CHECK(HDCS_FWROW, 0x00);						/* First Window Row Register */	I2C_SET_CHECK(HDCS_FWCOL, 0x0B);						/* First Window Column Register */	I2C_SET_CHECK(HDCS_LWROW, 0x3D);						/* Last Window Row Register */	I2C_SET_CHECK(HDCS_LWCOL, 0x5A);						/* Last Window Column Register */	if ((r = qc_i2c_wait(qc))<0) goto fail;	STV_SET_CHECK(0x1680, 0x00);							/* X-Control, 0xa: 352 columns, 6: 176 columns */	I2C_SET_CHECK(HDCS_TCTRL, IS_1020(qc) ? 0xCB : 0x6B);				/* Timing Control Register */	I2C_SET_CHECK(HDCS_ICTRL, 0x00);						/* Interface Control Register */	I2C_SET_CHECK(HDCS_ITMG, 0x16);							/* Interface Timing Register */	if (IS_1020(qc)) I2C_SET_CHECK(HDCS20_HBLANK, 0xD6);				/* Horizontal Blank Register */	if ((r = qc_i2c_wait(qc))<0) goto fail;	STV_SET_CHECK(0x1446, 0x00);							/* ? */	if ((r = qc_stv_get(qc, 0x1446)) != 0x00)					/* ? */		PDEBUG("Bad value 0x%02X in reg 0x1446, should be 0x00", r);	STV_SET_CHECK(0x1446, 0x00);							/* ? */

⌨️ 快捷键说明

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