summaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/sonixb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/sonixb.c')
-rw-r--r--drivers/media/video/gspca/sonixb.c486
1 files changed, 130 insertions, 356 deletions
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index dbeebe8625c..11210c71f66 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -24,9 +24,6 @@
#include "gspca.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 8)
-static const char version[] = "2.1.8";
-
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
MODULE_LICENSE("GPL");
@@ -44,25 +41,29 @@ struct sd {
unsigned char brightness;
unsigned char autogain;
unsigned char autogain_ignore_frames;
+ unsigned char frames_to_drop;
unsigned char freq; /* light freq filter setting */
- unsigned char saturation;
- unsigned char hue;
- unsigned char contrast;
unsigned char fr_h_sz; /* size of frame header */
char sensor; /* Type of image sensor chip */
#define SENSOR_HV7131R 0
#define SENSOR_OV6650 1
#define SENSOR_OV7630 2
-#define SENSOR_OV7630_3 3
-#define SENSOR_PAS106 4
-#define SENSOR_PAS202 5
-#define SENSOR_TAS5110 6
-#define SENSOR_TAS5130CXX 7
+#define SENSOR_PAS106 3
+#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 */
+#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 COMP2 0x8f
#define COMP 0xc7 /* 0x87 //0x07 */
#define COMP1 0xc9 /* 0x89 //0x09 */
@@ -92,12 +93,6 @@ 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_setfreq(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
static struct ctrl sd_ctrls[] = {
{
@@ -174,48 +169,6 @@ static struct ctrl sd_ctrls[] = {
.set = sd_setfreq,
.get = sd_getfreq,
},
- {
- {
- .id = V4L2_CID_SATURATION,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Saturation",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
-#define SATURATION_DEF 127
- .default_value = SATURATION_DEF,
- },
- .set = sd_setsaturation,
- .get = sd_getsaturation,
- },
- {
- {
- .id = V4L2_CID_HUE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Hue",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
-#define HUE_DEF 127
- .default_value = HUE_DEF,
- },
- .set = sd_sethue,
- .get = sd_gethue,
- },
- {
- {
- .id = V4L2_CID_CONTRAST,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Contrast",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
-#define CONTRAST_DEF 127
- .default_value = CONTRAST_DEF,
- },
- .set = sd_setcontrast,
- .get = sd_getcontrast,
- },
};
static struct v4l2_pix_format vga_mode[] = {
@@ -248,8 +201,6 @@ static struct v4l2_pix_format sif_mode[] = {
.priv = 0},
};
-static const __u8 probe_ov7630[] = {0x08, 0x44};
-
static const __u8 initHv7131[] = {
0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
0x00, 0x00,
@@ -321,7 +272,7 @@ static const __u8 initOv7630_3[] = {
0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */
};
-static const __u8 ov7630_sensor_init_com[][8] = {
+static const __u8 ov7630_sensor_init[][8] = {
{0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
{0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
/* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */
@@ -342,17 +293,6 @@ static const __u8 ov7630_sensor_init_com[][8] = {
{0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
{0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
};
-static const __u8 ov7630_sensor_init[][8] = {
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 200ms */
- {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x10}, /* jfm */
- {0xa0, 0x21, 0x10, 0x57, 0xbd, 0x06, 0xf6, 0x16},
- {0xa0, 0x21, 0x76, 0x02, 0xbd, 0x06, 0xf6, 0x16},
- {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */
-};
-static const __u8 ov7630_sensor_init_3[][8] = {
- {0xa0, 0x21, 0x2a, 0xa0, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x2a, 0x80, 0x00, 0x00, 0x00, 0x10},
-};
static const __u8 initPas106[] = {
0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
@@ -468,7 +408,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
const __u8 *buffer,
int len)
{
-#ifdef CONFIG_VIDEO_ADV_DEBUG
+#ifdef GSPCA_DEBUG
if (len > sizeof gspca_dev->usb_buf) {
PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
return;
@@ -542,7 +482,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
switch (sd->sensor) {
case SENSOR_OV6650:
- case SENSOR_OV7630_3:
case SENSOR_OV7630: {
__u8 i2cOV[] =
{0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
@@ -635,7 +574,7 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
case SENSOR_OV6650:
gain >>= 1;
/* fall thru */
- case SENSOR_OV7630_3: {
+ case SENSOR_OV7630: {
__u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
i2c[1] = sd->sensor_addr;
@@ -690,7 +629,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
break;
}
case SENSOR_OV6650:
- case SENSOR_OV7630_3: {
+ case SENSOR_OV7630: {
/* The ov6650 / ov7630 have 2 registers which both influence
exposure, register 11, whose low nibble sets the nr off fps
according to: fps = 30 / (low_nibble + 1)
@@ -705,16 +644,20 @@ static void setexposure(struct gspca_dev *gspca_dev)
The code maps our 0 - 510 ms exposure ctrl to these 2
registers, trying to keep fps as high as possible.
*/
- __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10};
- int reg10, reg11;
+ __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
+ int reg10, reg11, reg10_max;
+
/* ov6645 datasheet says reg10_max is 9a, but that uses
tline * 2 * reg10 as formula for calculating texpo, the
ov6650 probably uses the same formula as the 7730 which uses
tline * 4 * reg10, which explains why the reg10max we've
found experimentally for the ov6650 is exactly half that of
the ov6645. The ov7630 datasheet says the max is 0x41. */
- const int reg10_max = (sd->sensor == SENSOR_OV6650)
- ? 0x4d : 0x41;
+ if (sd->sensor == SENSOR_OV6650) {
+ reg10_max = 0x4d;
+ i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */
+ } else
+ reg10_max = 0x41;
reg11 = (60 * sd->exposure + 999) / 1000;
if (reg11 < 1)
@@ -735,20 +678,23 @@ 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;
i2c[4] |= reg11 - 1;
- if (sd->sensor == SENSOR_OV7630_3) {
- __u8 reg76 = reg10 & 0x03;
- __u8 i2c_reg76[] = {0xa0, 0x21, 0x76, 0x00,
- 0x00, 0x00, 0x00, 0x10};
- reg10 >>= 2;
- i2c_reg76[3] = reg76;
- if (i2c_w(gspca_dev, i2c_reg76) < 0)
- PDEBUG(D_ERR, "i2c error exposure");
- }
- if (i2c_w(gspca_dev, i2c) < 0)
+
+ /* If register 11 didn't change, don't change it */
+ if (sd->reg11 == reg11 )
+ i2c[0] = 0xa0;
+
+ if (i2c_w(gspca_dev, i2c) == 0)
+ sd->reg11 = reg11;
+ else
PDEBUG(D_ERR, "i2c error exposure");
break;
}
@@ -761,11 +707,11 @@ static void setfreq(struct gspca_dev *gspca_dev)
switch (sd->sensor) {
case SENSOR_OV6650:
- case SENSOR_OV7630_3: {
+ case SENSOR_OV7630: {
/* Framerate adjust register for artificial light 50 hz flicker
- compensation, identical to ov6630 0x2b register, see ov6630
- datasheet.
- 0x4f -> (30 fps -> 25 fps), 0x00 -> no adjustment */
+ compensation, for the ov6650 this is identical to ov6630
+ 0x2b register, see ov6630 datasheet.
+ 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
__u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
switch (sd->freq) {
default:
@@ -786,69 +732,6 @@ static void setfreq(struct gspca_dev *gspca_dev)
}
}
-static void setsaturation(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->sensor) {
-/* case SENSOR_OV6650: */
- case SENSOR_OV7630_3:
- case SENSOR_OV7630: {
- __u8 i2c[] = {0xa0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10};
- i2c[1] = sd->sensor_addr;
- i2c[3] = sd->saturation & 0xf0;
- if (i2c_w(gspca_dev, i2c) < 0)
- PDEBUG(D_ERR, "i2c error setsaturation");
- else
- PDEBUG(D_CONF, "saturation set to: %d",
- (int)sd->saturation);
- break;
- }
- }
-}
-
-static void sethue(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->sensor) {
-/* case SENSOR_OV6650: */
- case SENSOR_OV7630_3:
- case SENSOR_OV7630: {
- __u8 i2c[] = {0xa0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10};
- i2c[1] = sd->sensor_addr;
- i2c[3] = 0x20 | (sd->hue >> 3);
- if (i2c_w(gspca_dev, i2c) < 0)
- PDEBUG(D_ERR, "i2c error setsaturation");
- else
- PDEBUG(D_CONF, "hue set to: %d", (int)sd->hue);
- break;
- }
- }
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->sensor) {
-/* case SENSOR_OV6650: */
- case SENSOR_OV7630_3:
- case SENSOR_OV7630: {
- __u8 i2c[] = {0xa0, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10};
- i2c[1] = sd->sensor_addr;
- i2c[3] = 0x20 | (sd->contrast >> 3);
- if (i2c_w(gspca_dev, i2c) < 0)
- PDEBUG(D_ERR, "i2c error setcontrast");
- else
- PDEBUG(D_CONF, "contrast set to: %d",
- (int)sd->contrast);
- break;
- }
- }
-}
-
-
static void do_autogain(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -874,88 +757,32 @@ static int sd_config(struct gspca_dev *gspca_dev,
{
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam;
- __u16 product;
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;
- sd->fr_h_sz = 12; /* default size of the frame header */
- sd->sd_desc.nctrls = 2; /* default nb of ctrls */
- sd->autogain = AUTOGAIN_DEF; /* default is autogain active */
-
- product = id->idProduct;
-/* switch (id->idVendor) { */
-/* case 0x0c45: * Sonix */
- switch (product) {
- case 0x6001: /* SN9C102 */
- case 0x6005: /* SN9C101 */
- case 0x6007: /* SN9C101 */
- sd->sensor = SENSOR_TAS5110;
- sd->sensor_has_gain = 1;
- sd->sd_desc.nctrls = 4;
- sd->sd_desc.dq_callback = do_autogain;
- sif = 1;
- break;
- case 0x6009: /* SN9C101 */
- case 0x600d: /* SN9C101 */
- case 0x6029: /* SN9C101 */
- sd->sensor = SENSOR_PAS106;
- sif = 1;
- break;
- case 0x6011: /* SN9C101 - SN9C101G */
- sd->sensor = SENSOR_OV6650;
- sd->sensor_has_gain = 1;
- sd->sensor_addr = 0x60;
- sd->sd_desc.nctrls = 5;
- sd->sd_desc.dq_callback = do_autogain;
- sif = 1;
- break;
- case 0x6019: /* SN9C101 */
- case 0x602c: /* SN9C102 */
- case 0x602e: /* SN9C102 */
- sd->sensor = SENSOR_OV7630;
- sd->sensor_addr = 0x21;
- break;
- case 0x60b0: /* SN9C103 */
- sd->sensor = SENSOR_OV7630_3;
- sd->sensor_addr = 0x21;
- sd->fr_h_sz = 18; /* size of frame header */
- sd->sensor_has_gain = 1;
- sd->sd_desc.nctrls = 8;
- sd->sd_desc.dq_callback = do_autogain;
- sd->autogain = 0;
- break;
- case 0x6024: /* SN9C102 */
- case 0x6025: /* SN9C102 */
- sd->sensor = SENSOR_TAS5130CXX;
- break;
- case 0x6028: /* SN9C102 */
- sd->sensor = SENSOR_PAS202;
- break;
- case 0x602d: /* SN9C102 */
- sd->sensor = SENSOR_HV7131R;
- break;
- case 0x60af: /* SN9C103 */
- sd->sensor = SENSOR_PAS202;
- sd->fr_h_sz = 18; /* size of frame header (?) */
- break;
- }
-/* break; */
-/* } */
+ /* 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;
+ sd->sensor_addr = id->driver_info & 0xff;
cam = &gspca_dev->cam;
- cam->dev_name = (char *) id->driver_info;
cam->epaddr = 0x01;
if (!sif) {
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
- if (sd->sensor == SENSOR_OV7630_3) {
- /* We only have 320x240 & 640x480 */
- cam->cam_mode++;
- cam->nmodes--;
- }
} else {
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
@@ -963,12 +790,9 @@ 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;
sd->freq = FREQ_DEF;
- sd->contrast = CONTRAST_DEF;
- sd->saturation = SATURATION_DEF;
- sd->hue = HUE_DEF;
- if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */
- reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630);
+
return 0;
}
@@ -1002,9 +826,8 @@ static void pas106_i2cinit(struct gspca_dev *gspca_dev)
static void sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int mode, l;
+ int mode, l = 0x1f;
const __u8 *sn9c10x;
- __u8 reg01, reg17;
__u8 reg17_19[3];
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
@@ -1022,13 +845,11 @@ static void sd_start(struct gspca_dev *gspca_dev)
reg17_19[2] = 0x20;
break;
case SENSOR_OV7630:
- sn9c10x = initOv7630;
- reg17_19[0] = 0x68;
- reg17_19[1] = (mode << 4) | COMP2;
- reg17_19[2] = MCK_INIT1;
- break;
- case SENSOR_OV7630_3:
- sn9c10x = initOv7630_3;
+ 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;
@@ -1059,30 +880,11 @@ static void sd_start(struct gspca_dev *gspca_dev)
reg17_19[2] = mode ? 0x23 : 0x43;
break;
}
- switch (sd->sensor) {
- case SENSOR_OV7630:
- reg01 = 0x06;
- reg17 = 0x29;
- l = sizeof initOv7630;
- break;
- case SENSOR_OV7630_3:
- reg01 = 0x44;
- reg17 = 0x68;
- l = sizeof initOv7630_3;
- break;
- default:
- reg01 = sn9c10x[0];
- reg17 = sn9c10x[0x17 - 1];
- l = 0x1f;
- break;
- }
/* reg 0x01 bit 2 video transfert on */
- reg_w(gspca_dev, 0x01, &reg01, 1);
+ reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
/* reg 0x17 SensorClk enable inv Clk 0x60 */
- reg_w(gspca_dev, 0x17, &reg17, 1);
-/*fixme: for ov7630 102
- reg_w(gspca_dev, 0x01, {0x06, sn9c10x[1]}, 2); */
+ reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
/* Set the registers from the template */
reg_w_big(gspca_dev, 0x01, sn9c10x, l);
switch (sd->sensor) {
@@ -1095,17 +897,13 @@ static void sd_start(struct gspca_dev *gspca_dev)
sizeof ov6650_sensor_init);
break;
case SENSOR_OV7630:
- i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
- sizeof ov7630_sensor_init_com);
- msleep(200);
i2c_w_vector(gspca_dev, ov7630_sensor_init,
sizeof ov7630_sensor_init);
- break;
- case SENSOR_OV7630_3:
- i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
- sizeof ov7630_sensor_init_com);
- msleep(200);
- i2c_w(gspca_dev, ov7630_sensor_init_3[mode]);
+ 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);
@@ -1145,14 +943,14 @@ static void sd_start(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x18, &reg17_19[1], 2);
msleep(20);
+ sd->reg11 = -1;
+
setgain(gspca_dev);
setbrightness(gspca_dev);
setexposure(gspca_dev);
setfreq(gspca_dev);
- setsaturation(gspca_dev);
- sethue(gspca_dev);
- setcontrast(gspca_dev);
+ sd->frames_to_drop = 0;
sd->autogain_ignore_frames = 0;
atomic_set(&sd->avg_lum, -1);
}
@@ -1198,21 +996,31 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
&& data[3 + i] == 0xc4
&& data[4 + i] == 0xc4
&& data[5 + i] == 0x96) { /* start of frame */
- frame = gspca_frame_add(gspca_dev, LAST_PACKET,
- frame, data, 0);
+ int lum = -1;
+ int pkt_type = LAST_PACKET;
+
if (len - i < sd->fr_h_sz) {
- atomic_set(&sd->avg_lum, -1);
PDEBUG(D_STREAM, "packet too short to"
" get avg brightness");
} else if (sd->fr_h_sz == 12) {
- atomic_set(&sd->avg_lum,
- data[i + 8] +
- (data[i + 9] << 8));
+ lum = data[i + 8] + (data[i + 9] << 8);
} else {
- atomic_set(&sd->avg_lum,
- data[i + 9] +
- (data[i + 10] << 8));
+ lum = data[i + 9] +
+ (data[i + 10] << 8);
+ }
+ if (lum == 0) {
+ lum = -1;
+ sd->frames_to_drop = 2;
+ }
+ atomic_set(&sd->avg_lum, lum);
+
+ if (sd->frames_to_drop) {
+ sd->frames_to_drop--;
+ pkt_type = DISCARD_PACKET;
}
+
+ frame = gspca_frame_add(gspca_dev, pkt_type,
+ frame, data, 0);
data += i + sd->fr_h_sz;
len -= i + sd->fr_h_sz;
gspca_frame_add(gspca_dev, FIRST_PACKET,
@@ -1327,60 +1135,6 @@ static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
-static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->saturation = val;
- if (gspca_dev->streaming)
- setsaturation(gspca_dev);
- return 0;
-}
-
-static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->saturation;
- return 0;
-}
-
-static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->hue = val;
- if (gspca_dev->streaming)
- sethue(gspca_dev);
- return 0;
-}
-
-static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->hue;
- return 0;
-}
-
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->contrast = val;
- if (gspca_dev->streaming)
- setcontrast(gspca_dev);
- return 0;
-}
-
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->contrast;
- return 0;
-}
-
static int sd_querymenu(struct gspca_dev *gspca_dev,
struct v4l2_querymenu *menu)
{
@@ -1418,27 +1172,47 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
+#define SFCI(sensor, flags, nctrls, i2c_addr) \
+ .driver_info = (SENSOR_ ## sensor << 24) \
+ | ((flags) << 16) \
+ | ((nctrls) << 8) \
+ | (i2c_addr)
static __devinitdata struct usb_device_id device_table[] = {
#ifndef CONFIG_USB_SN9C102
- {USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")},
- {USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")},
- {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")},
- {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")},
- {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")},
+ {USB_DEVICE(0x0c45, 0x6001), /* SN9C102 */
+ SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
+ {USB_DEVICE(0x0c45, 0x6005), /* SN9C101 */
+ SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
+ {USB_DEVICE(0x0c45, 0x6007), /* SN9C101 */
+ SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
+ {USB_DEVICE(0x0c45, 0x6009), /* SN9C101 */
+ SFCI(PAS106, F_SIF, 2, 0)},
+ {USB_DEVICE(0x0c45, 0x600d), /* SN9C101 */
+ SFCI(PAS106, F_SIF, 2, 0)},
#endif
- {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia")},
+ {USB_DEVICE(0x0c45, 0x6011), /* SN9C101 - SN9C101G */
+ SFCI(OV6650, F_GAIN|F_AUTO|F_SIF, 5, 0x60)},
#ifndef CONFIG_USB_SN9C102
- {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")},
- {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")},
- {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")},
- {USB_DEVICE(0x0c45, 0x6028), DVNM("Sonix Btc Pc380")},
- {USB_DEVICE(0x0c45, 0x6029), DVNM("spcaCam@150")},
- {USB_DEVICE(0x0c45, 0x602c), DVNM("Generic Sonix OV7630")},
- {USB_DEVICE(0x0c45, 0x602d), DVNM("LIC-200 LG")},
- {USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")},
- {USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")},
- {USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")},
+ {USB_DEVICE(0x0c45, 0x6019), /* SN9C101 */
+ SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
+ {USB_DEVICE(0x0c45, 0x6024), /* SN9C102 */
+ SFCI(TAS5130CXX, 0, 2, 0)},
+ {USB_DEVICE(0x0c45, 0x6025), /* SN9C102 */
+ SFCI(TAS5130CXX, 0, 2, 0)},
+ {USB_DEVICE(0x0c45, 0x6028), /* SN9C102 */
+ SFCI(PAS202, 0, 2, 0)},
+ {USB_DEVICE(0x0c45, 0x6029), /* SN9C101 */
+ SFCI(PAS106, F_SIF, 2, 0)},
+ {USB_DEVICE(0x0c45, 0x602c), /* SN9C102 */
+ SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
+ {USB_DEVICE(0x0c45, 0x602d), /* SN9C102 */
+ SFCI(HV7131R, 0, 2, 0)},
+ {USB_DEVICE(0x0c45, 0x602e), /* SN9C102 */
+ SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
+ {USB_DEVICE(0x0c45, 0x60af), /* SN9C103 */
+ SFCI(PAS202, F_H18, 2, 0)},
+ {USB_DEVICE(0x0c45, 0x60b0), /* SN9C103 */
+ SFCI(OV7630, F_GAIN|F_AUTO|F_H18, 5, 0x21)},
#endif
{}
};
@@ -1464,7 +1238,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "v%s registered", version);
+ PDEBUG(D_PROBE, "registered");
return 0;
}
static void __exit sd_mod_exit(void)