📄 spca561.h
字号:
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 + -