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

📄 qc-vv6410.c

📁 在Linux下用于webeye的摄像头的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
			}		}	}	if (!IS_850(qc)) {		STV_SET_CHECK(0x1443, sd->subsample ? 0x10 : 0x20);	/* Scan rate */		STV_SET_CHECK(0x1446,1);		STV_SETW_CHECK(0x15C1,600);			/* ISO size, 0x380|orig:600 */		STV_SET_CHECK(0x1680,0x14);			/* X ctrl */	}	for (i=0; i<SIZE(vv_init); i++) {		I2C_SET_CHECK(vv_init[i][0], vv_init[i][1]);		if (i<2) if ((r = qc_i2c_wait(qc))<0) goto fail;	}	if (!sd->compress) {		/* Disable compression */		STV_SET_CHECK(0x1443, sd->subsample ? 0x00 : 0x10);	/* Scan rate: Larger -> slower */		STV_SETW_CHECK(0x15C1, 1023);				/* ISO-Size */		STV_SET_CHECK(0x15C3, 1);				/* Y control */		sd->width  = 356;		sd->height = 292;		if (qc->settings.subsample) {			//FIXME:subsampling (still) doesn't work yet			cols=250;			rows=160;			sd->width  = 180;			sd->height = 148;			I2C_SET_CHECK(VV6410_SETUP0, BIT(7)|BIT(6)|BIT(1)|BIT(0));	/* Subsampled timing mode */		}	}	I2C_SET_CHECK(VV6410_XOFFSETH,     x >> 8);	I2C_SET_CHECK(VV6410_XOFFSETL,     x & 0xFF);	I2C_SET_CHECK(VV6410_YOFFSETH,     y >> 8);	I2C_SET_CHECK(VV6410_YOFFSETL,     y & 0xFF);	I2C_SET_CHECK(VV6410_LINELENGTHH,  (cols-1) >> 8);	I2C_SET_CHECK(VV6410_LINELENGTHL,  (cols-1) & 0xFF);	I2C_SET_CHECK(VV6410_FIELDLENGTHH, (rows-1) >> 8);	I2C_SET_CHECK(VV6410_FIELDLENGTHL, (rows-1) & 0xFF);	sd->maxwidth  = sd->width;	sd->maxheight = sd->height;	return 0;/* }}} */	} else {#endif/* {{{ [fold] Initialization without compression support */	if (sd->compress) return -EINVAL;	if (sd->subsample) {		sd->maxwidth  = 180;		sd->maxheight = 148;	} else {		sd->maxwidth  = 356;		sd->maxheight = 292;	}#if QCEGA_MODE{int line_length = mode?250:416;//415;         if (mode) {           sd->subsample=1; // quater.           sd->width      = 180;           sd->height     = 148;        } else {           sd->subsample=0;           sd->width      = 356;           sd->height     = 292;        }        STV_SET_CHECK(STV_REG23, 5); // was 5.	if (!IS_850(qc)) {	     /* logitech quickcam web has 0x850 as idProduct */	     STV_SET_CHECK(0x1446, 1);        }	STV_SET_CHECK(STV_SCAN_RATE, 0x00);	STV_SET_CHECK(0x1423, 0x04);	STV_SET_CHECK(STV_REG00, 0x1b); // 0x0b	I2C_SET_CHECK(VV6410_CONTROL,0x04); // reset to defaults	if ((r = qc_i2c_wait(qc))<0) goto fail;        		// CIF or QCIF and sleep.	if (IS_850(qc)) {		I2C_SET_CHECK(VV6410_CONTROL,(mode?0xa2:0x02));	} else {	        I2C_SET_CHECK(VV6410_CONTROL,(mode?0xc2:0x02));	}	if ((r = qc_i2c_wait(qc))<0) goto fail;	I2C_SET_CHECK(VV6410_GAIN,0xfb);	if ((r = qc_i2c_wait(qc))<0) goto fail;		STV_SET_CHECK(STV_REG04, 0x07);		STV_SET_CHECK(STV_REG03, 0x45);        /* set window size */        if ((r=vv6410_set_window(qc,0,0,48,64)) < 0) {                PRINTK(KERN_ERR, "vv6410_set_window failed");                goto fail;        }	/* EXPERIMENTAL */        /*	 * line length default is 415 so it's the value we use to 	 * calculate values for  registers 0x20-0x21	 * Ref. DS Pag. 67         */   	I2C_SET_CHECK(0x20,mode? ((line_length-23)>>8):((line_length-51)>>8));	I2C_SET_CHECK(0x21,mode?((line_length-23)&0xff):((line_length-51)&0xff));	I2C_SET_CHECK(0x22,mode?0x00:0x01);         //usb_quickcam_i2c_add(&i2cbuff,0x23,mode?0x9e:0x3e);	I2C_SET_CHECK(0x23,mode?158:318&0xff);	I2C_SET_CHECK(0x24,0xfa);         // clock divisor.	I2C_SET_CHECK(0x25,0x01);	if ((r = qc_i2c_wait(qc))<0) goto fail;	/*	if (isaweb(dev))	  {	    //EXPERIMENTAL: dark/black pixel cancellation	    usb_quickcam_i2c_add(&i2cbuff,0x3e,0x01);	    usb_quickcam_i2c_add(&i2cbuff,0x72,0x01);	    if (usb_quickcam_i2c_send(dev,&i2cbuff,VV6410_ADDR) < 0) {      	      printk(KERN_ERR "usb_control_msg dark/black pixel failed");	      goto error;	    }	  }	 */	STV_SET_CHECK(STV_REG01, 0xb7);	STV_SET_CHECK(STV_REG02, 0xa7);	// setup	I2C_SET_CHECK(0x11,0x18); // 0x18 or Jochen 0x40	I2C_SET_CHECK(0x14,0x55); // was 0x55	I2C_SET_CHECK(0x15,0x10); // 0x10 or Jochen:0x00	I2C_SET_CHECK(0x16,0x81); // Pre clock dividor.	I2C_SET_CHECK(0x17,0x18); // they are reserved.	I2C_SET_CHECK(0x18,0x00);	I2C_SET_CHECK(0x77,0x5e);	I2C_SET_CHECK(0x78,0x04);// 0x04 or Jochen:0x00	if (IS_850(qc)) {	  I2C_SET_CHECK(0x79,0x11);//audio init	}	if ((r = qc_i2c_wait(qc))<0) goto fail;			STV_SETW_CHECK(STV_ISO_SIZE, IS_850(qc)?1023:600);	  // 0x380|orig:600	STV_SET_CHECK(STV_Y_CTRL, 1);	STV_SET_CHECK(STV_SCAN_RATE, mode?0x00:0x10);	if (!IS_850(qc)) {	    /* logitech quickam web has 0x0850 as idProduct */		STV_SET_CHECK(STV_X_CTRL, 0x14);	}}#else	STV_SET_CHECK(0x0423,0x05);			/* Unknown register, 0x04 or 0x05 */	STV_SET_CHECK(0x1423,0x04);			/* Unknown register, 0x04 or 0x05 */	STV_SET_CHECK(0x1443,0x00);			/* Scan rate */	STV_SET_CHECK(0x1500,0x1B);			/* 0x0B */	STV_SET_CHECK(0x1501,0xB7);	STV_SET_CHECK(0x1502,0xA7);	STV_SET_CHECK(0x1503,0x45);	STV_SET_CHECK(0x1504,0x07);	STV_SET_CHECK(0x15C3,1);			/* Y ctrl */	if (IS_850(qc)) {		STV_SET_CHECK(0x1443, sd->subsample ? 0x20 : 0x10);	/* Scan rate */		STV_SETW_CHECK(0x15C1,1023);				/* ISO size, 0x380|orig:600 */	} else {		STV_SET_CHECK(0x1443, sd->subsample ? 0x10 : 0x20);	/* Scan rate */		STV_SET_CHECK(0x1446,1);		STV_SETW_CHECK(0x15C1,600);				/* ISO size, 0x380|orig:600 */		STV_SET_CHECK(0x1680,0x14);				/* X ctrl */	}	I2C_SET_CHECK(0x10,0x04);			/*  Control register: reset to defaults */	if ((r = qc_i2c_wait(qc))<0) goto fail;	I2C_SET_CHECK(0x10,sd->subsample ? 0xC2 : 0x02);/*  Control register: CIF or QCIF and sleep */	if ((r = qc_i2c_wait(qc))<0) goto fail;	I2C_SET_CHECK(0x11,0x18);			/* 0x18 or Jochen 0x40 */	I2C_SET_CHECK(0x14,0x55);	I2C_SET_CHECK(0x15,0x10);			/* 0x10 or Jochen:0x00 */	I2C_SET_CHECK(0x16,0x81);			/* Pre clock dividor. */	I2C_SET_CHECK(0x17,0x18);			/* they are reserved. */	I2C_SET_CHECK(0x18,0x00);	I2C_SET_CHECK(0x24,0xFB);			/* Set gain value */	I2C_SET_CHECK(0x25,0x01);			/* Clock divisor value */	I2C_SET_CHECK(0x77,0x5E);	I2C_SET_CHECK(0x78,0x04);			/* 0x04 or Jochen:0x00 */	if (IS_850(qc)) {		I2C_SET_CHECK(0x3E,0x01);		/* EXPERIMENTAL: dark/black pixel cancellation */		I2C_SET_CHECK(0x72,0x01);	}	if ((r = qc_i2c_wait(qc))<0) goto fail;#endif	return 0;/* }}} */#if COMPRESS	}#endiffail:	return r;}/* }}} *//* {{{ [fold] vv6410_set_exposure() */static int vv6410_set_exposure(struct quickcam *qc, unsigned int val){	struct qc_sensor_data *sd = &qc->sensor_data;	static const unsigned int linelength = 415;	/* For CIF */	unsigned int fine;	unsigned int coarse;	int r;		val = (val*val >> 14) + val/4;	if (sd->exposure==val) return 0;	sd->exposure = val;	fine = val % linelength;	coarse = val / linelength;	if (coarse>=512) coarse = 512;	if (qcdebug&QC_DEBUGLOGIC) PDEBUG("vv6410_set_exposure %d (%i,%i)",val,coarse,fine);	I2C_SET_CHECK(VV6410_FINEH,   fine >> 8);	I2C_SET_CHECK(VV6410_FINEL,   fine & 0xFF);	I2C_SET_CHECK(VV6410_COARSEH, coarse >> 8);	I2C_SET_CHECK(VV6410_COARSEL, coarse & 0xFF);fail:	return r;}/* }}} *//* {{{ [fold] vv6410_set_gains() */static int vv6410_set_gains(struct quickcam *qc, unsigned int hue, unsigned int sat, unsigned int val){	static const int maxgain = 13;			/* Absolute maximum is 14, recommended is 12 */	struct qc_sensor_data *sd = &qc->sensor_data;	unsigned int gain;	int r;	if (qcdebug&QC_DEBUGLOGIC) PDEBUG("vv6410_set_gains %d %d %d", hue, sat, val);	gain = val / 256;	gain >>= 4;	if (gain > maxgain) gain = maxgain;	if (sd->rgain==gain) return 0;	sd->rgain = gain;	r = qc_i2c_set(qc, VV6410_ANALOGGAIN, 0xF0 | gain);	return r;}/* }}} *//* {{{ [fold] vv6410_set_levels() */static int vv6410_set_levels(struct quickcam *qc, unsigned int exp, unsigned int gain, unsigned int hue, unsigned int sat){	int r;	if ((r = vv6410_set_exposure(qc, exp))<0) goto fail;	vv6410_set_gains(qc, hue, sat, gain);fail:	return r;}/* }}} *//* {{{ [fold] struct qc_sensor qc_sensor_vv6410 */const struct qc_sensor qc_sensor_vv6410 = {	name:		"VV6410",	manufacturer:	"ST Microelectronics",	init:		vv6410_init,	start:		vv6410_start,	stop:		vv6410_stop,	set_size:	vv6410_set_size,	set_levels:	vv6410_set_levels,	/* Exposure and gain control information */	autoexposure:	FALSE,	adapt_gainlow:	40000,	adapt_gainhigh:	65535,	/* Information needed to access the sensor via I2C */	reg23: 		5,	i2c_addr: 	VV6410_ADDR,	/* Identification information used for auto-detection */	id_reg:		VV6410_DEVICEH,	id:		0x19,	length_id:	1,};/* }}} *//* End of file */

⌨️ 快捷键说明

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