📄 zc030x_cameras.c
字号:
/* Include headers */#include "zc030x_cameras.h"/* Include bridge chip communication */#include "zc030x_reg.h"/* Include memory management */#include "zc030x_mm.h"/* Include gamma sequence creation */#include "zc030x_matrix.h"/* Include sensors declarations */#include "sensors/CS2102.h"#include "sensors/CS2103.h"#include "sensors/HDCS1020.h"#include "sensors/HDCS2020.h"#include "sensors/HV7121B.h"#include "sensors/HV7131B.h"#include "sensors/ICM102A.h"#include "sensors/ICM105A.h"#include "sensors/OV7620.h"#include "sensors/OVCIF.h"#include "sensors/PAS106B.h"#include "sensors/PAS202B.h"#include "sensors/PB0111.h"#include "sensors/PB0330.h"#include "sensors/TAS5130C.h"#include "sensors/TAS5110B.h"/* Declare declaration macro */#define DeclareI2CInit(Name, E1, A1, V1, A2, V2, A3, V3, A4, V4, A5, V5, A6, V6) \ const I2CInitSequence i2c_init_##Name = { .Direction = { 1, 0, 0, 0, 0, 0 }, \ .Address = { A1, A2, A3, A4, A5, A6 }, \ .Value = { V1, V2, V3, V4, V5, V6 }, \ .ReturnSize = { 1, 0, 0, 0, 0, 0 }, \ .ReturnValue = { E1, 0, 0, 0, 0, 0 } } /* Declare I2CInitSequences *//* Look at the sniff after a plugin sequence first 6 packets */DeclareI2CInit(WebcamNXPro , 0x00, 0x10, 0x01, 0x00, 0x01, 0x10, 0x00, 0x01, 0x01, 0x12, 0x03, 0x12, 0x01);DeclareI2CInit(Generic , 0x00, 0x10, 0x01, 0x00, 0x01, 0x10, 0x00, 0x01, 0x01, 0x12, 0x03, 0x12, 0x01);DeclareI2CInit(WebcamNX , 0x00, 0x10, 0x01, 0x00, 0x01, 0x10, 0x0f, 0x01, 0x01, 0x12, 0x03, 0x8d, 0x08);DeclareI2CInit(GeniusV2 , 0x00, 0x10, 0x01, 0x00, 0x01, 0x10, 0x00, 0x01, 0x01, 0x12, 0x03, 0x12, 0x01);DeclareI2CInit(GeniusV4 , 0x00, 0x10, 0x01, 0x00, 0x01, 0x10, 0x00, 0x01, 0x01, 0x12, 0x03, 0x12, 0x01);DeclareI2CInit(MustekW300A , 0x00, 0x10, 0x01, 0x00, 0x01, 0x10, 0x00, 0x01, 0x01, 0x12, 0x03, 0x12, 0x01);/* This one is different */DeclareI2CInit(ZStarCorp , 0x00, 0x10, 0x01, 0x00, 0x01, 0x10, 0x0c, 0x01, 0x01, 0x12, 0x03, 0x12, 0x01);DeclareI2CInit(BenqCam , 0x01, 0x10, 0x01, 0x00, 0x01, 0x10, 0x01, 0x01, 0x01, 0x12, 0x03, 0x12, 0x01);DeclareI2CInit(WebcamMobile , 0x00, 0x10, 0x01, 0x00, 0x01, 0x10, 0x00, 0x01, 0x01, 0x12, 0x03, 0x12, 0x01);DeclareI2CInit(WebcamNotebook , 0x00, 0x10, 0x01, 0x00, 0x01, 0x10, 0x00, 0x01, 0x01, 0x12, 0x03, 0x8d, 0x04);DeclareI2CInit(WebcamNXPro2 , 0x00, 0x10, 0x01, 0x00, 0x01, 0x10, 0x0f, 0x01, 0x01, 0x12, 0x03, 0x8d, 0x08);DeclareI2CInit(WebcamInstant , 0x00, 0x10, 0x01, 0x00, 0x01, 0x10, 0x0f, 0x01, 0x01, 0x12, 0x03, 0x8d, 0x08);DeclareI2CInit(MustekW300A2 , 0x00, 0x10, 0x01, 0x00, 0x01, 0x10, 0x00, 0x01, 0x01, 0x12, 0x03, 0x12, 0x01);DeclareI2CInit(LabtechWcamPro , 0x00, 0x10, 0x01, 0x00, 0x01, 0x10, 0x00, 0x01, 0x01, 0x12, 0x03, 0x12, 0x01);#define MaxNbCamera (sizeof(CamList) / sizeof(CamList[0]))/* Declare declaration macro */#define DeclareCam(Nam, VID, PID, ID) \ { .ProductID = PID, .VendorID = VID, .Index = ID, .Name = #Nam, .pI2CInitSeq = &i2c_init_##Nam } /* And the supported camera */const CameraList CamList[] = { DeclareCam(MustekW300A , 0x055f, 0xd003, 0), DeclareCam(WebcamNXPro , 0x041e, 0x401e, 1), DeclareCam(WebcamNX , 0x041e, 0x401c, 2), DeclareCam(GeniusV2 , 0x0458, 0x7007, 3), DeclareCam(BenqCam , 0x0ac8, 0x0302, 4), DeclareCam(ZStarCorp , 0x0ac8, 0x301b, 5), DeclareCam(Generic , 0x0ac8, 0x0301, 6), DeclareCam(WebcamMobile , 0x041e, 0x4017, 7), DeclareCam(WebcamNotebook , 0x041e, 0x401f, 8), DeclareCam(WebcamNXPro2 , 0x041e, 0x403a, 9), DeclareCam(GeniusV4 , 0x0458, 0x700f, 10), DeclareCam(WebcamInstant , 0x041e, 0x4034, 11), DeclareCam(MustekW300A2 , 0x055f, 0xd005, 12), DeclareCam(LabtechWcamPro , 0x046d, 0x08a2, 13), };/* Declare the static usb_device_id Sadly, this can't be dynamic ! */const struct usb_device_id zc030x_table[] = { {USB_DEVICE (0x055f, 0xd003)}, {USB_DEVICE (0x041e, 0x401e)}, {USB_DEVICE (0x041e, 0x401c)}, {USB_DEVICE (0x0458, 0x7007)}, {USB_DEVICE (0x0ac8, 0x0302)}, {USB_DEVICE (0x0ac8, 0x301b)}, {USB_DEVICE (0x0ac8, 0x0301)}, {USB_DEVICE (0x041e, 0x4017)}, {USB_DEVICE (0x041e, 0x401f)}, {USB_DEVICE (0x041e, 0x403a)}, {USB_DEVICE (0x0458, 0x700f)}, {USB_DEVICE (0x041e, 0x4034)}, {USB_DEVICE (0x055f, 0xd005)}, {USB_DEVICE (0x046d, 0x08a2)}, {} /* Terminating entry */};#define MaxNbSensor (sizeof(SensList) / sizeof(SensList[0]))/* Declare declaration macro */#define DeclareSensor(Nam, ID) \ { .Index = ID, .Name = #Nam, .Address = ZcVal_##Nam, .pSignature = &sig_##Nam } /* And the supported camera */const SensorList SensList[] = { DeclareSensor(CS2102 , 0 ), DeclareSensor(CS2103 , 1 ), DeclareSensor(HDCS1020, 2 ), DeclareSensor(HDCS2020, 3 ), DeclareSensor(HV7121B , 4 ), DeclareSensor(HV7131B , 5 ), DeclareSensor(ICM102A , 6 ), DeclareSensor(ICM105A , 7 ), DeclareSensor(OV7620 , 8 ), DeclareSensor(OVCIF , 9 ), DeclareSensor(PAS106B , 10), DeclareSensor(PAS202B , 11), DeclareSensor(PB0111 , 12), DeclareSensor(PB0330 , 13), DeclareSensor(TAS5130C, 14), DeclareSensor(TAS5110B, 15),};/* Default sharpness sequence */__u8 SharpnessControlSeq[6] = { 0x10, 0x00, 0x01, 0x01, 0x01, 0x1e };/* Default RGB matrix sequence */__u8 RGBMatrix[3][4] = { { 0x5a, 0xf3, 0xf3, 0x00 }, { 0xf3, 0x5a, 0xf3, 0x00 }, { 0xf3, 0xf3, 0x5a, 0x00 }}; #define MaxNbSensor (sizeof(SensList) / sizeof(SensList[0]))/* Declare declaration macro */#define DeclareSensorSize(Nam, width, height, firstpixel, enable) \ { .Width = width, .Height = height, .FirstPixel = firstpixel, .Enable = enable } /* And the supported camera */const SensorSize SensorSizeList[] = { DeclareSensorSize(CS2102 , 640, 480, ZV(EnableInterpol) | ZV(GammaCorrection) | ZV(ColorCorrection), 0), DeclareSensorSize(CS2103 , 352, 288, ZV(EnableInterpol) | ZV(GammaCorrection) | ZV(ColorCorrection), 0), DeclareSensorSize(HDCS1020, 352, 288, ZV(EnableInterpol) | ZV(GammaCorrection) | ZV(ColorCorrection), 0), DeclareSensorSize(HDCS2020, 640, 480, ZV(GInterpolMedian) | ZV(RBInterpolAvg) | ZV(FirstPixelIsGreen) | ZV(EnableInterpol) | ZV(GammaCorrection) | ZV(ColorCorrection), 0), DeclareSensorSize(HV7121B , 352, 288, ZV(EnableInterpol) | ZV(GammaCorrection) | ZV(ColorCorrection), ZV(EnableSensor)), DeclareSensorSize(HV7131B , 640, 480, ZV(EnableInterpol) | ZV(GammaCorrection) | ZV(ColorCorrection), ZV(EnableSensor)), DeclareSensorSize(ICM102A , 352, 288, ZV(EnableInterpol) | ZV(GammaCorrection) | ZV(ColorCorrection), 0), DeclareSensorSize(ICM105A , 640, 480, ZV(EnableInterpol) | ZV(GammaCorrection) | ZV(ColorCorrection), 0), DeclareSensorSize(OV7620 , 640, 480, ZV(EnableInterpol) | ZV(GammaCorrection) | ZV(ColorCorrection), 0), DeclareSensorSize(OVCIF , 352, 288, ZV(EnableInterpol) | ZV(GammaCorrection) | ZV(ColorCorrection), 0), DeclareSensorSize(PAS106B , 352, 288, ZV(EnableInterpol) | ZV(GammaCorrection) | ZV(ColorCorrection), 0), DeclareSensorSize(PAS202B , 640, 480, ZV(EnableInterpol) | ZV(GammaCorrection) | ZV(ColorCorrection), 0), DeclareSensorSize(PB0111 , 352, 288, ZV(EnableInterpol) | ZV(GammaCorrection) | ZV(ColorCorrection), ZV(EnableSensor)), DeclareSensorSize(PB0330 , 640, 480, ZV(EnableInterpol) | ZV(GammaCorrection) | ZV(ColorCorrection), ZV(EnableSensor)), DeclareSensorSize(TAS5130C, 640, 480, ZV(GInterpolMedian) | ZV(RBInterpolAvg) | ZV(FirstPixelIsGreen) | ZV(EnableInterpol) | ZV(GammaCorrection) | ZV(ColorCorrection), ZV(EnableSensor)), DeclareSensorSize(TAS5110B, 352, 288, ZV(EnableInterpol) | ZV(GammaCorrection) | ZV(ColorCorrection), ZV(EnableSensor)),};/* Declare declaration macro */#define DeclareSensorConfig(Nam) \ &sc_##Nam /* And the supported camera */const SensorConfig * SensConfList[] = { DeclareSensorConfig(CS2102 ), DeclareSensorConfig(CS2103 ), DeclareSensorConfig(HDCS1020), DeclareSensorConfig(HDCS2020), DeclareSensorConfig(HV7121B ), DeclareSensorConfig(HV7131B ), DeclareSensorConfig(ICM102A ), DeclareSensorConfig(ICM105A ), DeclareSensorConfig(OV7620 ), DeclareSensorConfig(OVCIF ), DeclareSensorConfig(PAS106B ), DeclareSensorConfig(PAS202B ), DeclareSensorConfig(PB0111 ), DeclareSensorConfig(PB0330 ), DeclareSensorConfig(TAS5130C), DeclareSensorConfig(TAS5110B),};/* Detect the sensor */int zc030x_detect_sensor(struct usb_zc030x * dev, int id){ /* Iterators */ int i = 0; /* Sensor address */ unsigned char addr = 0; /* Find the sensor now */ addr = zc030x_i2c_detect(dev->udev, CamList[id].pI2CInitSeq); if (addr <= 0 || addr > 0x3f) { PDEBUG (1, "Sensor not found"); return -1; } /* Found */ dev->sensor_addr = addr - 1; /* Check the sensors signatures now */ i = 0; while (i < MaxNbSensor && SensList[i].pSignature != NULL && zc030x_i2c_checksignature(dev->udev, SensList[i].pSignature) < sensoraccept) i++; if (i == MaxNbSensor) { PDEBUG (1, "Unsupported sensor or sensor not detected. Exiting\n"); PDEBUG (1, "To help up improve this driver, please send the informations below"); /* Get a simple register map */ zc030x_i2c_simple_registermap(dev->udev); PDEBUG (1, "To zc0302-devs@lists.sf.net, with your ProductID:SensorID"); PDEBUG (1, "and your sensor type, if you could know this. Thanks"); return -1; } /* Found */ dev->sensor_id = SensList[i].Index; /* Check if this is a PAS106B or not (this is due to a bug in PAS202B) */ if (SensList[dev->sensor_id].pSignature->sensor_id == PAS106B && dev->sensor_addr == ZV(PAS202B)) { dev->sensor_addr = ZV(PAS106B); PDEBUG(1, "Corrected sensor to address %02X", dev->sensor_addr); } /* Okay, return */ return 0;}/* Detect the camera */int zc030x_detect_camera(struct usb_zc030x * dev){ /* Get the USB device */ struct usb_device *udev = dev->udev; /* Get Vendor ID */ int vend_id = udev->descriptor.idVendor; /* Get Product ID */ int prod_id = udev->descriptor.idProduct; /* Get release number */ int release = udev->descriptor.bcdDevice; /* Iterators */ int i = 0, id = 0; /* Some tests */ int sa = 0; int sb, sc, sd, se, sf; int ident = 0; /* some info about the device */ PDEBUG (1, "vend_id : %04x", vend_id); PDEBUG (1, "prod_id : %04x", prod_id); PDEBUG (1, "Release : %04x", release); /* See if the device offered us matches what we can accept */ /* Find the vendor ID in the camera list */ while (id < MaxNbCamera && (CamList[id].VendorID != vend_id || CamList[id].ProductID != prod_id) ) id++; /* Check the research */ if (id == MaxNbCamera) { PDEBUG (1, "Unsupported webcam. Exiting"); return -1; } /* Found */ dev->vend_id = vend_id; dev->prod_id = prod_id; dev->type_id = CamList[id].Index; /* Read the test register */ ident = zc030x_reg_read(dev->udev, ZR(TestModeControl), 0x01, 1); if ((ident & ZV(Zc301Plus)) == ZV(Zc301Plus)) { PDEBUG(1, "Detected Zc0301+ bridge chip"); } else { PDEBUG(1, "Detected Zc0302 bridge chip"); } /* Reset the camera */ if (zc030x_reg_reset(dev->udev) == REG_Error) { PDEBUG (1, "Cannot reset the camera"); return -1; } /* Get the sensor address by reading the 0x10 register */ sa = zc030x_reg_read(dev->udev, ZR(CMOSSensorSelect), 0x01, 1); sb = zc030x_reg_read(dev->udev, ZR(WinYStartLow), 0x01, 1); sc = zc030x_reg_read(dev->udev, ZR(WinXStartLow), 0x01, 1); sd = zc030x_reg_read(dev->udev, ZR(CompabilityMode), 0x01, 1); se = zc030x_reg_read(dev->udev, ZR(I2CIdleAndNAck), 0x01, 1); sf = (zc030x_reg_read(dev->udev, ZR(I2CDeviceAddr), 0x01, 1) & 0x7F); /* Check the macro */ if (strcmp(sensor, "auto") == 0) { PDEBUG(1, "Asked for autodectection..."); if (zc030x_detect_sensor(dev, id)<0) return -1; } else { // Need to parse the sensor name specified at insmoding i = 0; while (i < MaxNbSensor && strcmp(sensor, SensList[i].Name) != 0) { i++; } if (i == MaxNbSensor) { // Invalid name or sensor not supported, detect it PDEBUG(1, "Invalid name or sensor not supported, detection..."); if (zc030x_detect_sensor(dev, id)<0) return -1; } else { // Ugly debug to be tested if (strcmp(sensor, "TAS5130C")==0) { } // Found PDEBUG(1, "Sensor set to %s", sensor); dev->sensor_addr = SensList[i].Address; dev->sensor_id = SensList[i].Index; } } /* Debug this */ PDEBUG(1, "MaxNbSensor : %d", MaxNbSensor); PDEBUG(1, "Found sensor at address %02X", dev->sensor_addr); /* Debug this */ PDEBUG (1, "Detected camera %s with sensor id %s\n", CamList[dev->type_id].Name, SensList[dev->sensor_id].Name); PDEBUG (4, "HM[0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X]", sa, sb, sc, sd, se, sf); return 0;}/* Send the sharpness sequence */int zc030x_send_sharpness(struct usb_device *udev, const __u8 * value){ /* Check arguments */ if (udev == NULL || value == NULL) { PDEBUG(1, "udev or value is null"); return -1; } /* Send the sharpness sequence */ zc030x_reg_write(udev, ZR(Sharpness00), value[0]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -