summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux/Documentation/video4linux/gspca.txt1
-rw-r--r--linux/drivers/media/video/gspca/Kconfig2
-rw-r--r--linux/drivers/media/video/gspca/finepix.c3
-rw-r--r--linux/drivers/media/video/gspca/gspca.c14
-rw-r--r--linux/drivers/media/video/gspca/gspca.h11
-rw-r--r--linux/drivers/media/video/gspca/pac207.c1
-rw-r--r--linux/drivers/media/video/gspca/sonixb.c17
-rw-r--r--linux/drivers/media/video/gspca/sonixj.c64
-rw-r--r--linux/drivers/media/video/gspca/tv8532.c140
-rw-r--r--linux/drivers/media/video/gspca/zc3xx.c290
10 files changed, 288 insertions, 255 deletions
diff --git a/linux/Documentation/video4linux/gspca.txt b/linux/Documentation/video4linux/gspca.txt
index 004818fab..2a23fe31e 100644
--- a/linux/Documentation/video4linux/gspca.txt
+++ b/linux/Documentation/video4linux/gspca.txt
@@ -263,6 +263,7 @@ etoms 102c:6251 Qcam xxxxxx VGA
zc3xx 10fd:0128 Typhoon Webshot II USB 300k 0x0128
spca561 10fd:7e50 FlyCam Usb 100
zc3xx 10fd:8050 Typhoon Webshot II USB 300k
+pac207 145f:013a Trust WB-1300N
spca501 1776:501c Arowana 300K CMOS Camera
t613 17a1:0128 TASCORP JPEG Webcam, NGS Cyclops
vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC
diff --git a/linux/drivers/media/video/gspca/Kconfig b/linux/drivers/media/video/gspca/Kconfig
index 96a16db3d..6b557c057 100644
--- a/linux/drivers/media/video/gspca/Kconfig
+++ b/linux/drivers/media/video/gspca/Kconfig
@@ -201,7 +201,7 @@ config USB_GSPCA_VC032X
module will be called gspca_vc032x.
config USB_GSPCA_ZC3XX
- tristate "VC3xx USB Camera Driver"
+ tristate "ZC3XX USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
Say Y here if you want support for cameras based on the ZC3XX chip.
diff --git a/linux/drivers/media/video/gspca/finepix.c b/linux/drivers/media/video/gspca/finepix.c
index 65d3cbfe6..d3e3f085b 100644
--- a/linux/drivers/media/video/gspca/finepix.c
+++ b/linux/drivers/media/video/gspca/finepix.c
@@ -308,9 +308,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
int ret;
int size_ret;
- /* Reset bulk in endpoint */
- usb_clear_halt(gspca_dev->dev, gspca_dev->cam.epaddr);
-
/* Init the device */
memset(gspca_dev->usb_buf, 0, 12);
gspca_dev->usb_buf[0] = 0xc6;
diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c
index 4e0e7a32a..bdae0ce2c 100644
--- a/linux/drivers/media/video/gspca/gspca.c
+++ b/linux/drivers/media/video/gspca/gspca.c
@@ -49,7 +49,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
MODULE_DESCRIPTION("GSPCA USB Camera Driver");
MODULE_LICENSE("GPL");
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 3, 0)
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 4, 0)
static int video_nr = -1;
@@ -154,8 +154,11 @@ static void fill_frame(struct gspca_dev *gspca_dev,
/* check the packet status and length */
len = urb->iso_frame_desc[i].actual_length;
- if (len == 0)
+ if (len == 0) {
+ if (gspca_dev->empty_packet == 0)
+ gspca_dev->empty_packet = 1;
continue;
+ }
st = urb->iso_frame_desc[i].status;
if (st) {
PDEBUG(D_ERR,
@@ -607,6 +610,12 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
if (ret < 0)
goto out;
+ /* clear the bulk endpoint */
+ if (gspca_dev->alt == 0) /* if bulk transfer */
+ usb_clear_halt(gspca_dev->dev,
+ usb_rcvintpipe(gspca_dev->dev,
+ gspca_dev->cam.epaddr));
+
/* start the cam */
ret = gspca_dev->sd_desc->start(gspca_dev);
if (ret < 0) {
@@ -1860,6 +1869,7 @@ int gspca_dev_probe(struct usb_interface *intf,
gspca_dev->nbalt = intf->num_altsetting;
gspca_dev->sd_desc = sd_desc;
gspca_dev->nbufread = 2;
+ gspca_dev->empty_packet = -1; /* don't check the empty packets */
/* configure the subdriver and initialize the USB device */
ret = gspca_dev->sd_desc->config(gspca_dev, id);
diff --git a/linux/drivers/media/video/gspca/gspca.h b/linux/drivers/media/video/gspca/gspca.h
index 1d9dc90b4..6f097f4a1 100644
--- a/linux/drivers/media/video/gspca/gspca.h
+++ b/linux/drivers/media/video/gspca/gspca.h
@@ -142,22 +142,21 @@ struct gspca_dev {
char fr_q; /* next frame to queue */
char fr_o; /* next frame to dequeue */
signed char fr_queue[GSPCA_MAX_FRAMES]; /* frame queue */
- char last_packet_type;
+ __u8 last_packet_type;
+ __s8 empty_packet; /* if (-1) don't check empty packets */
+ __u8 streaming;
- __u8 iface; /* USB interface number */
- __u8 alt; /* USB alternate setting */
__u8 curr_mode; /* current camera mode */
__u32 pixfmt; /* current mode parameters */
__u16 width;
__u16 height;
+ __u32 sequence; /* frame sequence number */
atomic_t nevent; /* number of frames done */
wait_queue_head_t wq; /* wait queue */
struct mutex usb_lock; /* usb exchange protection */
struct mutex read_lock; /* read protection */
struct mutex queue_lock; /* ISOC queue protection */
- __u32 sequence; /* frame sequence number */
- char streaming;
#ifdef CONFIG_PM
char frozen; /* suspend - resume */
#endif
@@ -166,6 +165,8 @@ struct gspca_dev {
char nbufread; /* number of buffers for read() */
char nurbs; /* number of allocated URBs */
char memory; /* memory type (V4L2_MEMORY_xxx) */
+ __u8 iface; /* USB interface number */
+ __u8 alt; /* USB alternate setting */
__u8 nbalt; /* number of USB alternate settings */
};
diff --git a/linux/drivers/media/video/gspca/pac207.c b/linux/drivers/media/video/gspca/pac207.c
index 0b0c573d0..39473e6b9 100644
--- a/linux/drivers/media/video/gspca/pac207.c
+++ b/linux/drivers/media/video/gspca/pac207.c
@@ -536,6 +536,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x093a, 0x2471)},
{USB_DEVICE(0x093a, 0x2472)},
{USB_DEVICE(0x093a, 0x2476)},
+ {USB_DEVICE(0x145f, 0x013a)},
{USB_DEVICE(0x2001, 0xf115)},
{}
};
diff --git a/linux/drivers/media/video/gspca/sonixb.c b/linux/drivers/media/video/gspca/sonixb.c
index 4bae911da..4eec924ad 100644
--- a/linux/drivers/media/video/gspca/sonixb.c
+++ b/linux/drivers/media/video/gspca/sonixb.c
@@ -132,8 +132,6 @@ struct sensor_data {
ignore atleast the 2 next frames for the new settings to come into effect
before doing any other adjustments */
#define AUTOGAIN_IGNORE_FRAMES 3
-#define AUTOGAIN_DEADZONE 1000
-#define DESIRED_AVG_LUM 7000
/* V4L2 controls supported by the driver */
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
@@ -857,17 +855,28 @@ static void setfreq(struct gspca_dev *gspca_dev)
static void do_autogain(struct gspca_dev *gspca_dev)
{
+ int deadzone, desired_avg_lum;
struct sd *sd = (struct sd *) gspca_dev;
int avg_lum = atomic_read(&sd->avg_lum);
if (avg_lum == -1)
return;
+ /* SIF / VGA sensors have a different autoexposure area and thus
+ different avg_lum values for the same picture brightness */
+ if (sensor_data[sd->sensor].flags & F_SIF) {
+ deadzone = 1000;
+ desired_avg_lum = 7000;
+ } else {
+ deadzone = 3000;
+ desired_avg_lum = 23000;
+ }
+
if (sd->autogain_ignore_frames > 0)
sd->autogain_ignore_frames--;
else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
- sd->brightness * DESIRED_AVG_LUM / 127,
- AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE)) {
+ sd->brightness * desired_avg_lum / 127,
+ deadzone, GAIN_KNEE, EXPOSURE_KNEE)) {
PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d\n",
(int)sd->gain, (int)sd->exposure);
sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c
index aa11df134..94fa7f6d6 100644
--- a/linux/drivers/media/video/gspca/sonixj.c
+++ b/linux/drivers/media/video/gspca/sonixj.c
@@ -24,6 +24,8 @@
#include "gspca.h"
#include "jpeg.h"
+#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
+
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
MODULE_LICENSE("GPL");
@@ -40,6 +42,7 @@ struct sd {
unsigned char colors;
unsigned char autogain;
__u8 vflip; /* ov7630 only */
+ __u8 infrared; /* mi0360 only */
signed char ag_cnt;
#define AG_CNT_START 13
@@ -73,6 +76,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
static struct ctrl sd_ctrls[] = {
{
@@ -150,6 +155,22 @@ static struct ctrl sd_ctrls[] = {
.set = sd_setvflip,
.get = sd_getvflip,
},
+/* mi0360 only */
+#define INFRARED_IDX 5
+ {
+ {
+ .id = V4L2_CID_INFRARED,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Infrared",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+#define INFRARED_DEF 0
+ .default_value = INFRARED_DEF,
+ },
+ .set = sd_setinfrared,
+ .get = sd_getinfrared,
+ },
};
static struct v4l2_pix_format vga_mode[] = {
@@ -971,6 +992,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->colors = COLOR_DEF;
sd->autogain = AUTOGAIN_DEF;
sd->ag_cnt = -1;
+ sd->vflip = VFLIP_DEF;
+ sd->infrared = INFRARED_DEF;
switch (sd->sensor) {
case SENSOR_OV7630:
@@ -981,7 +1004,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
}
if (sd->sensor != SENSOR_OV7630)
gspca_dev->ctrl_dis |= (1 << VFLIP_IDX);
-
+ if (sd->sensor != SENSOR_MI0360)
+ gspca_dev->ctrl_dis |= (1 << INFRARED_IDX);
return 0;
}
@@ -1208,12 +1232,24 @@ static void setautogain(struct gspca_dev *gspca_dev)
static void setvflip(struct sd *sd)
{
- if (sd->sensor != SENSOR_OV7630)
- return;
i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
sd->vflip ? 0x82 : 0x02);
}
+static void setinfrared(struct sd *sd)
+{
+/*fixme: different sequence for StarCam Clip and StarCam 370i */
+#if 1
+/* Clip */
+ i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
+ sd->infrared ? 0x66 : 0x64);
+#else
+/* 370i */
+ i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
+ sd->infrared ? 0x55 : 0x54);
+#endif
+}
+
/* -- start the camera -- */
static int sd_start(struct gspca_dev *gspca_dev)
{
@@ -1358,8 +1394,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0x17, reg17);
switch (sd->sensor) {
- case SENSOR_HV7131R:
case SENSOR_MI0360:
+ setinfrared(sd);
+ /* fall thru */
+ case SENSOR_HV7131R:
case SENSOR_MO4000:
case SENSOR_OM6802:
setbrightness(gspca_dev);
@@ -1613,6 +1651,24 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
+static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->infrared = val;
+ if (gspca_dev->streaming)
+ setinfrared(sd);
+ return 0;
+}
+
+static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->infrared;
+ return 0;
+}
+
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
diff --git a/linux/drivers/media/video/gspca/tv8532.c b/linux/drivers/media/video/gspca/tv8532.c
index 8204dabb1..4e18f90ba 100644
--- a/linux/drivers/media/video/gspca/tv8532.c
+++ b/linux/drivers/media/video/gspca/tv8532.c
@@ -30,15 +30,10 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- int buflen; /* current length of tmpbuf */
- __u8 tmpbuf[352 * 288 + 10 * 288]; /* no protection... */
- __u8 tmpbuf2[352 * 288]; /* no protection... */
+ __u16 brightness;
+ __u16 contrast;
- unsigned short brightness;
- unsigned short contrast;
-
- char packet;
- char synchro;
+ __u8 packet;
};
/* V4L2 controls supported by the driver */
@@ -392,6 +387,8 @@ static void setbrightness(struct gspca_dev *gspca_dev)
/* -- start the camera -- */
static int sd_start(struct gspca_dev *gspca_dev)
{
+ struct sd *sd = (struct sd *) gspca_dev;
+
reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
tv_8532ReadRegisters(gspca_dev);
@@ -443,6 +440,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
/************************************************/
tv_8532_PollReg(gspca_dev);
reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
+
+ gspca_dev->empty_packet = 0; /* check the empty packets */
+ sd->packet = 0; /* ignore the first packets */
+
return 0;
}
@@ -451,111 +452,36 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
}
-static void tv8532_preprocess(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-/* we should received a whole frame with header and EOL marker
- * in gspca_dev->tmpbuf and return a GBRG pattern in gspca_dev->tmpbuf2
- * sequence 2bytes header the Alternate pixels bayer GB 4 bytes
- * Alternate pixels bayer RG 4 bytes EOL */
- int width = gspca_dev->width;
- int height = gspca_dev->height;
- unsigned char *dst = sd->tmpbuf2;
- unsigned char *data = sd->tmpbuf;
- int i;
-
- /* precompute where is the good bayer line */
- if (((data[3] + data[width + 7]) >> 1)
- + (data[4] >> 2)
- + (data[width + 6] >> 1) >= ((data[2] + data[width + 6]) >> 1)
- + (data[3] >> 2)
- + (data[width + 5] >> 1))
- data += 3;
- else
- data += 2;
- for (i = 0; i < height / 2; i++) {
- memcpy(dst, data, width);
- data += width + 3;
- dst += width;
- memcpy(dst, data, width);
- data += width + 7;
- dst += width;
- }
-}
-
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */
int len) /* iso packet length */
{
struct sd *sd = (struct sd *) gspca_dev;
-
- if (data[0] != 0x80) {
- sd->packet++;
- if (sd->buflen + len > sizeof sd->tmpbuf) {
- if (gspca_dev->last_packet_type != DISCARD_PACKET) {
- PDEBUG(D_PACK, "buffer overflow");
- gspca_dev->last_packet_type = DISCARD_PACKET;
- }
- return;
- }
- memcpy(&sd->tmpbuf[sd->buflen], data, len);
- sd->buflen += len;
- return;
- }
-
- /* here we detect 0x80 */
- /* counter is limited so we need few header for a frame :) */
-
- /* header 0x80 0x80 0x80 0x80 0x80 */
- /* packet 00 63 127 145 00 */
- /* sof 0 1 1 0 0 */
-
- /* update sequence */
- if (sd->packet == 63 || sd->packet == 127)
- sd->synchro = 1;
-
- /* is there a frame start ? */
- if (sd->packet >= (gspca_dev->height >> 1) - 1) {
- PDEBUG(D_PACK, "SOF > %d packet %d", sd->synchro,
- sd->packet);
- if (!sd->synchro) { /* start of frame */
- if (gspca_dev->last_packet_type == FIRST_PACKET) {
- tv8532_preprocess(gspca_dev);
- frame = gspca_frame_add(gspca_dev,
- LAST_PACKET,
- frame, sd->tmpbuf2,
- gspca_dev->width *
- gspca_dev->width);
- }
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- frame, data, 0);
- memcpy(sd->tmpbuf, data, len);
- sd->buflen = len;
- sd->packet = 0;
- return;
- }
- if (gspca_dev->last_packet_type != DISCARD_PACKET) {
- PDEBUG(D_PACK,
- "Warning wrong TV8532 frame detection %d",
- sd->packet);
- gspca_dev->last_packet_type = DISCARD_PACKET;
- }
- return;
- }
-
- if (!sd->synchro) {
- /* Drop packet frame corrupt */
- PDEBUG(D_PACK, "DROP SOF %d packet %d",
- sd->synchro, sd->packet);
- sd->packet = 0;
- gspca_dev->last_packet_type = DISCARD_PACKET;
- return;
- }
- sd->synchro = 1;
- sd->packet++;
- memcpy(&sd->tmpbuf[sd->buflen], data, len);
- sd->buflen += len;
+ int packet_type0, packet_type1;
+
+ packet_type0 = packet_type1 = INTER_PACKET;
+ if (gspca_dev->empty_packet) {
+ gspca_dev->empty_packet = 0;
+ sd->packet = gspca_dev->height / 2;
+ packet_type0 = FIRST_PACKET;
+ } else if (sd->packet == 0)
+ return; /* 2 more lines in 352x288 ! */
+ sd->packet--;
+ if (sd->packet == 0)
+ packet_type1 = LAST_PACKET;
+
+ /* each packet contains:
+ * - header 2 bytes
+ * - RG line
+ * - 4 bytes
+ * - GB line
+ * - 4 bytes
+ */
+ gspca_frame_add(gspca_dev, packet_type0,
+ frame, data + 2, gspca_dev->width);
+ gspca_frame_add(gspca_dev, packet_type1,
+ frame, data + gspca_dev->width + 6, gspca_dev->width);
}
static void setcontrast(struct gspca_dev *gspca_dev)
diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c
index 0b1871cec..b74ce0ef1 100644
--- a/linux/drivers/media/video/gspca/zc3xx.c
+++ b/linux/drivers/media/video/gspca/zc3xx.c
@@ -2266,7 +2266,7 @@ static const struct usb_action hdcs2020b_NoFliker[] = {
{}
};
-static const struct usb_action hv7131bxx_Initial[] = {
+static const struct usb_action hv7131bxx_Initial[] = { /* 320x240 */
{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
{0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -2290,7 +2290,7 @@ static const struct usb_action hv7131bxx_Initial[] = {
{0xaa, 0x14, 0x0001},
{0xaa, 0x15, 0x00e8},
{0xaa, 0x16, 0x0002},
- {0xaa, 0x17, 0x0086},
+ {0xaa, 0x17, 0x0086}, /* 00,17,88,aa */
{0xaa, 0x31, 0x0038},
{0xaa, 0x32, 0x0038},
{0xaa, 0x33, 0x0038},
@@ -2309,72 +2309,11 @@ static const struct usb_action hv7131bxx_Initial[] = {
{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xaa, 0x02, 0x0080}, /* {0xaa, 0x02, 0x0090}; */
- {0xa1, 0x01, 0x0002},
- {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
- {0xa1, 0x01, 0x0091},
- {0xa1, 0x01, 0x0095},
- {0xa1, 0x01, 0x0096},
-
- {0xa1, 0x01, 0x0008},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa1, 0x01, 0x01c8},
- {0xa1, 0x01, 0x01c9},
- {0xa1, 0x01, 0x01ca},
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
-
- {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xf8, ZC3XX_R10B_RGB01},
- {0xa0, 0xf8, ZC3XX_R10C_RGB02},
- {0xa0, 0xf8, ZC3XX_R10D_RGB10},
- {0xa0, 0x50, ZC3XX_R10E_RGB11},
- {0xa0, 0xf8, ZC3XX_R10F_RGB12},
- {0xa0, 0xf8, ZC3XX_R110_RGB20},
- {0xa0, 0xf8, ZC3XX_R111_RGB21},
- {0xa0, 0x50, ZC3XX_R112_RGB22},
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x25, 0x0007},
- {0xaa, 0x26, 0x00a1},
- {0xaa, 0x27, 0x0020},
- {0xaa, 0x20, 0x0000},
- {0xaa, 0x21, 0x00a0},
- {0xaa, 0x22, 0x0016},
- {0xaa, 0x23, 0x0040},
-
- {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2F */
- {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 4d */
- {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x86, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0xa0, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x07, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x0f, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x00, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xa0, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x16, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0x40, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa1, 0x01, 0x001d},
- {0xa1, 0x01, 0x001e},
- {0xa1, 0x01, 0x001f},
- {0xa1, 0x01, 0x0020},
- {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x40, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x40, ZC3XX_R118_BGAIN},
-/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */
+ {0xaa, 0x02, 0x0090}, /* 00,02,80,aa */
{}
};
-static const struct usb_action hv7131bxx_InitialScale[] = {
+static const struct usb_action hv7131bxx_InitialScale[] = { /* 640x480*/
{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
{0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -2418,65 +2357,156 @@ static const struct usb_action hv7131bxx_InitialScale[] = {
{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
{0xaa, 0x02, 0x0090}, /* {0xaa, 0x02, 0x0080}, */
- {0xa1, 0x01, 0x0002},
- {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
- {0xa1, 0x01, 0x0091},
- {0xa1, 0x01, 0x0095},
- {0xa1, 0x01, 0x0096},
- {0xa1, 0x01, 0x0008},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa1, 0x01, 0x01c8},
- {0xa1, 0x01, 0x01c9},
- {0xa1, 0x01, 0x01ca},
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
-
- {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xf8, ZC3XX_R10B_RGB01},
- {0xa0, 0xf8, ZC3XX_R10C_RGB02},
- {0xa0, 0xf8, ZC3XX_R10D_RGB10},
- {0xa0, 0x50, ZC3XX_R10E_RGB11},
- {0xa0, 0xf8, ZC3XX_R10F_RGB12},
- {0xa0, 0xf8, ZC3XX_R110_RGB20},
- {0xa0, 0xf8, ZC3XX_R111_RGB21},
- {0xa0, 0x50, ZC3XX_R112_RGB22},
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x25, 0x0007},
- {0xaa, 0x26, 0x00a1},
- {0xaa, 0x27, 0x0020},
- {0xaa, 0x20, 0x0000},
- {0xaa, 0x21, 0x0040},
- {0xaa, 0x22, 0x0013},
- {0xaa, 0x23, 0x004c},
- {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2f */
- {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 4d */
- {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 60 */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0xc3, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x50, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x00, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x13, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0x4c, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa1, 0x01, 0x001d},
- {0xa1, 0x01, 0x001e},
- {0xa1, 0x01, 0x001f},
- {0xa1, 0x01, 0x0020},
- {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x40, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x40, ZC3XX_R118_BGAIN},
-/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */
+ {}
+};
+static const struct usb_action hv7131b_50HZ[] = { /* 640x480*/
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
+ {0xaa, 0x26, 0x0053}, /* 00,26,53,aa */
+ {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
+ {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
+ {0xaa, 0x21, 0x0050}, /* 00,21,50,aa */
+ {0xaa, 0x22, 0x001b}, /* 00,22,1b,aa */
+ {0xaa, 0x23, 0x00fc}, /* 00,23,fc,aa */
+ {0xa0, 0x2f, ZC3XX_R190_SYNC00LOW}, /* 01,90,2f,cc */
+ {0xa0, 0x9b, ZC3XX_R191_SYNC00MID}, /* 01,91,9b,cc */
+ {0xa0, 0x80, ZC3XX_R192_SYNC00HIGH}, /* 01,92,80,cc */
+ {0xa0, 0x00, ZC3XX_R195_SYNC01LOW}, /* 01,95,00,cc */
+ {0xa0, 0xea, ZC3XX_R196_SYNC01MID}, /* 01,96,ea,cc */
+ {0xa0, 0x60, ZC3XX_R197_SYNC01HIGH}, /* 01,97,60,cc */
+ {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */
+ {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */
+ {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
+ {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
+ {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */
+ {0xa0, 0x1b, ZC3XX_R01F_HSYNC_2}, /* 00,1f,1b,cc */
+ {0xa0, 0xfc, ZC3XX_R020_HSYNC_3}, /* 00,20,fc,cc */
+ {}
+};
+static const struct usb_action hv7131b_50HZScale[] = { /* 320x240 */
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
+ {0xaa, 0x26, 0x0053}, /* 00,26,53,aa */
+ {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
+ {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
+ {0xaa, 0x21, 0x0050}, /* 00,21,50,aa */
+ {0xaa, 0x22, 0x0012}, /* 00,22,12,aa */
+ {0xaa, 0x23, 0x0080}, /* 00,23,80,aa */
+ {0xa0, 0x2f, ZC3XX_R190_SYNC00LOW}, /* 01,90,2f,cc */
+ {0xa0, 0x9b, ZC3XX_R191_SYNC00MID}, /* 01,91,9b,cc */
+ {0xa0, 0x80, ZC3XX_R192_SYNC00HIGH}, /* 01,92,80,cc */
+ {0xa0, 0x01, ZC3XX_R195_SYNC01LOW}, /* 01,95,01,cc */
+ {0xa0, 0xd4, ZC3XX_R196_SYNC01MID}, /* 01,96,d4,cc */
+ {0xa0, 0xc0, ZC3XX_R197_SYNC01HIGH}, /* 01,97,c0,cc */
+ {0xa0, 0x07, ZC3XX_R18C_AEFREEZE}, /* 01,8c,07,cc */
+ {0xa0, 0x0f, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,0f,cc */
+ {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
+ {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
+ {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */
+ {0xa0, 0x12, ZC3XX_R01F_HSYNC_2}, /* 00,1f,12,cc */
+ {0xa0, 0x80, ZC3XX_R020_HSYNC_3}, /* 00,20,80,cc */
+ {}
+};
+static const struct usb_action hv7131b_60HZ[] = { /* 640x480*/
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
+ {0xaa, 0x26, 0x00a1}, /* 00,26,a1,aa */
+ {0xaa, 0x27, 0x0020}, /* 00,27,20,aa */
+ {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
+ {0xaa, 0x21, 0x0040}, /* 00,21,40,aa */
+ {0xaa, 0x22, 0x0013}, /* 00,22,13,aa */
+ {0xaa, 0x23, 0x004c}, /* 00,23,4c,aa */
+ {0xa0, 0x2f, ZC3XX_R190_SYNC00LOW}, /* 01,90,2f,cc */
+ {0xa0, 0x4d, ZC3XX_R191_SYNC00MID}, /* 01,91,4d,cc */
+ {0xa0, 0x60, ZC3XX_R192_SYNC00HIGH}, /* 01,92,60,cc */
+ {0xa0, 0x00, ZC3XX_R195_SYNC01LOW}, /* 01,95,00,cc */
+ {0xa0, 0xc3, ZC3XX_R196_SYNC01MID}, /* 01,96,c3,cc */
+ {0xa0, 0x50, ZC3XX_R197_SYNC01HIGH}, /* 01,97,50,cc */
+ {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */
+ {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */
+ {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
+ {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
+ {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */
+ {0xa0, 0x13, ZC3XX_R01F_HSYNC_2}, /* 00,1f,13,cc */
+ {0xa0, 0x4c, ZC3XX_R020_HSYNC_3}, /* 00,20,4c,cc */
+ {}
+};
+static const struct usb_action hv7131b_60HZScale[] = { /* 320x240 */
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
+ {0xaa, 0x26, 0x00a1}, /* 00,26,a1,aa */
+ {0xaa, 0x27, 0x0020}, /* 00,27,20,aa */
+ {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
+ {0xaa, 0x21, 0x00a0}, /* 00,21,a0,aa */
+ {0xaa, 0x22, 0x0016}, /* 00,22,16,aa */
+ {0xaa, 0x23, 0x0040}, /* 00,23,40,aa */
+ {0xa0, 0x2f, ZC3XX_R190_SYNC00LOW}, /* 01,90,2f,cc */
+ {0xa0, 0x4d, ZC3XX_R191_SYNC00MID}, /* 01,91,4d,cc */
+ {0xa0, 0x60, ZC3XX_R192_SYNC00HIGH}, /* 01,92,60,cc */
+ {0xa0, 0x01, ZC3XX_R195_SYNC01LOW}, /* 01,95,01,cc */
+ {0xa0, 0x86, ZC3XX_R196_SYNC01MID}, /* 01,96,86,cc */
+ {0xa0, 0xa0, ZC3XX_R197_SYNC01HIGH}, /* 01,97,a0,cc */
+ {0xa0, 0x07, ZC3XX_R18C_AEFREEZE}, /* 01,8c,07,cc */
+ {0xa0, 0x0f, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,0f,cc */
+ {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
+ {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
+ {0xa0, 0xa0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,a0,cc */
+ {0xa0, 0x16, ZC3XX_R01F_HSYNC_2}, /* 00,1f,16,cc */
+ {0xa0, 0x40, ZC3XX_R020_HSYNC_3}, /* 00,20,40,cc */
+ {}
+};
+static const struct usb_action hv7131b_NoFliker[] = { /* 640x480*/
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x25, 0x0003}, /* 00,25,03,aa */
+ {0xaa, 0x26, 0x0000}, /* 00,26,00,aa */
+ {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
+ {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
+ {0xaa, 0x21, 0x0010}, /* 00,21,10,aa */
+ {0xaa, 0x22, 0x0000}, /* 00,22,00,aa */
+ {0xaa, 0x23, 0x0003}, /* 00,23,03,aa */
+ {0xa0, 0x2f, ZC3XX_R190_SYNC00LOW}, /* 01,90,2f,cc */
+ {0xa0, 0xf8, ZC3XX_R191_SYNC00MID}, /* 01,91,f8,cc */
+ {0xa0, 0x00, ZC3XX_R192_SYNC00HIGH}, /* 01,92,00,cc */
+ {0xa0, 0x00, ZC3XX_R195_SYNC01LOW}, /* 01,95,00,cc */
+ {0xa0, 0x02, ZC3XX_R196_SYNC01MID}, /* 01,96,02,cc */
+ {0xa0, 0x00, ZC3XX_R197_SYNC01HIGH}, /* 01,97,00,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
+ {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
+ {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
+ {0xa0, 0x10, ZC3XX_R01E_HSYNC_1}, /* 00,1e,10,cc */
+ {0xa0, 0x00, ZC3XX_R01F_HSYNC_2}, /* 00,1f,00,cc */
+ {0xa0, 0x03, ZC3XX_R020_HSYNC_3}, /* 00,20,03,cc */
+ {}
+};
+static const struct usb_action hv7131b_NoFlikerScale[] = { /* 320x240 */
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x25, 0x0003}, /* 00,25,03,aa */
+ {0xaa, 0x26, 0x0000}, /* 00,26,00,aa */
+ {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
+ {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
+ {0xaa, 0x21, 0x00a0}, /* 00,21,a0,aa */
+ {0xaa, 0x22, 0x0016}, /* 00,22,16,aa */
+ {0xaa, 0x23, 0x0040}, /* 00,23,40,aa */
+ {0xa0, 0x2f, ZC3XX_R190_SYNC00LOW}, /* 01,90,2f,cc */
+ {0xa0, 0xf8, ZC3XX_R191_SYNC00MID}, /* 01,91,f8,cc */
+ {0xa0, 0x00, ZC3XX_R192_SYNC00HIGH}, /* 01,92,00,cc */
+ {0xa0, 0x00, ZC3XX_R195_SYNC01LOW}, /* 01,95,00,cc */
+ {0xa0, 0x02, ZC3XX_R196_SYNC01MID}, /* 01,96,02,cc */
+ {0xa0, 0x00, ZC3XX_R197_SYNC01HIGH}, /* 01,97,00,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
+ {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
+ {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
+ {0xa0, 0xa0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,a0,cc */
+ {0xa0, 0x16, ZC3XX_R01F_HSYNC_2}, /* 00,1f,16,cc */
+ {0xa0, 0x40, ZC3XX_R020_HSYNC_3}, /* 00,20,40,cc */
{}
};
@@ -6358,6 +6388,7 @@ static void setmatrix(struct gspca_dev *gspca_dev)
switch (sd->sensor) {
case SENSOR_GC0305:
+ case SENSOR_HV7131B:
matrix = gc0305_matrix;
break;
case SENSOR_MC501CB:
@@ -6393,6 +6424,8 @@ static void setbrightness(struct gspca_dev *gspca_dev)
/*fixme: is it really write to 011d and 018d for all other sensors? */
brightness = sd->brightness;
reg_w(gspca_dev->dev, brightness, 0x011d);
+ if (sd->sensor == SENSOR_HV7131B)
+ return;
if (brightness < 0x70)
brightness += 0x10;
else
@@ -6534,6 +6567,7 @@ static void setquality(struct gspca_dev *gspca_dev)
switch (sd->sensor) {
case SENSOR_GC0305:
+ case SENSOR_HV7131B:
case SENSOR_OV7620:
case SENSOR_PO2030:
return;
@@ -6596,9 +6630,9 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
hdcs2020b_50HZ, hdcs2020b_50HZ,
hdcs2020b_60HZ, hdcs2020b_60HZ},
/* SENSOR_HV7131B 5 */
- {NULL, NULL,
- NULL, NULL,
- NULL, NULL},
+ {hv7131b_NoFlikerScale, hv7131b_NoFliker,
+ hv7131b_50HZScale, hv7131b_50HZ,
+ hv7131b_60HZScale, hv7131b_60HZ},
/* SENSOR_HV7131C 6 */
{NULL, NULL,
NULL, NULL,
@@ -7155,7 +7189,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->gamma = gamma[(int) sd->sensor];
sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value;
sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value;
- sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
switch (sd->sensor) {
case SENSOR_GC0305:
@@ -7214,7 +7247,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
zc3_init = init_tb[(int) sd->sensor][mode];
switch (sd->sensor) {
- case SENSOR_HV7131B:
case SENSOR_HV7131C:
zcxx_probeSensor(gspca_dev);
break;