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

📄 spca561.h

📁 摄像头驱动
💻 H
📖 第 1 页 / 共 2 页
字号:
 i++;	}}static int init_161rev12A(struct usb_spca50x *spca50x){	int err;	__u8 Reg8391[] = { 0x23,0x31,0x10,0x00,0x3a,0x00,0x00,0x00}; //14	__u8 Reg8307[] = { 0xaa,0x00};	err=spca50x_reg_write (spca50x->dev, 0, 0x8620,0x00);	//	sensor_Reset(spca50x);	spca50x_write_vector(spca50x,spca561_161rev12A_data1) ;	sensor_mapwrite (spca50x, Pb100_1map8300);	spca50x_write_vector(spca50x,spca561_161rev12A_data2) ;	sensor_mapwrite (spca50x, Pb100_2map8300);	err=spca50x_reg_write (spca50x->dev, 0, 0x8700, 0x85);	// 0x27 clock	spca5xxRegWrite(spca50x->dev,0,0, 0x8391,Reg8391,8);	spca5xxRegWrite(spca50x->dev,0,0, 0x8390,Reg8391,8);	err=spca50x_reg_write(spca50x->dev, 0, 0x8112, 0x10 | 0x20);	err=spca50x_reg_write(spca50x->dev, 0, 0x850b, 0x03);	err=spca50x_reg_write(spca50x->dev, 0, 0x8112, 0x00);//set_alternate setting 0	err=spca50x_reg_write (spca50x->dev, 0, 0x8118, 0x29);	err=spca50x_reg_write (spca50x->dev, 0, 0x8114, 0x00);	//set_alternate setting 7	spca50x_write_vector(spca50x,spca561_161rev12A_data2) ;	spca5xxRegWrite(spca50x->dev,0,0, 0x8307,Reg8307,2);	err=spca50x_reg_write (spca50x->dev, 0, 0x8700, 0x85);	// 0x27 clock	spca5xxRegWrite(spca50x->dev,0,0, 0x8391,Reg8391,8);	spca5xxRegWrite(spca50x->dev,0,0, 0x8390,Reg8391,8);	err=spca50x_reg_write(spca50x->dev, 0, 0x8112, 0x10 | 0x20);	err=spca50x_reg_write(spca50x->dev, 0, 0x850b, 0x03);	err=spca50x_reg_write(spca50x->dev, 0, 0x8112, 0x20);	//	return 0;}/************************* End spca561rev12A stuff **********************//************************* Core spca561 stuff ************************/static int spca561_init(struct usb_spca50x *spca50x){	int err;			switch (spca50x->chip_revision){	case Rev072A:		PDEBUG(0,"Find spca561 USB Product ID %x",spca50x->customid);		spca50x_write_vector(spca50x,spca561_init_data) ;	break;	case Rev012A:		PDEBUG(0,"Find spca561 USB Product ID %x",spca50x->customid);		err=init_161rev12A(spca50x);	break;	default:	PDEBUG(0,"Error reading USB Product ID from Global register");	break;	}	return 0;}#if 0static void spca561_dumpSensor(struct usb_spca50x *spca50x){	int i;	__u8 RegSens[] = {0,0};	switch (spca50x->chip_revision){	case Rev072A:	/*dump sensor registers */	for(i = 0; i< 0x36;i++){	/* mode 0x10 561, 0x14 mapped */   		err= spca561_ReadI2c(spca50x,i,0x10);   		PDEBUG(0,"reading Sensor i2c register 0x%02X -> 0x%04X",i,err);	}	break;	case Rev012A:	/* Sensor mapped registers */	for(i = 0; i< 0x36;i++){  		spca5xxRegRead(spca50x->dev,0,0, 0x8300+i,RegSens,2);  		PDEBUG(0,"reading Sensor map0x8300 register 0x%02X -> 0x%04X",i,RegSens[1] << 8 | RegSens[0]);	}	break;	}		}#endifstatic void spca561_start(struct usb_spca50x *spca50x){	int err;	int Clck = 0;	__u8 Reg8307[] = { 0xaa,0x00};	__u8 Reg8391[] = {  0x90,0x31,0x0b,0x00,0x25,0x00,0x00,0x00};//90 31 0c		switch (spca50x->chip_revision){	case Rev072A:	switch (spca50x->mode){		case 0:		case 1:			Clck = 0x25;		break;		case 2:			Clck = 0x22;		break;		case 3:			Clck = 0x21;		break;		default:			Clck = 0x25;	 	break;	}	err=spca50x_reg_write (spca50x->dev, 0, 0x8500,spca50x->mode);	// mode	err=spca50x_reg_write (spca50x->dev, 0, 0x8700, Clck);	// 0x27 clock	err=spca50x_reg_write(spca50x->dev, 0, 0x8112, 0x10 | 0x20); 		break;	case Rev012A:		switch (spca50x->mode){		case 0: 			//Clck =(spca50x->customid == 0x403b) ? 0x8a : 0x8f;			Clck = 0x8a;		break;		case 1:			Clck = 0x8a;		break;		case 2:			Clck = 0x85;			Reg8391[1]= 0x22; // increase pixel clock increase time exposure		break;		case 3:			Clck = 0x83;			Reg8391[1]= 0x22;		break;		default:			Clck = 0x25;	 	break;	}	if(compress && spca50x->mode <= 1){		// this is correct for 320x240; it also works at 352x288		// hell, I don't even know what this value means :)		Clck = 0x83; 		err=spca50x_reg_write (spca50x->dev, 0, 0x8500, 0x10+spca50x->mode);	}else{		// I couldn't get the compression to work below 320x240		// Fortunately at these resolutions the bandwidth is sufficient		// to push raw frames at ~20fps		err=spca50x_reg_write (spca50x->dev, 0, 0x8500, spca50x->mode);	} // -- qq@kuku.eu.org	spca5xxRegWrite(spca50x->dev,0,0, 0x8307,Reg8307,2);	err=spca50x_reg_write (spca50x->dev, 0, 0x8700, Clck);	// 0x8f 0x85 0x27 clock			spca5xxRegWrite(spca50x->dev,0,0, 0x8391,Reg8391,8);		spca5xxRegWrite(spca50x->dev,0,0, 0x8390,Reg8391,8);	spca50x->exposure = ((Reg8391[1]) << 8 )| Reg8391[0]; //set exposure with clock 	err=spca50x_reg_write(spca50x->dev, 0, 0x8112, 0x10 | 0x20);		err=spca50x_reg_write(spca50x->dev, 0, 0x850b, 0x03); 	err=spca561_setcontrast(spca50x);	break;	default:	PDEBUG(0,"Error reading USB Product ID from Global register");	break;	}}static void spca561_stop(struct usb_spca50x *spca50x){	int err;	err=spca50x_reg_write(spca50x->dev, 0, 0x8112, 0x20); //}static __u16 spca561_setbrightness(struct usb_spca50x *spca50x){	__u8 value = 0;	value = spca50x->brightness >> 9;	switch (spca50x->chip_revision){	case Rev072A:	spca5xxRegWrite(spca50x->dev,0,value,0x8611,NULL,0);	spca5xxRegWrite(spca50x->dev,0,value,0x8612,NULL,0);	spca5xxRegWrite(spca50x->dev,0,value,0x8613,NULL,0);	spca5xxRegWrite(spca50x->dev,0,value,0x8614,NULL,0);	break;	case Rev012A:	spca5xxRegWrite(spca50x->dev,0,value,0x8615,NULL,0);	spca5xxRegWrite(spca50x->dev,0,value,0x8614,NULL,0);	spca5xxRegWrite(spca50x->dev,0,value,0x8616,NULL,0);	spca5xxRegWrite(spca50x->dev,0,value,0x8617,NULL,0);	break;	}		return 0;} static __u16 spca561_getbrightness(struct usb_spca50x *spca50x){	__u8 value = 0;	__u16 tot = 0;	switch (spca50x->chip_revision){	case Rev072A:		spca5xxRegRead(spca50x->dev,0,0,0x8611,&value,1);	tot += value;	spca5xxRegRead(spca50x->dev,0,0,0x8612,&value,1);	tot += value;	spca5xxRegRead(spca50x->dev,0,0,0x8613,&value,1);	tot += value;	spca5xxRegRead(spca50x->dev,0,0,0x8614,&value,1);	tot += value;	spca50x->brightness = tot << 7;	break;	case Rev012A:	spca5xxRegRead(spca50x->dev,0,0,0x8615,&value,1);	spca50x->brightness = value << 9 ;	break;	}		return 0;} static __u16 spca561_setcontrast(struct usb_spca50x *spca50x){		__u8 lowb = 0;	int expotimes=0;	int pixelclk = 0;	__u8 Reg8391[] = {  0x90,0x31,0x0b,0x00,0x25,0x00,0x00,0x00};	switch (spca50x->chip_revision){	case Rev072A:	lowb = (spca50x->contrast >> 8) & 0xFF;	spca5xxRegWrite(spca50x->dev,0,lowb,0x8651,NULL,0);	spca5xxRegWrite(spca50x->dev,0,lowb,0x8652,NULL,0);	spca5xxRegWrite(spca50x->dev,0,lowb,0x8653,NULL,0);	spca5xxRegWrite(spca50x->dev,0,lowb,0x8654,NULL,0);	break;	case Rev012A:	lowb = (spca50x->contrast >> 10) & 0x7F;	if (lowb < 4) lowb = 3;	pixelclk = spca50x->exposure & 0xf800;	spca50x->exposure = ((spca50x->contrast >> 5) & 0x07ff) | pixelclk;	expotimes= spca50x->exposure & 0x07ff;	Reg8391[0] = expotimes & 0xff;	Reg8391[1] = ((pixelclk >> 8) & 0xf8 )|((expotimes >> 8) & 0x07);	Reg8391[2] = lowb;	PDEBUG(4, "Set Exposure 0x%02x 0x%02x gain 0x%02x", Reg8391[0],Reg8391[1], Reg8391[2]);	spca5xxRegWrite(spca50x->dev,0,0,0x8390,Reg8391,8);	break;	}	return 0;}static __u16 spca561_getcontrast(struct usb_spca50x *spca50x){	__u8 value = 0;	__u16 tot = 0;	__u8 contrast = 0x0b;	__u8 RegSens[] = {0,0};	switch (spca50x->chip_revision){	case Rev072A:		value = 0;	spca5xxRegRead(spca50x->dev,0,0,0x8651,&value,1);	tot += value;	spca5xxRegRead(spca50x->dev,0,0,0x8652,&value,1);	tot += value;	spca5xxRegRead(spca50x->dev,0,0,0x8653,&value,1);	tot += value;	spca5xxRegRead(spca50x->dev,0,0,0x8654,&value,1);	tot += value;	spca50x->contrast = tot << 6;		break;	case Rev012A:		spca5xxRegWrite(spca50x->dev,0,0, 0x8335,&contrast,1);	/* always 0x8335 return 0 */	 spca5xxRegRead(spca50x->dev,0,0,0x8335,RegSens,2);	spca50x->contrast = (contrast & 0x7f) << 10;	 PDEBUG(2, "Get constrast 0x8335 0x%04x", RegSens[1] << 8| RegSens[0]);	break;	}	return 0;} static int spca561_config(struct usb_spca50x *spca50x){	__u8 data1, data2;	// Read frm global register the USB product and vendor IDs, just to		// prove that we can communicate with the device.  This works, which	// confirms at we are communicating properly and that the device	// is a 561.	spca5xxRegRead(spca50x->dev,0,0,0x8104,&data1,1);	spca5xxRegRead(spca50x->dev,0,0,0x8105,&data2,1);	PDEBUG(1, "Read from GLOBAL: USB Vendor ID 0x%02x%02x", data2, data1);	spca5xxRegRead(spca50x->dev,0,0,0x8106,&data1,1);	spca5xxRegRead(spca50x->dev,0,0,0x8107,&data2,1);	PDEBUG(1, "Read from GLOBAL: USB Product ID 0x%02x%02x", data2, data1);	spca50x->customid = ((data2 << 8) | data1) & 0xffff;	switch (spca50x->customid){	case 0x7004:	case 0xa001:	case 0x0815:	case 0x0561:	case 0xcdee:	case 0x7e50: 		spca50x->chip_revision = Rev072A;	break;	case 0x0928:	case 0x0929:	case 0x092a:	case 0x403b:	case 0x092b:	case 0x092c:		spca50x->chip_revision = Rev012A;	break;	default:	PDEBUG(0, "Spca561 chip Unknow Contact the Author");	return -EINVAL;	break;	}	memset (spca50x->mode_cam, 0x00, TOTMODE * sizeof(struct mwebcam));		spca50x->mode_cam[SIF].width = 352;		spca50x->mode_cam[SIF].height = 288;		spca50x->mode_cam[SIF].t_palette =  P_RAW | P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16;		spca50x->mode_cam[SIF].pipe = 1023;		spca50x->mode_cam[SIF].method = 0;		spca50x->mode_cam[SIF].mode = 0;		spca50x->mode_cam[CIF].width = 320;		spca50x->mode_cam[CIF].height = 240;		spca50x->mode_cam[CIF].t_palette = P_RAW | P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16;		spca50x->mode_cam[CIF].pipe = 1023;		spca50x->mode_cam[CIF].method = 0;		spca50x->mode_cam[CIF].mode = 1;		spca50x->mode_cam[QPAL].width = 192;		spca50x->mode_cam[QPAL].height = 144;		spca50x->mode_cam[QPAL].t_palette = P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16;		spca50x->mode_cam[QPAL].pipe = 1023;		spca50x->mode_cam[QPAL].method = 1;		spca50x->mode_cam[QPAL].mode = 1;		spca50x->mode_cam[QSIF].width = 176;		spca50x->mode_cam[QSIF].height = 144;		spca50x->mode_cam[QSIF].t_palette = P_RAW |P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16;		spca50x->mode_cam[QSIF].pipe = 1023;		spca50x->mode_cam[QSIF].method = 0;		spca50x->mode_cam[QSIF].mode = 2;		spca50x->mode_cam[QCIF].width = 160;		spca50x->mode_cam[QCIF].height = 120;		spca50x->mode_cam[QCIF].t_palette = P_RAW |  P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16;		spca50x->mode_cam[QCIF].pipe = 1023;		spca50x->mode_cam[QCIF].method = 0;		spca50x->mode_cam[QCIF].mode = 3;		return 0; // success}static void spca561_shutdown(struct usb_spca50x *spca50x){	spca5xxRegWrite(spca50x->dev,0,0,0x8114,NULL,0);}static void spca561_setAutobright (struct usb_spca50x *spca50x){	int expotimes=0;	int pixelclk = 0;	int gainG = 0;	__u8 R,Gr,Gb,B;	int y;	__u8 luma_mean = 110;	__u8 luma_delta = 20;	__u8 spring = 4;	switch(spca50x->chip_revision){	case Rev072A:	spca5xxRegRead(spca50x->dev,0,0,0x8621,&Gr,1);	spca5xxRegRead(spca50x->dev,0,0,0x8622,&R,1);	spca5xxRegRead(spca50x->dev,0,0,0x8623,&B,1);	spca5xxRegRead(spca50x->dev,0,0,0x8624,&Gb,1);	y= (77*R+75*(Gr+Gb)+29*B) >> 8;	//u= (128*B-(43*(Gr+Gb+R))) >> 8;	//v= (128*R-(53*(Gr+Gb))-21*B) >> 8;	//PDEBUG(0,"reading Y %d U %d V %d ",y,u,v);		if ((y < (luma_mean - luma_delta)) ||	( y > (luma_mean + luma_delta))) {	expotimes= spca561_ReadI2c(spca50x,0x09,0x10);	pixelclk = 0x0800;	expotimes = expotimes & 0x07ff;	//PDEBUG(0,"Exposition Times 0x%03X Clock 0x%04X ",expotimes,pixelclk);	gainG= spca561_ReadI2c(spca50x,0x35,0x10);	//PDEBUG(0,"reading Gain register %d",gainG);		expotimes += ((luma_mean-y) >> spring);		gainG += ((luma_mean-y) / 50);		// PDEBUG(0 , "compute expotimes %d gain %d",expotimes,gainG);				if (gainG > 0x3F)			gainG = 0x3f;		else if (gainG < 4)			gainG = 3;		spca561_WriteI2c(spca50x,(__u16) gainG,0x35);										if(expotimes >= 0x0256)			expotimes = 0x0256;			else if (expotimes < 4){				expotimes = 3;				}		spca561_WriteI2c(spca50x,(__u16)(expotimes | pixelclk),0x09);	}	break;	case Rev012A:	/* sensor registers is access and memory mapped to 0x8300 */	/* readind all 0x83xx block the sensor */	/*	The data from the header seem wrong where is the luma and chroma mean value	at the moment set exposure in contrast set 	*/		;		break;	default:	break;	}} #endif

⌨️ 快捷键说明

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