From 6a709749228c5f76f128c69c16f39a52d639bd96 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 3 Sep 2008 16:48:10 -0300 Subject: V4L/DVB (8718): gspca: suspend/resume added. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/media/video/gspca/sonixb.c') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 11210c71f66c..e535ced79f16 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -1231,6 +1231,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ -- cgit v1.2.2 From e2ad2a54ad1e0f8d7c9e49c38b552a630e015af3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 3 Sep 2008 17:12:15 -0300 Subject: V4L/DVB (8816): gspca: Set disabled ctrls and fix a register pb with ovxxxx in sonixb. - set some controls as disabled instead of copying the device descr. - in the ov6650 / 7650 exposure code clamp reg 11 before (instead of after) using it to calculate reg 10. - disable brightness (instead of ignoring it) for the TAS5110. Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 80 +++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 40 deletions(-) (limited to 'drivers/media/video/gspca/sonixb.c') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index e535ced79f16..735d4260f2f8 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -31,9 +31,6 @@ MODULE_LICENSE("GPL"); /* specific webcam descriptor */ struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - - struct sd_desc sd_desc; /* our nctrls differ dependend upon the - sensor, so we use a per cam copy */ atomic_t avg_lum; unsigned char gain; @@ -60,9 +57,8 @@ struct sd { /* flags used in the device id table */ #define F_GAIN 0x01 /* has gain */ -#define F_AUTO 0x02 /* has autogain */ -#define F_SIF 0x04 /* sif or vga */ -#define F_H18 0x08 /* long (18 b) or short (12 b) frame header */ +#define F_SIF 0x02 /* sif or vga */ +#define F_H18 0x04 /* long (18 b) or short (12 b) frame header */ #define COMP2 0x8f #define COMP 0xc7 /* 0x87 //0x07 */ @@ -95,6 +91,7 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { +#define BRIGHTNESS_IDX 0 { { .id = V4L2_CID_BRIGHTNESS, @@ -109,6 +106,7 @@ static struct ctrl sd_ctrls[] = { .set = sd_setbrightness, .get = sd_getbrightness, }, +#define GAIN_IDX 1 { { .id = V4L2_CID_GAIN, @@ -124,6 +122,7 @@ static struct ctrl sd_ctrls[] = { .set = sd_setgain, .get = sd_getgain, }, +#define EXPOSURE_IDX 2 { { .id = V4L2_CID_EXPOSURE, @@ -140,6 +139,7 @@ static struct ctrl sd_ctrls[] = { .set = sd_setexposure, .get = sd_getexposure, }, +#define AUTOGAIN_IDX 3 { { .id = V4L2_CID_AUTOGAIN, @@ -155,6 +155,7 @@ static struct ctrl sd_ctrls[] = { .set = sd_setautogain, .get = sd_getautogain, }, +#define FREQ_IDX 4 { { .id = V4L2_CID_POWER_LINE_FREQUENCY, @@ -545,9 +546,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) goto err; break; } - case SENSOR_TAS5110: - /* FIXME figure out howto control brightness on TAS5110 */ - break; } return; err: @@ -665,6 +663,11 @@ static void setexposure(struct gspca_dev *gspca_dev) else if (reg11 > 16) reg11 = 16; + /* In 640x480, if the reg11 has less than 3, the image is + unstable (not enough bandwidth). */ + if (gspca_dev->width == 640 && reg11 < 3) + reg11 = 3; + /* frame exposure time in ms = 1000 * reg11 / 30 -> reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */ reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11); @@ -678,11 +681,6 @@ static void setexposure(struct gspca_dev *gspca_dev) else if (reg10 > reg10_max) reg10 = reg10_max; - /* In 640x480, if the reg11 has less than 3, the image is - unstable (not enough bandwidth). */ - if (gspca_dev->width == 640 && reg11 < 3) - reg11 = 3; - /* Write reg 10 and reg11 low nibble */ i2c[1] = sd->sensor_addr; i2c[3] = reg10; @@ -759,23 +757,17 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; int sif = 0; - /* nctrls depends upon the sensor, so we use a per cam copy */ - memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc)); - gspca_dev->sd_desc = &sd->sd_desc; - /* copy the webcam info from the device id */ sd->sensor = (id->driver_info >> 24) & 0xff; if (id->driver_info & (F_GAIN << 16)) sd->sensor_has_gain = 1; - if (id->driver_info & (F_AUTO << 16)) - sd->sd_desc.dq_callback = do_autogain; if (id->driver_info & (F_SIF << 16)) sif = 1; if (id->driver_info & (F_H18 << 16)) sd->fr_h_sz = 18; /* size of frame header */ else sd->fr_h_sz = 12; - sd->sd_desc.nctrls = (id->driver_info >> 8) & 0xff; + gspca_dev->ctrl_dis = (id->driver_info >> 8) & 0xff; sd->sensor_addr = id->driver_info & 0xff; cam = &gspca_dev->cam; @@ -790,7 +782,10 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->brightness = BRIGHTNESS_DEF; sd->gain = GAIN_DEF; sd->exposure = EXPOSURE_DEF; - sd->autogain = AUTOGAIN_DEF; + if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX)) + sd->autogain = 0; /* Disable do_autogain callback */ + else + sd->autogain = AUTOGAIN_DEF; sd->freq = FREQ_DEF; return 0; @@ -1169,50 +1164,55 @@ static const struct sd_desc sd_desc = { .close = sd_close, .pkt_scan = sd_pkt_scan, .querymenu = sd_querymenu, + .dq_callback = do_autogain, }; /* -- module initialisation -- */ -#define SFCI(sensor, flags, nctrls, i2c_addr) \ +#define SFCI(sensor, flags, disable_ctrls, i2c_addr) \ .driver_info = (SENSOR_ ## sensor << 24) \ | ((flags) << 16) \ - | ((nctrls) << 8) \ + | ((disable_ctrls) << 8) \ | (i2c_addr) +#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)) +#define NO_FREQ (1 << FREQ_IDX) +#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX) + static __devinitdata struct usb_device_id device_table[] = { #ifndef CONFIG_USB_SN9C102 {USB_DEVICE(0x0c45, 0x6001), /* SN9C102 */ - SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)}, + SFCI(TAS5110, F_GAIN|F_SIF, NO_BRIGHTNESS|NO_FREQ, 0)}, {USB_DEVICE(0x0c45, 0x6005), /* SN9C101 */ - SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)}, + SFCI(TAS5110, F_GAIN|F_SIF, NO_BRIGHTNESS|NO_FREQ, 0)}, {USB_DEVICE(0x0c45, 0x6007), /* SN9C101 */ - SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)}, + SFCI(TAS5110, F_GAIN|F_SIF, NO_BRIGHTNESS|NO_FREQ, 0)}, {USB_DEVICE(0x0c45, 0x6009), /* SN9C101 */ - SFCI(PAS106, F_SIF, 2, 0)}, + SFCI(PAS106, F_SIF, NO_EXPO|NO_FREQ, 0)}, {USB_DEVICE(0x0c45, 0x600d), /* SN9C101 */ - SFCI(PAS106, F_SIF, 2, 0)}, + SFCI(PAS106, F_SIF, NO_EXPO|NO_FREQ, 0)}, #endif {USB_DEVICE(0x0c45, 0x6011), /* SN9C101 - SN9C101G */ - SFCI(OV6650, F_GAIN|F_AUTO|F_SIF, 5, 0x60)}, + SFCI(OV6650, F_GAIN|F_SIF, 0, 0x60)}, #ifndef CONFIG_USB_SN9C102 {USB_DEVICE(0x0c45, 0x6019), /* SN9C101 */ - SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)}, + SFCI(OV7630, F_GAIN, 0, 0x21)}, {USB_DEVICE(0x0c45, 0x6024), /* SN9C102 */ - SFCI(TAS5130CXX, 0, 2, 0)}, + SFCI(TAS5130CXX, 0, NO_EXPO|NO_FREQ, 0)}, {USB_DEVICE(0x0c45, 0x6025), /* SN9C102 */ - SFCI(TAS5130CXX, 0, 2, 0)}, + SFCI(TAS5130CXX, 0, NO_EXPO|NO_FREQ, 0)}, {USB_DEVICE(0x0c45, 0x6028), /* SN9C102 */ - SFCI(PAS202, 0, 2, 0)}, + SFCI(PAS202, 0, NO_EXPO|NO_FREQ, 0)}, {USB_DEVICE(0x0c45, 0x6029), /* SN9C101 */ - SFCI(PAS106, F_SIF, 2, 0)}, + SFCI(PAS106, F_SIF, NO_EXPO|NO_FREQ, 0)}, {USB_DEVICE(0x0c45, 0x602c), /* SN9C102 */ - SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)}, + SFCI(OV7630, F_GAIN, 0, 0x21)}, {USB_DEVICE(0x0c45, 0x602d), /* SN9C102 */ - SFCI(HV7131R, 0, 2, 0)}, + SFCI(HV7131R, 0, NO_EXPO|NO_FREQ, 0)}, {USB_DEVICE(0x0c45, 0x602e), /* SN9C102 */ - SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)}, + SFCI(OV7630, F_GAIN, 0, 0x21)}, {USB_DEVICE(0x0c45, 0x60af), /* SN9C103 */ - SFCI(PAS202, F_H18, 2, 0)}, + SFCI(PAS202, F_H18, NO_EXPO|NO_FREQ, 0)}, {USB_DEVICE(0x0c45, 0x60b0), /* SN9C103 */ - SFCI(OV7630, F_GAIN|F_AUTO|F_H18, 5, 0x21)}, + SFCI(OV7630, F_GAIN|F_H18, 0, 0x21)}, #endif {} }; -- cgit v1.2.2 From 65f33396ab57f3346fb07ddee8e3aa616d13386c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 3 Sep 2008 17:12:15 -0300 Subject: V4L/DVB (8817): gspca: LED and proble changes in sonixb. - turn the led of the cam off after plugging in the cam - move the probe code from open to config, so that if the probe fails we never register Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/media/video/gspca/sonixb.c') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 735d4260f2f8..64aae060a934 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -756,6 +756,11 @@ static int sd_config(struct gspca_dev *gspca_dev, struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; int sif = 0; + const __u8 stop = 0x09; /* Disable stream turn of LED */ + + reg_r(gspca_dev, 0x00); + if (gspca_dev->usb_buf[0] != 0x10) + return -ENODEV; /* copy the webcam info from the device id */ sd->sensor = (id->driver_info >> 24) & 0xff; @@ -788,15 +793,15 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->autogain = AUTOGAIN_DEF; sd->freq = FREQ_DEF; + /* Disable stream turn of LED */ + reg_w(gspca_dev, 0x01, &stop, 1); + return 0; } /* this function is called at open time */ static int sd_open(struct gspca_dev *gspca_dev) { - reg_r(gspca_dev, 0x00); - if (gspca_dev->usb_buf[0] != 0x10) - return -ENODEV; return 0; } -- cgit v1.2.2 From 012d6b029ec17f45374303bbdccd0bc206725751 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 3 Sep 2008 17:12:16 -0300 Subject: V4L/DVB (8822): gspca: Change some subdriver functions for suspend/resume. - new function 'init' called on probe and resume - remove the functions 'open' and 'closed' - 'stopN' and 'stop0' are optional Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'drivers/media/video/gspca/sonixb.c') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 64aae060a934..044a9ec58db5 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -799,8 +799,8 @@ static int sd_config(struct gspca_dev *gspca_dev, return 0; } -/* this function is called at open time */ -static int sd_open(struct gspca_dev *gspca_dev) +/* this function is called at probe and resume time */ +static int sd_init(struct gspca_dev *gspca_dev) { return 0; } @@ -963,14 +963,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x01, &ByteSend, 1); } -static void sd_stop0(struct gspca_dev *gspca_dev) -{ -} - -static void sd_close(struct gspca_dev *gspca_dev) -{ -} - static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ unsigned char *data, /* isoc packet */ @@ -1162,11 +1154,9 @@ static const struct sd_desc sd_desc = { .ctrls = sd_ctrls, .nctrls = ARRAY_SIZE(sd_ctrls), .config = sd_config, - .open = sd_open, + .init = sd_init, .start = sd_start, .stopN = sd_stopN, - .stop0 = sd_stop0, - .close = sd_close, .pkt_scan = sd_pkt_scan, .querymenu = sd_querymenu, .dq_callback = do_autogain, -- cgit v1.2.2 From 8295d99ee5340f1e62b53c8adc979e0789299445 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 3 Sep 2008 17:12:19 -0300 Subject: V4L/DVB (8829): gspca: Have a clean kmalloc-ated buffer for USB exchanges. The USB buffer may be used for DMA and there may be a caching problem if the buffer is part of the device structure. Thanks to Alan Stern. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) (limited to 'drivers/media/video/gspca/sonixb.c') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 044a9ec58db5..162beb3feadb 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -410,7 +410,7 @@ static void reg_w(struct gspca_dev *gspca_dev, int len) { #ifdef GSPCA_DEBUG - if (len > sizeof gspca_dev->usb_buf) { + if (len > USB_BUF_SZ) { PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); return; } @@ -426,26 +426,6 @@ static void reg_w(struct gspca_dev *gspca_dev, 500); } -static void reg_w_big(struct gspca_dev *gspca_dev, - __u16 value, - const __u8 *buffer, - int len) -{ - __u8 *tmpbuf; - - tmpbuf = kmalloc(len, GFP_KERNEL); - memcpy(tmpbuf, buffer, len); - usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0x08, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - value, - 0, /* index */ - tmpbuf, len, - 500); - kfree(tmpbuf); -} - static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer) { int retry = 60; @@ -886,7 +866,7 @@ static void sd_start(struct gspca_dev *gspca_dev) /* reg 0x17 SensorClk enable inv Clk 0x60 */ reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1); /* Set the registers from the template */ - reg_w_big(gspca_dev, 0x01, sn9c10x, l); + reg_w(gspca_dev, 0x01, sn9c10x, l); switch (sd->sensor) { case SENSOR_HV7131R: i2c_w_vector(gspca_dev, hv7131_sensor_init, -- cgit v1.2.2 From 271315a9b4363ed884024022f2cf799344548e8f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 3 Sep 2008 17:12:19 -0300 Subject: V4L/DVB (8830): gspca: Move some probe code to the new init function. Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media/video/gspca/sonixb.c') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 162beb3feadb..602608031247 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -736,7 +736,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; int sif = 0; - const __u8 stop = 0x09; /* Disable stream turn of LED */ reg_r(gspca_dev, 0x00); if (gspca_dev->usb_buf[0] != 0x10) @@ -773,15 +772,16 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->autogain = AUTOGAIN_DEF; sd->freq = FREQ_DEF; - /* Disable stream turn of LED */ - reg_w(gspca_dev, 0x01, &stop, 1); - return 0; } /* this function is called at probe and resume time */ static int sd_init(struct gspca_dev *gspca_dev) { + const __u8 stop = 0x09; /* Disable stream turn of LED */ + + reg_w(gspca_dev, 0x01, &stop, 1); + return 0; } -- cgit v1.2.2 From 222a07ffd8e280b1bf4a6f7edab8b6fa27a5455a Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 3 Sep 2008 17:12:20 -0300 Subject: V4L/DVB (8831): gspca: Resolve webcam conflicts between some drivers. -remove USB-id's from zc0301 for cams for which zc0301.c does not support the sensor -remove USB-id's from sn9c102 for cams where sn9c102 does not support the bridge sensor combination -no longer make inclusion of usb id's removed from zc0301 and sn9c102 conditional in gspca -fix conditional inclusion of USB-id's in gspca to also work when the conflicting drivers are build as a module -add a number of USB-id's to gspca from various windows .inf files: 0c45:608f from generic sonix sn9c103 inf file (+ ov7630 which we support) 041e:4022 from creative webcam nx pro, same as already supported 041e:401e 0ac8:0301 from generic zc0301 driver which supports many sensors 10fd:804d from typhoon webshot driver (also FlyCAM-USB 300 plus) Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/media/video/gspca/sonixb.c') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 602608031247..f30e6ec91375 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -1153,7 +1153,7 @@ static const struct sd_desc sd_desc = { #define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX) static __devinitdata struct usb_device_id device_table[] = { -#ifndef CONFIG_USB_SN9C102 +#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE {USB_DEVICE(0x0c45, 0x6001), /* SN9C102 */ SFCI(TAS5110, F_GAIN|F_SIF, NO_BRIGHTNESS|NO_FREQ, 0)}, {USB_DEVICE(0x0c45, 0x6005), /* SN9C101 */ @@ -1167,7 +1167,7 @@ static __devinitdata struct usb_device_id device_table[] = { #endif {USB_DEVICE(0x0c45, 0x6011), /* SN9C101 - SN9C101G */ SFCI(OV6650, F_GAIN|F_SIF, 0, 0x60)}, -#ifndef CONFIG_USB_SN9C102 +#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE {USB_DEVICE(0x0c45, 0x6019), /* SN9C101 */ SFCI(OV7630, F_GAIN, 0, 0x21)}, {USB_DEVICE(0x0c45, 0x6024), /* SN9C102 */ @@ -1180,10 +1180,14 @@ static __devinitdata struct usb_device_id device_table[] = { SFCI(PAS106, F_SIF, NO_EXPO|NO_FREQ, 0)}, {USB_DEVICE(0x0c45, 0x602c), /* SN9C102 */ SFCI(OV7630, F_GAIN, 0, 0x21)}, +#endif {USB_DEVICE(0x0c45, 0x602d), /* SN9C102 */ SFCI(HV7131R, 0, NO_EXPO|NO_FREQ, 0)}, +#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE {USB_DEVICE(0x0c45, 0x602e), /* SN9C102 */ SFCI(OV7630, F_GAIN, 0, 0x21)}, + {USB_DEVICE(0x0c45, 0x608f), /* SN9C103 */ + SFCI(OV7630, F_GAIN|F_H18, 0, 0x21)}, {USB_DEVICE(0x0c45, 0x60af), /* SN9C103 */ SFCI(PAS202, F_H18, NO_EXPO|NO_FREQ, 0)}, {USB_DEVICE(0x0c45, 0x60b0), /* SN9C103 */ -- cgit v1.2.2 From f45f06b648bad82430c64a2e1ad67dc616eb54c6 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 3 Sep 2008 17:12:21 -0300 Subject: V4L/DVB (8833): gspca: Cleanup the sonixb code. -the usb-id table caried several flags which were not usb-id specific but sensor specific, add a sensor_data array and move these flag there -fr_h_sz was being abused to store and check which bridge was being used instead add a bridge member to the sd struct -now that we have a sensor_data table use that to store pointers to init_sequences instead of using switch cases on sd->sensor Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 365 ++++++++++++++++--------------------- 1 file changed, 162 insertions(+), 203 deletions(-) (limited to 'drivers/media/video/gspca/sonixb.c') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index f30e6ec91375..8eaeaa3a96d7 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -41,8 +41,12 @@ struct sd { unsigned char frames_to_drop; unsigned char freq; /* light freq filter setting */ - unsigned char fr_h_sz; /* size of frame header */ - char sensor; /* Type of image sensor chip */ + __u8 bridge; /* Type of bridge */ +#define BRIDGE_101 0 +#define BRIDGE_102 0 /* We make no difference between 101 and 102 */ +#define BRIDGE_103 1 + + __u8 sensor; /* Type of image sensor chip */ #define SENSOR_HV7131R 0 #define SENSOR_OV6650 1 #define SENSOR_OV7630 2 @@ -50,15 +54,31 @@ struct sd { #define SENSOR_PAS202 4 #define SENSOR_TAS5110 5 #define SENSOR_TAS5130CXX 6 - char sensor_has_gain; - __u8 sensor_addr; __u8 reg11; }; -/* flags used in the device id table */ +typedef const __u8 sensor_init_t[8]; + +struct sensor_data { + const __u8 *bridge_init[2]; + int bridge_init_size[2]; + sensor_init_t *sensor_init; + int sensor_init_size; + sensor_init_t *sensor_bridge_init[2]; + int sensor_bridge_init_size[2]; + int flags; + unsigned ctrl_dis; + __u8 sensor_addr; +}; + +/* sensor_data flags */ #define F_GAIN 0x01 /* has gain */ #define F_SIF 0x02 /* sif or vga */ -#define F_H18 0x04 /* long (18 b) or short (12 b) frame header */ + +/* ctrl_dis helper macros */ +#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)) +#define NO_FREQ (1 << FREQ_IDX) +#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX) #define COMP2 0x8f #define COMP 0xc7 /* 0x87 //0x07 */ @@ -69,6 +89,18 @@ struct sd { #define SYS_CLK 0x04 +#define SENS(bridge_1, bridge_3, sensor, sensor_1, \ + sensor_3, _flags, _ctrl_dis, _sensor_addr) \ +{ \ + .bridge_init = { bridge_1, bridge_3 }, \ + .bridge_init_size = { sizeof(bridge_1), sizeof(bridge_3) }, \ + .sensor_init = sensor, \ + .sensor_init_size = sizeof(sensor), \ + .sensor_bridge_init = { sensor_1, sensor_3,}, \ + .sensor_bridge_init_size = { sizeof(sensor_1), sizeof(sensor_3)}, \ + .flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \ +} + /* We calculate the autogain at the end of the transfer of a frame, at this moment a frame with the old settings is being transmitted, and a frame is being captured with the old settings. So if we adjust the autogain we must @@ -219,7 +251,7 @@ static const __u8 hv7131_sensor_init[][8] = { static const __u8 initOv6650[] = { 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x0b, + 0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b, 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00 }; static const __u8 ov6650_sensor_init[][8] = @@ -260,7 +292,7 @@ static const __u8 initOv7630[] = { 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */ 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ 0x28, 0x1e, /* H & V sizes r15 .. r16 */ - 0x68, COMP1, MCK_INIT1, /* r17 .. r19 */ + 0x68, COMP2, MCK_INIT1, /* r17 .. r19 */ 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */ }; static const __u8 initOv7630_3[] = { @@ -295,47 +327,65 @@ static const __u8 ov7630_sensor_init[][8] = { {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10}, }; +static const __u8 ov7630_sensor_init_3[][8] = { + {0xa0, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10}, +}; + static const __u8 initPas106[] = { 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, - 0x16, 0x12, 0x28, COMP1, MCK_INIT1, + 0x16, 0x12, 0x24, COMP1, MCK_INIT1, 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c }; /* compression 0x86 mckinit1 0x2b */ -static const __u8 pas106_data[][2] = { - {0x02, 0x04}, /* Pixel Clock Divider 6 */ - {0x03, 0x13}, /* Frame Time MSB */ -/* {0x03, 0x12}, * Frame Time MSB */ - {0x04, 0x06}, /* Frame Time LSB */ -/* {0x04, 0x05}, * Frame Time LSB */ - {0x05, 0x65}, /* Shutter Time Line Offset */ -/* {0x05, 0x6d}, * Shutter Time Line Offset */ -/* {0x06, 0xb1}, * Shutter Time Pixel Offset */ - {0x06, 0xcd}, /* Shutter Time Pixel Offset */ - {0x07, 0xc1}, /* Black Level Subtract Sign */ -/* {0x07, 0x00}, * Black Level Subtract Sign */ - {0x08, 0x06}, /* Black Level Subtract Level */ - {0x08, 0x06}, /* Black Level Subtract Level */ -/* {0x08, 0x01}, * Black Level Subtract Level */ - {0x09, 0x05}, /* Color Gain B Pixel 5 a */ - {0x0a, 0x04}, /* Color Gain G1 Pixel 1 5 */ - {0x0b, 0x04}, /* Color Gain G2 Pixel 1 0 5 */ - {0x0c, 0x05}, /* Color Gain R Pixel 3 1 */ - {0x0d, 0x00}, /* Color GainH Pixel */ - {0x0e, 0x0e}, /* Global Gain */ - {0x0f, 0x00}, /* Contrast */ - {0x10, 0x06}, /* H&V synchro polarity */ - {0x11, 0x06}, /* ?default */ - {0x12, 0x06}, /* DAC scale */ - {0x14, 0x02}, /* ?default */ - {0x13, 0x01}, /* Validate Settings */ +static const __u8 pas106_sensor_init[][8] = { + /* Pixel Clock Divider 6 */ + { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 }, + /* Frame Time MSB (also seen as 0x12) */ + { 0xa1, 0x40, 0x03, 0x13, 0x00, 0x00, 0x00, 0x14 }, + /* Frame Time LSB (also seen as 0x05) */ + { 0xa1, 0x40, 0x04, 0x06, 0x00, 0x00, 0x00, 0x14 }, + /* Shutter Time Line Offset (also seen as 0x6d) */ + { 0xa1, 0x40, 0x05, 0x65, 0x00, 0x00, 0x00, 0x14 }, + /* Shutter Time Pixel Offset (also seen as 0xb1) */ + { 0xa1, 0x40, 0x06, 0xcd, 0x00, 0x00, 0x00, 0x14 }, + /* Black Level Subtract Sign (also seen 0x00) */ + { 0xa1, 0x40, 0x07, 0xc1, 0x00, 0x00, 0x00, 0x14 }, + /* Black Level Subtract Level (also seen 0x01) */ + { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 }, + { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 }, + /* Color Gain B Pixel 5 a */ + { 0xa1, 0x40, 0x09, 0x05, 0x00, 0x00, 0x00, 0x14 }, + /* Color Gain G1 Pixel 1 5 */ + { 0xa1, 0x40, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x14 }, + /* Color Gain G2 Pixel 1 0 5 */ + { 0xa1, 0x40, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x14 }, + /* Color Gain R Pixel 3 1 */ + { 0xa1, 0x40, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x14 }, + /* Color GainH Pixel */ + { 0xa1, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x14 }, + /* Global Gain */ + { 0xa1, 0x40, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x14 }, + /* Contrast */ + { 0xa1, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x14 }, + /* H&V synchro polarity */ + { 0xa1, 0x40, 0x10, 0x06, 0x00, 0x00, 0x00, 0x14 }, + /* ?default */ + { 0xa1, 0x40, 0x11, 0x06, 0x00, 0x00, 0x00, 0x14 }, + /* DAC scale */ + { 0xa1, 0x40, 0x12, 0x06, 0x00, 0x00, 0x00, 0x14 }, + /* ?default */ + { 0xa1, 0x40, 0x14, 0x02, 0x00, 0x00, 0x00, 0x14 }, + /* Validate Settings */ + { 0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14 }, }; + static const __u8 initPas202[] = { 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x03, 0x0a, /* 6 */ - 0x28, 0x1e, 0x28, 0x89, 0x30, + 0x28, 0x1e, 0x28, 0x89, 0x20, 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c }; static const __u8 pas202_sensor_init[][8] = { @@ -390,6 +440,21 @@ static const __u8 tas5130_sensor_init[][8] = { {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}, }; +struct sensor_data sensor_data[] = { +SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0), +SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60), +SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3, + F_GAIN, 0, 0x21), +SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ, + 0), +SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0, + NO_EXPO|NO_FREQ, 0), +SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF, + NO_BRIGHTNESS|NO_FREQ, 0), +SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, + 0), +}; + /* get one byte in gspca_dev->usb_buf */ static void reg_r(struct gspca_dev *gspca_dev, __u16 value) @@ -468,7 +533,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}; /* change reg 0x06 */ - i2cOV[1] = sd->sensor_addr; + i2cOV[1] = sensor_data[sd->sensor].sensor_addr; i2cOV[3] = sd->brightness; if (i2c_w(gspca_dev, i2cOV) < 0) goto err; @@ -555,7 +620,7 @@ static void setsensorgain(struct gspca_dev *gspca_dev) case SENSOR_OV7630: { __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; - i2c[1] = sd->sensor_addr; + i2c[1] = sensor_data[sd->sensor].sensor_addr; i2c[3] = gain >> 2; if (i2c_w(gspca_dev, i2c) < 0) goto err; @@ -582,7 +647,7 @@ static void setgain(struct gspca_dev *gspca_dev) rgb_value = gain; reg_w(gspca_dev, 0x11, &rgb_value, 1); - if (sd->sensor_has_gain) + if (sensor_data[sd->sensor].flags & F_GAIN) setsensorgain(gspca_dev); } @@ -662,7 +727,7 @@ static void setexposure(struct gspca_dev *gspca_dev) reg10 = reg10_max; /* Write reg 10 and reg11 low nibble */ - i2c[1] = sd->sensor_addr; + i2c[1] = sensor_data[sd->sensor].sensor_addr; i2c[3] = reg10; i2c[4] |= reg11 - 1; @@ -702,7 +767,7 @@ static void setfreq(struct gspca_dev *gspca_dev) ? 0x4f : 0x8a; break; } - i2c[1] = sd->sensor_addr; + i2c[1] = sensor_data[sd->sensor].sensor_addr; if (i2c_w(gspca_dev, i2c) < 0) PDEBUG(D_ERR, "i2c error setfreq"); break; @@ -735,28 +800,19 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - int sif = 0; reg_r(gspca_dev, 0x00); if (gspca_dev->usb_buf[0] != 0x10) return -ENODEV; /* copy the webcam info from the device id */ - sd->sensor = (id->driver_info >> 24) & 0xff; - if (id->driver_info & (F_GAIN << 16)) - sd->sensor_has_gain = 1; - if (id->driver_info & (F_SIF << 16)) - sif = 1; - if (id->driver_info & (F_H18 << 16)) - sd->fr_h_sz = 18; /* size of frame header */ - else - sd->fr_h_sz = 12; - gspca_dev->ctrl_dis = (id->driver_info >> 8) & 0xff; - sd->sensor_addr = id->driver_info & 0xff; + sd->sensor = id->driver_info >> 8; + sd->bridge = id->driver_info & 0xff; + gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis; cam = &gspca_dev->cam; cam->epaddr = 0x01; - if (!sif) { + if (!(sensor_data[sd->sensor].flags & F_SIF)) { cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); } else { @@ -785,78 +841,29 @@ static int sd_init(struct gspca_dev *gspca_dev) return 0; } -static void pas106_i2cinit(struct gspca_dev *gspca_dev) -{ - int i; - const __u8 *data; - __u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 }; - - i = ARRAY_SIZE(pas106_data); - data = pas106_data[0]; - while (--i >= 0) { - memcpy(&i2c1[2], data, 2); - /* copy 2 bytes from the template */ - if (i2c_w(gspca_dev, i2c1) < 0) - PDEBUG(D_ERR, "i2c error pas106"); - data += 2; - } -} - /* -- start the camera -- */ static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - int mode, l = 0x1f; + int mode, l; const __u8 *sn9c10x; __u8 reg17_19[3]; - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 0x07; + sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge]; + l = sensor_data[sd->sensor].bridge_init_size[sd->bridge]; + reg17_19[0] = sn9c10x[0x17 - 1]; + reg17_19[1] = sn9c10x[0x18 - 1] | (mode << 4); + reg17_19[2] = sn9c10x[0x19 - 1]; + /* Special cases where reg 17 and or 19 value depends on mode */ switch (sd->sensor) { - case SENSOR_HV7131R: - sn9c10x = initHv7131; - reg17_19[0] = 0x60; - reg17_19[1] = (mode << 4) | 0x8a; - reg17_19[2] = 0x20; - break; - case SENSOR_OV6650: - sn9c10x = initOv6650; - reg17_19[0] = 0x68; - reg17_19[1] = (mode << 4) | 0x8b; - reg17_19[2] = 0x20; - break; - case SENSOR_OV7630: - if (sd->fr_h_sz == 18) { /* SN9C103 */ - sn9c10x = initOv7630_3; - l = sizeof initOv7630_3; - } else - sn9c10x = initOv7630; - reg17_19[0] = 0x68; - reg17_19[1] = (mode << 4) | COMP2; - reg17_19[2] = MCK_INIT1; - break; - case SENSOR_PAS106: - sn9c10x = initPas106; - reg17_19[0] = 0x24; /* 0x28 */ - reg17_19[1] = (mode << 4) | COMP1; - reg17_19[2] = MCK_INIT1; - break; case SENSOR_PAS202: - sn9c10x = initPas202; reg17_19[0] = mode ? 0x24 : 0x20; - reg17_19[1] = (mode << 4) | 0x89; - reg17_19[2] = 0x20; break; - case SENSOR_TAS5110: - sn9c10x = initTas5110; - reg17_19[0] = 0x60; - reg17_19[1] = (mode << 4) | 0x86; - reg17_19[2] = 0x2b; /* 0xf3; */ - break; - default: -/* case SENSOR_TAS5130CXX: */ - sn9c10x = initTas5130; - reg17_19[0] = 0x60; - reg17_19[1] = (mode << 4) | COMP; + case SENSOR_TAS5130CXX: + /* probably not mode specific at all most likely the upper + nibble of 0x19 is exposure (clock divider) just as with + the tas5110, we need someone to test this. */ reg17_19[2] = mode ? 0x23 : 0x43; break; } @@ -867,41 +874,16 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1); /* Set the registers from the template */ reg_w(gspca_dev, 0x01, sn9c10x, l); - switch (sd->sensor) { - case SENSOR_HV7131R: - i2c_w_vector(gspca_dev, hv7131_sensor_init, - sizeof hv7131_sensor_init); - break; - case SENSOR_OV6650: - i2c_w_vector(gspca_dev, ov6650_sensor_init, - sizeof ov6650_sensor_init); - break; - case SENSOR_OV7630: - i2c_w_vector(gspca_dev, ov7630_sensor_init, - sizeof ov7630_sensor_init); - if (sd->fr_h_sz == 18) { /* SN9C103 */ - const __u8 i2c[] = { 0xa0, 0x21, 0x13, 0x80, 0x00, - 0x00, 0x00, 0x10 }; - i2c_w(gspca_dev, i2c); - } - break; - case SENSOR_PAS106: - pas106_i2cinit(gspca_dev); - break; - case SENSOR_PAS202: - i2c_w_vector(gspca_dev, pas202_sensor_init, - sizeof pas202_sensor_init); - break; - case SENSOR_TAS5110: - i2c_w_vector(gspca_dev, tas5110_sensor_init, - sizeof tas5110_sensor_init); - break; - default: -/* case SENSOR_TAS5130CXX: */ - i2c_w_vector(gspca_dev, tas5130_sensor_init, - sizeof tas5130_sensor_init); - break; - } + + /* Init the sensor */ + i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init, + sensor_data[sd->sensor].sensor_init_size); + if (sensor_data[sd->sensor].sensor_bridge_init[sd->bridge]) + i2c_w_vector(gspca_dev, + sensor_data[sd->sensor].sensor_bridge_init[sd->bridge], + sensor_data[sd->sensor].sensor_bridge_init_size[ + sd->bridge]); + /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */ reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2); /* compression register */ @@ -937,10 +919,7 @@ static void sd_start(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev) { - __u8 ByteSend; - - ByteSend = 0x09; /* 0X00 */ - reg_w(gspca_dev, 0x01, &ByteSend, 1); + sd_init(gspca_dev); } static void sd_pkt_scan(struct gspca_dev *gspca_dev, @@ -970,15 +949,17 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, && data[5 + i] == 0x96) { /* start of frame */ int lum = -1; int pkt_type = LAST_PACKET; + int fr_h_sz = (sd->bridge == BRIDGE_103) ? + 18 : 12; - if (len - i < sd->fr_h_sz) { + if (len - i < fr_h_sz) { PDEBUG(D_STREAM, "packet too short to" " get avg brightness"); - } else if (sd->fr_h_sz == 12) { - lum = data[i + 8] + (data[i + 9] << 8); - } else { + } else if (sd->bridge == BRIDGE_103) { lum = data[i + 9] + (data[i + 10] << 8); + } else { + lum = data[i + 8] + (data[i + 9] << 8); } if (lum == 0) { lum = -1; @@ -993,8 +974,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, frame = gspca_frame_add(gspca_dev, pkt_type, frame, data, 0); - data += i + sd->fr_h_sz; - len -= i + sd->fr_h_sz; + data += i + fr_h_sz; + len -= i + fr_h_sz; gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); return; @@ -1143,55 +1124,33 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define SFCI(sensor, flags, disable_ctrls, i2c_addr) \ - .driver_info = (SENSOR_ ## sensor << 24) \ - | ((flags) << 16) \ - | ((disable_ctrls) << 8) \ - | (i2c_addr) -#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)) -#define NO_FREQ (1 << FREQ_IDX) -#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX) +#define SB(sensor, bridge) \ + .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge + static __devinitdata struct usb_device_id device_table[] = { #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE - {USB_DEVICE(0x0c45, 0x6001), /* SN9C102 */ - SFCI(TAS5110, F_GAIN|F_SIF, NO_BRIGHTNESS|NO_FREQ, 0)}, - {USB_DEVICE(0x0c45, 0x6005), /* SN9C101 */ - SFCI(TAS5110, F_GAIN|F_SIF, NO_BRIGHTNESS|NO_FREQ, 0)}, - {USB_DEVICE(0x0c45, 0x6007), /* SN9C101 */ - SFCI(TAS5110, F_GAIN|F_SIF, NO_BRIGHTNESS|NO_FREQ, 0)}, - {USB_DEVICE(0x0c45, 0x6009), /* SN9C101 */ - SFCI(PAS106, F_SIF, NO_EXPO|NO_FREQ, 0)}, - {USB_DEVICE(0x0c45, 0x600d), /* SN9C101 */ - SFCI(PAS106, F_SIF, NO_EXPO|NO_FREQ, 0)}, + {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, + {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, + {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110, 101)}, + {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)}, + {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)}, #endif - {USB_DEVICE(0x0c45, 0x6011), /* SN9C101 - SN9C101G */ - SFCI(OV6650, F_GAIN|F_SIF, 0, 0x60)}, + {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)}, #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE - {USB_DEVICE(0x0c45, 0x6019), /* SN9C101 */ - SFCI(OV7630, F_GAIN, 0, 0x21)}, - {USB_DEVICE(0x0c45, 0x6024), /* SN9C102 */ - SFCI(TAS5130CXX, 0, NO_EXPO|NO_FREQ, 0)}, - {USB_DEVICE(0x0c45, 0x6025), /* SN9C102 */ - SFCI(TAS5130CXX, 0, NO_EXPO|NO_FREQ, 0)}, - {USB_DEVICE(0x0c45, 0x6028), /* SN9C102 */ - SFCI(PAS202, 0, NO_EXPO|NO_FREQ, 0)}, - {USB_DEVICE(0x0c45, 0x6029), /* SN9C101 */ - SFCI(PAS106, F_SIF, NO_EXPO|NO_FREQ, 0)}, - {USB_DEVICE(0x0c45, 0x602c), /* SN9C102 */ - SFCI(OV7630, F_GAIN, 0, 0x21)}, + {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)}, + {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)}, + {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)}, + {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)}, + {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)}, + {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)}, #endif - {USB_DEVICE(0x0c45, 0x602d), /* SN9C102 */ - SFCI(HV7131R, 0, NO_EXPO|NO_FREQ, 0)}, + {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)}, #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE - {USB_DEVICE(0x0c45, 0x602e), /* SN9C102 */ - SFCI(OV7630, F_GAIN, 0, 0x21)}, - {USB_DEVICE(0x0c45, 0x608f), /* SN9C103 */ - SFCI(OV7630, F_GAIN|F_H18, 0, 0x21)}, - {USB_DEVICE(0x0c45, 0x60af), /* SN9C103 */ - SFCI(PAS202, F_H18, NO_EXPO|NO_FREQ, 0)}, - {USB_DEVICE(0x0c45, 0x60b0), /* SN9C103 */ - SFCI(OV7630, F_GAIN|F_H18, 0, 0x21)}, + {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)}, + {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)}, + {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)}, + {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)}, #endif {} }; -- cgit v1.2.2 From 5c51518da2cabc08af535cf041c6a3697f9e931f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 3 Sep 2008 17:12:22 -0300 Subject: V4L/DVB (8834): gspca: Have a bigger buffer for sn9c10x compressed images. Under certain conditions sonixb compressed frame size can get bigger then the uncompressed size (seen with 0c45:6028), so make the buffers slightly bigger. Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/media/video/gspca/sonixb.c') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 8eaeaa3a96d7..346305b12647 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -207,29 +207,29 @@ static struct ctrl sd_ctrls[] = { static struct v4l2_pix_format vga_mode[] = { {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, .bytesperline = 160, - .sizeimage = 160 * 120, + .sizeimage = 160 * 120 * 5 / 4, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 2}, {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, .bytesperline = 320, - .sizeimage = 320 * 240, + .sizeimage = 320 * 240 * 5 / 4, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 1}, {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, .bytesperline = 640, - .sizeimage = 640 * 480, + .sizeimage = 640 * 480 * 5 / 4, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 0}, }; static struct v4l2_pix_format sif_mode[] = { {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, .bytesperline = 176, - .sizeimage = 176 * 144, + .sizeimage = 176 * 144 * 5 / 4, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 1}, {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, .bytesperline = 352, - .sizeimage = 352 * 288, + .sizeimage = 352 * 288 * 5 / 4, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 0}, }; -- cgit v1.2.2 From c437d657c59921b048997d5bc1f5733670112902 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 3 Sep 2008 17:12:22 -0300 Subject: V4L/DVB (8835): gspca: Same pixfmt as the sn9c102 driver and raw Bayer added in sonixb. 1) Lower the hstart setting for all sensor by 1 so that we generate (compressed) BGGR data just like sn9c102 does (instead of GBRG data) 2) Add support for raw bayer output in the lowest resolutions (not enough bandwidth for higher resolutions), this should work with all sensors but to be sure only enable it for sensors where it has been tested. Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 54 +++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 10 deletions(-) (limited to 'drivers/media/video/gspca/sonixb.c') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 346305b12647..5033810f56fc 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -74,6 +74,10 @@ struct sensor_data { /* sensor_data flags */ #define F_GAIN 0x01 /* has gain */ #define F_SIF 0x02 /* sif or vga */ +#define F_RAW 0x04 /* sensor tested ok with raw bayer mode */ + +/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */ +#define MODE_RAW 0x10 /* raw bayer mode */ /* ctrl_dis helper macros */ #define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)) @@ -205,6 +209,11 @@ static struct ctrl sd_ctrls[] = { }; static struct v4l2_pix_format vga_mode[] = { + {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 160, + .sizeimage = 160 * 120, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 2 | MODE_RAW}, {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, .bytesperline = 160, .sizeimage = 160 * 120 * 5 / 4, @@ -222,6 +231,11 @@ static struct v4l2_pix_format vga_mode[] = { .priv = 0}, }; static struct v4l2_pix_format sif_mode[] = { + {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 176, + .sizeimage = 176 * 144, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1 | MODE_RAW}, {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, .bytesperline = 176, .sizeimage = 176 * 144 * 5 / 4, @@ -237,7 +251,7 @@ static struct v4l2_pix_format sif_mode[] = { static const __u8 initHv7131[] = { 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* shift from 0x02 0x01 0x00 */ + 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x28, 0x1e, 0x60, 0x8a, 0x20, 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c }; @@ -251,7 +265,7 @@ static const __u8 hv7131_sensor_init[][8] = { static const __u8 initOv6650[] = { 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b, + 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b, 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00 }; static const __u8 ov6650_sensor_init[][8] = @@ -290,7 +304,7 @@ static const __u8 ov6650_sensor_init[][8] = static const __u8 initOv7630[] = { 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */ 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */ - 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ + 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */ 0x28, 0x1e, /* H & V sizes r15 .. r16 */ 0x68, COMP2, MCK_INIT1, /* r17 .. r19 */ 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */ @@ -334,7 +348,7 @@ static const __u8 ov7630_sensor_init_3[][8] = { static const __u8 initPas106[] = { 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x16, 0x12, 0x24, COMP1, MCK_INIT1, 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c }; @@ -384,7 +398,7 @@ static const __u8 pas106_sensor_init[][8] = { static const __u8 initPas202[] = { 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x07, 0x03, 0x0a, /* 6 */ + 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a, 0x28, 0x1e, 0x28, 0x89, 0x20, 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c }; @@ -415,7 +429,7 @@ static const __u8 pas202_sensor_init[][8] = { static const __u8 initTas5110[] = { 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x46, 0x09, 0x0a, /* shift from 0x45 0x09 0x0a */ + 0x00, 0x01, 0x00, 0x45, 0x09, 0x0a, 0x16, 0x12, 0x60, 0x86, 0x2b, 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07 }; @@ -428,7 +442,7 @@ static const __u8 tas5110_sensor_init[][8] = { static const __u8 initTas5130[] = { 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x69, 0x0c, 0x0a, + 0x00, 0x01, 0x00, 0x68, 0x0c, 0x0a, 0x28, 0x1e, 0x60, COMP, MCK_INIT, 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c }; @@ -442,14 +456,15 @@ static const __u8 tas5130_sensor_init[][8] = { struct sensor_data sensor_data[] = { SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0), -SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60), +SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF|F_RAW, 0, + 0x60), SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3, F_GAIN, 0, 0x21), SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ, 0), -SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0, +SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, F_RAW, NO_EXPO|NO_FREQ, 0), -SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF, +SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF|F_RAW, NO_BRIGHTNESS|NO_FREQ, 0), SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0), @@ -819,6 +834,10 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); } + if (!(sensor_data[sd->sensor].flags & F_RAW)) { + cam->cam_mode++; + cam->nmodes--; + } sd->brightness = BRIGHTNESS_DEF; sd->gain = GAIN_DEF; sd->exposure = EXPOSURE_DEF; @@ -867,6 +886,9 @@ static void sd_start(struct gspca_dev *gspca_dev) reg17_19[2] = mode ? 0x23 : 0x43; break; } + /* Disable compression when the raw bayer format has been selected */ + if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) + reg17_19[1] &= ~0x80; /* reg 0x01 bit 2 video transfert on */ reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1); @@ -929,6 +951,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, { int i; struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam = &gspca_dev->cam; /* frames start with: * ff ff 00 c4 c4 96 synchro @@ -982,6 +1005,17 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, } } } + + if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) { + /* In raw mode we sometimes get some garbage after the frame + ignore this */ + int used = frame->data_end - frame->data; + int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage; + + if (used + len > size) + len = size - used; + } + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); } -- cgit v1.2.2 From 9362773624bcde3ccc198fefcf3c584e5058f645 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 4 Sep 2008 16:20:12 -0300 Subject: V4L/DVB (8868): gspca: Support for vga modes with sif sensors in sonixb. - Add documentation for some known registers - Add support for vga modes (320x240, 160x120) for sif sensors - Remove F_RAW sensor flag raw mode should work on any sensor as its a bridge only thing and keeping the flag was becoming awkward. - Fixup ov6650 and pas106 auto exposure window settings Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 96 ++++++++++++++++++++++++++------------ 1 file changed, 67 insertions(+), 29 deletions(-) (limited to 'drivers/media/video/gspca/sonixb.c') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 5033810f56fc..7f67148a5230 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -20,6 +20,26 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* Some documentation on known sonixb registers: + +Reg Use +0x10 high nibble red gain low nibble blue gain +0x11 low nibble green gain +0x12 hstart +0x13 vstart +0x15 hsize (hsize = register-value * 16) +0x16 vsize (vsize = register-value * 16) +0x17 bit 0 toggle compression quality (according to sn9c102 driver) +0x18 bit 7 enables compression, bit 4-5 set image down scaling: + 00 scale 1, 01 scale 1/2, 10, scale 1/4 +0x19 high-nibble is sensor clock divider, changes exposure on sensors which + use a clock generated by the bridge. Some sensors have their own clock. +0x1c auto_exposure area (for avg_lum) startx (startx = register-value * 32) +0x1d auto_exposure area (for avg_lum) starty (starty = register-value * 32) +0x1e auto_exposure area (for avg_lum) stopx (hsize = (0x1e - 0x1c) * 32) +0x1f auto_exposure area (for avg_lum) stopy (vsize = (0x1f - 0x1d) * 32) +*/ + #define MODULE_NAME "sonixb" #include "gspca.h" @@ -74,10 +94,10 @@ struct sensor_data { /* sensor_data flags */ #define F_GAIN 0x01 /* has gain */ #define F_SIF 0x02 /* sif or vga */ -#define F_RAW 0x04 /* sensor tested ok with raw bayer mode */ /* priv field of struct v4l2_pix_format flags (do not use low nibble!) */ #define MODE_RAW 0x10 /* raw bayer mode */ +#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */ /* ctrl_dis helper macros */ #define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)) @@ -211,7 +231,7 @@ static struct ctrl sd_ctrls[] = { static struct v4l2_pix_format vga_mode[] = { {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, .bytesperline = 160, - .sizeimage = 160 * 120, + .sizeimage = 160 * 120 * 5 / 4, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 2 | MODE_RAW}, {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, @@ -231,9 +251,19 @@ static struct v4l2_pix_format vga_mode[] = { .priv = 0}, }; static struct v4l2_pix_format sif_mode[] = { + {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 160, + .sizeimage = 160 * 120, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1 | MODE_RAW | MODE_REDUCED_SIF}, + {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, + .bytesperline = 160, + .sizeimage = 160 * 120 * 5 / 4, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1 | MODE_REDUCED_SIF}, {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, .bytesperline = 176, - .sizeimage = 176 * 144, + .sizeimage = 176 * 144 * 5 / 4, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 1 | MODE_RAW}, {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, @@ -241,6 +271,11 @@ static struct v4l2_pix_format sif_mode[] = { .sizeimage = 176 * 144 * 5 / 4, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 1}, + {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240 * 5 / 4, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0 | MODE_REDUCED_SIF}, {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, .bytesperline = 352, .sizeimage = 352 * 288 * 5 / 4, @@ -266,7 +301,7 @@ static const __u8 initOv6650[] = { 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b, - 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00 + 0x10, 0x1d, 0x10, 0x02, 0x02, 0x09, 0x07 }; static const __u8 ov6650_sensor_init[][8] = { @@ -350,7 +385,7 @@ static const __u8 initPas106[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x16, 0x12, 0x24, COMP1, MCK_INIT1, - 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c + 0x18, 0x10, 0x02, 0x02, 0x09, 0x07 }; /* compression 0x86 mckinit1 0x2b */ static const __u8 pas106_sensor_init[][8] = { @@ -456,15 +491,14 @@ static const __u8 tas5130_sensor_init[][8] = { struct sensor_data sensor_data[] = { SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0), -SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF|F_RAW, 0, - 0x60), +SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60), SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3, F_GAIN, 0, 0x21), SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ, 0), -SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, F_RAW, +SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0), -SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF|F_RAW, +SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF, NO_BRIGHTNESS|NO_FREQ, 0), SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0), @@ -834,10 +868,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); } - if (!(sensor_data[sd->sensor].flags & F_RAW)) { - cam->cam_mode++; - cam->nmodes--; - } sd->brightness = BRIGHTNESS_DEF; sd->gain = GAIN_DEF; sd->exposure = EXPOSURE_DEF; @@ -864,31 +894,39 @@ static int sd_init(struct gspca_dev *gspca_dev) static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam = &gspca_dev->cam; int mode, l; const __u8 *sn9c10x; - __u8 reg17_19[3]; + __u8 reg12_19[8]; - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 0x07; + mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07; sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge]; l = sensor_data[sd->sensor].bridge_init_size[sd->bridge]; - reg17_19[0] = sn9c10x[0x17 - 1]; - reg17_19[1] = sn9c10x[0x18 - 1] | (mode << 4); - reg17_19[2] = sn9c10x[0x19 - 1]; + memcpy(reg12_19, &sn9c10x[0x12 - 1], 8); + reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4); /* Special cases where reg 17 and or 19 value depends on mode */ switch (sd->sensor) { case SENSOR_PAS202: - reg17_19[0] = mode ? 0x24 : 0x20; + reg12_19[5] = mode ? 0x24 : 0x20; break; case SENSOR_TAS5130CXX: /* probably not mode specific at all most likely the upper nibble of 0x19 is exposure (clock divider) just as with the tas5110, we need someone to test this. */ - reg17_19[2] = mode ? 0x23 : 0x43; + reg12_19[7] = mode ? 0x23 : 0x43; break; } /* Disable compression when the raw bayer format has been selected */ - if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) - reg17_19[1] &= ~0x80; + if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) + reg12_19[6] &= ~0x80; + + /* Vga mode emulation on SIF sensor? */ + if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) { + reg12_19[0] += 16; /* 0x12: hstart adjust */ + reg12_19[1] += 24; /* 0x13: vstart adjust */ + reg12_19[3] = 320 / 16; /* 0x15: hsize */ + reg12_19[4] = 240 / 16; /* 0x16: vsize */ + } /* reg 0x01 bit 2 video transfert on */ reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1); @@ -907,24 +945,24 @@ static void sd_start(struct gspca_dev *gspca_dev) sd->bridge]); /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */ - reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2); + reg_w(gspca_dev, 0x15, ®12_19[3], 2); /* compression register */ - reg_w(gspca_dev, 0x18, ®17_19[1], 1); + reg_w(gspca_dev, 0x18, ®12_19[6], 1); /* H_start */ - reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1); + reg_w(gspca_dev, 0x12, ®12_19[0], 1); /* V_START */ - reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1); + reg_w(gspca_dev, 0x13, ®12_19[1], 1); /* reset 0x17 SensorClk enable inv Clk 0x60 */ /*fixme: ov7630 [17]=68 8f (+20 if 102)*/ - reg_w(gspca_dev, 0x17, ®17_19[0], 1); + reg_w(gspca_dev, 0x17, ®12_19[5], 1); /*MCKSIZE ->3 */ /*fixme: not ov7630*/ - reg_w(gspca_dev, 0x19, ®17_19[2], 1); + reg_w(gspca_dev, 0x19, ®12_19[7], 1); /* AE_STRX AE_STRY AE_ENDX AE_ENDY */ reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4); /* Enable video transfert */ reg_w(gspca_dev, 0x01, &sn9c10x[0], 1); /* Compression */ - reg_w(gspca_dev, 0x18, ®17_19[1], 2); + reg_w(gspca_dev, 0x18, ®12_19[6], 2); msleep(20); sd->reg11 = -1; -- cgit v1.2.2 From a94a508691d16420ad10572a33db4d45115b5f75 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 4 Sep 2008 16:22:55 -0300 Subject: V4L/DVB (8869): gspca: Move the Sonix webcams with TAS5110C1B from sn9c102 to gspca. This patch makes gspca claim the USB-ID for sn9c101/2 cams with a TAS5110C1B sensor even if both gspca and sn9c102 are enabled, as these cams are much better supported under gspca (and extensively tested with gspca). It also removes an usb-id from sn9c102 for one more unsupported bridge sensor combo. Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media/video/gspca/sonixb.c') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 7f67148a5230..bde9ea9b980e 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -1201,10 +1201,10 @@ static const struct sd_desc sd_desc = { static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, /* TAS5110C1B */ + {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, /* TAS5110C1B */ #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE - {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, - {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, - {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110, 101)}, + {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110, 101)}, /* TAS5110D */ {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)}, {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)}, #endif -- cgit v1.2.2 From bf2a2202f75cda679303f09d150f9549f9835953 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 4 Sep 2008 16:22:56 -0300 Subject: V4L/DVB (8870): gspca: Fix dark room problem with sonixb. When using the sonixb driver in a dark room and given that the autoexposure algorithm starts with a setting most suitable for daylight, the picture produced by the cam may actually be 100% black leading to a avg_lum value of 0, so an avg_lum value of 0 does not always signal an exposure settings change (which it normally does). This patch adds a check for the really black image case and stops dropping all frames as invalid in this case. Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers/media/video/gspca/sonixb.c') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index bde9ea9b980e..64bc758fbae5 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -52,6 +52,7 @@ MODULE_LICENSE("GPL"); struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ atomic_t avg_lum; + int prev_avg_lum; unsigned char gain; unsigned char exposure; @@ -1022,10 +1023,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, } else { lum = data[i + 8] + (data[i + 9] << 8); } - if (lum == 0) { + /* When exposure changes midway a frame we + get a lum of 0 in this case drop 2 frames + as the frames directly after an exposure + change have an unstable image. Sometimes lum + *really* is 0 (cam used in low light with + low exposure setting), so do not drop frames + if the previous lum was 0 too. */ + if (lum == 0 && sd->prev_avg_lum != 0) { lum = -1; sd->frames_to_drop = 2; - } + sd->prev_avg_lum = 0; + } else + sd->prev_avg_lum = lum; atomic_set(&sd->avg_lum, lum); if (sd->frames_to_drop) { -- cgit v1.2.2 From 4cce1655b26a4df1e619b2aa3d2eea1b7a6e906c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 4 Sep 2008 16:22:57 -0300 Subject: V4L/DVB (8874): gspca: Adjust hstart for sn9c103/ov7630 and update usb-id's. - Adjust hstart in ov7630 on sn9c103 initdata to shift bayer pattern, this is the same change as done for the other initdata tables in a previous patch. - Assign usb-id's for the ov7630 + sn9c103 to gspca if gspca and sn9c102 drivers are both enabled. Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/media/video/gspca/sonixb.c') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 64bc758fbae5..5dd78c6766ea 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -348,7 +348,7 @@ static const __u8 initOv7630[] = { static const __u8 initOv7630_3[] = { 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */ 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */ - 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */ + 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ 0x28, 0x1e, /* H & V sizes r15 .. r16 */ 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */ 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */ @@ -1230,10 +1230,12 @@ static __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)}, #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)}, +#endif {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)}, +#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)}, - {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)}, #endif + {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); -- cgit v1.2.2