www.pudn.com > zc030x.rar > zc030x_cameras.c, change:2008-06-04,size:29843b
/* 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]);
zc030x_reg_read(udev, ZR(Sharpness01), value[1], 1);
zc030x_reg_read(udev, ZR(Sharpness02), value[2], 1);
zc030x_reg_read(udev, ZR(Sharpness03), value[3], 1);
zc030x_reg_read(udev, ZR(Sharpness04), value[4], 1);
zc030x_reg_write(udev, ZR(Sharpness05), value[5]);
/* Return */
return 0;
}
/* Send the gamma sequence */
int zc030x_send_gamma(struct usb_device *udev, const __u16 brightness, const __u16 contrast, const __u16 gamma)
{
/* Iterator */
int i = 0;
/* Need to convert the value to emulated floating points */
const FPNum dBrightness = CreateFPNumFromInt(((int)brightness - 32768));
const FPNum dContrast = CreateFPNumFromInt(((int)contrast - 32768));
const FPNum dGamma = CreateFPNumFromInt((int)gamma);
FPNum OneOutOf256;
FPNum OneOutOf32768;
/* Init the FP Numbers */
InitFPNum(&OneOutOf256, "0.00390625");
InitFPNum(&OneOutOf32768, "0.000030517578125");
/* Gamma matrix */
{
const __u8 * Gamma = zc030x_gamma_create_FPNum(Mul(dGamma, OneOutOf256), Mul(dBrightness, OneOutOf32768), Mul(dContrast, OneOutOf32768));
PDEBUG(4, "Gamma matrix [%02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X]", Gamma[0x00], Gamma[0x01], Gamma[0x02], Gamma[0x03], Gamma[0x04], Gamma[0x05], Gamma[0x06], Gamma[0x07], Gamma[0x08], Gamma[0x09], Gamma[0x0a], Gamma[0x0b], Gamma[0x0c], Gamma[0x0d], Gamma[0x0e], Gamma[0x0f]);
PDEBUG(4, "Gamma Slope matrix [%02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X]", Gamma[0x10], Gamma[0x11], Gamma[0x12], Gamma[0x13], Gamma[0x14], Gamma[0x15], Gamma[0x16], Gamma[0x17], Gamma[0x18], Gamma[0x19], Gamma[0x1a], Gamma[0x1b], Gamma[0x1c], Gamma[0x1d], Gamma[0x1e], Gamma[0x1f]);
/* Check arguments */
if (udev == NULL || Gamma == NULL)
{
PDEBUG(1, "udev or gamma is null");
return -1;
}
/* Send the gamma sequence */
for (; i < 32; i++)
zc030x_reg_write(udev, ZR(Gamma00) + i, Gamma[i]);
}
/* Return */
return 0;
}
/* Send the RGB to RGB conversion matrix */
int zc030x_send_RGBmatrix(struct usb_device *udev, __u8 matrix[3][4])
{
/* Check arguments */
if (udev == NULL)
{
PDEBUG(1, "udev is null");
return -1;
}
/* Send the sharpness sequence */
zc030x_reg_write(udev, ZR(RGB00), matrix[0][0]);
zc030x_reg_write(udev, ZR(RGB01), matrix[0][1]);
zc030x_reg_write(udev, ZR(RGB02), matrix[0][2]);
zc030x_reg_write(udev, ZR(RGB03), matrix[0][3]);
zc030x_reg_write(udev, ZR(RGB10), matrix[1][0]);
zc030x_reg_write(udev, ZR(RGB11), matrix[1][1]);
zc030x_reg_write(udev, ZR(RGB12), matrix[1][2]);
zc030x_reg_write(udev, ZR(RGB13), matrix[1][3]);
zc030x_reg_write(udev, ZR(RGB20), matrix[2][0]);
zc030x_reg_write(udev, ZR(RGB21), matrix[2][1]);
zc030x_reg_write(udev, ZR(RGB22), matrix[2][2]);
zc030x_reg_write(udev, ZR(RGB23), matrix[2][3]);
/* Return */
return 0;
}
/* Configure the camera */
int zc030x_configure_camera(struct usb_zc030x * dev, int width, int height, int quality)
{
/* Iterator */
// int i = 0;
/* Debug this */
PDEBUG(1, ">>> CONFCAM %dx%d:%d", width, height, quality);
/* Allocate buffers */
if (zc030x_allocate_buffers(dev) < 0)
{
PDEBUG(1, "Failed while allocating the buffers!");
return -1;
}
/* Reset the camera */
if (zc030x_reg_reset(dev->udev) != REG_OK)
{
PDEBUG(1, "Failed while resetting the camera!");
return -1;
}
/* Send the I2C start sequence */
zc030x_i2c_start(dev->udev, CamList[dev->type_id].pI2CInitSeq, dev->sensor_addr);
/* Change the interface */
usb_set_interface (dev->udev, 0, 6);
/* Change the debug level */
if (debug == 5) debug = 6;
/* Reset the camera */
zc030x_reg_write(dev->udev, ZR(SystemControl), ZV(Reset));
/* Resend the sensor address after a reset */
zc030x_reg_write(dev->udev, ZR(CMOSSensorSelect), dev->sensor_addr);
/* Start operating */
zc030x_reg_write(dev->udev, ZR(SystemOperating), ZV(Start));
/* Reset the internal stuff */
zc030x_reg_write(dev->udev, ZR(VideoControlFunc), SensorSizeList[dev->sensor_id].Enable | ZV(ResetSensor)|ZV(SensorTurnOn));
zc030x_reg_write(dev->udev, ZR(VideoControlFunc), SensorSizeList[dev->sensor_id].Enable | ZV(SensorTurnOn));
PDEBUG(1, "Please report this to the list [101=%02X, %s-VID%04X:PID%04X:SID-%s]", zc030x_reg_read(dev->udev, ZR(SensorCorrection), 1, 1), CamList[dev->type_id].Name, dev->udev->descriptor.idVendor, dev->udev->descriptor.idProduct, SensList[dev->sensor_id].Name);
/* Set the window size */
switch(SensList[dev->sensor_id].pSignature->sensor_id)
{
case TAS5130C:
/* Set the size */
if (zc030x_reg_setsize(dev, width, height, ZV(DoubleClock)) != REG_OK)
{
PDEBUG(1, "Failed while setting the size!");
return -1;
}
zc030x_reg_write(dev->udev, ZR(CompabilityMode) , ZV(TASxxxxC)|ZV(Round9To8Bit));
zc030x_reg_write(dev->udev, ZR(WinYStartHigh), ZV(HalfscalY_Default));
if (currentheight < SensorSizeList[dev->sensor_id].Height)
zc030x_reg_write(dev->udev, ZR(WinYStartLow), ZV(HalfscalY_TASCVGA));
else
zc030x_reg_write(dev->udev, ZR(WinYStartLow), ZV(FullscalY_TASCVGA));
zc030x_reg_write(dev->udev, ZR(WinXStartHigh), ZV(HalfscalX_Default));
if (currentwidth < SensorSizeList[dev->sensor_id].Width)
zc030x_reg_write(dev->udev, ZR(WinXStartLow), ZV(HalfscalX_TASCVGA));
else
zc030x_reg_write(dev->udev, ZR(WinXStartLow), ZV(FullscalX_TASCVGA));
break;
case TAS5110B:
/* Set the size */
if (zc030x_reg_setsize(dev, width, height, ZV(DoubleClock)) != REG_OK)
{
PDEBUG(1, "Failed while setting the size!");
return -1;
}
zc030x_reg_write(dev->udev, ZR(CompabilityMode) , ZV(TASxxxxC)|ZV(Round9To8Bit));
zc030x_reg_write(dev->udev, ZR(WinYStartHigh), ZV(HalfscalY_Default));
if (currentheight < SensorSizeList[dev->sensor_id].Height)
zc030x_reg_write(dev->udev, ZR(WinYStartLow), ZV(HalfscalY_TASCCIF));
else
zc030x_reg_write(dev->udev, ZR(WinYStartLow), ZV(FullscalY_TASCCIF));
zc030x_reg_write(dev->udev, ZR(WinXStartHigh), ZV(HalfscalX_Default));
if (currentwidth < SensorSizeList[dev->sensor_id].Width)
zc030x_reg_write(dev->udev, ZR(WinXStartLow), ZV(HalfscalX_TASCCIF));
else
zc030x_reg_write(dev->udev, ZR(WinXStartLow), ZV(FullscalX_TASCCIF));
break;
case ICM105A:
case ICM102A:
/* Set the size */
if (zc030x_reg_setsize(dev, width, height, 0) != REG_OK)
{
PDEBUG(1, "Failed while setting the size!");
return -1;
}
zc030x_reg_write(dev->udev, ZR(CompabilityMode), 0);
zc030x_reg_write(dev->udev, ZR(WinYStartHigh), ZV(HalfscalY_Default));
if (currentheight < SensorSizeList[dev->sensor_id].Height)
zc030x_reg_write(dev->udev, ZR(WinYStartLow), ZV(HalfscalY_ICM));
else
zc030x_reg_write(dev->udev, ZR(WinYStartLow), ZV(FullscalY_ICM));
zc030x_reg_write(dev->udev, ZR(WinXStartHigh), ZV(HalfscalX_Default));
if (currentwidth < SensorSizeList[dev->sensor_id].Width)
zc030x_reg_write(dev->udev, ZR(WinXStartLow), ZV(HalfscalX_ICM));
else
zc030x_reg_write(dev->udev, ZR(WinXStartLow), ZV(FullscalX_ICM));
break;
case OV7620:
case OVCIF:
/* Set the size */
if (zc030x_reg_setsize(dev, width, height, 0) != REG_OK)
{
PDEBUG(1, "Failed while setting the size!");
return -1;
}
zc030x_reg_write(dev->udev, ZR(CompabilityMode), ZV(OVSensor));
break;
case PAS202B:
case PAS106B:
/* Set the size */
if (zc030x_reg_setsize(dev, width, height, width < SensorSizeList[dev->sensor_id].Width / 2 ? ZV(PCLCK_750Khz) : 0) != REG_OK)
{
PDEBUG(1, "Failed while setting the size!");
return -1;
}
zc030x_reg_write(dev->udev, ZR(CompabilityMode), ZV(OVSensor));
zc030x_reg_write(dev->udev, ZR(WinYStartHigh), ZV(HalfscalY_Default));
zc030x_reg_write(dev->udev, ZR(WinYStartLow), ZV(HalfscalY_Default));
zc030x_reg_write(dev->udev, ZR(WinXStartHigh), ZV(HalfscalX_Default));
if (currentwidth < SensorSizeList[dev->sensor_id].Width)
zc030x_reg_write(dev->udev, ZR(WinXStartLow), ZV(HalfscalX_PAS));
else
zc030x_reg_write(dev->udev, ZR(WinXStartLow), ZV(FullscalX_PAS));
break;
case HDCS2020:
/* Set the size */
if (zc030x_reg_setsize(dev, width, height, width < SensorSizeList[dev->sensor_id].Width / 2 ? ZV(PCLCK_3Mhz) : 0) != REG_OK)
{
PDEBUG(1, "Failed while setting the size!");
return -1;
}
/* Sensor parameters */
if (currentwidth >= SensorSizeList[dev->sensor_id].Width)
zc030x_reg_write(dev->udev, ZR(SensorCorrection), SensorSizeList[dev->sensor_id].FirstPixel | ZV(FirstLineIsGBGBG));
case HV7131B:
default:
/* Set the size */
if (zc030x_reg_setsize(dev, width, height, 0) != REG_OK)
{
PDEBUG(1, "Failed while setting the size!");
return -1;
}
zc030x_reg_write(dev->udev, ZR(CompabilityMode), 0);
zc030x_reg_write(dev->udev, ZR(WinYStartHigh), ZV(HalfscalY_Default));
zc030x_reg_write(dev->udev, ZR(WinYStartLow), ZV(HalfscalY_Default));
zc030x_reg_write(dev->udev, ZR(WinXStartHigh), ZV(HalfscalX_Default));
zc030x_reg_write(dev->udev, ZR(WinXStartLow), ZV(HalfscalX_Default));
break;
}
/* Set the window size */
switch(SensList[dev->sensor_id].pSignature->sensor_id)
{
case HDCS2020:
case TAS5130C:
case TAS5110B:
if (currentheight < SensorSizeList[dev->sensor_id].Height)
{
zc030x_reg_write(dev->udev, ZR(MaxXHigh), 0x03);
zc030x_reg_write(dev->udev, ZR(MaxXLow), 0xc0);
zc030x_reg_write(dev->udev, ZR(ExposureTimeHigh), 0x01);
zc030x_reg_write(dev->udev, ZR(ExposureTimeLow), 0x77);
zc030x_reg_write(dev->udev, ZR(ExposureGain), 0x01);
}
else
{
zc030x_reg_write(dev->udev, ZR(MaxXHigh), ZV(XMaxHighDefault));
zc030x_reg_write(dev->udev, ZR(MaxXLow), ZV(XMaxLowVGADefault));
zc030x_reg_write(dev->udev, ZR(ExposureTimeHigh), ZV(DefExpTimeVGAHigh));
zc030x_reg_write(dev->udev, ZR(ExposureTimeLow), ZV(DefExpTimeVGALow));
zc030x_reg_write(dev->udev, ZR(ExposureGain), ZV(DefExpGainVGA));
}
zc030x_reg_write(dev->udev, ZR(ExposureBlackLvl), 0x3c);
break;
default:
break;
}
/* Set the automatic features */
zc030x_reg_write(dev->udev, ZR(OperationMode), ZV(DigitalColorGain)|ZV(YGammaGain)|ZV(DigitalGlobalGain));
/* Auto white balance */
WriteDefaultValue(dev->udev, AWBStatus);
/* Sharpness */
zc030x_reg_write(dev->udev, ZR(SharpnessMode), ZV(UseAvgValue)|ZV(EnableSharpening));
/* Write the Zc030x I2C registers */
zc030x_i2c_writeconfig(dev->udev, SensConfList[dev->sensor_id]);
/* Dead pixels */
zc030x_reg_write(dev->udev, ZR(DeadPixelsMode), ZV(RemoveDeadPixels));
zc030x_reg_write(dev->udev, ZR(EEPROMAccess), ZV(BatchReadControl));
/* Enable autoexposure */
zc030x_reg_write(dev->udev, ZR(AutoCorrectEnable), ZV(AutoWhiteBalance) | ZV(AutoColorGain) | ZV(AutoExpAntiFlick));
/* Set the Auto exposure window */
WriteDefaultValue(dev->udev, WinXStart);
WriteDefaultValue(dev->udev, WinXWidth);
WriteDefaultValue(dev->udev, WinXCenter);
WriteDefaultValue(dev->udev, WinYStart);
WriteDefaultValue(dev->udev, WinYWidth);
WriteDefaultValue(dev->udev, WinYCenter);
/* Control the AE */
zc030x_reg_write(dev->udev, ZR(AEStatus), ZV(WinAndBlockWeight)|ZV(LargeCenterWindow));
zc030x_reg_write(dev->udev, ZR(AEFreeze), MakeAELockRange(0x14));
zc030x_reg_write(dev->udev, ZR(AEUnfreeze), MakeAELockRange(0x20));
/* Sensor parameters */
zc030x_reg_write(dev->udev, ZR(SensorCorrection), SensorSizeList[dev->sensor_id].FirstPixel);
/* Reset the clock */
zc030x_reg_write(dev->udev, ZR(ClockSetting), ZV(Rounding)|ZV(QuarterQuant));
/* And send the sharpness informations */
zc030x_send_sharpness(dev->udev, SharpnessControlSeq);
/* Send the gamma sequence */
zc030x_send_gamma(dev->udev, dev->Brightness, dev->Contrast, dev->Gamma);
/* Send the RGB matrix sequence */
zc030x_send_RGBmatrix(dev->udev, RGBMatrix);
/* Set the gains */
zc030x_reg_write(dev->udev, ZR(RGain), MakeGain(1,0));
zc030x_reg_write(dev->udev, ZR(GGain), MakeGain(1,0));
zc030x_reg_write(dev->udev, ZR(BGain), MakeGain(1,0));
zc030x_reg_write(dev->udev, ZR(GlobalGain), MakeGain(1,0));
zc030x_reg_write(dev->udev, ZR(DigitalGain), MakeDigitalGain(1,0));
zc030x_reg_write(dev->udev, ZR(DigitalLimitDiff), MakeDigitalLimitDiff(0x0c));
zc030x_reg_write(dev->udev, ZR(DigitalGainStep), MakeDigitalGainStep(2,4));
/* Set the clocks now */
zc030x_reg_write(dev->udev, ZR(Sync00Low) , 0x00);
zc030x_reg_write(dev->udev, ZR(Sync00Mid) , 0x04);
zc030x_reg_write(dev->udev, ZR(Sync00High), 0x20);
zc030x_reg_write(dev->udev, ZR(Sync01Low) , 0x00);
zc030x_reg_write(dev->udev, ZR(Sync01Mid) , 0x00);
zc030x_reg_write(dev->udev, ZR(Sync01High), 0x84);
/* The horizontal and vertical synchros */
zc030x_reg_write(dev->udev, ZR(HSYNC_0) , 0xe3);
zc030x_reg_write(dev->udev, ZR(HSYNC_1) , 0xec);
zc030x_reg_write(dev->udev, ZR(HSYNC_2) , 0xf5);
zc030x_reg_write(dev->udev, ZR(HSYNC_3) , 0xff);
/* The PB0330 stuff */
if (SensList[dev->sensor_id].pSignature->sensor_id == PB0330)
{
zc030x_reg_write(dev->udev, 0x1ad, 0x09);
zc030x_reg_write(dev->udev, 0x1ae, 0x15);
zc030x_reg_write(dev->udev, 0x1a9, 0x14);
zc030x_reg_write(dev->udev, 0x197, 0x8a);
zc030x_reg_write(dev->udev, 0x191, 0x07);
zc030x_reg_write(dev->udev, 0x192, 0x8c);
zc030x_reg_write(dev->udev, 0x101, 0x37);
zc030x_reg_write(dev->udev, 0x11a, 0x00);
zc030x_reg_write(dev->udev, 0x11c, 0x00);
zc030x_reg_write(dev->udev, 0x11d, 0x60);
zc030x_reg_write(dev->udev, 0x180, 0x42);
zc030x_reg_write(dev->udev, 0x189, 0x06);
zc030x_reg_write(dev->udev, 0x18c, 0x10);
zc030x_reg_write(dev->udev, 0x18d, 0x6c);
zc030x_reg_write(dev->udev, 0x019, 0x00);
zc030x_reg_write(dev->udev, 0x087, 0x10);
zc030x_reg_write(dev->udev, 0x08d, 0x08);
}
/* Mostly implemented yet */
PDEBUG(1, "<<< CONFCAM");
/* Reset the previous debug level */
if (debug == 6) debug = 5;
return 0;
}