V4L/DVB (8352): gspca: Buffers for USB exchanges cannot be in the stack.

gspca:    Protect dq_callback() against simultaneous USB exchanges.
          Temporary buffer for USB exchanges added in the device struct.
(all)     Use a temporary buffer for all USB exchanges.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
Jean-Francois Moine 2008-07-14 09:38:29 -03:00 committed by Mauro Carvalho Chehab
parent 5b77ae7776
commit 739570bb21
22 changed files with 1692 additions and 1787 deletions

View File

@ -25,8 +25,8 @@
#define CONEX_CAM 1 /* special JPEG header */ #define CONEX_CAM 1 /* special JPEG header */
#include "jpeg.h" #include "jpeg.h"
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.5"; static const char version[] = "2.1.7";
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver"); MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver");
@ -119,40 +119,67 @@ static struct v4l2_pix_format vga_mode[] = {
.priv = 0}, .priv = 0},
}; };
static void reg_r(struct usb_device *dev, /* the read bytes are found in gspca_dev->usb_buf */
__u16 index, static void reg_r(struct gspca_dev *gspca_dev,
__u8 *buffer, __u16 length) __u16 index,
__u16 len)
{ {
struct usb_device *dev = gspca_dev->dev;
#ifdef CONFIG_VIDEO_ADV_DEBUG
if (len > sizeof gspca_dev->usb_buf) {
err("reg_r: buffer overflow");
return;
}
#endif
usb_control_msg(dev, usb_control_msg(dev,
usb_rcvctrlpipe(dev, 0), usb_rcvctrlpipe(dev, 0),
0, 0,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, 0,
index, buffer, length, index, gspca_dev->usb_buf, len,
500); 500);
PDEBUG(D_USBI, "reg read [%02x] -> %02x ..", index, *buffer); PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
index, gspca_dev->usb_buf[0]);
} }
static void reg_w(struct usb_device *dev, /* the bytes to write are in gspca_dev->usb_buf */
__u16 index, static void reg_w_val(struct gspca_dev *gspca_dev,
const __u8 *buffer, __u16 len) __u16 index,
__u8 val)
{ {
__u8 tmpbuf[8]; struct usb_device *dev = gspca_dev->dev;
#ifdef CONFIG_VIDEO_ADV_DEBUG gspca_dev->usb_buf[0] = val;
if (len > sizeof tmpbuf) {
PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
return;
}
PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
#endif
memcpy(tmpbuf, buffer, len);
usb_control_msg(dev, usb_control_msg(dev,
usb_sndctrlpipe(dev, 0), usb_sndctrlpipe(dev, 0),
0, 0,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, 0,
index, tmpbuf, len, 500); index, gspca_dev->usb_buf, 1, 500);
}
static void reg_w(struct gspca_dev *gspca_dev,
__u16 index,
const __u8 *buffer,
__u16 len)
{
struct usb_device *dev = gspca_dev->dev;
#ifdef CONFIG_VIDEO_ADV_DEBUG
if (len > sizeof gspca_dev->usb_buf) {
err("reg_w: buffer overflow");
return;
}
PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
#endif
memcpy(gspca_dev->usb_buf, buffer, len);
usb_control_msg(dev,
usb_sndctrlpipe(dev, 0),
0,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0,
index, gspca_dev->usb_buf, len, 500);
} }
static const __u8 cx_sensor_init[][4] = { static const __u8 cx_sensor_init[][4] = {
@ -232,17 +259,14 @@ static const __u8 cx11646_fw1[][3] = {
}; };
static void cx11646_fw(struct gspca_dev*gspca_dev) static void cx11646_fw(struct gspca_dev*gspca_dev)
{ {
__u8 val;
int i = 0; int i = 0;
val = 0x02; reg_w_val(gspca_dev, 0x006a, 0x02);
reg_w(gspca_dev->dev, 0x006a, &val, 1);
while (cx11646_fw1[i][1]) { while (cx11646_fw1[i][1]) {
reg_w(gspca_dev->dev, 0x006b, cx11646_fw1[i], 3); reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3);
i++; i++;
} }
val = 0x00; reg_w_val(gspca_dev, 0x006a, 0x00);
reg_w(gspca_dev->dev, 0x006a, &val, 1);
} }
static const __u8 cxsensor[] = { static const __u8 cxsensor[] = {
@ -273,52 +297,47 @@ static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
static void cx_sensor(struct gspca_dev*gspca_dev) static void cx_sensor(struct gspca_dev*gspca_dev)
{ {
__u8 val;
int i = 0; int i = 0;
__u8 bufread[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
int length; int length;
const __u8 *ptsensor = cxsensor; const __u8 *ptsensor = cxsensor;
reg_w(gspca_dev->dev, 0x0020, reg20, 8); reg_w(gspca_dev, 0x0020, reg20, 8);
reg_w(gspca_dev->dev, 0x0028, reg28, 8); reg_w(gspca_dev, 0x0028, reg28, 8);
reg_w(gspca_dev->dev, 0x0010, reg10, 8); reg_w(gspca_dev, 0x0010, reg10, 8);
val = 0x03; reg_w_val(gspca_dev, 0x0092, 0x03);
reg_w(gspca_dev->dev, 0x0092, &val, 1);
switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
case 0: case 0:
reg_w(gspca_dev->dev, 0x0071, reg71a, 4); reg_w(gspca_dev, 0x0071, reg71a, 4);
break; break;
case 1: case 1:
reg_w(gspca_dev->dev, 0x0071, reg71b, 4); reg_w(gspca_dev, 0x0071, reg71b, 4);
break; break;
default: default:
/* case 2: */ /* case 2: */
reg_w(gspca_dev->dev, 0x0071, reg71c, 4); reg_w(gspca_dev, 0x0071, reg71c, 4);
break; break;
case 3: case 3:
reg_w(gspca_dev->dev, 0x0071, reg71d, 4); reg_w(gspca_dev, 0x0071, reg71d, 4);
break; break;
} }
reg_w(gspca_dev->dev, 0x007b, reg7b, 6); reg_w(gspca_dev, 0x007b, reg7b, 6);
val = 0x00; reg_w_val(gspca_dev, 0x00f8, 0x00);
reg_w(gspca_dev->dev, 0x00f8, &val, 1); reg_w(gspca_dev, 0x0010, reg10, 8);
reg_w(gspca_dev->dev, 0x0010, reg10, 8); reg_w_val(gspca_dev, 0x0098, 0x41);
val = 0x41;
reg_w(gspca_dev->dev, 0x0098, &val, 1);
for (i = 0; i < 11; i++) { for (i = 0; i < 11; i++) {
if (i == 3 || i == 5 || i == 8) if (i == 3 || i == 5 || i == 8)
length = 8; length = 8;
else else
length = 4; length = 4;
reg_w(gspca_dev->dev, 0x00e5, ptsensor, length); reg_w(gspca_dev, 0x00e5, ptsensor, length);
if (length == 4) if (length == 4)
reg_r(gspca_dev->dev, 0x00e8, &val, 1); reg_r(gspca_dev, 0x00e8, 1);
else else
reg_r(gspca_dev->dev, 0x00e8, bufread, length); reg_r(gspca_dev, 0x00e8, length);
ptsensor += length; ptsensor += length;
} }
reg_r(gspca_dev->dev, 0x00e7, bufread, 8); reg_r(gspca_dev, 0x00e7, 8);
} }
static const __u8 cx_inits_176[] = { static const __u8 cx_inits_176[] = {
@ -358,10 +377,9 @@ static const __u8 cx_inits_640[] = {
0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
static int cx11646_initsize(struct gspca_dev *gspca_dev) static void cx11646_initsize(struct gspca_dev *gspca_dev)
{ {
const __u8 *cxinit; const __u8 *cxinit;
__u8 val;
static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 }; static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
static const __u8 reg17[] = static const __u8 reg17[] =
{ 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 }; { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
@ -381,35 +399,29 @@ static int cx11646_initsize(struct gspca_dev *gspca_dev)
cxinit = cx_inits_176; cxinit = cx_inits_176;
break; break;
} }
val = 0x01; reg_w_val(gspca_dev, 0x009a, 0x01);
reg_w(gspca_dev->dev, 0x009a, &val, 1); reg_w_val(gspca_dev, 0x0010, 0x10);
val = 0x10; reg_w(gspca_dev, 0x0012, reg12, 5);
reg_w(gspca_dev->dev, 0x0010, &val, 1); reg_w(gspca_dev, 0x0017, reg17, 8);
reg_w(gspca_dev->dev, 0x0012, reg12, 5); reg_w_val(gspca_dev, 0x00c0, 0x00);
reg_w(gspca_dev->dev, 0x0017, reg17, 8); reg_w_val(gspca_dev, 0x00c1, 0x04);
val = 0x00; reg_w_val(gspca_dev, 0x00c2, 0x04);
reg_w(gspca_dev->dev, 0x00c0, &val, 1);
val = 0x04;
reg_w(gspca_dev->dev, 0x00c1, &val, 1);
val = 0x04;
reg_w(gspca_dev->dev, 0x00c2, &val, 1);
reg_w(gspca_dev->dev, 0x0061, cxinit, 8); reg_w(gspca_dev, 0x0061, cxinit, 8);
cxinit += 8; cxinit += 8;
reg_w(gspca_dev->dev, 0x00ca, cxinit, 8); reg_w(gspca_dev, 0x00ca, cxinit, 8);
cxinit += 8; cxinit += 8;
reg_w(gspca_dev->dev, 0x00d2, cxinit, 8); reg_w(gspca_dev, 0x00d2, cxinit, 8);
cxinit += 8; cxinit += 8;
reg_w(gspca_dev->dev, 0x00da, cxinit, 6); reg_w(gspca_dev, 0x00da, cxinit, 6);
cxinit += 8; cxinit += 8;
reg_w(gspca_dev->dev, 0x0041, cxinit, 8); reg_w(gspca_dev, 0x0041, cxinit, 8);
cxinit += 8; cxinit += 8;
reg_w(gspca_dev->dev, 0x0049, cxinit, 8); reg_w(gspca_dev, 0x0049, cxinit, 8);
cxinit += 8; cxinit += 8;
reg_w(gspca_dev->dev, 0x0051, cxinit, 2); reg_w(gspca_dev, 0x0051, cxinit, 2);
reg_r(gspca_dev->dev, 0x0010, &val, 1); reg_r(gspca_dev, 0x0010, 1);
return val;
} }
static const __u8 cx_jpeg_init[][8] = { static const __u8 cx_jpeg_init[][8] = {
@ -636,26 +648,21 @@ static const __u8 cxjpeg_qtable[][8] = {
static void cx11646_jpegInit(struct gspca_dev*gspca_dev) static void cx11646_jpegInit(struct gspca_dev*gspca_dev)
{ {
__u8 val;
int i; int i;
int length; int length;
val = 0x01; reg_w_val(gspca_dev, 0x00c0, 0x01);
reg_w(gspca_dev->dev, 0x00c0, &val, 1); reg_w_val(gspca_dev, 0x00c3, 0x00);
val = 0x00; reg_w_val(gspca_dev, 0x00c0, 0x00);
reg_w(gspca_dev->dev, 0x00c3, &val, 1); reg_r(gspca_dev, 0x0001, 1);
val = 0x00;
reg_w(gspca_dev->dev, 0x00c0, &val, 1);
reg_r(gspca_dev->dev, 0x0001, &val, 1);
length = 8; length = 8;
for (i = 0; i < 79; i++) { for (i = 0; i < 79; i++) {
if (i == 78) if (i == 78)
length = 6; length = 6;
reg_w(gspca_dev->dev, 0x0008, cx_jpeg_init[i], length); reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length);
} }
reg_r(gspca_dev->dev, 0x0002, &val, 1); reg_r(gspca_dev, 0x0002, 1);
val = 0x14; reg_w_val(gspca_dev, 0x0055, 0x14);
reg_w(gspca_dev->dev, 0x0055, &val, 1);
} }
static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 }; static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
@ -665,31 +672,26 @@ static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 };
static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 }; static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 };
static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 }; static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 };
static const __u8 reg51[] = { 0x77, 0x03 }; static const __u8 reg51[] = { 0x77, 0x03 };
static const __u8 reg70 = 0x03; #define reg70 0x03
static void cx11646_jpeg(struct gspca_dev*gspca_dev) static void cx11646_jpeg(struct gspca_dev*gspca_dev)
{ {
__u8 val;
int i; int i;
int length; int length;
__u8 Reg55; __u8 Reg55;
__u8 bufread[8];
int retry; int retry;
val = 0x01; reg_w_val(gspca_dev, 0x00c0, 0x01);
reg_w(gspca_dev->dev, 0x00c0, &val, 1); reg_w_val(gspca_dev, 0x00c3, 0x00);
val = 0x00; reg_w_val(gspca_dev, 0x00c0, 0x00);
reg_w(gspca_dev->dev, 0x00c3, &val, 1); reg_r(gspca_dev, 0x0001, 1);
val = 0x00;
reg_w(gspca_dev->dev, 0x00c0, &val, 1);
reg_r(gspca_dev->dev, 0x0001, &val, 1);
length = 8; length = 8;
switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
case 0: case 0:
for (i = 0; i < 27; i++) { for (i = 0; i < 27; i++) {
if (i == 26) if (i == 26)
length = 2; length = 2;
reg_w(gspca_dev->dev, 0x0008, cxjpeg_640[i], length); reg_w(gspca_dev, 0x0008, cxjpeg_640[i], length);
} }
Reg55 = 0x28; Reg55 = 0x28;
break; break;
@ -697,7 +699,7 @@ static void cx11646_jpeg(struct gspca_dev*gspca_dev)
for (i = 0; i < 27; i++) { for (i = 0; i < 27; i++) {
if (i == 26) if (i == 26)
length = 2; length = 2;
reg_w(gspca_dev->dev, 0x0008, cxjpeg_352[i], length); reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length);
} }
Reg55 = 0x16; Reg55 = 0x16;
break; break;
@ -706,7 +708,7 @@ static void cx11646_jpeg(struct gspca_dev*gspca_dev)
for (i = 0; i < 27; i++) { for (i = 0; i < 27; i++) {
if (i == 26) if (i == 26)
length = 2; length = 2;
reg_w(gspca_dev->dev, 0x0008, cxjpeg_320[i], length); reg_w(gspca_dev, 0x0008, cxjpeg_320[i], length);
} }
Reg55 = 0x14; Reg55 = 0x14;
break; break;
@ -714,124 +716,98 @@ static void cx11646_jpeg(struct gspca_dev*gspca_dev)
for (i = 0; i < 27; i++) { for (i = 0; i < 27; i++) {
if (i == 26) if (i == 26)
length = 2; length = 2;
reg_w(gspca_dev->dev, 0x0008, cxjpeg_176[i], length); reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length);
} }
Reg55 = 0x0B; Reg55 = 0x0B;
break; break;
} }
reg_r(gspca_dev->dev, 0x0002, &val, 1); reg_r(gspca_dev, 0x0002, 1);
val = Reg55; reg_w_val(gspca_dev, 0x0055, Reg55);
reg_w(gspca_dev->dev, 0x0055, &val, 1); reg_r(gspca_dev, 0x0002, 1);
reg_r(gspca_dev->dev, 0x0002, &val, 1); reg_w(gspca_dev, 0x0010, reg10, 2);
reg_w(gspca_dev->dev, 0x0010, reg10, 2); reg_w_val(gspca_dev, 0x0054, 0x02);
val = 0x02; reg_w_val(gspca_dev, 0x0054, 0x01);
reg_w(gspca_dev->dev, 0x0054, &val, 1); reg_w_val(gspca_dev, 0x0000, 0x94);
val = 0x01; reg_w_val(gspca_dev, 0x0053, 0xc0);
reg_w(gspca_dev->dev, 0x0054, &val, 1); reg_w_val(gspca_dev, 0x00fc, 0xe1);
val = 0x94; reg_w_val(gspca_dev, 0x0000, 0x00);
reg_w(gspca_dev->dev, 0x0000, &val, 1);
val = 0xc0;
reg_w(gspca_dev->dev, 0x0053, &val, 1);
val = 0xe1;
reg_w(gspca_dev->dev, 0x00fc, &val, 1);
val = 0x00;
reg_w(gspca_dev->dev, 0x0000, &val, 1);
/* wait for completion */ /* wait for completion */
retry = 50; retry = 50;
while (retry--) { while (retry--) {
reg_r(gspca_dev->dev, 0x0002, &val, 1); reg_r(gspca_dev, 0x0002, 1);
/* 0x07 until 0x00 */ /* 0x07 until 0x00 */
if (val == 0x00) if (gspca_dev->usb_buf[0] == 0x00)
break; break;
val = 0x00; reg_w_val(gspca_dev, 0x0053, 0x00);
reg_w(gspca_dev->dev, 0x0053, &val, 1);
} }
if (retry == 0) if (retry == 0)
PDEBUG(D_ERR, "Damned Errors sending jpeg Table"); PDEBUG(D_ERR, "Damned Errors sending jpeg Table");
/* send the qtable now */ /* send the qtable now */
reg_r(gspca_dev->dev, 0x0001, &val, 1); /* -> 0x18 */ reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */
length = 8; length = 8;
for (i = 0; i < 18; i++) { for (i = 0; i < 18; i++) {
if (i == 17) if (i == 17)
length = 2; length = 2;
reg_w(gspca_dev->dev, 0x0008, cxjpeg_qtable[i], length); reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length);
} }
reg_r(gspca_dev->dev, 0x0002, &val, 1); /* 0x00 */ reg_r(gspca_dev, 0x0002, 1); /* 0x00 */
reg_r(gspca_dev->dev, 0x0053, &val, 1); /* 0x00 */ reg_r(gspca_dev, 0x0053, 1); /* 0x00 */
val = 0x02; reg_w_val(gspca_dev, 0x0054, 0x02);
reg_w(gspca_dev->dev, 0x0054, &val, 1); reg_w_val(gspca_dev, 0x0054, 0x01);
val = 0x01; reg_w_val(gspca_dev, 0x0000, 0x94);
reg_w(gspca_dev->dev, 0x0054, &val, 1); reg_w_val(gspca_dev, 0x0053, 0xc0);
val = 0x94;
reg_w(gspca_dev->dev, 0x0000, &val, 1);
val = 0xc0;
reg_w(gspca_dev->dev, 0x0053, &val, 1);
reg_r(gspca_dev->dev, 0x0038, &val, 1); /* 0x40 */ reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
reg_r(gspca_dev->dev, 0x0038, &val, 1); /* 0x40 */ reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
reg_r(gspca_dev->dev, 0x001f, &val, 1); /* 0x38 */ reg_r(gspca_dev, 0x001f, 1); /* 0x38 */
reg_w(gspca_dev->dev, 0x0012, reg12, 5); reg_w(gspca_dev, 0x0012, reg12, 5);
reg_w(gspca_dev->dev, 0x00e5, regE5_8, 8); reg_w(gspca_dev, 0x00e5, regE5_8, 8);
reg_r(gspca_dev->dev, 0x00e8, bufread, 8); reg_r(gspca_dev, 0x00e8, 8);
reg_w(gspca_dev->dev, 0x00e5, regE5a, 4); reg_w(gspca_dev, 0x00e5, regE5a, 4);
reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
val = 0x01; reg_w_val(gspca_dev, 0x009a, 0x01);
reg_w(gspca_dev->dev, 0x009a, &val, 1); reg_w(gspca_dev, 0x00e5, regE5b, 4);
reg_w(gspca_dev->dev, 0x00e5, regE5b, 4); reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ reg_w(gspca_dev, 0x00e5, regE5c, 4);
reg_w(gspca_dev->dev, 0x00e5, regE5c, 4); reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */
reg_w(gspca_dev->dev, 0x0051, reg51, 2); reg_w(gspca_dev, 0x0051, reg51, 2);
reg_w(gspca_dev->dev, 0x0010, reg10, 2); reg_w(gspca_dev, 0x0010, reg10, 2);
reg_w(gspca_dev->dev, 0x0070, &reg70, 1); reg_w_val(gspca_dev, 0x0070, reg70);
} }
static void cx11646_init1(struct gspca_dev *gspca_dev) static void cx11646_init1(struct gspca_dev *gspca_dev)
{ {
__u8 val;
int i = 0; int i = 0;
val = 0; reg_w_val(gspca_dev, 0x0010, 0x00);
reg_w(gspca_dev->dev, 0x0010, &val, 1); reg_w_val(gspca_dev, 0x0053, 0x00);
reg_w(gspca_dev->dev, 0x0053, &val, 1); reg_w_val(gspca_dev, 0x0052, 0x00);
reg_w(gspca_dev->dev, 0x0052, &val, 1); reg_w_val(gspca_dev, 0x009b, 0x2f);
val = 0x2f; reg_w_val(gspca_dev, 0x009c, 0x10);
reg_w(gspca_dev->dev, 0x009b, &val, 1); reg_r(gspca_dev, 0x0098, 1);
val = 0x10; reg_w_val(gspca_dev, 0x0098, 0x40);
reg_w(gspca_dev->dev, 0x009c, &val, 1); reg_r(gspca_dev, 0x0099, 1);
reg_r(gspca_dev->dev, 0x0098, &val, 1); reg_w_val(gspca_dev, 0x0099, 0x07);
val = 0x40; reg_w_val(gspca_dev, 0x0039, 0x40);
reg_w(gspca_dev->dev, 0x0098, &val, 1); reg_w_val(gspca_dev, 0x003c, 0xff);
reg_r(gspca_dev->dev, 0x0099, &val, 1); reg_w_val(gspca_dev, 0x003f, 0x1f);
val = 0x07; reg_w_val(gspca_dev, 0x003d, 0x40);
reg_w(gspca_dev->dev, 0x0099, &val, 1); /* reg_w_val(gspca_dev, 0x003d, 0x60); */
val = 0x40; reg_r(gspca_dev, 0x0099, 1); /* ->0x07 */
reg_w(gspca_dev->dev, 0x0039, &val, 1);
val = 0xff;
reg_w(gspca_dev->dev, 0x003c, &val, 1);
val = 0x1f;
reg_w(gspca_dev->dev, 0x003f, &val, 1);
val = 0x40;
reg_w(gspca_dev->dev, 0x003d, &val, 1);
/* val= 0x60; */
/* reg_w(gspca_dev->dev, 0x00, 0x00, 0x003d, &val, 1); */
reg_r(gspca_dev->dev, 0x0099, &val, 1); /* ->0x07 */
while (cx_sensor_init[i][0]) { while (cx_sensor_init[i][0]) {
reg_w(gspca_dev->dev, 0x00e5, cx_sensor_init[i], 1); reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]);
reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* -> 0x00 */ reg_r(gspca_dev, 0x00e8, 1); /* -> 0x00 */
if (i == 1) { if (i == 1) {
val = 1; reg_w_val(gspca_dev, 0x00ed, 0x01);
reg_w(gspca_dev->dev, 0x00ed, &val, 1); reg_r(gspca_dev, 0x00ed, 1); /* -> 0x01 */
reg_r(gspca_dev->dev, 0x00ed, &val, 1); /* -> 0x01 */
} }
i++; i++;
} }
val = 0x00; reg_w_val(gspca_dev, 0x00c3, 0x00);
reg_w(gspca_dev->dev, 0x00c3, &val, 1);
} }
/* this function is called at probe time */ /* this function is called at probe time */
@ -880,29 +856,23 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
static void sd_stop0(struct gspca_dev *gspca_dev) static void sd_stop0(struct gspca_dev *gspca_dev)
{ {
int retry = 50; int retry = 50;
__u8 val;
val = 0; reg_w_val(gspca_dev, 0x0000, 0x00);
reg_w(gspca_dev->dev, 0x0000, &val, 1); reg_r(gspca_dev, 0x0002, 1);
reg_r(gspca_dev->dev, 0x0002, &val, 1); reg_w_val(gspca_dev, 0x0053, 0x00);
val = 0;
reg_w(gspca_dev->dev, 0x0053, &val, 1);
while (retry--) { while (retry--) {
/* reg_r(gspca_dev->dev, 0x0002, &val, 1);*/ /* reg_r(gspca_dev, 0x0002, 1);*/
reg_r(gspca_dev->dev, 0x0053, &val, 1); reg_r(gspca_dev, 0x0053, 1);
if (val == 0) if (gspca_dev->usb_buf[0] == 0)
break; break;
} }
val = 0; reg_w_val(gspca_dev, 0x0000, 0x00);
reg_w(gspca_dev->dev, 0x0000, &val, 1); reg_r(gspca_dev, 0x0002, 1);
reg_r(gspca_dev->dev, 0x0002, &val, 1);
val = 0; reg_w_val(gspca_dev, 0x0010, 0x00);
reg_w(gspca_dev->dev, 0x0010, &val, 1); reg_r(gspca_dev, 0x0033, 1);
reg_r(gspca_dev->dev, 0x0033, &val, 1); reg_w_val(gspca_dev, 0x00fc, 0xe0);
val = 0xe0;
reg_w(gspca_dev->dev, 0x00fc, &val, 1);
} }
static void sd_close(struct gspca_dev *gspca_dev) static void sd_close(struct gspca_dev *gspca_dev)
@ -937,22 +907,20 @@ static void setbrightness(struct gspca_dev*gspca_dev)
__u8 reg51c[2]; __u8 reg51c[2];
__u8 bright; __u8 bright;
__u8 colors; __u8 colors;
__u8 val;
__u8 bufread[8];
bright = sd->brightness; bright = sd->brightness;
regE5cbx[2] = bright; regE5cbx[2] = bright;
reg_w(gspca_dev->dev, 0x00e5, regE5cbx, 8); reg_w(gspca_dev, 0x00e5, regE5cbx, 8);
reg_r(gspca_dev->dev, 0x00e8, bufread, 8); reg_r(gspca_dev, 0x00e8, 8);
reg_w(gspca_dev->dev, 0x00e5, regE5c, 4); reg_w(gspca_dev, 0x00e5, regE5c, 4);
reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
colors = sd->colors; colors = sd->colors;
reg51c[0] = 0x77; reg51c[0] = 0x77;
reg51c[1] = colors; reg51c[1] = colors;
reg_w(gspca_dev->dev, 0x0051, reg51c, 2); reg_w(gspca_dev, 0x0051, reg51c, 2);
reg_w(gspca_dev->dev, 0x0010, reg10, 2); reg_w(gspca_dev, 0x0010, reg10, 2);
reg_w(gspca_dev->dev, 0x0070, &reg70, 1); reg_w_val(gspca_dev, 0x0070, reg70);
} }
static void setcontrast(struct gspca_dev*gspca_dev) static void setcontrast(struct gspca_dev*gspca_dev)
@ -961,16 +929,15 @@ static void setcontrast(struct gspca_dev*gspca_dev)
__u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */ __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
/* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */ /* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
__u8 reg51c[2]; __u8 reg51c[2];
__u8 val;
regE5acx[2] = sd->contrast; regE5acx[2] = sd->contrast;
reg_w(gspca_dev->dev, 0x00e5, regE5acx, 4); reg_w(gspca_dev, 0x00e5, regE5acx, 4);
reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
reg51c[0] = 0x77; reg51c[0] = 0x77;
reg51c[1] = sd->colors; reg51c[1] = sd->colors;
reg_w(gspca_dev->dev, 0x0051, reg51c, 2); reg_w(gspca_dev, 0x0051, reg51c, 2);
reg_w(gspca_dev->dev, 0x0010, reg10, 2); reg_w(gspca_dev, 0x0010, reg10, 2);
reg_w(gspca_dev->dev, 0x0070, &reg70, 1); reg_w_val(gspca_dev, 0x0070, reg70);
} }
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)

View File

@ -22,8 +22,8 @@
#include "gspca.h" #include "gspca.h"
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.5"; static const char version[] = "2.1.7";
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("Etoms USB Camera Driver"); MODULE_DESCRIPTION("Etoms USB Camera Driver");
@ -229,201 +229,215 @@ static const __u8 I2c3[] = { 0x12, 0x05 };
static const __u8 I2c4[] = { 0x41, 0x08 }; static const __u8 I2c4[] = { 0x41, 0x08 };
static void reg_r(struct usb_device *dev, /* read 'len' bytes to gspca_dev->usb_buf */
__u16 index, __u8 *buffer, int len) static void reg_r(struct gspca_dev *gspca_dev,
__u16 index,
__u16 len)
{ {
struct usb_device *dev = gspca_dev->dev;
#ifdef CONFIG_VIDEO_ADV_DEBUG
if (len > sizeof gspca_dev->usb_buf) {
err("reg_r: buffer overflow");
return;
}
#endif
usb_control_msg(dev, usb_control_msg(dev,
usb_rcvctrlpipe(dev, 0), usb_rcvctrlpipe(dev, 0),
0, 0,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
0, index, buffer, len, 500); 0,
index, gspca_dev->usb_buf, len, 500);
PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
index, gspca_dev->usb_buf[0]);
} }
static void reg_w_val(struct usb_device *dev, static void reg_w_val(struct gspca_dev *gspca_dev,
__u16 index, __u8 val) __u16 index,
__u8 val)
{ {
__u8 data; struct usb_device *dev = gspca_dev->dev;
data = val; gspca_dev->usb_buf[0] = val;
usb_control_msg(dev, usb_control_msg(dev,
usb_sndctrlpipe(dev, 0), usb_sndctrlpipe(dev, 0),
0, 0,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
0, index, &data, 1, 500); 0,
index, gspca_dev->usb_buf, 1, 500);
} }
static void reg_w(struct usb_device *dev, static void reg_w(struct gspca_dev *gspca_dev,
__u16 index, const __u8 *buffer, __u16 len) __u16 index,
const __u8 *buffer,
__u16 len)
{ {
__u8 tmpbuf[8]; struct usb_device *dev = gspca_dev->dev;
memcpy(tmpbuf, buffer, len); #ifdef CONFIG_VIDEO_ADV_DEBUG
if (len > sizeof gspca_dev->usb_buf) {
err("reg_w: buffer overflow");
return;
}
PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
#endif
memcpy(gspca_dev->usb_buf, buffer, len);
usb_control_msg(dev, usb_control_msg(dev,
usb_sndctrlpipe(dev, 0), usb_sndctrlpipe(dev, 0),
0, 0,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
0, index, tmpbuf, len, 500); 0, index, gspca_dev->usb_buf, len, 500);
} }
static int Et_i2cwrite(struct usb_device *dev, __u8 reg, static int i2c_w(struct gspca_dev *gspca_dev,
const __u8 *buffer, __u8 reg,
__u16 len, __u8 mode) const __u8 *buffer,
__u16 len, __u8 mode)
{ {
/* buffer should be [D0..D7] */ /* buffer should be [D0..D7] */
__u8 ptchcount; __u8 ptchcount;
/* set the base address */ /* set the base address */
reg_w_val(dev, ET_I2C_BASE, 0x40); /* sensor base for the pas106 */ reg_w_val(gspca_dev, ET_I2C_BASE, 0x40);
/* sensor base for the pas106 */
/* set count and prefetch */ /* set count and prefetch */
ptchcount = ((len & 0x07) << 4) | (mode & 0x03); ptchcount = ((len & 0x07) << 4) | (mode & 0x03);
reg_w_val(dev, ET_I2C_COUNT, ptchcount); reg_w_val(gspca_dev, ET_I2C_COUNT, ptchcount);
/* set the register base */ /* set the register base */
reg_w_val(dev, ET_I2C_REG, reg); reg_w_val(gspca_dev, ET_I2C_REG, reg);
while (--len >= 0) while (--len >= 0)
reg_w_val(dev, ET_I2C_DATA0 + len, buffer[len]); reg_w_val(gspca_dev, ET_I2C_DATA0 + len, buffer[len]);
return 0; return 0;
} }
static int Et_i2cread(struct usb_device *dev, __u8 reg, static int i2c_r(struct gspca_dev *gspca_dev,
__u8 *buffer, __u8 reg)
__u16 length, __u8 mode)
{ {
/* buffer should be [D0..D7] */
int i, j;
__u8 ptchcount;
/* set the base address */ /* set the base address */
reg_w_val(dev, ET_I2C_BASE, 0x40); /* sensor base for the pas106 */ reg_w_val(gspca_dev, ET_I2C_BASE, 0x40);
/* set count and prefetch */ /* sensor base for the pas106 */
ptchcount = ((length & 0x07) << 4) | (mode & 0x03); /* set count and prefetch (cnd: 4 bits - mode: 4 bits) */
reg_w_val(dev, ET_I2C_COUNT, ptchcount); reg_w_val(gspca_dev, ET_I2C_COUNT, 0x11);
/* set the register base */ reg_w_val(gspca_dev, ET_I2C_REG, reg); /* set the register base */
reg_w_val(dev, ET_I2C_REG, reg); reg_w_val(gspca_dev, ET_I2C_PREFETCH, 0x02); /* prefetch */
reg_w_val(dev, ET_I2C_PREFETCH, 0x02); /* prefetch */ reg_w_val(gspca_dev, ET_I2C_PREFETCH, 0x00);
reg_w_val(dev, ET_I2C_PREFETCH, 0); reg_r(gspca_dev, ET_I2C_DATA0, 1); /* read one byte */
j = length - 1;
for (i = 0; i < length; i++) {
reg_r(dev, (ET_I2C_DATA0 + j), &buffer[j], 1);
j--;
}
return 0; return 0;
} }
static int Et_WaitStatus(struct usb_device *dev) static int Et_WaitStatus(struct gspca_dev *gspca_dev)
{ {
__u8 bytereceived;
int retry = 10; int retry = 10;
while (retry--) { while (retry--) {
reg_r(dev, ET_ClCK, &bytereceived, 1); reg_r(gspca_dev, ET_ClCK, 1);
if (bytereceived != 0) if (gspca_dev->usb_buf[0] != 0)
return 1; return 1;
} }
return 0; return 0;
} }
static int et_video(struct usb_device *dev, int on) static int et_video(struct gspca_dev *gspca_dev,
int on)
{ {
int err; int ret;
reg_w_val(dev, ET_GPIO_OUT, on reg_w_val(gspca_dev, ET_GPIO_OUT,
? 0x10 /* startvideo - set Bit5 */ on ? 0x10 /* startvideo - set Bit5 */
: 0); /* stopvideo */ : 0); /* stopvideo */
err = Et_WaitStatus(dev); ret = Et_WaitStatus(gspca_dev);
if (!err) if (ret != 0)
PDEBUG(D_ERR, "timeout video on/off"); PDEBUG(D_ERR, "timeout video on/off");
return err; return ret;
} }
static void Et_init2(struct gspca_dev *gspca_dev) static void Et_init2(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev;
__u8 value; __u8 value;
__u8 received;
static const __u8 FormLine[] = { 0x84, 0x03, 0x14, 0xf4, 0x01, 0x05 }; static const __u8 FormLine[] = { 0x84, 0x03, 0x14, 0xf4, 0x01, 0x05 };
PDEBUG(D_STREAM, "Open Init2 ET"); PDEBUG(D_STREAM, "Open Init2 ET");
reg_w_val(dev, ET_GPIO_DIR_CTRL, 0x2f); reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 0x2f);
reg_w_val(dev, ET_GPIO_OUT, 0x10); reg_w_val(gspca_dev, ET_GPIO_OUT, 0x10);
reg_r(dev, ET_GPIO_IN, &received, 1); reg_r(gspca_dev, ET_GPIO_IN, 1);
reg_w_val(dev, ET_ClCK, 0x14); /* 0x14 // 0x16 enabled pattern */ reg_w_val(gspca_dev, ET_ClCK, 0x14); /* 0x14 // 0x16 enabled pattern */
reg_w_val(dev, ET_CTRL, 0x1b); reg_w_val(gspca_dev, ET_CTRL, 0x1b);
/* compression et subsampling */ /* compression et subsampling */
if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv)
value = ET_COMP_VAL1; /* 320 */ value = ET_COMP_VAL1; /* 320 */
else else
value = ET_COMP_VAL0; /* 640 */ value = ET_COMP_VAL0; /* 640 */
reg_w_val(dev, ET_COMP, value); reg_w_val(gspca_dev, ET_COMP, value);
reg_w_val(dev, ET_MAXQt, 0x1f); reg_w_val(gspca_dev, ET_MAXQt, 0x1f);
reg_w_val(dev, ET_MINQt, 0x04); reg_w_val(gspca_dev, ET_MINQt, 0x04);
/* undocumented registers */ /* undocumented registers */
reg_w_val(dev, ET_REG1d, 0xff); reg_w_val(gspca_dev, ET_REG1d, 0xff);
reg_w_val(dev, ET_REG1e, 0xff); reg_w_val(gspca_dev, ET_REG1e, 0xff);
reg_w_val(dev, ET_REG1f, 0xff); reg_w_val(gspca_dev, ET_REG1f, 0xff);
reg_w_val(dev, ET_REG20, 0x35); reg_w_val(gspca_dev, ET_REG20, 0x35);
reg_w_val(dev, ET_REG21, 0x01); reg_w_val(gspca_dev, ET_REG21, 0x01);
reg_w_val(dev, ET_REG22, 0x00); reg_w_val(gspca_dev, ET_REG22, 0x00);
reg_w_val(dev, ET_REG23, 0xff); reg_w_val(gspca_dev, ET_REG23, 0xff);
reg_w_val(dev, ET_REG24, 0xff); reg_w_val(gspca_dev, ET_REG24, 0xff);
reg_w_val(dev, ET_REG25, 0x0f); reg_w_val(gspca_dev, ET_REG25, 0x0f);
/* colors setting */ /* colors setting */
reg_w_val(dev, 0x30, 0x11); /* 0x30 */ reg_w_val(gspca_dev, 0x30, 0x11); /* 0x30 */
reg_w_val(dev, 0x31, 0x40); reg_w_val(gspca_dev, 0x31, 0x40);
reg_w_val(dev, 0x32, 0x00); reg_w_val(gspca_dev, 0x32, 0x00);
reg_w_val(dev, ET_O_RED, 0x00); /* 0x34 */ reg_w_val(gspca_dev, ET_O_RED, 0x00); /* 0x34 */
reg_w_val(dev, ET_O_GREEN1, 0x00); reg_w_val(gspca_dev, ET_O_GREEN1, 0x00);
reg_w_val(dev, ET_O_BLUE, 0x00); reg_w_val(gspca_dev, ET_O_BLUE, 0x00);
reg_w_val(dev, ET_O_GREEN2, 0x00); reg_w_val(gspca_dev, ET_O_GREEN2, 0x00);
/*************/ /*************/
reg_w_val(dev, ET_G_RED, 0x80); /* 0x4d */ reg_w_val(gspca_dev, ET_G_RED, 0x80); /* 0x4d */
reg_w_val(dev, ET_G_GREEN1, 0x80); reg_w_val(gspca_dev, ET_G_GREEN1, 0x80);
reg_w_val(dev, ET_G_BLUE, 0x80); reg_w_val(gspca_dev, ET_G_BLUE, 0x80);
reg_w_val(dev, ET_G_GREEN2, 0x80); reg_w_val(gspca_dev, ET_G_GREEN2, 0x80);
reg_w_val(dev, ET_G_GR_H, 0x00); reg_w_val(gspca_dev, ET_G_GR_H, 0x00);
reg_w_val(dev, ET_G_GB_H, 0x00); /* 0x52 */ reg_w_val(gspca_dev, ET_G_GB_H, 0x00); /* 0x52 */
/* Window control registers */ /* Window control registers */
reg_w_val(dev, 0x61, 0x80); /* use cmc_out */ reg_w_val(gspca_dev, 0x61, 0x80); /* use cmc_out */
reg_w_val(dev, 0x62, 0x02); reg_w_val(gspca_dev, 0x62, 0x02);
reg_w_val(dev, 0x63, 0x03); reg_w_val(gspca_dev, 0x63, 0x03);
reg_w_val(dev, 0x64, 0x14); reg_w_val(gspca_dev, 0x64, 0x14);
reg_w_val(dev, 0x65, 0x0e); reg_w_val(gspca_dev, 0x65, 0x0e);
reg_w_val(dev, 0x66, 0x02); reg_w_val(gspca_dev, 0x66, 0x02);
reg_w_val(dev, 0x67, 0x02); reg_w_val(gspca_dev, 0x67, 0x02);
/**************************************/ /**************************************/
reg_w_val(dev, ET_SYNCHRO, 0x8f); /* 0x68 */ reg_w_val(gspca_dev, ET_SYNCHRO, 0x8f); /* 0x68 */
reg_w_val(dev, ET_STARTX, 0x69); /* 0x6a //0x69 */ reg_w_val(gspca_dev, ET_STARTX, 0x69); /* 0x6a //0x69 */
reg_w_val(dev, ET_STARTY, 0x0d); /* 0x0d //0x0c */ reg_w_val(gspca_dev, ET_STARTY, 0x0d); /* 0x0d //0x0c */
reg_w_val(dev, ET_WIDTH_LOW, 0x80); reg_w_val(gspca_dev, ET_WIDTH_LOW, 0x80);
reg_w_val(dev, ET_HEIGTH_LOW, 0xe0); reg_w_val(gspca_dev, ET_HEIGTH_LOW, 0xe0);
reg_w_val(dev, ET_W_H_HEIGTH, 0x60); /* 6d */ reg_w_val(gspca_dev, ET_W_H_HEIGTH, 0x60); /* 6d */
reg_w_val(dev, ET_REG6e, 0x86); reg_w_val(gspca_dev, ET_REG6e, 0x86);
reg_w_val(dev, ET_REG6f, 0x01); reg_w_val(gspca_dev, ET_REG6f, 0x01);
reg_w_val(dev, ET_REG70, 0x26); reg_w_val(gspca_dev, ET_REG70, 0x26);
reg_w_val(dev, ET_REG71, 0x7a); reg_w_val(gspca_dev, ET_REG71, 0x7a);
reg_w_val(dev, ET_REG72, 0x01); reg_w_val(gspca_dev, ET_REG72, 0x01);
/* Clock Pattern registers ***************** */ /* Clock Pattern registers ***************** */
reg_w_val(dev, ET_REG73, 0x00); reg_w_val(gspca_dev, ET_REG73, 0x00);
reg_w_val(dev, ET_REG74, 0x18); /* 0x28 */ reg_w_val(gspca_dev, ET_REG74, 0x18); /* 0x28 */
reg_w_val(dev, ET_REG75, 0x0f); /* 0x01 */ reg_w_val(gspca_dev, ET_REG75, 0x0f); /* 0x01 */
/**********************************************/ /**********************************************/
reg_w_val(dev, 0x8a, 0x20); reg_w_val(gspca_dev, 0x8a, 0x20);
reg_w_val(dev, 0x8d, 0x0f); reg_w_val(gspca_dev, 0x8d, 0x0f);
reg_w_val(dev, 0x8e, 0x08); reg_w_val(gspca_dev, 0x8e, 0x08);
/**************************************/ /**************************************/
reg_w_val(dev, 0x03, 0x08); reg_w_val(gspca_dev, 0x03, 0x08);
reg_w_val(dev, ET_PXL_CLK, 0x03); reg_w_val(gspca_dev, ET_PXL_CLK, 0x03);
reg_w_val(dev, 0x81, 0xff); reg_w_val(gspca_dev, 0x81, 0xff);
reg_w_val(dev, 0x80, 0x00); reg_w_val(gspca_dev, 0x80, 0x00);
reg_w_val(dev, 0x81, 0xff); reg_w_val(gspca_dev, 0x81, 0xff);
reg_w_val(dev, 0x80, 0x20); reg_w_val(gspca_dev, 0x80, 0x20);
reg_w_val(dev, 0x03, 0x01); reg_w_val(gspca_dev, 0x03, 0x01);
reg_w_val(dev, 0x03, 0x00); reg_w_val(gspca_dev, 0x03, 0x00);
reg_w_val(dev, 0x03, 0x08); reg_w_val(gspca_dev, 0x03, 0x08);
/********************************************/ /********************************************/
/* reg_r(dev, ET_I2C_BASE, &received, 1); /* reg_r(gspca_dev, ET_I2C_BASE, 1);
always 0x40 as the pas106 ??? */ always 0x40 as the pas106 ??? */
/* set the sensor */ /* set the sensor */
if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv)
@ -435,25 +449,24 @@ static void Et_init2(struct gspca_dev *gspca_dev)
* 0x0b -> 24/(11+1) = 2 Mhz * 0x0b -> 24/(11+1) = 2 Mhz
* 0x17 -> 24/(23+1) = 1 Mhz * 0x17 -> 24/(23+1) = 1 Mhz
*/ */
reg_w_val(dev, ET_PXL_CLK, value); reg_w_val(gspca_dev, ET_PXL_CLK, value);
/* now set by fifo the FormatLine setting */ /* now set by fifo the FormatLine setting */
reg_w(dev, 0x62, FormLine, 6); reg_w(gspca_dev, 0x62, FormLine, 6);
/* set exposure times [ 0..0x78] 0->longvalue 0x78->shortvalue */ /* set exposure times [ 0..0x78] 0->longvalue 0x78->shortvalue */
reg_w_val(dev, 0x81, 0x47); /* 0x47; */ reg_w_val(gspca_dev, 0x81, 0x47); /* 0x47; */
reg_w_val(dev, 0x80, 0x40); /* 0x40; */ reg_w_val(gspca_dev, 0x80, 0x40); /* 0x40; */
/* Pedro change */ /* Pedro change */
/* Brightness change Brith+ decrease value */ /* Brightness change Brith+ decrease value */
/* Brigth- increase value */ /* Brigth- increase value */
/* original value = 0x70; */ /* original value = 0x70; */
reg_w_val(dev, 0x81, 0x30); /* 0x20; - set brightness */ reg_w_val(gspca_dev, 0x81, 0x30); /* 0x20; - set brightness */
reg_w_val(dev, 0x80, 0x20); /* 0x20; */ reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */
} }
static void setcolors(struct gspca_dev *gspca_dev) static void setcolors(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
__u8 I2cc[] = { 0x05, 0x02, 0x02, 0x05, 0x0d }; __u8 I2cc[] = { 0x05, 0x02, 0x02, 0x05, 0x0d };
__u8 i2cflags = 0x01; __u8 i2cflags = 0x01;
/* __u8 green = 0; */ /* __u8 green = 0; */
@ -464,8 +477,8 @@ static void setcolors(struct gspca_dev *gspca_dev)
/* green = 15 - ((((7*I2cc[0]) >> 2 ) + I2cc[3]) >> 1); */ /* green = 15 - ((((7*I2cc[0]) >> 2 ) + I2cc[3]) >> 1); */
/* I2cc[1] = I2cc[2] = green; */ /* I2cc[1] = I2cc[2] = green; */
if (sd->sensor == SENSOR_PAS106) { if (sd->sensor == SENSOR_PAS106) {
Et_i2cwrite(dev, PAS106_REG13, &i2cflags, 1, 3); i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3);
Et_i2cwrite(dev, PAS106_REG9, I2cc, sizeof I2cc, 1); i2c_w(gspca_dev, PAS106_REG9, I2cc, sizeof I2cc, 1);
} }
/* PDEBUG(D_CONF , "Etoms red %d blue %d green %d", /* PDEBUG(D_CONF , "Etoms red %d blue %d green %d",
I2cc[3], I2cc[0], green); */ I2cc[3], I2cc[0], green); */
@ -474,21 +487,17 @@ static void setcolors(struct gspca_dev *gspca_dev)
static void getcolors(struct gspca_dev *gspca_dev) static void getcolors(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
/* __u8 valblue; */
__u8 valred;
if (sd->sensor == SENSOR_PAS106) { if (sd->sensor == SENSOR_PAS106) {
/* Et_i2cread(gspca_dev->dev, PAS106_REG9, &valblue, 1, 1); */ /* i2c_r(gspca_dev, PAS106_REG9); * blue */
Et_i2cread(gspca_dev->dev, PAS106_REG9 + 3, &valred, 1, 1); i2c_r(gspca_dev, PAS106_REG9 + 3); /* red */
sd->colors = valred & 0x0f; sd->colors = gspca_dev->usb_buf[0] & 0x0f;
} }
} }
static void Et_init1(struct gspca_dev *gspca_dev) static void Et_init1(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev;
__u8 value; __u8 value;
__u8 received;
/* __u8 I2c0 [] = {0x0a, 0x12, 0x05, 0x22, 0xac, 0x00, 0x01, 0x00}; */ /* __u8 I2c0 [] = {0x0a, 0x12, 0x05, 0x22, 0xac, 0x00, 0x01, 0x00}; */
__u8 I2c0[] = { 0x0a, 0x12, 0x05, 0x6d, 0xcd, 0x00, 0x01, 0x00 }; __u8 I2c0[] = { 0x0a, 0x12, 0x05, 0x6d, 0xcd, 0x00, 0x01, 0x00 };
/* try 1/120 0x6d 0xcd 0x40 */ /* try 1/120 0x6d 0xcd 0x40 */
@ -496,12 +505,12 @@ static void Et_init1(struct gspca_dev *gspca_dev)
* 1/60000 hmm ?? */ * 1/60000 hmm ?? */
PDEBUG(D_STREAM, "Open Init1 ET"); PDEBUG(D_STREAM, "Open Init1 ET");
reg_w_val(dev, ET_GPIO_DIR_CTRL, 7); reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 7);
reg_r(dev, ET_GPIO_IN, &received, 1); reg_r(gspca_dev, ET_GPIO_IN, 1);
reg_w_val(dev, ET_RESET_ALL, 1); reg_w_val(gspca_dev, ET_RESET_ALL, 1);
reg_w_val(dev, ET_RESET_ALL, 0); reg_w_val(gspca_dev, ET_RESET_ALL, 0);
reg_w_val(dev, ET_ClCK, 0x10); reg_w_val(gspca_dev, ET_ClCK, 0x10);
reg_w_val(dev, ET_CTRL, 0x19); reg_w_val(gspca_dev, ET_CTRL, 0x19);
/* compression et subsampling */ /* compression et subsampling */
if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv)
value = ET_COMP_VAL1; value = ET_COMP_VAL1;
@ -510,80 +519,79 @@ static void Et_init1(struct gspca_dev *gspca_dev)
PDEBUG(D_STREAM, "Open mode %d Compression %d", PDEBUG(D_STREAM, "Open mode %d Compression %d",
gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv, gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv,
value); value);
reg_w_val(dev, ET_COMP, value); reg_w_val(gspca_dev, ET_COMP, value);
reg_w_val(dev, ET_MAXQt, 0x1d); reg_w_val(gspca_dev, ET_MAXQt, 0x1d);
reg_w_val(dev, ET_MINQt, 0x02); reg_w_val(gspca_dev, ET_MINQt, 0x02);
/* undocumented registers */ /* undocumented registers */
reg_w_val(dev, ET_REG1d, 0xff); reg_w_val(gspca_dev, ET_REG1d, 0xff);
reg_w_val(dev, ET_REG1e, 0xff); reg_w_val(gspca_dev, ET_REG1e, 0xff);
reg_w_val(dev, ET_REG1f, 0xff); reg_w_val(gspca_dev, ET_REG1f, 0xff);
reg_w_val(dev, ET_REG20, 0x35); reg_w_val(gspca_dev, ET_REG20, 0x35);
reg_w_val(dev, ET_REG21, 0x01); reg_w_val(gspca_dev, ET_REG21, 0x01);
reg_w_val(dev, ET_REG22, 0x00); reg_w_val(gspca_dev, ET_REG22, 0x00);
reg_w_val(dev, ET_REG23, 0xf7); reg_w_val(gspca_dev, ET_REG23, 0xf7);
reg_w_val(dev, ET_REG24, 0xff); reg_w_val(gspca_dev, ET_REG24, 0xff);
reg_w_val(dev, ET_REG25, 0x07); reg_w_val(gspca_dev, ET_REG25, 0x07);
/* colors setting */ /* colors setting */
reg_w_val(dev, ET_G_RED, 0x80); reg_w_val(gspca_dev, ET_G_RED, 0x80);
reg_w_val(dev, ET_G_GREEN1, 0x80); reg_w_val(gspca_dev, ET_G_GREEN1, 0x80);
reg_w_val(dev, ET_G_BLUE, 0x80); reg_w_val(gspca_dev, ET_G_BLUE, 0x80);
reg_w_val(dev, ET_G_GREEN2, 0x80); reg_w_val(gspca_dev, ET_G_GREEN2, 0x80);
reg_w_val(dev, ET_G_GR_H, 0x00); reg_w_val(gspca_dev, ET_G_GR_H, 0x00);
reg_w_val(dev, ET_G_GB_H, 0x00); reg_w_val(gspca_dev, ET_G_GB_H, 0x00);
/* Window control registers */ /* Window control registers */
reg_w_val(dev, ET_SYNCHRO, 0xf0); reg_w_val(gspca_dev, ET_SYNCHRO, 0xf0);
reg_w_val(dev, ET_STARTX, 0x56); /* 0x56 */ reg_w_val(gspca_dev, ET_STARTX, 0x56); /* 0x56 */
reg_w_val(dev, ET_STARTY, 0x05); /* 0x04 */ reg_w_val(gspca_dev, ET_STARTY, 0x05); /* 0x04 */
reg_w_val(dev, ET_WIDTH_LOW, 0x60); reg_w_val(gspca_dev, ET_WIDTH_LOW, 0x60);
reg_w_val(dev, ET_HEIGTH_LOW, 0x20); reg_w_val(gspca_dev, ET_HEIGTH_LOW, 0x20);
reg_w_val(dev, ET_W_H_HEIGTH, 0x50); reg_w_val(gspca_dev, ET_W_H_HEIGTH, 0x50);
reg_w_val(dev, ET_REG6e, 0x86); reg_w_val(gspca_dev, ET_REG6e, 0x86);
reg_w_val(dev, ET_REG6f, 0x01); reg_w_val(gspca_dev, ET_REG6f, 0x01);
reg_w_val(dev, ET_REG70, 0x86); reg_w_val(gspca_dev, ET_REG70, 0x86);
reg_w_val(dev, ET_REG71, 0x14); reg_w_val(gspca_dev, ET_REG71, 0x14);
reg_w_val(dev, ET_REG72, 0x00); reg_w_val(gspca_dev, ET_REG72, 0x00);
/* Clock Pattern registers */ /* Clock Pattern registers */
reg_w_val(dev, ET_REG73, 0x00); reg_w_val(gspca_dev, ET_REG73, 0x00);
reg_w_val(dev, ET_REG74, 0x00); reg_w_val(gspca_dev, ET_REG74, 0x00);
reg_w_val(dev, ET_REG75, 0x0a); reg_w_val(gspca_dev, ET_REG75, 0x0a);
reg_w_val(dev, ET_I2C_CLK, 0x04); reg_w_val(gspca_dev, ET_I2C_CLK, 0x04);
reg_w_val(dev, ET_PXL_CLK, 0x01); reg_w_val(gspca_dev, ET_PXL_CLK, 0x01);
/* set the sensor */ /* set the sensor */
if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
I2c0[0] = 0x06; I2c0[0] = 0x06;
Et_i2cwrite(dev, PAS106_REG2, I2c0, sizeof I2c0, 1); i2c_w(gspca_dev, PAS106_REG2, I2c0, sizeof I2c0, 1);
Et_i2cwrite(dev, PAS106_REG9, I2c2, sizeof I2c2, 1); i2c_w(gspca_dev, PAS106_REG9, I2c2, sizeof I2c2, 1);
value = 0x06; value = 0x06;
Et_i2cwrite(dev, PAS106_REG2, &value, 1, 1); i2c_w(gspca_dev, PAS106_REG2, &value, 1, 1);
Et_i2cwrite(dev, PAS106_REG3, I2c3, sizeof I2c3, 1); i2c_w(gspca_dev, PAS106_REG3, I2c3, sizeof I2c3, 1);
/* value = 0x1f; */ /* value = 0x1f; */
value = 0x04; value = 0x04;
Et_i2cwrite(dev, PAS106_REG0e, &value, 1, 1); i2c_w(gspca_dev, PAS106_REG0e, &value, 1, 1);
} else { } else {
I2c0[0] = 0x0a; I2c0[0] = 0x0a;
Et_i2cwrite(dev, PAS106_REG2, I2c0, sizeof I2c0, 1); i2c_w(gspca_dev, PAS106_REG2, I2c0, sizeof I2c0, 1);
Et_i2cwrite(dev, PAS106_REG9, I2c2, sizeof I2c2, 1); i2c_w(gspca_dev, PAS106_REG9, I2c2, sizeof I2c2, 1);
value = 0x0a; value = 0x0a;
i2c_w(gspca_dev, PAS106_REG2, &value, 1, 1);
Et_i2cwrite(dev, PAS106_REG2, &value, 1, 1); i2c_w(gspca_dev, PAS106_REG3, I2c3, sizeof I2c3, 1);
Et_i2cwrite(dev, PAS106_REG3, I2c3, sizeof I2c3, 1);
value = 0x04; value = 0x04;
/* value = 0x10; */ /* value = 0x10; */
Et_i2cwrite(dev, PAS106_REG0e, &value, 1, 1); i2c_w(gspca_dev, PAS106_REG0e, &value, 1, 1);
/* bit 2 enable bit 1:2 select 0 1 2 3 /* bit 2 enable bit 1:2 select 0 1 2 3
value = 0x07; * curve 0 * value = 0x07; * curve 0 *
Et_i2cwrite(dev,PAS106_REG0f,&value,1,1); i2c_w(gspca_dev, PAS106_REG0f, &value, 1, 1);
*/ */
} }
/* value = 0x01; */ /* value = 0x01; */
/* value = 0x22; */ /* value = 0x22; */
/* Et_i2cwrite(dev, PAS106_REG5, &value, 1, 1); */ /* i2c_w(gspca_dev, PAS106_REG5, &value, 1, 1); */
/* magnetude and sign bit for DAC */ /* magnetude and sign bit for DAC */
Et_i2cwrite(dev, PAS106_REG7, I2c4, sizeof I2c4, 1); i2c_w(gspca_dev, PAS106_REG7, I2c4, sizeof I2c4, 1);
/* now set by fifo the whole colors setting */ /* now set by fifo the whole colors setting */
reg_w(dev, ET_G_RED, GainRGBG, 6); reg_w(gspca_dev, ET_G_RED, GainRGBG, 6);
getcolors(gspca_dev); getcolors(gspca_dev);
setcolors(gspca_dev); setcolors(gspca_dev);
} }
@ -632,14 +640,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
static int sd_open(struct gspca_dev *gspca_dev) static int sd_open(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
if (sd->sensor == SENSOR_PAS106) if (sd->sensor == SENSOR_PAS106)
Et_init1(gspca_dev); Et_init1(gspca_dev);
else else
Et_init2(gspca_dev); Et_init2(gspca_dev);
reg_w_val(dev, ET_RESET_ALL, 0x08); reg_w_val(gspca_dev, ET_RESET_ALL, 0x08);
et_video(dev, 0); /* video off */ et_video(gspca_dev, 0); /* video off */
return 0; return 0;
} }
@ -647,20 +654,19 @@ static int sd_open(struct gspca_dev *gspca_dev)
static void sd_start(struct gspca_dev *gspca_dev) static void sd_start(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
if (sd->sensor == SENSOR_PAS106) if (sd->sensor == SENSOR_PAS106)
Et_init1(gspca_dev); Et_init1(gspca_dev);
else else
Et_init2(gspca_dev); Et_init2(gspca_dev);
reg_w_val(dev, ET_RESET_ALL, 0x08); reg_w_val(gspca_dev, ET_RESET_ALL, 0x08);
et_video(dev, 1); /* video on */ et_video(gspca_dev, 1); /* video on */
} }
static void sd_stopN(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev)
{ {
et_video(gspca_dev->dev, 0); /* video off */ et_video(gspca_dev, 0); /* video off */
} }
static void sd_stop0(struct gspca_dev *gspca_dev) static void sd_stop0(struct gspca_dev *gspca_dev)
@ -678,7 +684,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
__u8 brightness = sd->brightness; __u8 brightness = sd->brightness;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
reg_w_val(gspca_dev->dev, (ET_O_RED + i), brightness); reg_w_val(gspca_dev, ET_O_RED + i, brightness);
} }
static void getbrightness(struct gspca_dev *gspca_dev) static void getbrightness(struct gspca_dev *gspca_dev)
@ -686,11 +692,10 @@ static void getbrightness(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
int i; int i;
int brightness = 0; int brightness = 0;
__u8 value;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
reg_r(gspca_dev->dev, (ET_O_RED + i), &value, 1); reg_r(gspca_dev, ET_O_RED + i, 1);
brightness += value; brightness += gspca_dev->usb_buf[0];
} }
sd->brightness = brightness >> 3; sd->brightness = brightness >> 3;
} }
@ -701,8 +706,8 @@ static void setcontrast(struct gspca_dev *gspca_dev)
__u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
__u8 contrast = sd->contrast; __u8 contrast = sd->contrast;
memset(RGBG, contrast, sizeof RGBG - 2); memset(RGBG, contrast, sizeof(RGBG) - 2);
reg_w(gspca_dev->dev, ET_G_RED, RGBG, 6); reg_w(gspca_dev, ET_G_RED, RGBG, 6);
} }
static void getcontrast(struct gspca_dev *gspca_dev) static void getcontrast(struct gspca_dev *gspca_dev)
@ -710,11 +715,10 @@ static void getcontrast(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
int i; int i;
int contrast = 0; int contrast = 0;
__u8 value = 0;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
reg_r(gspca_dev->dev, (ET_G_RED + i), &value, 1); reg_r(gspca_dev, ET_G_RED + i, 1);
contrast += value; contrast += gspca_dev->usb_buf[0];
} }
sd->contrast = contrast >> 2; sd->contrast = contrast >> 2;
} }
@ -722,12 +726,11 @@ static void getcontrast(struct gspca_dev *gspca_dev)
static __u8 Et_getgainG(struct gspca_dev *gspca_dev) static __u8 Et_getgainG(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
__u8 value = 0;
if (sd->sensor == SENSOR_PAS106) { if (sd->sensor == SENSOR_PAS106) {
Et_i2cread(gspca_dev->dev, PAS106_REG0e, &value, 1, 1); i2c_r(gspca_dev, PAS106_REG0e);
PDEBUG(D_CONF, "Etoms gain G %d", value); PDEBUG(D_CONF, "Etoms gain G %d", gspca_dev->usb_buf[0]);
return value; return gspca_dev->usb_buf[0];
} }
return 0x1f; return 0x1f;
} }
@ -735,12 +738,12 @@ static __u8 Et_getgainG(struct gspca_dev *gspca_dev)
static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain) static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
__u8 i2cflags = 0x01;
if (sd->sensor == SENSOR_PAS106) { if (sd->sensor == SENSOR_PAS106) {
Et_i2cwrite(dev, PAS106_REG13, &i2cflags, 1, 3); __u8 i2cflags = 0x01;
Et_i2cwrite(dev, PAS106_REG0e, &gain, 1, 1);
i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3);
i2c_w(gspca_dev, PAS106_REG0e, &gain, 1, 1);
} }
} }
@ -751,8 +754,6 @@ static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain)
static void setautogain(struct gspca_dev *gspca_dev) static void setautogain(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev;
__u8 GRBG[] = { 0, 0, 0, 0 };
__u8 luma = 0; __u8 luma = 0;
__u8 luma_mean = 128; __u8 luma_mean = 128;
__u8 luma_delta = 20; __u8 luma_delta = 20;
@ -761,10 +762,10 @@ static void setautogain(struct gspca_dev *gspca_dev)
__u8 r, g, b; __u8 r, g, b;
Gbright = Et_getgainG(gspca_dev); Gbright = Et_getgainG(gspca_dev);
reg_r(dev, ET_LUMA_CENTER, GRBG, 4); reg_r(gspca_dev, ET_LUMA_CENTER, 4);
g = (GRBG[0] + GRBG[3]) >> 1; g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1;
r = GRBG[1]; r = gspca_dev->usb_buf[1];
b = GRBG[2]; b = gspca_dev->usb_buf[2];
r = ((r << 8) - (r << 4) - (r << 3)) >> 10; r = ((r << 8) - (r << 4) - (r << 3)) >> 10;
b = ((b << 7) >> 10); b = ((b << 7) >> 10);
g = ((g << 9) + (g << 7) + (g << 5)) >> 10; g = ((g << 9) + (g << 7) + (g << 5)) >> 10;

View File

@ -1347,9 +1347,11 @@ ok:
gspca_dev->fr_i, gspca_dev->fr_i,
gspca_dev->fr_o); gspca_dev->fr_o);
if (gspca_dev->sd_desc->dq_callback) if (gspca_dev->sd_desc->dq_callback) {
mutex_lock(&gspca_dev->usb_lock);
gspca_dev->sd_desc->dq_callback(gspca_dev); gspca_dev->sd_desc->dq_callback(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
}
return j; return j;
} }

View File

@ -125,6 +125,7 @@ struct gspca_dev {
struct cam cam; /* device information */ struct cam cam; /* device information */
const struct sd_desc *sd_desc; /* subdriver description */ const struct sd_desc *sd_desc; /* subdriver description */
__u8 usb_buf[8]; /* buffer for USB exchanges */
struct urb *urb[MAX_NURBS]; struct urb *urb[MAX_NURBS];
__u8 *frbuf; /* buffer for nframes */ __u8 *frbuf; /* buffer for nframes */

View File

@ -24,8 +24,8 @@
#include "gspca.h" #include "gspca.h"
#include "jpeg.h" #include "jpeg.h"
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.5"; static const char version[] = "2.1.7";
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver"); MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver");
@ -83,39 +83,53 @@ enum {
REG_HW_MI_63, REG_HW_MI_63,
REG_HW_MI_64, REG_HW_MI_64,
REG_HW_MI_F1 = 0xf1, REG_HW_MI_F1 = 0xf1,
ATTR_TOTAL_MI_REG = 242 ATTR_TOTAL_MI_REG = 0xf2
}; };
static int pcam_reg_write(struct usb_device *dev, /* the bytes to write are in gspca_dev->usb_buf */
__u16 index, __u8 *value, int len) static int reg_w(struct gspca_dev *gspca_dev,
__u16 index, int len)
{ {
int rc; int rc;
rc = usb_control_msg(dev, rc = usb_control_msg(gspca_dev->dev,
usb_sndbulkpipe(dev, 4), usb_sndbulkpipe(gspca_dev->dev, 4),
0x12, 0x12,
/* ?? 0xc8 = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_??? !? */ 0xc8, /* ?? */
0xc8,
0, /* value */ 0, /* value */
index, value, len, 500); index, gspca_dev->usb_buf, len, 500);
if (rc < 0) if (rc < 0)
PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc); PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc);
return rc; return rc;
} }
static void MISensor_BulkWrite(struct usb_device *dev, static int reg_w_buf(struct gspca_dev *gspca_dev,
unsigned short *pch, __u16 index, __u8 *buf, int len)
char Address)
{ {
__u8 data[6]; int rc;
data[0] = 0x1f; rc = usb_control_msg(gspca_dev->dev,
data[1] = 0; /* control byte */ usb_sndbulkpipe(gspca_dev->dev, 4),
data[2] = Address; 0x12,
data[3] = *pch >> 8; /* high byte */ 0xc8, /* ?? */
data[4] = *pch; /* low byte */ 0, /* value */
index, buf, len, 500);
if (rc < 0)
PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc);
return rc;
}
pcam_reg_write(dev, Address, data, 5); static void bulk_w(struct gspca_dev *gspca_dev,
__u16 *pch,
__u16 Address)
{
gspca_dev->usb_buf[0] = 0x1f;
gspca_dev->usb_buf[1] = 0; /* control byte */
gspca_dev->usb_buf[2] = Address;
gspca_dev->usb_buf[3] = *pch >> 8; /* high byte */
gspca_dev->usb_buf[4] = *pch; /* low byte */
reg_w(gspca_dev, Address, 5);
} }
/* this function is called at probe time */ /* this function is called at probe time */
@ -142,33 +156,30 @@ static int sd_open(struct gspca_dev *gspca_dev)
static void sd_start(struct gspca_dev *gspca_dev) static void sd_start(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev;
int err_code; int err_code;
__u8 data[12]; __u8 *data;
__u16 MI_buf[242]; __u16 *MI_buf;
int h_size, v_size; int h_size, v_size;
int intpipe; int intpipe;
/* struct usb_device *dev = pcam->dev; */
memset(data, 0, sizeof data);
memset(MI_buf, 0, sizeof MI_buf);
PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface); PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface);
if (usb_set_interface(dev, gspca_dev->iface, 8) < 0) { if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 8) < 0) {
PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error"); PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error");
return; return;
} }
data = gspca_dev->usb_buf;
data[0] = 0x01; /* address */ data[0] = 0x01; /* address */
data[1] = 0x01; data[1] = 0x01;
err_code = pcam_reg_write(dev, data[0], data, 2); err_code = reg_w(gspca_dev, data[0], 2);
if (err_code < 0) if (err_code < 0)
return; return;
/* /*
Initialize the MR97113 chip register Initialize the MR97113 chip register
*/ */
data = kmalloc(16, GFP_KERNEL);
data[0] = 0x00; /* address */ data[0] = 0x00; /* address */
data[1] = 0x0c | 0x01; /* reg 0 */ data[1] = 0x0c | 0x01; /* reg 0 */
data[2] = 0x01; /* reg 1 */ data[2] = 0x01; /* reg 1 */
@ -181,34 +192,34 @@ static void sd_start(struct gspca_dev *gspca_dev)
data[6] = 4; /* reg 5, H start */ data[6] = 4; /* reg 5, H start */
data[7] = 0xc0; /* reg 6, gamma 1.5 */ data[7] = 0xc0; /* reg 6, gamma 1.5 */
data[8] = 3; /* reg 7, V start */ data[8] = 3; /* reg 7, V start */
/* if(h_size == 320 ) */ /* if (h_size == 320 ) */
/* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */ /* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */
/* else */ /* else */
data[9] = 0x52; /* reg 8, 24MHz, no scale down */ data[9] = 0x52; /* reg 8, 24MHz, no scale down */
data[10] = 0x5d; /* reg 9, I2C device address data[10] = 0x5d; /* reg 9, I2C device address
* [for PAS5101 (0x40)] [for MI (0x5d)] */ * [for PAS5101 (0x40)] [for MI (0x5d)] */
err_code = pcam_reg_write(dev, data[0], data, 11); err_code = reg_w_buf(gspca_dev, data[0], data, 11);
kfree(data);
if (err_code < 0) if (err_code < 0)
return; return;
data = gspca_dev->usb_buf;
data[0] = 0x23; /* address */ data[0] = 0x23; /* address */
data[1] = 0x09; /* reg 35, append frame header */ data[1] = 0x09; /* reg 35, append frame header */
err_code = pcam_reg_write(dev, data[0], data, 2); err_code = reg_w(gspca_dev, data[0], 2);
if (err_code < 0) { if (err_code < 0)
PDEBUG(D_ERR, "Register write failed");
return; return;
}
data[0] = 0x3C; /* address */ data[0] = 0x3c; /* address */
/* if (pcam->width == 1280) */ /* if (gspca_dev->width == 1280) */
/* data[1] = 200; * reg 60, pc-cam frame size /* data[1] = 200; * reg 60, pc-cam frame size
* (unit: 4KB) 800KB */ * (unit: 4KB) 800KB */
/* else */ /* else */
data[1] = 50; /* 50 reg 60, pc-cam frame size data[1] = 50; /* 50 reg 60, pc-cam frame size
* (unit: 4KB) 200KB */ * (unit: 4KB) 200KB */
err_code = pcam_reg_write(dev, data[0], data, 2); err_code = reg_w(gspca_dev, data[0], 2);
if (err_code < 0) if (err_code < 0)
return; return;
@ -250,19 +261,20 @@ static void sd_start(struct gspca_dev *gspca_dev)
/* auto dark-gain */ /* auto dark-gain */
data[0] = 0x5e; /* address */ data[0] = 0x5e; /* address */
err_code = pcam_reg_write(dev, data[0], data, 6); err_code = reg_w(gspca_dev, data[0], 6);
if (err_code < 0) if (err_code < 0)
return; return;
data[0] = 0x67; data[0] = 0x67;
data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */ data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */
err_code = pcam_reg_write(dev, data[0], data, 2); err_code = reg_w(gspca_dev, data[0], 2);
if (err_code < 0) if (err_code < 0)
return; return;
/* /*
* initialize the value of MI sensor... * initialize the value of MI sensor...
*/ */
MI_buf = kzalloc(ATTR_TOTAL_MI_REG * sizeof *MI_buf, GFP_KERNEL);
MI_buf[REG_HW_MI_1] = 0x000a; MI_buf[REG_HW_MI_1] = 0x000a;
MI_buf[REG_HW_MI_2] = 0x000c; MI_buf[REG_HW_MI_2] = 0x000c;
MI_buf[REG_HW_MI_3] = 0x0405; MI_buf[REG_HW_MI_3] = 0x0405;
@ -304,48 +316,48 @@ static void sd_start(struct gspca_dev *gspca_dev)
} }
MI_buf[0x20] = 0x1104; MI_buf[0x20] = 0x1104;
MISensor_BulkWrite(dev, MI_buf + 1, 1); bulk_w(gspca_dev, MI_buf + 1, 1);
MISensor_BulkWrite(dev, MI_buf + 2, 2); bulk_w(gspca_dev, MI_buf + 2, 2);
MISensor_BulkWrite(dev, MI_buf + 3, 3); bulk_w(gspca_dev, MI_buf + 3, 3);
MISensor_BulkWrite(dev, MI_buf + 4, 4); bulk_w(gspca_dev, MI_buf + 4, 4);
MISensor_BulkWrite(dev, MI_buf + 5, 5); bulk_w(gspca_dev, MI_buf + 5, 5);
MISensor_BulkWrite(dev, MI_buf + 6, 6); bulk_w(gspca_dev, MI_buf + 6, 6);
MISensor_BulkWrite(dev, MI_buf + 7, 7); bulk_w(gspca_dev, MI_buf + 7, 7);
MISensor_BulkWrite(dev, MI_buf + 9, 9); bulk_w(gspca_dev, MI_buf + 9, 9);
MISensor_BulkWrite(dev, MI_buf + 0x0b, 0x0b); bulk_w(gspca_dev, MI_buf + 0x0b, 0x0b);
MISensor_BulkWrite(dev, MI_buf + 0x0c, 0x0c); bulk_w(gspca_dev, MI_buf + 0x0c, 0x0c);
MISensor_BulkWrite(dev, MI_buf + 0x0d, 0x0d); bulk_w(gspca_dev, MI_buf + 0x0d, 0x0d);
MISensor_BulkWrite(dev, MI_buf + 0x1e, 0x1e); bulk_w(gspca_dev, MI_buf + 0x1e, 0x1e);
MISensor_BulkWrite(dev, MI_buf + 0x20, 0x20); bulk_w(gspca_dev, MI_buf + 0x20, 0x20);
MISensor_BulkWrite(dev, MI_buf + 0x2b, 0x2b); bulk_w(gspca_dev, MI_buf + 0x2b, 0x2b);
MISensor_BulkWrite(dev, MI_buf + 0x2c, 0x2c); bulk_w(gspca_dev, MI_buf + 0x2c, 0x2c);
MISensor_BulkWrite(dev, MI_buf + 0x2d, 0x2d); bulk_w(gspca_dev, MI_buf + 0x2d, 0x2d);
MISensor_BulkWrite(dev, MI_buf + 0x2e, 0x2e); bulk_w(gspca_dev, MI_buf + 0x2e, 0x2e);
MISensor_BulkWrite(dev, MI_buf + 0x35, 0x35); bulk_w(gspca_dev, MI_buf + 0x35, 0x35);
MISensor_BulkWrite(dev, MI_buf + 0x5f, 0x5f); bulk_w(gspca_dev, MI_buf + 0x5f, 0x5f);
MISensor_BulkWrite(dev, MI_buf + 0x60, 0x60); bulk_w(gspca_dev, MI_buf + 0x60, 0x60);
MISensor_BulkWrite(dev, MI_buf + 0x61, 0x61); bulk_w(gspca_dev, MI_buf + 0x61, 0x61);
MISensor_BulkWrite(dev, MI_buf + 0x62, 0x62); bulk_w(gspca_dev, MI_buf + 0x62, 0x62);
MISensor_BulkWrite(dev, MI_buf + 0x63, 0x63); bulk_w(gspca_dev, MI_buf + 0x63, 0x63);
MISensor_BulkWrite(dev, MI_buf + 0x64, 0x64); bulk_w(gspca_dev, MI_buf + 0x64, 0x64);
MISensor_BulkWrite(dev, MI_buf + 0xf1, 0xf1); bulk_w(gspca_dev, MI_buf + 0xf1, 0xf1);
kfree(MI_buf);
intpipe = usb_sndintpipe(dev, 0); intpipe = usb_sndintpipe(gspca_dev->dev, 0);
err_code = usb_clear_halt(dev, intpipe); err_code = usb_clear_halt(gspca_dev->dev, intpipe);
data[0] = 0x00; data[0] = 0x00;
data[1] = 0x4d; /* ISOC transfering enable... */ data[1] = 0x4d; /* ISOC transfering enable... */
pcam_reg_write(dev, data[0], data, 2); reg_w(gspca_dev, data[0], 2);
} }
static void sd_stopN(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev)
{ {
int result; int result;
__u8 data[2];
data[0] = 1; gspca_dev->usb_buf[0] = 1;
data[1] = 0; gspca_dev->usb_buf[1] = 0;
result = pcam_reg_write(gspca_dev->dev, data[0], data, 2); result = reg_w(gspca_dev, gspca_dev->usb_buf[0], 2);
if (result < 0) if (result < 0)
PDEBUG(D_ERR, "Camera Stop failed"); PDEBUG(D_ERR, "Camera Stop failed");
} }

View File

@ -24,8 +24,8 @@
#include "gspca.h" #include "gspca.h"
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.5"; static const char version[] = "2.1.7";
MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
MODULE_DESCRIPTION("OV519 USB Camera Driver"); MODULE_DESCRIPTION("OV519 USB Camera Driver");
@ -282,15 +282,14 @@ static unsigned char ov7670_abs_to_sm(unsigned char v)
static int reg_w(struct sd *sd, __u16 index, __u8 value) static int reg_w(struct sd *sd, __u16 index, __u8 value)
{ {
int ret; int ret;
__u8 data;
data = value; sd->gspca_dev.usb_buf[0] = value;
ret = usb_control_msg(sd->gspca_dev.dev, ret = usb_control_msg(sd->gspca_dev.dev,
usb_sndctrlpipe(sd->gspca_dev.dev, 0), usb_sndctrlpipe(sd->gspca_dev.dev, 0),
1, /* REQ_IO (ov518/519) */ 1, /* REQ_IO (ov518/519) */
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, index, 0, index,
&data, 1, 500); sd->gspca_dev.usb_buf, 1, 500);
if (ret < 0) if (ret < 0)
PDEBUG(D_ERR, "Write reg [%02x] %02x failed", index, value); PDEBUG(D_ERR, "Write reg [%02x] %02x failed", index, value);
return ret; return ret;
@ -301,16 +300,15 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value)
static int reg_r(struct sd *sd, __u16 index) static int reg_r(struct sd *sd, __u16 index)
{ {
int ret; int ret;
__u8 data;
ret = usb_control_msg(sd->gspca_dev.dev, ret = usb_control_msg(sd->gspca_dev.dev,
usb_rcvctrlpipe(sd->gspca_dev.dev, 0), usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
1, /* REQ_IO */ 1, /* REQ_IO */
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, index, &data, 1, 500); 0, index, sd->gspca_dev.usb_buf, 1, 500);
if (ret >= 0) if (ret >= 0)
ret = data; ret = sd->gspca_dev.usb_buf[0];
else else
PDEBUG(D_ERR, "Read reg [0x%02x] failed", index); PDEBUG(D_ERR, "Read reg [0x%02x] failed", index);
return ret; return ret;
@ -321,16 +319,15 @@ static int reg_r8(struct sd *sd,
__u16 index) __u16 index)
{ {
int ret; int ret;
__u8 buf[8];
ret = usb_control_msg(sd->gspca_dev.dev, ret = usb_control_msg(sd->gspca_dev.dev,
usb_rcvctrlpipe(sd->gspca_dev.dev, 0), usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
1, /* REQ_IO */ 1, /* REQ_IO */
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, index, &buf[0], 8, 500); 0, index, sd->gspca_dev.usb_buf, 8, 500);
if (ret >= 0) if (ret >= 0)
ret = buf[0]; ret = sd->gspca_dev.usb_buf[0];
else else
PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index); PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index);
return ret; return ret;

View File

@ -27,8 +27,8 @@
#include "gspca.h" #include "gspca.h"
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.5"; static const char version[] = "2.1.7";
MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>"); MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>");
MODULE_DESCRIPTION("Pixart PAC207"); MODULE_DESCRIPTION("Pixart PAC207");
@ -187,18 +187,18 @@ static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 };
static const unsigned char pac207_sof_marker[5] = static const unsigned char pac207_sof_marker[5] =
{ 0xff, 0xff, 0x00, 0xff, 0x96 }; { 0xff, 0xff, 0x00, 0xff, 0x96 };
int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index, static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
const u8 *buffer, u16 length) const u8 *buffer, u16 length)
{ {
struct usb_device *udev = gspca_dev->dev; struct usb_device *udev = gspca_dev->dev;
int err; int err;
u8 kbuf[8];
memcpy(kbuf, buffer, length); memcpy(gspca_dev->usb_buf, buffer, length);
err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01, err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
0x00, index, kbuf, length, PAC207_CTRL_TIMEOUT); 0x00, index,
gspca_dev->usb_buf, length, PAC207_CTRL_TIMEOUT);
if (err < 0) if (err < 0)
PDEBUG(D_ERR, PDEBUG(D_ERR,
"Failed to write registers to index 0x%04X, error %d)", "Failed to write registers to index 0x%04X, error %d)",
@ -227,12 +227,12 @@ int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value)
int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index) int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index)
{ {
struct usb_device *udev = gspca_dev->dev; struct usb_device *udev = gspca_dev->dev;
u8 buff;
int res; int res;
res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
0x00, index, &buff, 1, PAC207_CTRL_TIMEOUT); 0x00, index,
gspca_dev->usb_buf, 1, PAC207_CTRL_TIMEOUT);
if (res < 0) { if (res < 0) {
PDEBUG(D_ERR, PDEBUG(D_ERR,
"Failed to read a register (index 0x%04X, error %d)", "Failed to read a register (index 0x%04X, error %d)",
@ -240,10 +240,9 @@ int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index)
return res; return res;
} }
return buff; return gspca_dev->usb_buf[0];
} }
/* this function is called at probe time */ /* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev, static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id) const struct usb_device_id *id)

View File

@ -23,8 +23,8 @@
#include "gspca.h" #include "gspca.h"
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.5"; static const char version[] = "2.1.7";
MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
MODULE_DESCRIPTION("Pixart PAC7311"); MODULE_DESCRIPTION("Pixart PAC7311");
@ -206,46 +206,43 @@ static const __u8 pac7311_jpeg_header[] = {
0x11, 0x00, 0x3f, 0x00 0x11, 0x00, 0x3f, 0x00
}; };
static void reg_w(struct usb_device *dev, static void reg_w_buf(struct gspca_dev *gspca_dev,
__u16 index, __u16 index,
const char *buffer, __u16 len) const char *buffer, __u16 len)
{ {
__u8 tmpbuf[8]; memcpy(gspca_dev->usb_buf, buffer, len);
usb_control_msg(gspca_dev->dev,
memcpy(tmpbuf, buffer, len); usb_sndctrlpipe(gspca_dev->dev, 0),
usb_control_msg(dev,
usb_sndctrlpipe(dev, 0),
1, /* request */ 1, /* request */
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */ 0, /* value */
index, tmpbuf, len, index, gspca_dev->usb_buf, len,
500); 500);
} }
static void pac7311_reg_read(struct usb_device *dev, __u16 index, static __u8 reg_r(struct gspca_dev *gspca_dev,
__u8 *buffer) __u16 index)
{ {
usb_control_msg(dev, usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(dev, 0), usb_rcvctrlpipe(gspca_dev->dev, 0),
0, /* request */ 0, /* request */
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */ 0, /* value */
index, buffer, 1, index, gspca_dev->usb_buf, 1,
500); 500);
return gspca_dev->usb_buf[0];
} }
static void pac7311_reg_write(struct usb_device *dev, static void reg_w(struct gspca_dev *gspca_dev,
__u16 index, __u16 index,
__u8 value) __u8 value)
{ {
__u8 buf; gspca_dev->usb_buf[0] = value;
usb_control_msg(gspca_dev->dev,
buf = value; usb_sndctrlpipe(gspca_dev->dev, 0),
usb_control_msg(dev,
usb_sndctrlpipe(dev, 0),
0, /* request */ 0, /* request */
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, index, &buf, 1, value, index, gspca_dev->usb_buf, 1,
500); 500);
} }
@ -254,20 +251,19 @@ static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
struct cam *cam; struct cam *cam;
PDEBUG(D_CONF, "Find Sensor PAC7311"); PDEBUG(D_CONF, "Find Sensor PAC7311");
pac7311_reg_write(dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */ reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */
pac7311_reg_write(dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */ reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */
pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
pac7311_reg_write(dev, 0xff, 0x04); reg_w(gspca_dev, 0xff, 0x04);
pac7311_reg_write(dev, 0x27, 0x80); reg_w(gspca_dev, 0x27, 0x80);
pac7311_reg_write(dev, 0x28, 0xca); reg_w(gspca_dev, 0x28, 0xca);
pac7311_reg_write(dev, 0x29, 0x53); reg_w(gspca_dev, 0x29, 0x53);
pac7311_reg_write(dev, 0x2a, 0x0e); reg_w(gspca_dev, 0x2a, 0x0e);
pac7311_reg_write(dev, 0xff, 0x01); reg_w(gspca_dev, 0xff, 0x01);
pac7311_reg_write(dev, 0x3e, 0x20); reg_w(gspca_dev, 0x3e, 0x20);
cam = &gspca_dev->cam; cam = &gspca_dev->cam;
cam->dev_name = (char *) id->driver_info; cam->dev_name = (char *) id->driver_info;
@ -289,11 +285,11 @@ static void setbrightness(struct gspca_dev *gspca_dev)
/*jfm: inverted?*/ /*jfm: inverted?*/
brightness = BRIGHTNESS_MAX - sd->brightness; brightness = BRIGHTNESS_MAX - sd->brightness;
pac7311_reg_write(gspca_dev->dev, 0xff, 0x04); reg_w(gspca_dev, 0xff, 0x04);
/* pac7311_reg_write(gspca_dev->dev, 0x0e, 0x00); */ /* reg_w(gspca_dev, 0x0e, 0x00); */
pac7311_reg_write(gspca_dev->dev, 0x0f, brightness); reg_w(gspca_dev, 0x0f, brightness);
/* load registers to sensor (Bit 0, auto clear) */ /* load registers to sensor (Bit 0, auto clear) */
pac7311_reg_write(gspca_dev->dev, 0x11, 0x01); reg_w(gspca_dev, 0x11, 0x01);
PDEBUG(D_CONF|D_STREAM, "brightness: %i", brightness); PDEBUG(D_CONF|D_STREAM, "brightness: %i", brightness);
} }
@ -301,10 +297,10 @@ static void setcontrast(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
pac7311_reg_write(gspca_dev->dev, 0xff, 0x01); reg_w(gspca_dev, 0xff, 0x01);
pac7311_reg_write(gspca_dev->dev, 0x80, sd->contrast); reg_w(gspca_dev, 0x80, sd->contrast);
/* load registers to sensor (Bit 0, auto clear) */ /* load registers to sensor (Bit 0, auto clear) */
pac7311_reg_write(gspca_dev->dev, 0x11, 0x01); reg_w(gspca_dev, 0x11, 0x01);
PDEBUG(D_CONF|D_STREAM, "contrast: %i", sd->contrast); PDEBUG(D_CONF|D_STREAM, "contrast: %i", sd->contrast);
} }
@ -312,94 +308,93 @@ static void setcolors(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
pac7311_reg_write(gspca_dev->dev, 0xff, 0x01); reg_w(gspca_dev, 0xff, 0x01);
pac7311_reg_write(gspca_dev->dev, 0x10, sd->colors); reg_w(gspca_dev, 0x10, sd->colors);
/* load registers to sensor (Bit 0, auto clear) */ /* load registers to sensor (Bit 0, auto clear) */
pac7311_reg_write(gspca_dev->dev, 0x11, 0x01); reg_w(gspca_dev, 0x11, 0x01);
PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
} }
/* this function is called at open time */ /* this function is called at open time */
static int sd_open(struct gspca_dev *gspca_dev) static int sd_open(struct gspca_dev *gspca_dev)
{ {
pac7311_reg_write(gspca_dev->dev, 0x78, 0x00); /* Turn on LED */ reg_w(gspca_dev, 0x78, 0x00); /* Turn on LED */
return 0; return 0;
} }
static void sd_start(struct gspca_dev *gspca_dev) static void sd_start(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev;
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
pac7311_reg_write(dev, 0xff, 0x01); reg_w(gspca_dev, 0xff, 0x01);
reg_w(dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8);
reg_w(dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8);
reg_w(dev, 0x0012, "\x00\x07\x00\x0a\x10\x00\xa0\x10", 8); reg_w_buf(gspca_dev, 0x0012, "\x00\x07\x00\x0a\x10\x00\xa0\x10", 8);
reg_w(dev, 0x001a, "\x02\x00\x00\x00\x00\x0b\x01\x00", 8); reg_w_buf(gspca_dev, 0x001a, "\x02\x00\x00\x00\x00\x0b\x01\x00", 8);
reg_w(dev, 0x0022, "\x00\x00\x00\x00\x00\x00\x00\x00", 8); reg_w_buf(gspca_dev, 0x0022, "\x00\x00\x00\x00\x00\x00\x00\x00", 8);
reg_w(dev, 0x002a, "\x00\x00\x00", 3); reg_w_buf(gspca_dev, 0x002a, "\x00\x00\x00", 3);
reg_w(dev, 0x003e, "\x00\x00\x78\x52\x4a\x52\x78\x6e", 8); reg_w_buf(gspca_dev, 0x003e, "\x00\x00\x78\x52\x4a\x52\x78\x6e", 8);
reg_w(dev, 0x0046, "\x48\x46\x48\x6e\x5f\x49\x42\x49", 8); reg_w_buf(gspca_dev, 0x0046, "\x48\x46\x48\x6e\x5f\x49\x42\x49", 8);
reg_w(dev, 0x004e, "\x5f\x5f\x49\x42\x49\x5f\x6e\x48", 8); reg_w_buf(gspca_dev, 0x004e, "\x5f\x5f\x49\x42\x49\x5f\x6e\x48", 8);
reg_w(dev, 0x0056, "\x46\x48\x6e\x78\x52\x4a\x52\x78", 8); reg_w_buf(gspca_dev, 0x0056, "\x46\x48\x6e\x78\x52\x4a\x52\x78", 8);
reg_w(dev, 0x005e, "\x00\x00\x09\x1b\x34\x49\x5c\x9b", 8); reg_w_buf(gspca_dev, 0x005e, "\x00\x00\x09\x1b\x34\x49\x5c\x9b", 8);
reg_w(dev, 0x0066, "\xd0\xff", 2); reg_w_buf(gspca_dev, 0x0066, "\xd0\xff", 2);
reg_w(dev, 0x0078, "\x44\x00\xf2\x01\x01\x80", 6); reg_w_buf(gspca_dev, 0x0078, "\x44\x00\xf2\x01\x01\x80", 6);
reg_w(dev, 0x007f, "\x2a\x1c\x00\xc8\x02\x58\x03\x84", 8); reg_w_buf(gspca_dev, 0x007f, "\x2a\x1c\x00\xc8\x02\x58\x03\x84", 8);
reg_w(dev, 0x0087, "\x12\x00\x1a\x04\x08\x0c\x10\x14", 8); reg_w_buf(gspca_dev, 0x0087, "\x12\x00\x1a\x04\x08\x0c\x10\x14", 8);
reg_w(dev, 0x008f, "\x18\x20", 2); reg_w_buf(gspca_dev, 0x008f, "\x18\x20", 2);
reg_w(dev, 0x0096, "\x01\x08\x04", 3); reg_w_buf(gspca_dev, 0x0096, "\x01\x08\x04", 3);
reg_w(dev, 0x00a0, "\x44\x44\x44\x04", 4); reg_w_buf(gspca_dev, 0x00a0, "\x44\x44\x44\x04", 4);
reg_w(dev, 0x00f0, "\x01\x00\x00\x00\x22\x00\x20\x00", 8); reg_w_buf(gspca_dev, 0x00f0, "\x01\x00\x00\x00\x22\x00\x20\x00", 8);
reg_w(dev, 0x00f8, "\x3f\x00\x0a\x01\x00", 5); reg_w_buf(gspca_dev, 0x00f8, "\x3f\x00\x0a\x01\x00", 5);
pac7311_reg_write(dev, 0xff, 0x04); reg_w(gspca_dev, 0xff, 0x04);
pac7311_reg_write(dev, 0x02, 0x04); reg_w(gspca_dev, 0x02, 0x04);
pac7311_reg_write(dev, 0x03, 0x54); reg_w(gspca_dev, 0x03, 0x54);
pac7311_reg_write(dev, 0x04, 0x07); reg_w(gspca_dev, 0x04, 0x07);
pac7311_reg_write(dev, 0x05, 0x2b); reg_w(gspca_dev, 0x05, 0x2b);
pac7311_reg_write(dev, 0x06, 0x09); reg_w(gspca_dev, 0x06, 0x09);
pac7311_reg_write(dev, 0x07, 0x0f); reg_w(gspca_dev, 0x07, 0x0f);
pac7311_reg_write(dev, 0x08, 0x09); reg_w(gspca_dev, 0x08, 0x09);
pac7311_reg_write(dev, 0x09, 0x00); reg_w(gspca_dev, 0x09, 0x00);
pac7311_reg_write(dev, 0x0c, 0x07); reg_w(gspca_dev, 0x0c, 0x07);
pac7311_reg_write(dev, 0x0d, 0x00); reg_w(gspca_dev, 0x0d, 0x00);
pac7311_reg_write(dev, 0x0e, 0x00); reg_w(gspca_dev, 0x0e, 0x00);
pac7311_reg_write(dev, 0x0f, 0x62); reg_w(gspca_dev, 0x0f, 0x62);
pac7311_reg_write(dev, 0x10, 0x08); reg_w(gspca_dev, 0x10, 0x08);
pac7311_reg_write(dev, 0x12, 0x07); reg_w(gspca_dev, 0x12, 0x07);
pac7311_reg_write(dev, 0x13, 0x00); reg_w(gspca_dev, 0x13, 0x00);
pac7311_reg_write(dev, 0x14, 0x00); reg_w(gspca_dev, 0x14, 0x00);
pac7311_reg_write(dev, 0x15, 0x00); reg_w(gspca_dev, 0x15, 0x00);
pac7311_reg_write(dev, 0x16, 0x00); reg_w(gspca_dev, 0x16, 0x00);
pac7311_reg_write(dev, 0x17, 0x00); reg_w(gspca_dev, 0x17, 0x00);
pac7311_reg_write(dev, 0x18, 0x00); reg_w(gspca_dev, 0x18, 0x00);
pac7311_reg_write(dev, 0x19, 0x00); reg_w(gspca_dev, 0x19, 0x00);
pac7311_reg_write(dev, 0x1a, 0x00); reg_w(gspca_dev, 0x1a, 0x00);
pac7311_reg_write(dev, 0x1b, 0x03); reg_w(gspca_dev, 0x1b, 0x03);
pac7311_reg_write(dev, 0x1c, 0xa0); reg_w(gspca_dev, 0x1c, 0xa0);
pac7311_reg_write(dev, 0x1d, 0x01); reg_w(gspca_dev, 0x1d, 0x01);
pac7311_reg_write(dev, 0x1e, 0xf4); reg_w(gspca_dev, 0x1e, 0xf4);
pac7311_reg_write(dev, 0x21, 0x00); reg_w(gspca_dev, 0x21, 0x00);
pac7311_reg_write(dev, 0x22, 0x08); reg_w(gspca_dev, 0x22, 0x08);
pac7311_reg_write(dev, 0x24, 0x03); reg_w(gspca_dev, 0x24, 0x03);
pac7311_reg_write(dev, 0x26, 0x00); reg_w(gspca_dev, 0x26, 0x00);
pac7311_reg_write(dev, 0x27, 0x01); reg_w(gspca_dev, 0x27, 0x01);
pac7311_reg_write(dev, 0x28, 0xca); reg_w(gspca_dev, 0x28, 0xca);
pac7311_reg_write(dev, 0x29, 0x10); reg_w(gspca_dev, 0x29, 0x10);
pac7311_reg_write(dev, 0x2a, 0x06); reg_w(gspca_dev, 0x2a, 0x06);
pac7311_reg_write(dev, 0x2b, 0x78); reg_w(gspca_dev, 0x2b, 0x78);
pac7311_reg_write(dev, 0x2c, 0x00); reg_w(gspca_dev, 0x2c, 0x00);
pac7311_reg_write(dev, 0x2d, 0x00); reg_w(gspca_dev, 0x2d, 0x00);
pac7311_reg_write(dev, 0x2e, 0x00); reg_w(gspca_dev, 0x2e, 0x00);
pac7311_reg_write(dev, 0x2f, 0x00); reg_w(gspca_dev, 0x2f, 0x00);
pac7311_reg_write(dev, 0x30, 0x23); reg_w(gspca_dev, 0x30, 0x23);
pac7311_reg_write(dev, 0x31, 0x28); reg_w(gspca_dev, 0x31, 0x28);
pac7311_reg_write(dev, 0x32, 0x04); reg_w(gspca_dev, 0x32, 0x04);
pac7311_reg_write(dev, 0x33, 0x11); reg_w(gspca_dev, 0x33, 0x11);
pac7311_reg_write(dev, 0x34, 0x00); reg_w(gspca_dev, 0x34, 0x00);
pac7311_reg_write(dev, 0x35, 0x00); reg_w(gspca_dev, 0x35, 0x00);
pac7311_reg_write(dev, 0x11, 0x01); reg_w(gspca_dev, 0x11, 0x01);
setcontrast(gspca_dev); setcontrast(gspca_dev);
setbrightness(gspca_dev); setbrightness(gspca_dev);
setcolors(gspca_dev); setcolors(gspca_dev);
@ -407,39 +402,39 @@ static void sd_start(struct gspca_dev *gspca_dev)
/* set correct resolution */ /* set correct resolution */
switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
case 2: /* 160x120 */ case 2: /* 160x120 */
pac7311_reg_write(dev, 0xff, 0x04); reg_w(gspca_dev, 0xff, 0x04);
pac7311_reg_write(dev, 0x02, 0x03); reg_w(gspca_dev, 0x02, 0x03);
pac7311_reg_write(dev, 0xff, 0x01); reg_w(gspca_dev, 0xff, 0x01);
pac7311_reg_write(dev, 0x08, 0x09); reg_w(gspca_dev, 0x08, 0x09);
pac7311_reg_write(dev, 0x17, 0x20); reg_w(gspca_dev, 0x17, 0x20);
pac7311_reg_write(dev, 0x1b, 0x00); reg_w(gspca_dev, 0x1b, 0x00);
/* pac7311_reg_write(dev, 0x80, 0x69); */ /* reg_w(gspca_dev, 0x80, 0x69); */
pac7311_reg_write(dev, 0x87, 0x10); reg_w(gspca_dev, 0x87, 0x10);
break; break;
case 1: /* 320x240 */ case 1: /* 320x240 */
pac7311_reg_write(dev, 0xff, 0x04); reg_w(gspca_dev, 0xff, 0x04);
pac7311_reg_write(dev, 0x02, 0x03); reg_w(gspca_dev, 0x02, 0x03);
pac7311_reg_write(dev, 0xff, 0x01); reg_w(gspca_dev, 0xff, 0x01);
pac7311_reg_write(dev, 0x08, 0x09); reg_w(gspca_dev, 0x08, 0x09);
pac7311_reg_write(dev, 0x17, 0x30); reg_w(gspca_dev, 0x17, 0x30);
/* pac7311_reg_write(dev, 0x80, 0x3f); */ /* reg_w(gspca_dev, 0x80, 0x3f); */
pac7311_reg_write(dev, 0x87, 0x11); reg_w(gspca_dev, 0x87, 0x11);
break; break;
case 0: /* 640x480 */ case 0: /* 640x480 */
pac7311_reg_write(dev, 0xff, 0x04); reg_w(gspca_dev, 0xff, 0x04);
pac7311_reg_write(dev, 0x02, 0x03); reg_w(gspca_dev, 0x02, 0x03);
pac7311_reg_write(dev, 0xff, 0x01); reg_w(gspca_dev, 0xff, 0x01);
pac7311_reg_write(dev, 0x08, 0x08); reg_w(gspca_dev, 0x08, 0x08);
pac7311_reg_write(dev, 0x17, 0x00); reg_w(gspca_dev, 0x17, 0x00);
/* pac7311_reg_write(dev, 0x80, 0x1c); */ /* reg_w(gspca_dev, 0x80, 0x1c); */
pac7311_reg_write(dev, 0x87, 0x12); reg_w(gspca_dev, 0x87, 0x12);
break; break;
} }
/* start stream */ /* start stream */
pac7311_reg_write(dev, 0xff, 0x01); reg_w(gspca_dev, 0xff, 0x01);
pac7311_reg_write(dev, 0x78, 0x04); reg_w(gspca_dev, 0x78, 0x04);
pac7311_reg_write(dev, 0x78, 0x05); reg_w(gspca_dev, 0x78, 0x05);
if (sd->autogain) { if (sd->autogain) {
sd->ag_cnt = AG_CNT_START; sd->ag_cnt = AG_CNT_START;
@ -451,18 +446,16 @@ static void sd_start(struct gspca_dev *gspca_dev)
static void sd_stopN(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev; reg_w(gspca_dev, 0xff, 0x04);
reg_w(gspca_dev, 0x27, 0x80);
pac7311_reg_write(dev, 0xff, 0x04); reg_w(gspca_dev, 0x28, 0xca);
pac7311_reg_write(dev, 0x27, 0x80); reg_w(gspca_dev, 0x29, 0x53);
pac7311_reg_write(dev, 0x28, 0xca); reg_w(gspca_dev, 0x2a, 0x0e);
pac7311_reg_write(dev, 0x29, 0x53); reg_w(gspca_dev, 0xff, 0x01);
pac7311_reg_write(dev, 0x2a, 0x0e); reg_w(gspca_dev, 0x3e, 0x20);
pac7311_reg_write(dev, 0xff, 0x01); reg_w(gspca_dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */
pac7311_reg_write(dev, 0x3e, 0x20); reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
pac7311_reg_write(dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */ reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
} }
static void sd_stop0(struct gspca_dev *gspca_dev) static void sd_stop0(struct gspca_dev *gspca_dev)
@ -472,18 +465,16 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
/* this function is called at close time */ /* this function is called at close time */
static void sd_close(struct gspca_dev *gspca_dev) static void sd_close(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev; reg_w(gspca_dev, 0xff, 0x04);
reg_w(gspca_dev, 0x27, 0x80);
pac7311_reg_write(dev, 0xff, 0x04); reg_w(gspca_dev, 0x28, 0xca);
pac7311_reg_write(dev, 0x27, 0x80); reg_w(gspca_dev, 0x29, 0x53);
pac7311_reg_write(dev, 0x28, 0xca); reg_w(gspca_dev, 0x2a, 0x0e);
pac7311_reg_write(dev, 0x29, 0x53); reg_w(gspca_dev, 0xff, 0x01);
pac7311_reg_write(dev, 0x2a, 0x0e); reg_w(gspca_dev, 0x3e, 0x20);
pac7311_reg_write(dev, 0xff, 0x01); reg_w(gspca_dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */
pac7311_reg_write(dev, 0x3e, 0x20); reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
pac7311_reg_write(dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */ reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
} }
static void setautogain(struct gspca_dev *gspca_dev, int luma) static void setautogain(struct gspca_dev *gspca_dev, int luma)
@ -491,11 +482,9 @@ static void setautogain(struct gspca_dev *gspca_dev, int luma)
int luma_mean = 128; int luma_mean = 128;
int luma_delta = 20; int luma_delta = 20;
__u8 spring = 5; __u8 spring = 5;
__u8 Pxclk;
int Gbright; int Gbright;
pac7311_reg_read(gspca_dev->dev, 0x02, &Pxclk); Gbright = reg_r(gspca_dev, 0x02);
Gbright = Pxclk;
PDEBUG(D_FRAM, "luma mean %d", luma); PDEBUG(D_FRAM, "luma mean %d", luma);
if (luma < luma_mean - luma_delta || if (luma < luma_mean - luma_delta ||
luma > luma_mean + luma_delta) { luma > luma_mean + luma_delta) {
@ -505,10 +494,10 @@ static void setautogain(struct gspca_dev *gspca_dev, int luma)
else if (Gbright < 4) else if (Gbright < 4)
Gbright = 4; Gbright = 4;
PDEBUG(D_FRAM, "gbright %d", Gbright); PDEBUG(D_FRAM, "gbright %d", Gbright);
pac7311_reg_write(gspca_dev->dev, 0xff, 0x04); reg_w(gspca_dev, 0xff, 0x04);
pac7311_reg_write(gspca_dev->dev, 0x0f, Gbright); reg_w(gspca_dev, 0x0f, Gbright);
/* load registers to sensor (Bit 0, auto clear) */ /* load registers to sensor (Bit 0, auto clear) */
pac7311_reg_write(gspca_dev->dev, 0x11, 0x01); reg_w(gspca_dev, 0x11, 0x01);
} }
} }
@ -623,11 +612,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
static void getbrightness(struct gspca_dev *gspca_dev) static void getbrightness(struct gspca_dev *gspca_dev)
{ {
/* __u8 brightness = 0; /* sd->brightness = reg_r(gspca_dev, 0x08);
return sd->brightness; */
pac7311_reg_read(gspca_dev->dev, 0x0008, &brightness);
spca50x->brightness = brightness;
return spca50x->brightness; */
/* PDEBUG(D_CONF, "Called pac7311_getbrightness: Not implemented yet"); */ /* PDEBUG(D_CONF, "Called pac7311_getbrightness: Not implemented yet"); */
} }

View File

@ -384,64 +384,82 @@ static const __u8 tas5130_sensor_init[][8] = {
{0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}, {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
}; };
static void reg_r(struct usb_device *dev, /* get one byte in gspca_dev->usb_buf */
__u16 value, __u8 *buffer) static void reg_r(struct gspca_dev *gspca_dev,
__u16 value)
{ {
usb_control_msg(dev, usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(dev, 0), usb_rcvctrlpipe(gspca_dev->dev, 0),
0, /* request */ 0, /* request */
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
value, value,
0, /* index */ 0, /* index */
buffer, 1, gspca_dev->usb_buf, 1,
500); 500);
} }
static void reg_w(struct usb_device *dev, static void reg_w(struct gspca_dev *gspca_dev,
__u16 value, __u16 value,
const __u8 *buffer, const __u8 *buffer,
int len) int len)
{ {
__u8 tmpbuf[48];
#ifdef CONFIG_VIDEO_ADV_DEBUG #ifdef CONFIG_VIDEO_ADV_DEBUG
if (len > sizeof tmpbuf) { if (len > sizeof gspca_dev->usb_buf) {
PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
return; return;
} }
#endif #endif
memcpy(gspca_dev->usb_buf, 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 */
gspca_dev->usb_buf, len,
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); memcpy(tmpbuf, buffer, len);
usb_control_msg(dev, usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(dev, 0), usb_sndctrlpipe(gspca_dev->dev, 0),
0x08, /* request */ 0x08, /* request */
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
value, value,
0, /* index */ 0, /* index */
tmpbuf, len, tmpbuf, len,
500); 500);
kfree(tmpbuf);
} }
static int i2c_w(struct usb_device *dev, const __u8 *buffer) static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
{ {
int retry = 60; int retry = 60;
__u8 ByteReceive;
/* is i2c ready */ /* is i2c ready */
reg_w(dev, 0x08, buffer, 8); reg_w(gspca_dev, 0x08, buffer, 8);
while (retry--) { while (retry--) {
msleep(10); msleep(10);
reg_r(dev, 0x08, &ByteReceive); reg_r(gspca_dev, 0x08);
if (ByteReceive == 4) if (gspca_dev->usb_buf[0] == 4)
return 0; return 0;
} }
return -1; return -1;
} }
static void i2c_w_vector(struct usb_device *dev, static void i2c_w_vector(struct gspca_dev *gspca_dev,
const __u8 buffer[][8], int len) const __u8 buffer[][8], int len)
{ {
for (;;) { for (;;) {
reg_w(dev, 0x08, *buffer, 8); reg_w(gspca_dev, 0x08, *buffer, 8);
len -= 8; len -= 8;
if (len <= 0) if (len <= 0)
break; break;
@ -460,7 +478,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
{0xa0, 0x60, 0x06, 0x11, 0x99, 0x04, 0x94, 0x15}; {0xa0, 0x60, 0x06, 0x11, 0x99, 0x04, 0x94, 0x15};
i2cOV6650[3] = sd->brightness; i2cOV6650[3] = sd->brightness;
if (i2c_w(gspca_dev->dev, i2cOV6650) < 0) if (i2c_w(gspca_dev, i2cOV6650) < 0)
goto err; goto err;
break; break;
} }
@ -470,7 +488,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
/* change reg 0x06 */ /* change reg 0x06 */
i2cOV[3] = sd->brightness; i2cOV[3] = sd->brightness;
if (i2c_w(gspca_dev->dev, i2cOV) < 0) if (i2c_w(gspca_dev, i2cOV) < 0)
goto err; goto err;
break; break;
} }
@ -480,11 +498,11 @@ static void setbrightness(struct gspca_dev *gspca_dev)
i2c1[3] = sd->brightness >> 3; i2c1[3] = sd->brightness >> 3;
i2c1[2] = 0x0e; i2c1[2] = 0x0e;
if (i2c_w(gspca_dev->dev, i2c1) < 0) if (i2c_w(gspca_dev, i2c1) < 0)
goto err; goto err;
i2c1[3] = 0x01; i2c1[3] = 0x01;
i2c1[2] = 0x13; i2c1[2] = 0x13;
if (i2c_w(gspca_dev->dev, i2c1) < 0) if (i2c_w(gspca_dev, i2c1) < 0)
goto err; goto err;
break; break;
} }
@ -500,18 +518,18 @@ static void setbrightness(struct gspca_dev *gspca_dev)
/* change reg 0x10 */ /* change reg 0x10 */
i2cpexpo[4] = 0xff - sd->brightness; i2cpexpo[4] = 0xff - sd->brightness;
/* if(i2c_w(gspca_dev->dev,i2cpexpo1) < 0) /* if(i2c_w(gspca_dev,i2cpexpo1) < 0)
goto err; */ goto err; */
/* if(i2c_w(gspca_dev->dev,i2cpdoit) < 0) /* if(i2c_w(gspca_dev,i2cpdoit) < 0)
goto err; */ goto err; */
if (i2c_w(gspca_dev->dev, i2cpexpo) < 0) if (i2c_w(gspca_dev, i2cpexpo) < 0)
goto err; goto err;
if (i2c_w(gspca_dev->dev, i2cpdoit) < 0) if (i2c_w(gspca_dev, i2cpdoit) < 0)
goto err; goto err;
i2cp202[3] = sd->brightness >> 3; i2cp202[3] = sd->brightness >> 3;
if (i2c_w(gspca_dev->dev, i2cp202) < 0) if (i2c_w(gspca_dev, i2cp202) < 0)
goto err; goto err;
if (i2c_w(gspca_dev->dev, i2cpdoit) < 0) if (i2c_w(gspca_dev, i2cpdoit) < 0)
goto err; goto err;
break; break;
} }
@ -522,7 +540,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
value = 0xff - sd->brightness; value = 0xff - sd->brightness;
i2c[4] = value; i2c[4] = value;
PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]); PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
if (i2c_w(gspca_dev->dev, i2c) < 0) if (i2c_w(gspca_dev, i2c) < 0)
goto err; goto err;
break; break;
} }
@ -551,14 +569,14 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
{0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
i2c[4] = 255 - gain; i2c[4] = 255 - gain;
if (i2c_w(gspca_dev->dev, i2c) < 0) if (i2c_w(gspca_dev, i2c) < 0)
goto err; goto err;
break; break;
} }
case SENSOR_OV6650: { case SENSOR_OV6650: {
__u8 i2c[] = {0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; __u8 i2c[] = {0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
i2c[3] = gain; i2c[3] = gain;
if (i2c_w(gspca_dev->dev, i2c) < 0) if (i2c_w(gspca_dev, i2c) < 0)
goto err; goto err;
break; break;
} }
@ -578,10 +596,10 @@ static void setgain(struct gspca_dev *gspca_dev)
/* red and blue gain */ /* red and blue gain */
rgb_value = gain << 4 | gain; rgb_value = gain << 4 | gain;
reg_w(gspca_dev->dev, 0x10, &rgb_value, 1); reg_w(gspca_dev, 0x10, &rgb_value, 1);
/* green gain */ /* green gain */
rgb_value = gain; rgb_value = gain;
reg_w(gspca_dev->dev, 0x11, &rgb_value, 1); reg_w(gspca_dev, 0x11, &rgb_value, 1);
if (sd->sensor_has_gain) if (sd->sensor_has_gain)
setsensorgain(gspca_dev); setsensorgain(gspca_dev);
@ -604,7 +622,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
if (reg > 15) if (reg > 15)
reg = 15; reg = 15;
reg = (reg << 4) | 0x0b; reg = (reg << 4) | 0x0b;
reg_w(gspca_dev->dev, 0x19, &reg, 1); reg_w(gspca_dev, 0x19, &reg, 1);
break; break;
} }
case SENSOR_OV6650: { case SENSOR_OV6650: {
@ -613,7 +631,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
if (i2c[3] > 15) if (i2c[3] > 15)
i2c[3] = 15; i2c[3] = 15;
i2c[3] |= 0xc0; i2c[3] |= 0xc0;
if (i2c_w(gspca_dev->dev, i2c) < 0) if (i2c_w(gspca_dev, i2c) < 0)
PDEBUG(D_ERR, "i2c error exposure"); PDEBUG(D_ERR, "i2c error exposure");
break; break;
} }
@ -721,22 +739,20 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->exposure = EXPOSURE_DEF; sd->exposure = EXPOSURE_DEF;
sd->autogain = AUTOGAIN_DEF; sd->autogain = AUTOGAIN_DEF;
if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */ if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */
reg_w(gspca_dev->dev, 0x01, probe_ov7630, sizeof probe_ov7630); reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630);
return 0; return 0;
} }
/* this function is called at open time */ /* this function is called at open time */
static int sd_open(struct gspca_dev *gspca_dev) static int sd_open(struct gspca_dev *gspca_dev)
{ {
__u8 ByteReceive; reg_r(gspca_dev, 0x00);
if (gspca_dev->usb_buf[0] != 0x10)
reg_r(gspca_dev->dev, 0x00, &ByteReceive);
if (ByteReceive != 0x10)
return -ENODEV; return -ENODEV;
return 0; return 0;
} }
static void pas106_i2cinit(struct usb_device *dev) static void pas106_i2cinit(struct gspca_dev *gspca_dev)
{ {
int i; int i;
const __u8 *data; const __u8 *data;
@ -747,7 +763,7 @@ static void pas106_i2cinit(struct usb_device *dev)
while (--i >= 0) { while (--i >= 0) {
memcpy(&i2c1[2], data, 2); memcpy(&i2c1[2], data, 2);
/* copy 2 bytes from the template */ /* copy 2 bytes from the template */
if (i2c_w(dev, i2c1) < 0) if (i2c_w(gspca_dev, i2c1) < 0)
PDEBUG(D_ERR, "i2c error pas106"); PDEBUG(D_ERR, "i2c error pas106");
data += 2; data += 2;
} }
@ -757,7 +773,6 @@ static void pas106_i2cinit(struct usb_device *dev)
static void sd_start(struct gspca_dev *gspca_dev) static void sd_start(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
int mode, l; int mode, l;
const __u8 *sn9c10x; const __u8 *sn9c10x;
__u8 reg01, reg17; __u8 reg01, reg17;
@ -835,75 +850,75 @@ static void sd_start(struct gspca_dev *gspca_dev)
} }
/* reg 0x01 bit 2 video transfert on */ /* reg 0x01 bit 2 video transfert on */
reg_w(dev, 0x01, &reg01, 1); reg_w(gspca_dev, 0x01, &reg01, 1);
/* reg 0x17 SensorClk enable inv Clk 0x60 */ /* reg 0x17 SensorClk enable inv Clk 0x60 */
reg_w(dev, 0x17, &reg17, 1); reg_w(gspca_dev, 0x17, &reg17, 1);
/*fixme: for ov7630 102 /*fixme: for ov7630 102
reg_w(dev, 0x01, {0x06, sn9c10x[1]}, 2); */ reg_w(gspca_dev, 0x01, {0x06, sn9c10x[1]}, 2); */
/* Set the registers from the template */ /* Set the registers from the template */
reg_w(dev, 0x01, sn9c10x, l); reg_w_big(gspca_dev, 0x01, sn9c10x, l);
switch (sd->sensor) { switch (sd->sensor) {
case SENSOR_HV7131R: case SENSOR_HV7131R:
i2c_w_vector(dev, hv7131_sensor_init, i2c_w_vector(gspca_dev, hv7131_sensor_init,
sizeof hv7131_sensor_init); sizeof hv7131_sensor_init);
break; break;
case SENSOR_OV6650: case SENSOR_OV6650:
i2c_w_vector(dev, ov6650_sensor_init, i2c_w_vector(gspca_dev, ov6650_sensor_init,
sizeof ov6650_sensor_init); sizeof ov6650_sensor_init);
break; break;
case SENSOR_OV7630: case SENSOR_OV7630:
i2c_w_vector(dev, ov7630_sensor_init_com, i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
sizeof ov7630_sensor_init_com); sizeof ov7630_sensor_init_com);
msleep(200); msleep(200);
i2c_w_vector(dev, ov7630_sensor_init, i2c_w_vector(gspca_dev, ov7630_sensor_init,
sizeof ov7630_sensor_init); sizeof ov7630_sensor_init);
break; break;
case SENSOR_OV7630_3: case SENSOR_OV7630_3:
i2c_w_vector(dev, ov7630_sensor_init_com, i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
sizeof ov7630_sensor_init_com); sizeof ov7630_sensor_init_com);
msleep(200); msleep(200);
i2c_w_vector(dev, ov7630_sensor_init_3, i2c_w_vector(gspca_dev, ov7630_sensor_init_3,
sizeof ov7630_sensor_init_3); sizeof ov7630_sensor_init_3);
break; break;
case SENSOR_PAS106: case SENSOR_PAS106:
pas106_i2cinit(dev); pas106_i2cinit(gspca_dev);
break; break;
case SENSOR_PAS202: case SENSOR_PAS202:
i2c_w_vector(dev, pas202_sensor_init, i2c_w_vector(gspca_dev, pas202_sensor_init,
sizeof pas202_sensor_init); sizeof pas202_sensor_init);
break; break;
case SENSOR_TAS5110: case SENSOR_TAS5110:
i2c_w_vector(dev, tas5110_sensor_init, i2c_w_vector(gspca_dev, tas5110_sensor_init,
sizeof tas5110_sensor_init); sizeof tas5110_sensor_init);
break; break;
default: default:
/* case SENSOR_TAS5130CXX: */ /* case SENSOR_TAS5130CXX: */
i2c_w_vector(dev, tas5130_sensor_init, i2c_w_vector(gspca_dev, tas5130_sensor_init,
sizeof tas5130_sensor_init); sizeof tas5130_sensor_init);
break; break;
} }
/* H_size V_size 0x28, 0x1e maybe 640x480 */ /* H_size V_size 0x28, 0x1e maybe 640x480 */
reg_w(dev, 0x15, reg15, 2); reg_w(gspca_dev, 0x15, reg15, 2);
/* compression register */ /* compression register */
reg_w(dev, 0x18, &reg17_19[1], 1); reg_w(gspca_dev, 0x18, &reg17_19[1], 1);
if (sd->sensor != SENSOR_OV7630_3) { if (sd->sensor != SENSOR_OV7630_3) {
/* H_start */ /* H_start */
reg_w(dev, 0x12, &sn9c10x[0x12 - 1], 1); reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1);
/* V_START */ /* V_START */
reg_w(dev, 0x13, &sn9c10x[0x13 - 1], 1); reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1);
} }
/* reset 0x17 SensorClk enable inv Clk 0x60 */ /* reset 0x17 SensorClk enable inv Clk 0x60 */
/*fixme: ov7630 [17]=68 8f (+20 if 102)*/ /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
reg_w(dev, 0x17, &reg17_19[0], 1); reg_w(gspca_dev, 0x17, &reg17_19[0], 1);
/*MCKSIZE ->3 */ /*fixme: not ov7630*/ /*MCKSIZE ->3 */ /*fixme: not ov7630*/
if (sd->sensor != SENSOR_OV7630_3) if (sd->sensor != SENSOR_OV7630_3)
reg_w(dev, 0x19, &reg17_19[2], 1); reg_w(gspca_dev, 0x19, &reg17_19[2], 1);
/* AE_STRX AE_STRY AE_ENDX AE_ENDY */ /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
reg_w(dev, 0x1c, &sn9c10x[0x1c - 1], 4); reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
/* Enable video transfert */ /* Enable video transfert */
reg_w(dev, 0x01, &sn9c10x[0], 1); reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
/* Compression */ /* Compression */
reg_w(dev, 0x18, &reg17_19[1], 2); reg_w(gspca_dev, 0x18, &reg17_19[1], 2);
msleep(20); msleep(20);
setgain(gspca_dev); setgain(gspca_dev);
@ -919,7 +934,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
__u8 ByteSend; __u8 ByteSend;
ByteSend = 0x09; /* 0X00 */ ByteSend = 0x09; /* 0X00 */
reg_w(gspca_dev->dev, 0x01, &ByteSend, 1); reg_w(gspca_dev, 0x01, &ByteSend, 1);
} }
static void sd_stop0(struct gspca_dev *gspca_dev) static void sd_stop0(struct gspca_dev *gspca_dev)

View File

@ -24,8 +24,8 @@
#include "gspca.h" #include "gspca.h"
#include "jpeg.h" #include "jpeg.h"
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.5"; static const char version[] = "2.1.7";
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
@ -512,42 +512,40 @@ static const __u8 qtable4[] = {
0x29, 0x29, 0x29, 0x29 0x29, 0x29, 0x29, 0x29
}; };
static void reg_r(struct usb_device *dev, /* read <len> bytes (len < sizeof gspca_dev->usb_buf) to gspca_dev->usb_buf */
__u16 value, static void reg_r(struct gspca_dev *gspca_dev,
__u8 *buffer, int len) __u16 value, int len)
{ {
usb_control_msg(dev, usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(dev, 0), usb_rcvctrlpipe(gspca_dev->dev, 0),
0, 0,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
value, 0, value, 0,
buffer, len, gspca_dev->usb_buf, len,
500); 500);
} }
static void reg_w(struct usb_device *dev, static void reg_w(struct gspca_dev *gspca_dev,
__u16 value, __u16 value,
const __u8 *buffer, const __u8 *buffer,
int len) int len)
{ {
if (len < 16) { if (len <= sizeof gspca_dev->usb_buf) {
__u8 tmpbuf[16]; memcpy(gspca_dev->usb_buf, buffer, len);
usb_control_msg(gspca_dev->dev,
memcpy(tmpbuf, buffer, len); usb_sndctrlpipe(gspca_dev->dev, 0),
usb_control_msg(dev,
usb_sndctrlpipe(dev, 0),
0x08, 0x08,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
value, 0, value, 0,
tmpbuf, len, gspca_dev->usb_buf, len,
500); 500);
} else { } else {
__u8 *tmpbuf; __u8 *tmpbuf;
tmpbuf = kmalloc(len, GFP_KERNEL); tmpbuf = kmalloc(len, GFP_KERNEL);
memcpy(tmpbuf, buffer, len); memcpy(tmpbuf, buffer, len);
usb_control_msg(dev, usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(dev, 0), usb_sndctrlpipe(gspca_dev->dev, 0),
0x08, 0x08,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
value, 0, value, 0,
@ -557,12 +555,11 @@ static void reg_w(struct usb_device *dev,
} }
} }
/* write 2 bytes */ /* I2C write 2 bytes */
static void i2c_w2(struct gspca_dev *gspca_dev, static void i2c_w2(struct gspca_dev *gspca_dev,
const __u8 *buffer) const __u8 *buffer)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
__u8 mode[8]; __u8 mode[8];
/* is i2c ready */ /* is i2c ready */
@ -574,22 +571,21 @@ static void i2c_w2(struct gspca_dev *gspca_dev,
mode[5] = 0; mode[5] = 0;
mode[6] = 0; mode[6] = 0;
mode[7] = 0x10; mode[7] = 0x10;
reg_w(dev, 0x08, mode, 8); reg_w(gspca_dev, 0x08, mode, 8);
} }
/* write 8 bytes */ /* I2C write 8 bytes */
static void i2c_w8(struct usb_device *dev, const __u8 *buffer) static void i2c_w8(struct gspca_dev *gspca_dev,
const __u8 *buffer)
{ {
reg_w(dev, 0x08, buffer, 8); reg_w(gspca_dev, 0x08, buffer, 8);
msleep(1); msleep(1);
} }
/* read 5 bytes */ /* read 5 bytes in gspca_dev->usb_buf */
static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg, static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
__u8 *buffer)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
__u8 mode[8]; __u8 mode[8];
mode[0] = sd->i2c_ctrl_reg | 0x10; mode[0] = sd->i2c_ctrl_reg | 0x10;
@ -600,40 +596,39 @@ static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg,
mode[5] = 0; mode[5] = 0;
mode[6] = 0; mode[6] = 0;
mode[7] = 0x10; mode[7] = 0x10;
i2c_w8(dev, mode); i2c_w8(gspca_dev, mode);
mode[0] = sd->i2c_ctrl_reg | (5 << 4) | 0x02; mode[0] = sd->i2c_ctrl_reg | (5 << 4) | 0x02;
mode[2] = 0; mode[2] = 0;
i2c_w8(dev, mode); i2c_w8(gspca_dev, mode);
reg_r(dev, 0x0a, buffer, 5); reg_r(gspca_dev, 0x0a, 5);
} }
static int probesensor(struct gspca_dev *gspca_dev) static int probesensor(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
__u8 reg02; __u8 reg02;
static const __u8 datasend[] = { 2, 0 }; static const __u8 datasend[] = { 2, 0 };
/* reg val1 val2 val3 val4 */ /* reg val1 val2 val3 val4 */
__u8 datarecd[6];
i2c_w2(gspca_dev, datasend); i2c_w2(gspca_dev, datasend);
/* should write 0xa1 0x11 0x02 0x00 0x00 0x00 0x00 the 0x10 is add by i2cw */ /* should write 0xa1 0x11 0x02 0x00 0x00 0x00 0x00 the 0x10 is add by i2cw */
msleep(10); msleep(10);
reg02 = 0x66; reg02 = 0x66;
reg_w(dev, 0x02, &reg02, 1); /* Gpio on */ reg_w(gspca_dev, 0x02, &reg02, 1); /* Gpio on */
msleep(10); msleep(10);
i2c_r5(gspca_dev, 0, datarecd); /* read sensor id */ i2c_r5(gspca_dev, 0); /* read sensor id */
if (datarecd[0] == 0x02 if (gspca_dev->usb_buf[0] == 0x02
&& datarecd[1] == 0x09 && gspca_dev->usb_buf[1] == 0x09
&& datarecd[2] == 0x01 && gspca_dev->usb_buf[2] == 0x01
&& datarecd[3] == 0x00 && gspca_dev->usb_buf[3] == 0x00
&& datarecd[4] == 0x00) { && gspca_dev->usb_buf[4] == 0x00) {
PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R"); PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
sd->sensor = SENSOR_HV7131R; sd->sensor = SENSOR_HV7131R;
return SENSOR_HV7131R; return SENSOR_HV7131R;
} }
PDEBUG(D_PROBE, "Find Sensor %d %d %d", PDEBUG(D_PROBE, "Find Sensor %d %d %d",
datarecd[0], datarecd[1], datarecd[2]); gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
gspca_dev->usb_buf[2]);
PDEBUG(D_PROBE, "Sensor sn9c102P Not found"); PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
return -ENODEV; return -ENODEV;
} }
@ -642,7 +637,6 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
const __u8 *sn9c1xx) const __u8 *sn9c1xx)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
__u8 data; __u8 data;
__u8 regF1; __u8 regF1;
const __u8 *reg9a; const __u8 *reg9a;
@ -655,14 +649,15 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
regF1 = 0x00; regF1 = 0x00;
reg_w(dev, 0xf1, &regF1, 1); reg_w(gspca_dev, 0xf1, &regF1, 1);
reg_w(dev, 0x01, &sn9c1xx[0], 1); /*fixme:jfm was [1] en v1*/ reg_w(gspca_dev, 0x01, &sn9c1xx[0], 1);
/*fixme:jfm was [1] en v1*/
/* configure gpio */ /* configure gpio */
reg_w(dev, 0x01, &sn9c1xx[1], 2); reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
reg_w(dev, 0x08, &sn9c1xx[8], 2); reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
reg_w(dev, 0x17, &sn9c1xx[0x17], 3); reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 3);
switch (sd->customid) { switch (sd->customid) {
case SN9C325: case SN9C325:
reg9a = reg9a_sn9c325; reg9a = reg9a_sn9c325;
@ -674,37 +669,37 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
reg9a = reg9a_def; reg9a = reg9a_def;
break; break;
} }
reg_w(dev, 0x9a, reg9a, 6); reg_w(gspca_dev, 0x9a, reg9a, 6);
data = 0x60; /*fixme:jfm 60 00 00 (3) */ data = 0x60; /*fixme:jfm 60 00 00 (3) */
reg_w(dev, 0xd4, &data, 1); reg_w(gspca_dev, 0xd4, &data, 1);
reg_w(dev, 0x03, &sn9c1xx[3], 0x0f); reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
switch (sd->customid) { switch (sd->customid) {
case SN9C120: /* from win trace */ case SN9C120: /* from win trace */
data = 0x61; data = 0x61;
reg_w(dev, 0x01, &data, 1); reg_w(gspca_dev, 0x01, &data, 1);
data = 0x20; data = 0x20;
reg_w(dev, 0x17, &data, 1); reg_w(gspca_dev, 0x17, &data, 1);
data = 0x60; data = 0x60;
reg_w(dev, 0x01, &data, 1); reg_w(gspca_dev, 0x01, &data, 1);
break; break;
case SN9C325: case SN9C325:
data = 0x43; data = 0x43;
reg_w(dev, 0x01, &data, 1); reg_w(gspca_dev, 0x01, &data, 1);
data = 0xae; data = 0xae;
reg_w(dev, 0x17, &data, 1); reg_w(gspca_dev, 0x17, &data, 1);
data = 0x42; data = 0x42;
reg_w(dev, 0x01, &data, 1); reg_w(gspca_dev, 0x01, &data, 1);
break; break;
default: default:
data = 0x43; data = 0x43;
reg_w(dev, 0x01, &data, 1); reg_w(gspca_dev, 0x01, &data, 1);
data = 0x61; data = 0x61;
reg_w(dev, 0x17, &data, 1); reg_w(gspca_dev, 0x17, &data, 1);
data = 0x42; data = 0x42;
reg_w(dev, 0x01, &data, 1); reg_w(gspca_dev, 0x01, &data, 1);
} }
if (sd->sensor == SENSOR_HV7131R) { if (sd->sensor == SENSOR_HV7131R) {
@ -717,24 +712,22 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
static void hv7131R_InitSensor(struct gspca_dev *gspca_dev) static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
{ {
int i = 0; int i = 0;
struct usb_device *dev = gspca_dev->dev;
static const __u8 SetSensorClk[] = /* 0x08 Mclk */ static const __u8 SetSensorClk[] = /* 0x08 Mclk */
{ 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 }; { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
while (hv7131r_sensor_init[i][0]) { while (hv7131r_sensor_init[i][0]) {
i2c_w8(dev, hv7131r_sensor_init[i]); i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
i++; i++;
} }
i2c_w8(dev, SetSensorClk); i2c_w8(gspca_dev, SetSensorClk);
} }
static void mi0360_InitSensor(struct gspca_dev *gspca_dev) static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
{ {
int i = 0; int i = 0;
struct usb_device *dev = gspca_dev->dev;
while (mi0360_sensor_init[i][0]) { while (mi0360_sensor_init[i][0]) {
i2c_w8(dev, mi0360_sensor_init[i]); i2c_w8(gspca_dev, mi0360_sensor_init[i]);
i++; i++;
} }
} }
@ -742,21 +735,19 @@ static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
static void mo4000_InitSensor(struct gspca_dev *gspca_dev) static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
{ {
int i = 0; int i = 0;
struct usb_device *dev = gspca_dev->dev;
while (mo4000_sensor_init[i][0]) { while (mo4000_sensor_init[i][0]) {
i2c_w8(dev, mo4000_sensor_init[i]); i2c_w8(gspca_dev, mo4000_sensor_init[i]);
i++; i++;
} }
} }
static void ov7648_InitSensor(struct gspca_dev *gspca_dev) static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev;
int i = 0; int i = 0;
while (ov7648_sensor_init[i][0]) { while (ov7648_sensor_init[i][0]) {
i2c_w8(dev, ov7648_sensor_init[i]); i2c_w8(gspca_dev, ov7648_sensor_init[i]);
i++; i++;
} }
} }
@ -764,10 +755,9 @@ static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
static void ov7660_InitSensor(struct gspca_dev *gspca_dev) static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
{ {
int i = 0; int i = 0;
struct usb_device *dev = gspca_dev->dev;
while (ov7660_sensor_init[i][0]) { while (ov7660_sensor_init[i][0]) {
i2c_w8(dev, ov7660_sensor_init[i]); i2c_w8(gspca_dev, ov7660_sensor_init[i]);
i++; i++;
} }
} }
@ -1005,51 +995,52 @@ static int sd_config(struct gspca_dev *gspca_dev,
static int sd_open(struct gspca_dev *gspca_dev) static int sd_open(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
/* const __u8 *sn9c1xx; */ /* const __u8 *sn9c1xx; */
__u8 regF1; __u8 regF1;
__u8 regGpio[] = { 0x29, 0x74 }; __u8 regGpio[] = { 0x29, 0x74 };
/* setup a selector by customid */ /* setup a selector by customid */
regF1 = 0x01; regF1 = 0x01;
reg_w(dev, 0xf1, &regF1, 1); reg_w(gspca_dev, 0xf1, &regF1, 1);
reg_r(dev, 0x00, &regF1, 1); /* -> regF1 = 0x00 */ reg_r(gspca_dev, 0x00, 1); /* -> regF1 = 0x00 */
reg_w(dev, 0xf1, &regF1, 1); regF1 = gspca_dev->usb_buf[0];
reg_r(dev, 0x00, &regF1, 1); reg_w(gspca_dev, 0xf1, &regF1, 1);
reg_r(gspca_dev, 0x00, 1);
regF1 = gspca_dev->usb_buf[0];
switch (sd->customid) { switch (sd->customid) {
case SN9C102P: case SN9C102P:
if (regF1 != 0x11) if (regF1 != 0x11)
return -ENODEV; return -ENODEV;
reg_w(dev, 0x02, &regGpio[1], 1); reg_w(gspca_dev, 0x02, &regGpio[1], 1);
break; break;
case SN9C105: case SN9C105:
if (regF1 != 0x11) if (regF1 != 0x11)
return -ENODEV; return -ENODEV;
reg_w(dev, 0x02, regGpio, 2); reg_w(gspca_dev, 0x02, regGpio, 2);
break; break;
case SN9C110: case SN9C110:
if (regF1 != 0x12) if (regF1 != 0x12)
return -ENODEV; return -ENODEV;
regGpio[1] = 0x62; regGpio[1] = 0x62;
reg_w(dev, 0x02, &regGpio[1], 1); reg_w(gspca_dev, 0x02, &regGpio[1], 1);
break; break;
case SN9C120: case SN9C120:
if (regF1 != 0x12) if (regF1 != 0x12)
return -ENODEV; return -ENODEV;
regGpio[1] = 0x70; regGpio[1] = 0x70;
reg_w(dev, 0x02, regGpio, 2); reg_w(gspca_dev, 0x02, regGpio, 2);
break; break;
default: default:
/* case SN9C325: */ /* case SN9C325: */
if (regF1 != 0x12) if (regF1 != 0x12)
return -ENODEV; return -ENODEV;
regGpio[1] = 0x62; regGpio[1] = 0x62;
reg_w(dev, 0x02, &regGpio[1], 1); reg_w(gspca_dev, 0x02, &regGpio[1], 1);
break; break;
} }
regF1 = 0x01; regF1 = 0x01;
reg_w(dev, 0xf1, &regF1, 1); reg_w(gspca_dev, 0xf1, &regF1, 1);
return 0; return 0;
} }
@ -1073,7 +1064,7 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
Expodoit[3] = expo >> 16; Expodoit[3] = expo >> 16;
Expodoit[4] = expo >> 8; Expodoit[4] = expo >> 8;
Expodoit[5] = expo; Expodoit[5] = expo;
i2c_w8(gspca_dev->dev, Expodoit); i2c_w8(gspca_dev, Expodoit);
break; break;
} }
case SENSOR_MI0360: { case SENSOR_MI0360: {
@ -1086,9 +1077,9 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
expo = 0x0001; expo = 0x0001;
expoMi[3] = expo >> 8; expoMi[3] = expo >> 8;
expoMi[4] = expo; expoMi[4] = expo;
i2c_w8(gspca_dev->dev, expoMi); i2c_w8(gspca_dev, expoMi);
i2c_w8(gspca_dev->dev, doit); i2c_w8(gspca_dev, doit);
i2c_w8(gspca_dev->dev, sensorgo); i2c_w8(gspca_dev, sensorgo);
break; break;
} }
case SENSOR_MO4000: { case SENSOR_MO4000: {
@ -1102,11 +1093,11 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
else if (expo < 0x0001) else if (expo < 0x0001)
expo = 0x0001; expo = 0x0001;
expoMof[3] = (expo & 0x03fc) >> 2; expoMof[3] = (expo & 0x03fc) >> 2;
i2c_w8(gspca_dev->dev, expoMof); i2c_w8(gspca_dev, expoMof);
expoMo10[3] = ((expo & 0x1c00) >> 10) expoMo10[3] = ((expo & 0x1c00) >> 10)
| ((expo & 0x0003) << 4); | ((expo & 0x0003) << 4);
i2c_w8(gspca_dev->dev, expoMo10); i2c_w8(gspca_dev, expoMo10);
i2c_w8(gspca_dev->dev, gainMo); i2c_w8(gspca_dev, gainMo);
PDEBUG(D_CONF, "set exposure %d", PDEBUG(D_CONF, "set exposure %d",
((expoMo10[3] & 0x07) << 10) ((expoMo10[3] & 0x07) << 10)
| (expoMof[3] << 2) | (expoMof[3] << 2)
@ -1145,7 +1136,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
} }
k2 = sd->brightness >> 10; k2 = sd->brightness >> 10;
reg_w(gspca_dev->dev, 0x96, &k2, 1); reg_w(gspca_dev, 0x96, &k2, 1);
} }
static void setcontrast(struct gspca_dev *gspca_dev) static void setcontrast(struct gspca_dev *gspca_dev)
@ -1160,7 +1151,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
contrast[2] = k2; contrast[2] = k2;
contrast[0] = (k2 + 1) >> 1; contrast[0] = (k2 + 1) >> 1;
contrast[4] = (k2 + 1) / 5; contrast[4] = (k2 + 1) / 5;
reg_w(gspca_dev->dev, 0x84, contrast, 6); reg_w(gspca_dev, 0x84, contrast, 6);
} }
static void setcolors(struct gspca_dev *gspca_dev) static void setcolors(struct gspca_dev *gspca_dev)
@ -1174,14 +1165,13 @@ static void setcolors(struct gspca_dev *gspca_dev)
data = (colour + 32) & 0x7f; /* blue */ data = (colour + 32) & 0x7f; /* blue */
else else
data = (-colour + 32) & 0x7f; /* red */ data = (-colour + 32) & 0x7f; /* red */
reg_w(gspca_dev->dev, 0x05, &data, 1); reg_w(gspca_dev, 0x05, &data, 1);
} }
/* -- start the camera -- */ /* -- start the camera -- */
static void sd_start(struct gspca_dev *gspca_dev) static void sd_start(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
int i; int i;
__u8 data; __u8 data;
__u8 reg1; __u8 reg1;
@ -1203,45 +1193,45 @@ static void sd_start(struct gspca_dev *gspca_dev)
/*fixme:jfm this sequence should appear at end of sd_start */ /*fixme:jfm this sequence should appear at end of sd_start */
/* with /* with
data = 0x44; data = 0x44;
reg_w(dev, 0x01, &data, 1); */ reg_w(gspca_dev, 0x01, &data, 1); */
reg_w(dev, 0x15, &sn9c1xx[0x15], 1); reg_w(gspca_dev, 0x15, &sn9c1xx[0x15], 1);
reg_w(dev, 0x16, &sn9c1xx[0x16], 1); reg_w(gspca_dev, 0x16, &sn9c1xx[0x16], 1);
reg_w(dev, 0x12, &sn9c1xx[0x12], 1); reg_w(gspca_dev, 0x12, &sn9c1xx[0x12], 1);
reg_w(dev, 0x13, &sn9c1xx[0x13], 1); reg_w(gspca_dev, 0x13, &sn9c1xx[0x13], 1);
reg_w(dev, 0x18, &sn9c1xx[0x18], 1); reg_w(gspca_dev, 0x18, &sn9c1xx[0x18], 1);
reg_w(dev, 0xd2, &DC29[0], 1); reg_w(gspca_dev, 0xd2, &DC29[0], 1);
reg_w(dev, 0xd3, &DC29[1], 1); reg_w(gspca_dev, 0xd3, &DC29[1], 1);
reg_w(dev, 0xc6, &DC29[2], 1); reg_w(gspca_dev, 0xc6, &DC29[2], 1);
reg_w(dev, 0xc7, &DC29[3], 1); reg_w(gspca_dev, 0xc7, &DC29[3], 1);
reg_w(dev, 0xc8, &DC29[4], 1); reg_w(gspca_dev, 0xc8, &DC29[4], 1);
reg_w(dev, 0xc9, &DC29[5], 1); reg_w(gspca_dev, 0xc9, &DC29[5], 1);
/*fixme:jfm end of ending sequence */ /*fixme:jfm end of ending sequence */
reg_w(dev, 0x18, &sn9c1xx[0x18], 1); reg_w(gspca_dev, 0x18, &sn9c1xx[0x18], 1);
if (sd->customid == SN9C325) if (sd->customid == SN9C325)
data = 0xae; data = 0xae;
else else
data = 0x60; data = 0x60;
reg_w(dev, 0x17, &data, 1); reg_w(gspca_dev, 0x17, &data, 1);
reg_w(dev, 0x05, &sn9c1xx[5], 1); reg_w(gspca_dev, 0x05, &sn9c1xx[5], 1);
reg_w(dev, 0x07, &sn9c1xx[7], 1); reg_w(gspca_dev, 0x07, &sn9c1xx[7], 1);
reg_w(dev, 0x06, &sn9c1xx[6], 1); reg_w(gspca_dev, 0x06, &sn9c1xx[6], 1);
reg_w(dev, 0x14, &sn9c1xx[0x14], 1); reg_w(gspca_dev, 0x14, &sn9c1xx[0x14], 1);
if (sd->customid == SN9C325) { if (sd->customid == SN9C325) {
reg_w(dev, 0x20, regsn20_sn9c325, 0x11); reg_w(gspca_dev, 0x20, regsn20_sn9c325, 0x11);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
reg_w(dev, 0x84, reg84_sn9c325, 0x15); reg_w(gspca_dev, 0x84, reg84_sn9c325, 0x15);
data = 0x0a; data = 0x0a;
reg_w(dev, 0x9a, &data, 1); reg_w(gspca_dev, 0x9a, &data, 1);
data = 0x60; data = 0x60;
reg_w(dev, 0x99, &data, 1); reg_w(gspca_dev, 0x99, &data, 1);
} else { } else {
reg_w(dev, 0x20, regsn20, 0x11); reg_w(gspca_dev, 0x20, regsn20, 0x11);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
reg_w(dev, 0x84, reg84, 0x15); reg_w(gspca_dev, 0x84, reg84, 0x15);
data = 0x08; data = 0x08;
reg_w(dev, 0x9a, &data, 1); reg_w(gspca_dev, 0x9a, &data, 1);
data = 0x59; data = 0x59;
reg_w(dev, 0x99, &data, 1); reg_w(gspca_dev, 0x99, &data, 1);
} }
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
@ -1294,38 +1284,38 @@ static void sd_start(struct gspca_dev *gspca_dev)
} }
break; break;
} }
reg_w(dev, 0xc0, C0, 6); reg_w(gspca_dev, 0xc0, C0, 6);
switch (sd->customid) { switch (sd->customid) {
case SN9C120: /*jfm ?? */ case SN9C120: /*jfm ?? */
reg_w(dev, 0xca, CA_sn9c120, 4); reg_w(gspca_dev, 0xca, CA_sn9c120, 4);
break; break;
default: default:
reg_w(dev, 0xca, CA, 4); reg_w(gspca_dev, 0xca, CA, 4);
break; break;
} }
switch (sd->customid) { switch (sd->customid) {
case SN9C120: /*jfm ?? */ case SN9C120: /*jfm ?? */
case SN9C325: case SN9C325:
reg_w(dev, 0xce, CE_sn9c325, 4); reg_w(gspca_dev, 0xce, CE_sn9c325, 4);
break; break;
default: default:
reg_w(dev, 0xce, CE, 4); reg_w(gspca_dev, 0xce, CE, 4);
/* ?? {0x1e, 0xdd, 0x2d, 0xe7} */ /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
break; break;
} }
/* here change size mode 0 -> VGA; 1 -> CIF */ /* here change size mode 0 -> VGA; 1 -> CIF */
data = 0x40 | sn9c1xx[0x18] | (mode << 4); data = 0x40 | sn9c1xx[0x18] | (mode << 4);
reg_w(dev, 0x18, &data, 1); reg_w(gspca_dev, 0x18, &data, 1);
reg_w(dev, 0x100, qtable4, 0x40); reg_w(gspca_dev, 0x100, qtable4, 0x40);
reg_w(dev, 0x140, qtable4 + 0x40, 0x40); reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
data = sn9c1xx[0x18] | (mode << 4); data = sn9c1xx[0x18] | (mode << 4);
reg_w(dev, 0x18, &data, 1); reg_w(gspca_dev, 0x18, &data, 1);
reg_w(dev, 0x17, &reg17, 1); reg_w(gspca_dev, 0x17, &reg17, 1);
reg_w(dev, 0x01, &reg1, 1); reg_w(gspca_dev, 0x01, &reg1, 1);
setbrightness(gspca_dev); setbrightness(gspca_dev);
setcontrast(gspca_dev); setcontrast(gspca_dev);
} }
@ -1333,7 +1323,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
static void sd_stopN(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
static const __u8 stophv7131[] = static const __u8 stophv7131[] =
{ 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 }; { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
static const __u8 stopmi0360[] = static const __u8 stopmi0360[] =
@ -1345,11 +1334,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
data = 0x0b; data = 0x0b;
switch (sd->sensor) { switch (sd->sensor) {
case SENSOR_HV7131R: case SENSOR_HV7131R:
i2c_w8(dev, stophv7131); i2c_w8(gspca_dev, stophv7131);
data = 0x2b; data = 0x2b;
break; break;
case SENSOR_MI0360: case SENSOR_MI0360:
i2c_w8(dev, stopmi0360); i2c_w8(gspca_dev, stopmi0360);
data = 0x29; data = 0x29;
break; break;
case SENSOR_MO4000: case SENSOR_MO4000:
@ -1362,12 +1351,12 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
break; break;
} }
sn9c1xx = sn_tb[(int) sd->sensor]; sn9c1xx = sn_tb[(int) sd->sensor];
reg_w(dev, 0x01, &sn9c1xx[1], 1); reg_w(gspca_dev, 0x01, &sn9c1xx[1], 1);
reg_w(dev, 0x17, &sn9c1xx[0x17], 1); reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 1);
reg_w(dev, 0x01, &sn9c1xx[1], 1); reg_w(gspca_dev, 0x01, &sn9c1xx[1], 1);
reg_w(dev, 0x01, &data, 1); reg_w(gspca_dev, 0x01, &data, 1);
regF1 = 0x01; regF1 = 0x01;
reg_w(dev, 0xf1, &regF1, 1); reg_w(gspca_dev, 0xf1, &regF1, 1);
} }
static void sd_stop0(struct gspca_dev *gspca_dev) static void sd_stop0(struct gspca_dev *gspca_dev)
@ -1463,33 +1452,35 @@ static unsigned int getexposure(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
__u8 hexpo, mexpo, lexpo; __u8 hexpo, mexpo, lexpo;
__u8 expo[6];
switch (sd->sensor) { switch (sd->sensor) {
case SENSOR_HV7131R: case SENSOR_HV7131R:
/* read sensor exposure */ /* read sensor exposure */
i2c_r5(gspca_dev, 0x25, expo); i2c_r5(gspca_dev, 0x25);
return (expo[0] << 16) | (expo[1] << 8) | expo[2]; return (gspca_dev->usb_buf[0] << 16)
| (gspca_dev->usb_buf[1] << 8)
| gspca_dev->usb_buf[2];
case SENSOR_MI0360: case SENSOR_MI0360:
/* read sensor exposure */ /* read sensor exposure */
i2c_r5(gspca_dev, 0x09, expo); i2c_r5(gspca_dev, 0x09);
return (expo[0] << 8) | expo[1]; return (gspca_dev->usb_buf[0] << 8)
| gspca_dev->usb_buf[1];
case SENSOR_MO4000: case SENSOR_MO4000:
i2c_r5(gspca_dev, 0x0e, expo); i2c_r5(gspca_dev, 0x0e);
hexpo = 0; /* expo[1] & 0x07; */ hexpo = 0; /* gspca_dev->usb_buf[1] & 0x07; */
mexpo = 0x40; /* expo[2] &0xff; */ mexpo = 0x40; /* gspca_dev->usb_buf[2] & 0xff; */
lexpo = (expo[1] & 0x30) >> 4; lexpo = (gspca_dev->usb_buf[1] & 0x30) >> 4;
PDEBUG(D_CONF, "exposure %d", PDEBUG(D_CONF, "exposure %d",
(hexpo << 10) | (mexpo << 2) | lexpo); (hexpo << 10) | (mexpo << 2) | lexpo);
return (hexpo << 10) | (mexpo << 2) | lexpo; return (hexpo << 10) | (mexpo << 2) | lexpo;
default: default:
/* case SENSOR_OV7660: */ /* case SENSOR_OV7660: */
/* read sensor exposure */ /* read sensor exposure */
i2c_r5(gspca_dev, 0x04, expo); i2c_r5(gspca_dev, 0x04);
hexpo = expo[3] & 0x2f; hexpo = gspca_dev->usb_buf[3] & 0x2f;
lexpo = expo[0] & 0x02; lexpo = gspca_dev->usb_buf[0] & 0x02;
i2c_r5(gspca_dev, 0x08, expo); i2c_r5(gspca_dev, 0x08);
mexpo = expo[2]; mexpo = gspca_dev->usb_buf[2];
return (hexpo << 10) | (mexpo << 2) | lexpo; return (hexpo << 10) | (mexpo << 2) | lexpo;
} }
} }

View File

@ -24,8 +24,8 @@
#include "gspca.h" #include "gspca.h"
#include "jpeg.h" #include "jpeg.h"
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.5"; static const char version[] = "2.1.7";
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver"); MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
@ -372,26 +372,27 @@ static const __u8 qtable_pocketdv[2][64] = {
0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28} 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
}; };
static void reg_r(struct usb_device *dev, /* read 'len' bytes to gspca_dev->usb_buf */
__u16 index, static void reg_r(struct gspca_dev *gspca_dev,
__u8 *buffer, __u16 length) __u16 index,
__u16 length)
{ {
usb_control_msg(dev, usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(dev, 0), usb_rcvctrlpipe(gspca_dev->dev, 0),
0, 0,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */ 0, /* value */
index, buffer, length, 500); index, gspca_dev->usb_buf, length, 500);
} }
static int reg_w(struct usb_device *dev, static int reg_w(struct gspca_dev *gspca_dev,
__u16 req, __u16 index, __u16 value) __u16 req, __u16 index, __u16 value)
{ {
int ret; int ret;
PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value); PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
ret = usb_control_msg(dev, ret = usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(dev, 0), usb_sndctrlpipe(gspca_dev->dev, 0),
req, req,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, index, NULL, 0, 500); value, index, NULL, 0, 500);
@ -401,28 +402,27 @@ static int reg_w(struct usb_device *dev,
} }
/* returns: negative is error, pos or zero is data */ /* returns: negative is error, pos or zero is data */
static int reg_r_12(struct usb_device *dev, static int reg_r_12(struct gspca_dev *gspca_dev,
__u16 req, /* bRequest */ __u16 req, /* bRequest */
__u16 index, /* wIndex */ __u16 index, /* wIndex */
__u16 length) /* wLength (1 or 2 only) */ __u16 length) /* wLength (1 or 2 only) */
{ {
int ret; int ret;
__u8 buf[2];
buf[1] = 0; gspca_dev->usb_buf[1] = 0;
ret = usb_control_msg(dev, ret = usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(dev, 0), usb_rcvctrlpipe(gspca_dev->dev, 0),
req, req,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */ 0, /* value */
index, index,
buf, length, gspca_dev->usb_buf, length,
500); /* timeout */ 500); /* timeout */
if (ret < 0) { if (ret < 0) {
PDEBUG(D_ERR, "reg_r_12 err %d", ret); PDEBUG(D_ERR, "reg_r_12 err %d", ret);
return -1; return -1;
} }
return (buf[1] << 8) + buf[0]; return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
} }
/* /*
@ -430,13 +430,13 @@ static int reg_r_12(struct usb_device *dev,
* a reg_read call. * a reg_read call.
* Returns: negative is error or timeout, zero is success. * Returns: negative is error or timeout, zero is success.
*/ */
static int reg_r_wait(struct usb_device *dev, static int reg_r_wait(struct gspca_dev *gspca_dev,
__u16 reg, __u16 index, __u16 value) __u16 reg, __u16 index, __u16 value)
{ {
int ret, cnt = 20; int ret, cnt = 20;
while (--cnt > 0) { while (--cnt > 0) {
ret = reg_r_12(dev, reg, index, 1); ret = reg_r_12(gspca_dev, reg, index, 1);
if (ret == value) if (ret == value)
return 0; return 0;
msleep(50); msleep(50);
@ -447,11 +447,10 @@ static int reg_r_wait(struct usb_device *dev,
static int write_vector(struct gspca_dev *gspca_dev, static int write_vector(struct gspca_dev *gspca_dev,
const __u16 data[][3]) const __u16 data[][3])
{ {
struct usb_device *dev = gspca_dev->dev;
int ret, i = 0; int ret, i = 0;
while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
ret = reg_w(dev, data[i][0], data[i][2], data[i][1]); ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
if (ret < 0) if (ret < 0)
return ret; return ret;
i++; i++;
@ -465,19 +464,18 @@ static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
unsigned int cbase, unsigned int cbase,
const __u8 qtable[2][64]) const __u8 qtable[2][64])
{ {
struct usb_device *dev = gspca_dev->dev;
int i, err; int i, err;
/* loop over y components */ /* loop over y components */
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
err = reg_w(dev, request, ybase + i, qtable[0][i]); err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
if (err < 0) if (err < 0)
return err; return err;
} }
/* loop over c components */ /* loop over c components */
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
err = reg_w(dev, request, cbase + i, qtable[1][i]); err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
if (err < 0) if (err < 0)
return err; return err;
} }
@ -486,37 +484,33 @@ static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
static void spca500_ping310(struct gspca_dev *gspca_dev) static void spca500_ping310(struct gspca_dev *gspca_dev)
{ {
__u8 Data[2]; reg_r(gspca_dev, 0x0d04, 2);
reg_r(gspca_dev->dev, 0x0d04, Data, 2);
PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x", PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
Data[0], Data[1]); gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
} }
static void spca500_clksmart310_init(struct gspca_dev *gspca_dev) static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
{ {
__u8 Data[2]; reg_r(gspca_dev, 0x0d05, 2);
reg_r(gspca_dev->dev, 0x0d05, Data, 2);
PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x", PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
Data[0], Data[1]); gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
reg_w(gspca_dev->dev, 0x00, 0x8167, 0x5a); reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
spca500_ping310(gspca_dev); spca500_ping310(gspca_dev);
reg_w(gspca_dev->dev, 0x00, 0x8168, 0x22); reg_w(gspca_dev, 0x00, 0x8168, 0x22);
reg_w(gspca_dev->dev, 0x00, 0x816a, 0xc0); reg_w(gspca_dev, 0x00, 0x816a, 0xc0);
reg_w(gspca_dev->dev, 0x00, 0x816b, 0x0b); reg_w(gspca_dev, 0x00, 0x816b, 0x0b);
reg_w(gspca_dev->dev, 0x00, 0x8169, 0x25); reg_w(gspca_dev, 0x00, 0x8169, 0x25);
reg_w(gspca_dev->dev, 0x00, 0x8157, 0x5b); reg_w(gspca_dev, 0x00, 0x8157, 0x5b);
reg_w(gspca_dev->dev, 0x00, 0x8158, 0x5b); reg_w(gspca_dev, 0x00, 0x8158, 0x5b);
reg_w(gspca_dev->dev, 0x00, 0x813f, 0x03); reg_w(gspca_dev, 0x00, 0x813f, 0x03);
reg_w(gspca_dev->dev, 0x00, 0x8151, 0x4a); reg_w(gspca_dev, 0x00, 0x8151, 0x4a);
reg_w(gspca_dev->dev, 0x00, 0x8153, 0x78); reg_w(gspca_dev, 0x00, 0x8153, 0x78);
reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x04); reg_w(gspca_dev, 0x00, 0x0d01, 0x04);
/* 00 for adjust shutter */ /* 00 for adjust shutter */
reg_w(gspca_dev->dev, 0x00, 0x0d02, 0x01); reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
reg_w(gspca_dev->dev, 0x00, 0x8169, 0x25); reg_w(gspca_dev, 0x00, 0x8169, 0x25);
reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x02); reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
} }
static void spca500_setmode(struct gspca_dev *gspca_dev, static void spca500_setmode(struct gspca_dev *gspca_dev,
@ -525,14 +519,14 @@ static void spca500_setmode(struct gspca_dev *gspca_dev,
int mode; int mode;
/* set x multiplier */ /* set x multiplier */
reg_w(gspca_dev->dev, 0, 0x8001, xmult); reg_w(gspca_dev, 0, 0x8001, xmult);
/* set y multiplier */ /* set y multiplier */
reg_w(gspca_dev->dev, 0, 0x8002, ymult); reg_w(gspca_dev, 0, 0x8002, ymult);
/* use compressed mode, VGA, with mode specific subsample */ /* use compressed mode, VGA, with mode specific subsample */
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
reg_w(gspca_dev->dev, 0, 0x8003, mode << 4); reg_w(gspca_dev, 0, 0x8003, mode << 4);
} }
static int spca500_full_reset(struct gspca_dev *gspca_dev) static int spca500_full_reset(struct gspca_dev *gspca_dev)
@ -540,18 +534,18 @@ static int spca500_full_reset(struct gspca_dev *gspca_dev)
int err; int err;
/* send the reset command */ /* send the reset command */
err = reg_w(gspca_dev->dev, 0xe0, 0x0001, 0x0000); err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
if (err < 0) if (err < 0)
return err; return err;
/* wait for the reset to complete */ /* wait for the reset to complete */
err = reg_r_wait(gspca_dev->dev, 0x06, 0x0000, 0x0000); err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
if (err < 0) if (err < 0)
return err; return err;
err = reg_w(gspca_dev->dev, 0xe0, 0x0000, 0x0000); err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
if (err < 0) if (err < 0)
return err; return err;
err = reg_r_wait(gspca_dev->dev, 0x06, 0, 0); err = reg_r_wait(gspca_dev, 0x06, 0, 0);
if (err < 0) { if (err < 0) {
PDEBUG(D_ERR, "reg_r_wait() failed"); PDEBUG(D_ERR, "reg_r_wait() failed");
return err; return err;
@ -568,15 +562,13 @@ static int spca500_full_reset(struct gspca_dev *gspca_dev)
/* up-port the same feature as in 2.4.x kernel */ /* up-port the same feature as in 2.4.x kernel */
static int spca500_synch310(struct gspca_dev *gspca_dev) static int spca500_synch310(struct gspca_dev *gspca_dev)
{ {
__u8 Data;
if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) { if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
PDEBUG(D_ERR, "Set packet size: set interface error"); PDEBUG(D_ERR, "Set packet size: set interface error");
goto error; goto error;
} }
spca500_ping310(gspca_dev); spca500_ping310(gspca_dev);
reg_r(gspca_dev->dev, 0x0d00, &Data, 1); reg_r(gspca_dev, 0x0d00, 1);
/* need alt setting here */ /* need alt setting here */
PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt); PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
@ -600,12 +592,12 @@ static void spca500_reinit(struct gspca_dev *gspca_dev)
/* some unknow command from Aiptek pocket dv and family300 */ /* some unknow command from Aiptek pocket dv and family300 */
reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x01); reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
reg_w(gspca_dev->dev, 0x00, 0x0d03, 0x00); reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
reg_w(gspca_dev->dev, 0x00, 0x0d02, 0x01); reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
/* enable drop packet */ /* enable drop packet */
reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
qtable_pocketdv); qtable_pocketdv);
@ -613,22 +605,23 @@ static void spca500_reinit(struct gspca_dev *gspca_dev)
PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init"); PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init");
/* set qtable index */ /* set qtable index */
reg_w(gspca_dev->dev, 0x00, 0x8880, 2); reg_w(gspca_dev, 0x00, 0x8880, 2);
/* family cam Quicksmart stuff */ /* family cam Quicksmart stuff */
reg_w(gspca_dev->dev, 0x00, 0x800a, 0x00); reg_w(gspca_dev, 0x00, 0x800a, 0x00);
/* Set agc transfer: synced inbetween frames */ /* Set agc transfer: synced inbetween frames */
reg_w(gspca_dev->dev, 0x00, 0x820f, 0x01); reg_w(gspca_dev, 0x00, 0x820f, 0x01);
/* Init SDRAM - needed for SDRAM access */ /* Init SDRAM - needed for SDRAM access */
reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04); reg_w(gspca_dev, 0x00, 0x870a, 0x04);
/*Start init sequence or stream */ /*Start init sequence or stream */
reg_w(gspca_dev, 0, 0x8003, 0x00);
reg_w(gspca_dev->dev, 0, 0x8003, 0x00);
/* switch to video camera mode */ /* switch to video camera mode */
reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
msleep(2000); msleep(2000);
if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {
reg_r(gspca_dev->dev, 0x816b, &Data, 1); reg_r(gspca_dev, 0x816b, 1);
reg_w(gspca_dev->dev, 0x00, 0x816b, Data); Data = gspca_dev->usb_buf[0];
reg_w(gspca_dev, 0x00, 0x816b, Data);
}
} }
/* this function is called at probe time */ /* this function is called at probe time */
@ -785,9 +778,10 @@ static void sd_start(struct gspca_dev *gspca_dev)
} }
/* is there a sensor here ? */ /* is there a sensor here ? */
reg_r(gspca_dev->dev, 0x8a04, &Data, 1); reg_r(gspca_dev, 0x8a04, 1);
PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02X", Data); PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02X, Ymult: 0x%02X", gspca_dev->usb_buf[0]);
PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
gspca_dev->curr_mode, xmult, ymult); gspca_dev->curr_mode, xmult, ymult);
/* setup qtable */ /* setup qtable */
@ -796,33 +790,34 @@ static void sd_start(struct gspca_dev *gspca_dev)
spca500_setmode(gspca_dev, xmult, ymult); spca500_setmode(gspca_dev, xmult, ymult);
/* enable drop packet */ /* enable drop packet */
reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
reg_w(gspca_dev->dev, 0x00, 0x8880, 3); reg_w(gspca_dev, 0x00, 0x8880, 3);
err = spca50x_setup_qtable(gspca_dev, err = spca50x_setup_qtable(gspca_dev,
0x00, 0x8800, 0x8840, 0x00, 0x8800, 0x8840,
qtable_creative_pccam); qtable_creative_pccam);
if (err < 0) if (err < 0)
PDEBUG(D_ERR, "spca50x_setup_qtable failed"); PDEBUG(D_ERR, "spca50x_setup_qtable failed");
/* Init SDRAM - needed for SDRAM access */ /* Init SDRAM - needed for SDRAM access */
reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04); reg_w(gspca_dev, 0x00, 0x870a, 0x04);
/* switch to video camera mode */ /* switch to video camera mode */
reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
msleep(500); msleep(500);
if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
PDEBUG(D_ERR, "reg_r_wait() failed"); PDEBUG(D_ERR, "reg_r_wait() failed");
reg_r(gspca_dev->dev, 0x816b, &Data, 1); reg_r(gspca_dev, 0x816b, 1);
reg_w(gspca_dev->dev, 0x00, 0x816b, Data); Data = gspca_dev->usb_buf[0];
reg_w(gspca_dev, 0x00, 0x816b, Data);
spca500_synch310(gspca_dev); spca500_synch310(gspca_dev);
write_vector(gspca_dev, spca500_visual_defaults); write_vector(gspca_dev, spca500_visual_defaults);
spca500_setmode(gspca_dev, xmult, ymult); spca500_setmode(gspca_dev, xmult, ymult);
/* enable drop packet */ /* enable drop packet */
reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
PDEBUG(D_ERR, "failed to enable drop packet"); PDEBUG(D_ERR, "failed to enable drop packet");
reg_w(gspca_dev->dev, 0x00, 0x8880, 3); reg_w(gspca_dev, 0x00, 0x8880, 3);
err = spca50x_setup_qtable(gspca_dev, err = spca50x_setup_qtable(gspca_dev,
0x00, 0x8800, 0x8840, 0x00, 0x8800, 0x8840,
qtable_creative_pccam); qtable_creative_pccam);
@ -830,16 +825,17 @@ static void sd_start(struct gspca_dev *gspca_dev)
PDEBUG(D_ERR, "spca50x_setup_qtable failed"); PDEBUG(D_ERR, "spca50x_setup_qtable failed");
/* Init SDRAM - needed for SDRAM access */ /* Init SDRAM - needed for SDRAM access */
reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04); reg_w(gspca_dev, 0x00, 0x870a, 0x04);
/* switch to video camera mode */ /* switch to video camera mode */
reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
PDEBUG(D_ERR, "reg_r_wait() failed"); PDEBUG(D_ERR, "reg_r_wait() failed");
reg_r(gspca_dev->dev, 0x816b, &Data, 1); reg_r(gspca_dev, 0x816b, 1);
reg_w(gspca_dev->dev, 0x00, 0x816b, Data); Data = gspca_dev->usb_buf[0];
reg_w(gspca_dev, 0x00, 0x816b, Data);
break; break;
case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */ case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */
case IntelPocketPCCamera: /* FIXME: Temporary fix for case IntelPocketPCCamera: /* FIXME: Temporary fix for
@ -852,10 +848,10 @@ static void sd_start(struct gspca_dev *gspca_dev)
PDEBUG(D_ERR, "spca500_full_reset failed"); PDEBUG(D_ERR, "spca500_full_reset failed");
/* enable drop packet */ /* enable drop packet */
err = reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
if (err < 0) if (err < 0)
PDEBUG(D_ERR, "failed to enable drop packet"); PDEBUG(D_ERR, "failed to enable drop packet");
reg_w(gspca_dev->dev, 0x00, 0x8880, 3); reg_w(gspca_dev, 0x00, 0x8880, 3);
err = spca50x_setup_qtable(gspca_dev, err = spca50x_setup_qtable(gspca_dev,
0x00, 0x8800, 0x8840, 0x00, 0x8800, 0x8840,
qtable_creative_pccam); qtable_creative_pccam);
@ -863,16 +859,17 @@ static void sd_start(struct gspca_dev *gspca_dev)
PDEBUG(D_ERR, "spca50x_setup_qtable failed"); PDEBUG(D_ERR, "spca50x_setup_qtable failed");
spca500_setmode(gspca_dev, xmult, ymult); spca500_setmode(gspca_dev, xmult, ymult);
reg_w(gspca_dev->dev, 0x20, 0x0001, 0x0004); reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
/* switch to video camera mode */ /* switch to video camera mode */
reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
PDEBUG(D_ERR, "reg_r_wait() failed"); PDEBUG(D_ERR, "reg_r_wait() failed");
reg_r(gspca_dev->dev, 0x816b, &Data, 1); reg_r(gspca_dev, 0x816b, 1);
reg_w(gspca_dev->dev, 0x00, 0x816b, Data); Data = gspca_dev->usb_buf[0];
reg_w(gspca_dev, 0x00, 0x816b, Data);
/* write_vector(gspca_dev, spca500_visual_defaults); */ /* write_vector(gspca_dev, spca500_visual_defaults); */
break; break;
@ -883,8 +880,8 @@ static void sd_start(struct gspca_dev *gspca_dev)
if (err < 0) if (err < 0)
PDEBUG(D_ERR, "spca500_full_reset failed"); PDEBUG(D_ERR, "spca500_full_reset failed");
/* enable drop packet */ /* enable drop packet */
reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
reg_w(gspca_dev->dev, 0x00, 0x8880, 0); reg_w(gspca_dev, 0x00, 0x8880, 0);
err = spca50x_setup_qtable(gspca_dev, err = spca50x_setup_qtable(gspca_dev,
0x00, 0x8800, 0x8840, 0x00, 0x8800, 0x8840,
qtable_kodak_ez200); qtable_kodak_ez200);
@ -892,16 +889,17 @@ static void sd_start(struct gspca_dev *gspca_dev)
PDEBUG(D_ERR, "spca50x_setup_qtable failed"); PDEBUG(D_ERR, "spca50x_setup_qtable failed");
spca500_setmode(gspca_dev, xmult, ymult); spca500_setmode(gspca_dev, xmult, ymult);
reg_w(gspca_dev->dev, 0x20, 0x0001, 0x0004); reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
/* switch to video camera mode */ /* switch to video camera mode */
reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
PDEBUG(D_ERR, "reg_r_wait() failed"); PDEBUG(D_ERR, "reg_r_wait() failed");
reg_r(gspca_dev->dev, 0x816b, &Data, 1); reg_r(gspca_dev, 0x816b, 1);
reg_w(gspca_dev->dev, 0x00, 0x816b, Data); Data = gspca_dev->usb_buf[0];
reg_w(gspca_dev, 0x00, 0x816b, Data);
/* write_vector(gspca_dev, spca500_visual_defaults); */ /* write_vector(gspca_dev, spca500_visual_defaults); */
break; break;
@ -916,56 +914,58 @@ static void sd_start(struct gspca_dev *gspca_dev)
case ToptroIndus: case ToptroIndus:
case AgfaCl20: case AgfaCl20:
spca500_reinit(gspca_dev); spca500_reinit(gspca_dev);
reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x01); reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
/* enable drop packet */ /* enable drop packet */
reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
err = spca50x_setup_qtable(gspca_dev, err = spca50x_setup_qtable(gspca_dev,
0x00, 0x8800, 0x8840, qtable_pocketdv); 0x00, 0x8800, 0x8840, qtable_pocketdv);
if (err < 0) if (err < 0)
PDEBUG(D_ERR, "spca50x_setup_qtable failed"); PDEBUG(D_ERR, "spca50x_setup_qtable failed");
reg_w(gspca_dev->dev, 0x00, 0x8880, 2); reg_w(gspca_dev, 0x00, 0x8880, 2);
/* familycam Quicksmart pocketDV stuff */ /* familycam Quicksmart pocketDV stuff */
reg_w(gspca_dev->dev, 0x00, 0x800a, 0x00); reg_w(gspca_dev, 0x00, 0x800a, 0x00);
/* Set agc transfer: synced inbetween frames */ /* Set agc transfer: synced inbetween frames */
reg_w(gspca_dev->dev, 0x00, 0x820f, 0x01); reg_w(gspca_dev, 0x00, 0x820f, 0x01);
/* Init SDRAM - needed for SDRAM access */ /* Init SDRAM - needed for SDRAM access */
reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04); reg_w(gspca_dev, 0x00, 0x870a, 0x04);
spca500_setmode(gspca_dev, xmult, ymult); spca500_setmode(gspca_dev, xmult, ymult);
/* switch to video camera mode */ /* switch to video camera mode */
reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44); reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
reg_r(gspca_dev->dev, 0x816b, &Data, 1); reg_r(gspca_dev, 0x816b, 1);
reg_w(gspca_dev->dev, 0x00, 0x816b, Data); Data = gspca_dev->usb_buf[0];
reg_w(gspca_dev, 0x00, 0x816b, Data);
break; break;
case LogitechTraveler: case LogitechTraveler:
case LogitechClickSmart510: case LogitechClickSmart510:
reg_w(gspca_dev->dev, 0x02, 0x00, 0x00); reg_w(gspca_dev, 0x02, 0x00, 0x00);
/* enable drop packet */ /* enable drop packet */
reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
err = spca50x_setup_qtable(gspca_dev, err = spca50x_setup_qtable(gspca_dev,
0x00, 0x8800, 0x00, 0x8800,
0x8840, qtable_creative_pccam); 0x8840, qtable_creative_pccam);
if (err < 0) if (err < 0)
PDEBUG(D_ERR, "spca50x_setup_qtable failed"); PDEBUG(D_ERR, "spca50x_setup_qtable failed");
reg_w(gspca_dev->dev, 0x00, 0x8880, 3); reg_w(gspca_dev, 0x00, 0x8880, 3);
reg_w(gspca_dev->dev, 0x00, 0x800a, 0x00); reg_w(gspca_dev, 0x00, 0x800a, 0x00);
/* Init SDRAM - needed for SDRAM access */ /* Init SDRAM - needed for SDRAM access */
reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04); reg_w(gspca_dev, 0x00, 0x870a, 0x04);
spca500_setmode(gspca_dev, xmult, ymult); spca500_setmode(gspca_dev, xmult, ymult);
/* switch to video camera mode */ /* switch to video camera mode */
reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44); reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
reg_r(gspca_dev->dev, 0x816b, &Data, 1); reg_r(gspca_dev, 0x816b, 1);
reg_w(gspca_dev->dev, 0x00, 0x816b, Data); Data = gspca_dev->usb_buf[0];
reg_w(gspca_dev, 0x00, 0x816b, Data);
write_vector(gspca_dev, Clicksmart510_defaults); write_vector(gspca_dev, Clicksmart510_defaults);
break; break;
} }
@ -973,14 +973,13 @@ static void sd_start(struct gspca_dev *gspca_dev)
static void sd_stopN(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev)
{ {
__u8 data; reg_w(gspca_dev, 0, 0x8003, 0x00);
reg_w(gspca_dev->dev, 0, 0x8003, 0x00);
/* switch to video camera mode */ /* switch to video camera mode */
reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
reg_r(gspca_dev->dev, 0x8000, &data, 1); reg_r(gspca_dev, 0x8000, 1);
PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x", data); PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
gspca_dev->usb_buf[0]);
} }
static void sd_stop0(struct gspca_dev *gspca_dev) static void sd_stop0(struct gspca_dev *gspca_dev)
@ -1043,7 +1042,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
reg_w(gspca_dev->dev, 0x00, 0x8167, reg_w(gspca_dev, 0x00, 0x8167,
(__u8) (sd->brightness - 128)); (__u8) (sd->brightness - 128));
} }
@ -1052,7 +1051,7 @@ static void getbrightness(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
int ret; int ret;
ret = reg_r_12(gspca_dev->dev, 0x00, 0x8167, 1); ret = reg_r_12(gspca_dev, 0x00, 0x8167, 1);
if (ret >= 0) if (ret >= 0)
sd->brightness = ret + 128; sd->brightness = ret + 128;
} }
@ -1061,7 +1060,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
reg_w(gspca_dev->dev, 0x00, 0x8168, sd->contrast); reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);
} }
static void getcontrast(struct gspca_dev *gspca_dev) static void getcontrast(struct gspca_dev *gspca_dev)
@ -1069,7 +1068,7 @@ static void getcontrast(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
int ret; int ret;
ret = reg_r_12(gspca_dev->dev, 0x0, 0x8168, 1); ret = reg_r_12(gspca_dev, 0x0, 0x8168, 1);
if (ret >= 0) if (ret >= 0)
sd->contrast = ret; sd->contrast = ret;
} }
@ -1078,7 +1077,7 @@ static void setcolors(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
reg_w(gspca_dev->dev, 0x00, 0x8169, sd->colors); reg_w(gspca_dev, 0x00, 0x8169, sd->colors);
} }
static void getcolors(struct gspca_dev *gspca_dev) static void getcolors(struct gspca_dev *gspca_dev)
@ -1086,7 +1085,7 @@ static void getcolors(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
int ret; int ret;
ret = reg_r_12(gspca_dev->dev, 0x0, 0x8169, 1); ret = reg_r_12(gspca_dev, 0x0, 0x8169, 1);
if (ret >= 0) if (ret >= 0)
sd->colors = ret; sd->colors = ret;
} }

View File

@ -23,8 +23,8 @@
#include "gspca.h" #include "gspca.h"
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.5"; static const char version[] = "2.1.7";
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SPCA501 USB Camera Driver"); MODULE_DESCRIPTION("GSPCA/SPCA501 USB Camera Driver");
@ -1826,28 +1826,27 @@ static int reg_write(struct usb_device *dev,
} }
/* returns: negative is error, pos or zero is data */ /* returns: negative is error, pos or zero is data */
static int reg_read(struct usb_device *dev, static int reg_read(struct gspca_dev *gspca_dev,
__u16 req, /* bRequest */ __u16 req, /* bRequest */
__u16 index, /* wIndex */ __u16 index, /* wIndex */
__u16 length) /* wLength (1 or 2 only) */ __u16 length) /* wLength (1 or 2 only) */
{ {
int ret; int ret;
__u8 buf[2];
buf[1] = 0; gspca_dev->usb_buf[1] = 0;
ret = usb_control_msg(dev, ret = usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(dev, 0), usb_rcvctrlpipe(gspca_dev->dev, 0),
req, req,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */ 0, /* value */
index, index,
buf, length, gspca_dev->usb_buf, length,
500); /* timeout */ 500); /* timeout */
if (ret < 0) { if (ret < 0) {
PDEBUG(D_ERR, "reg_read err %d", ret); PDEBUG(D_ERR, "reg_read err %d", ret);
return -1; return -1;
} }
return (buf[1] << 8) + buf[0]; return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
} }
static int write_vector(struct gspca_dev *gspca_dev, static int write_vector(struct gspca_dev *gspca_dev,
@ -1883,7 +1882,7 @@ static void getbrightness(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
__u16 brightness; __u16 brightness;
brightness = reg_read(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, 2); brightness = reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x11, 2);
sd->brightness = brightness << 1; sd->brightness = brightness << 1;
} }
@ -1913,8 +1912,8 @@ static void getcolors(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
sd->colors = reg_read(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, 2); sd->colors = reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x0c, 2);
/* sd->hue = (reg_read(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, */ /* sd->hue = (reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x13, */
/* 2) & 0xFF) << 8; */ /* 2) & 0xFF) << 8; */
} }

View File

@ -23,8 +23,8 @@
#include "gspca.h" #include "gspca.h"
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.5"; static const char version[] = "2.1.7";
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver"); MODULE_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver");
@ -593,29 +593,27 @@ static int reg_write(struct usb_device *dev,
} }
/* returns: negative is error, pos or zero is data */ /* returns: negative is error, pos or zero is data */
static int reg_read(struct usb_device *dev, static int reg_read(struct gspca_dev *gspca_dev,
__u16 reg, /* bRequest */ __u16 reg, /* bRequest */
__u16 index, /* wIndex */ __u16 index, /* wIndex */
__u16 length) /* wLength (1 or 2 only) */ __u16 length) /* wLength (1 or 2 only) */
{ {
int ret; int ret;
__u8 buf[4];
buf[1] = 0; gspca_dev->usb_buf[1] = 0;
ret = usb_control_msg(dev, ret = usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(dev, 0), usb_rcvctrlpipe(gspca_dev->dev, 0),
reg, reg,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
(__u16) 0, /* value */ (__u16) 0, /* value */
(__u16) index, (__u16) index,
buf, gspca_dev->usb_buf, length,
length,
500); /* timeout */ 500); /* timeout */
if (ret < 0) { if (ret < 0) {
PDEBUG(D_ERR, "reg_read err %d", ret); PDEBUG(D_ERR, "reg_read err %d", ret);
return -1; return -1;
} }
return (buf[1] << 8) + buf[0]; return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
} }
static int write_vector(struct gspca_dev *gspca_dev, static int write_vector(struct gspca_dev *gspca_dev,
@ -697,7 +695,7 @@ static int sd_open(struct gspca_dev *gspca_dev)
write_vector(gspca_dev, spca505b_open_data_ccd); write_vector(gspca_dev, spca505b_open_data_ccd);
else else
write_vector(gspca_dev, spca505_open_data_ccd); write_vector(gspca_dev, spca505_open_data_ccd);
ret = reg_read(gspca_dev->dev, 6, 0x16, 2); ret = reg_read(gspca_dev, 6, 0x16, 2);
if (ret < 0) { if (ret < 0) {
PDEBUG(D_ERR|D_STREAM, PDEBUG(D_ERR|D_STREAM,
@ -874,8 +872,8 @@ static void getbrightness(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
sd->brightness = 255 sd->brightness = 255
- ((reg_read(gspca_dev->dev, 5, 0x01, 1) >> 2) - ((reg_read(gspca_dev, 5, 0x01, 1) >> 2)
+ (reg_read(gspca_dev->dev, 5, 0x0, 1) << 6)); + (reg_read(gspca_dev, 5, 0x0, 1) << 6));
} }
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)

View File

@ -25,8 +25,8 @@
#include "gspca.h" #include "gspca.h"
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.5"; static const char version[] = "2.1.7";
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SPCA506 USB Camera Driver"); MODULE_DESCRIPTION("GSPCA/SPCA506 USB Camera Driver");
@ -153,17 +153,18 @@ static struct v4l2_pix_format vga_mode[] = {
#define SAA7113_hue 0x0d /* defaults 0x00 */ #define SAA7113_hue 0x0d /* defaults 0x00 */
#define SAA7113_I2C_BASE_WRITE 0x4a #define SAA7113_I2C_BASE_WRITE 0x4a
static void reg_r(struct usb_device *dev, /* read 'len' bytes to gspca_dev->usb_buf */
static void reg_r(struct gspca_dev *gspca_dev,
__u16 req, __u16 req,
__u16 index, __u16 index,
__u8 *buffer, __u16 length) __u16 length)
{ {
usb_control_msg(dev, usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(dev, 0), usb_rcvctrlpipe(gspca_dev->dev, 0),
req, req,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */ 0, /* value */
index, buffer, length, index, gspca_dev->usb_buf, length,
500); 500);
} }
@ -189,13 +190,12 @@ static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur,
__u16 reg) __u16 reg)
{ {
int retry = 60; int retry = 60;
__u8 Data[2];
reg_w(gspca_dev->dev, 0x07, reg, 0x0001); reg_w(gspca_dev->dev, 0x07, reg, 0x0001);
reg_w(gspca_dev->dev, 0x07, valeur, 0x0000); reg_w(gspca_dev->dev, 0x07, valeur, 0x0000);
while (retry--) { while (retry--) {
reg_r(gspca_dev->dev, 0x07, 0x0003, Data, 2); reg_r(gspca_dev, 0x07, 0x0003, 2);
if ((Data[0] | Data[1]) == 0x00) if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00)
break; break;
} }
} }
@ -203,21 +203,19 @@ static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur,
static int spca506_ReadI2c(struct gspca_dev *gspca_dev, __u16 reg) static int spca506_ReadI2c(struct gspca_dev *gspca_dev, __u16 reg)
{ {
int retry = 60; int retry = 60;
__u8 Data[2];
__u8 value;
reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004); reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004);
reg_w(gspca_dev->dev, 0x07, reg, 0x0001); reg_w(gspca_dev->dev, 0x07, reg, 0x0001);
reg_w(gspca_dev->dev, 0x07, 0x01, 0x0002); reg_w(gspca_dev->dev, 0x07, 0x01, 0x0002);
while (--retry) { while (--retry) {
reg_r(gspca_dev->dev, 0x07, 0x0003, Data, 2); reg_r(gspca_dev, 0x07, 0x0003, 2);
if ((Data[0] | Data[1]) == 0x00) if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00)
break; break;
} }
if (retry == 0) if (retry == 0)
return -1; return -1;
reg_r(gspca_dev->dev, 0x07, 0x0000, &value, 1); reg_r(gspca_dev, 0x07, 0x0000, 1);
return value; return gspca_dev->usb_buf[0];
} }
static void spca506_SetNormeInput(struct gspca_dev *gspca_dev, static void spca506_SetNormeInput(struct gspca_dev *gspca_dev,
@ -437,7 +435,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
__u16 norme; __u16 norme;
__u16 channel; __u16 channel;
__u8 Data[2];
/**************************************/ /**************************************/
reg_w(dev, 0x03, 0x00, 0x0004); reg_w(dev, 0x03, 0x00, 0x0004);
@ -555,8 +552,8 @@ static void sd_start(struct gspca_dev *gspca_dev)
/* compress setting and size */ /* compress setting and size */
/* set i2c luma */ /* set i2c luma */
reg_w(dev, 0x02, 0x01, 0x0000); reg_w(dev, 0x02, 0x01, 0x0000);
reg_w(dev, 0x03, 0x12, 0x000); reg_w(dev, 0x03, 0x12, 0x0000);
reg_r(dev, 0x04, 0x0001, Data, 2); reg_r(gspca_dev, 0x04, 0x0001, 2);
PDEBUG(D_STREAM, "webcam started"); PDEBUG(D_STREAM, "webcam started");
spca506_GetNormeInput(gspca_dev, &norme, &channel); spca506_GetNormeInput(gspca_dev, &norme, &channel);
spca506_SetNormeInput(gspca_dev, norme, channel); spca506_SetNormeInput(gspca_dev, norme, channel);

View File

@ -22,8 +22,8 @@
#include "gspca.h" #include "gspca.h"
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.5"; static const char version[] = "2.1.7";
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SPCA508 USB Camera Driver"); MODULE_DESCRIPTION("GSPCA/SPCA508 USB Camera Driver");
@ -1433,26 +1433,26 @@ static int reg_write(struct usb_device *dev,
/* read 1 byte */ /* read 1 byte */
/* returns: negative is error, pos or zero is data */ /* returns: negative is error, pos or zero is data */
static int reg_read(struct usb_device *dev, static int reg_read(struct gspca_dev *gspca_dev,
__u16 index) /* wIndex */ __u16 index) /* wIndex */
{ {
int ret; int ret;
__u8 data;
ret = usb_control_msg(dev, ret = usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(dev, 0), usb_rcvctrlpipe(gspca_dev->dev, 0),
0, /* register */ 0, /* register */
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
(__u16) 0, /* value */ 0, /* value */
index, index,
&data, 1, gspca_dev->usb_buf, 1,
500); /* timeout */ 500); /* timeout */
PDEBUG(D_USBI, "reg read i:%04x --> %02x", index, data); PDEBUG(D_USBI, "reg read i:%04x --> %02x",
index, gspca_dev->usb_buf[0]);
if (ret < 0) { if (ret < 0) {
PDEBUG(D_ERR|D_USBI, "reg_read err %d", ret); PDEBUG(D_ERR|D_USBI, "reg_read err %d", ret);
return ret; return ret;
} }
return data; return gspca_dev->usb_buf[0];
} }
static int write_vector(struct gspca_dev *gspca_dev, static int write_vector(struct gspca_dev *gspca_dev,
@ -1475,15 +1475,12 @@ static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
struct cam *cam; struct cam *cam;
__u16 vendor;
__u16 product; __u16 product;
int data1, data2; int data1, data2;
vendor = id->idVendor;
product = id->idProduct; product = id->idProduct;
switch (vendor) { switch (id->idVendor) {
case 0x0130: /* Clone webcam */ case 0x0130: /* Clone webcam */
/* switch (product) { */ /* switch (product) { */
/* case 0x0130: */ /* case 0x0130: */
@ -1535,15 +1532,15 @@ static int sd_config(struct gspca_dev *gspca_dev,
* prove that we can communicate with the device. This works, which * prove that we can communicate with the device. This works, which
* confirms at we are communicating properly and that the device * confirms at we are communicating properly and that the device
* is a 508. */ * is a 508. */
data1 = reg_read(dev, 0x8104); data1 = reg_read(gspca_dev, 0x8104);
data2 = reg_read(dev, 0x8105); data2 = reg_read(gspca_dev, 0x8105);
PDEBUG(D_PROBE, "Webcam Vendor ID: 0x%02x%02x", data2, data1); PDEBUG(D_PROBE, "Webcam Vendor ID: 0x%02x%02x", data2, data1);
data1 = reg_read(dev, 0x8106); data1 = reg_read(gspca_dev, 0x8106);
data2 = reg_read(dev, 0x8107); data2 = reg_read(gspca_dev, 0x8107);
PDEBUG(D_PROBE, "Webcam Product ID: 0x%02x%02x", data2, data1); PDEBUG(D_PROBE, "Webcam Product ID: 0x%02x%02x", data2, data1);
data1 = reg_read(dev, 0x8621); data1 = reg_read(gspca_dev, 0x8621);
PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1); PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1);
cam = &gspca_dev->cam; cam = &gspca_dev->cam;
@ -1711,7 +1708,7 @@ static void getbrightness(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
sd->brightness = reg_read(gspca_dev->dev, 0x8651); sd->brightness = reg_read(gspca_dev, 0x8651);
} }
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)

View File

@ -24,8 +24,8 @@
#include "gspca.h" #include "gspca.h"
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.5"; static const char version[] = "2.1.7";
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver"); MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver");
@ -177,27 +177,28 @@ static void write_vector(struct gspca_dev *gspca_dev,
} }
} }
static void reg_r(struct usb_device *dev, /* read 'len' bytes to gspca_dev->usb_buf */
__u16 index, __u8 *buffer, __u16 length) static void reg_r(struct gspca_dev *gspca_dev,
__u16 index, __u16 length)
{ {
usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
0, /* request */ 0, /* request */
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */ 0, /* value */
index, buffer, length, 500); index, gspca_dev->usb_buf, length, 500);
} }
static void reg_w_buf(struct usb_device *dev, static void reg_w_buf(struct gspca_dev *gspca_dev,
__u16 index, const __u8 *buffer, __u16 len) __u16 index, const __u8 *buffer, __u16 len)
{ {
__u8 tmpbuf[8]; memcpy(gspca_dev->usb_buf, buffer, len);
usb_control_msg(gspca_dev->dev,
memcpy(tmpbuf, buffer, len); usb_sndctrlpipe(gspca_dev->dev, 0),
usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
0, /* request */ 0, /* request */
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */ 0, /* value */
index, tmpbuf, len, 500); index, gspca_dev->usb_buf, len, 500);
} }
static void i2c_init(struct gspca_dev *gspca_dev, __u8 mode) static void i2c_init(struct gspca_dev *gspca_dev, __u8 mode)
@ -211,7 +212,6 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg)
int retry = 60; int retry = 60;
__u8 DataLow; __u8 DataLow;
__u8 DataHight; __u8 DataHight;
__u8 Data;
DataLow = valeur; DataLow = valeur;
DataHight = valeur >> 8; DataHight = valeur >> 8;
@ -219,8 +219,8 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg)
reg_w_val(gspca_dev->dev, DataLow, 0x8805); reg_w_val(gspca_dev->dev, DataLow, 0x8805);
reg_w_val(gspca_dev->dev, DataHight, 0x8800); reg_w_val(gspca_dev->dev, DataHight, 0x8800);
while (retry--) { while (retry--) {
reg_r(gspca_dev->dev, 0x8803, &Data, 1); reg_r(gspca_dev, 0x8803, 1);
if (!Data) if (!gspca_dev->usb_buf[0])
break; break;
} }
} }
@ -230,20 +230,21 @@ static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
int retry = 60; int retry = 60;
__u8 value; __u8 value;
__u8 vallsb; __u8 vallsb;
__u8 Data;
reg_w_val(gspca_dev->dev, 0x92, 0x8804); reg_w_val(gspca_dev->dev, 0x92, 0x8804);
reg_w_val(gspca_dev->dev, reg, 0x8801); reg_w_val(gspca_dev->dev, reg, 0x8801);
reg_w_val(gspca_dev->dev, (mode | 0x01), 0x8802); reg_w_val(gspca_dev->dev, (mode | 0x01), 0x8802);
while (retry--) { while (retry--) {
reg_r(gspca_dev->dev, 0x8803, &Data, 1); reg_r(gspca_dev, 0x8803, 1);
if (!Data) if (!gspca_dev->usb_buf)
break; break;
} }
if (retry == 0) if (retry == 0)
return -1; return -1;
reg_r(gspca_dev->dev, 0x8800, &value, 1); reg_r(gspca_dev, 0x8800, 1);
reg_r(gspca_dev->dev, 0x8805, &vallsb, 1); value = gspca_dev->usb_buf[0];
reg_r(gspca_dev, 0x8805, 1);
vallsb = gspca_dev->usb_buf[0];
return ((int) value << 8) | vallsb; return ((int) value << 8) | vallsb;
} }
@ -541,7 +542,7 @@ static void sensor_mapwrite(struct gspca_dev *gspca_dev,
while (sensormap[i][0]) { while (sensormap[i][0]) {
usbval[0] = sensormap[i][1]; usbval[0] = sensormap[i][1];
usbval[1] = sensormap[i][1] >> 8; usbval[1] = sensormap[i][1] >> 8;
reg_w_buf(gspca_dev->dev, sensormap[i][0], usbval, 2); reg_w_buf(gspca_dev, sensormap[i][0], usbval, 2);
i++; i++;
} }
} }
@ -559,7 +560,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
struct cam *cam; struct cam *cam;
__u16 vendor, product; __u16 vendor, product;
__u8 data1, data2; __u8 data1, data2;
@ -568,11 +568,15 @@ static int sd_config(struct gspca_dev *gspca_dev,
* prove that we can communicate with the device. This works, which * prove that we can communicate with the device. This works, which
* confirms at we are communicating properly and that the device * confirms at we are communicating properly and that the device
* is a 561. */ * is a 561. */
reg_r(dev, 0x8104, &data1, 1); reg_r(gspca_dev, 0x8104, 1);
reg_r(dev, 0x8105, &data2, 1); data1 = gspca_dev->usb_buf[0];
reg_r(gspca_dev, 0x8105, 1);
data2 = gspca_dev->usb_buf[0];
vendor = (data2 << 8) | data1; vendor = (data2 << 8) | data1;
reg_r(dev, 0x8106, &data1, 1); reg_r(gspca_dev, 0x8106, 1);
reg_r(dev, 0x8107, &data2, 1); data1 = gspca_dev->usb_buf[0];
reg_r(gspca_dev, 0x8107, 1);
data2 = gspca_dev->usb_buf[0];
product = (data2 << 8) | data1; product = (data2 << 8) | data1;
if (vendor != id->idVendor || product != id->idProduct) { if (vendor != id->idVendor || product != id->idProduct) {
PDEBUG(D_PROBE, "Bad vendor / product from device"); PDEBUG(D_PROBE, "Bad vendor / product from device");
@ -656,8 +660,8 @@ static void setcontrast(struct gspca_dev *gspca_dev)
Reg8391[0] = expotimes & 0xff; /* exposure */ Reg8391[0] = expotimes & 0xff; /* exposure */
Reg8391[1] = 0x18 | (expotimes >> 8); Reg8391[1] = 0x18 | (expotimes >> 8);
Reg8391[2] = sd->brightness; /* gain */ Reg8391[2] = sd->brightness; /* gain */
reg_w_buf(dev, 0x8391, Reg8391, 8); reg_w_buf(gspca_dev, 0x8391, Reg8391, 8);
reg_w_buf(dev, 0x8390, Reg8391, 8); reg_w_buf(gspca_dev, 0x8390, Reg8391, 8);
break; break;
} }
} }
@ -714,10 +718,11 @@ static void sd_start(struct gspca_dev *gspca_dev)
* is sufficient to push raw frames at ~20fps */ * is sufficient to push raw frames at ~20fps */
reg_w_val(dev, 0x8500, mode); reg_w_val(dev, 0x8500, mode);
} /* -- qq@kuku.eu.org */ } /* -- qq@kuku.eu.org */
reg_w_buf(dev, 0x8307, Reg8307, 2); reg_w_buf(gspca_dev, 0x8307, Reg8307, 2);
reg_w_val(dev, 0x8700, Clck); /* 0x8f 0x85 0x27 clock */ reg_w_val(gspca_dev->dev, 0x8700, Clck);
reg_w_val(dev, 0x8112, 0x1e | 0x20); /* 0x8f 0x85 0x27 clock */
reg_w_val(dev, 0x850b, 0x03); reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
reg_w_val(gspca_dev->dev, 0x850b, 0x03);
setcontrast(gspca_dev); setcontrast(gspca_dev);
break; break;
} }
@ -752,10 +757,14 @@ static void setautogain(struct gspca_dev *gspca_dev)
switch (sd->chip_revision) { switch (sd->chip_revision) {
case Rev072A: case Rev072A:
reg_r(gspca_dev->dev, 0x8621, &Gr, 1); reg_r(gspca_dev, 0x8621, 1);
reg_r(gspca_dev->dev, 0x8622, &R, 1); Gr = gspca_dev->usb_buf[0];
reg_r(gspca_dev->dev, 0x8623, &B, 1); reg_r(gspca_dev, 0x8622, 1);
reg_r(gspca_dev->dev, 0x8624, &Gb, 1); R = gspca_dev->usb_buf[0];
reg_r(gspca_dev, 0x8623, 1);
B = gspca_dev->usb_buf[0];
reg_r(gspca_dev, 0x8624, 1);
Gb = gspca_dev->usb_buf[0];
y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8; y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8;
/* u= (128*B-(43*(Gr+Gb+R))) >> 8; */ /* u= (128*B-(43*(Gr+Gb+R))) >> 8; */
/* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */ /* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */
@ -867,20 +876,19 @@ static void setbrightness(struct gspca_dev *gspca_dev)
static void getbrightness(struct gspca_dev *gspca_dev) static void getbrightness(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
__u8 value;
__u16 tot; __u16 tot;
switch (sd->chip_revision) { switch (sd->chip_revision) {
case Rev072A: case Rev072A:
tot = 0; tot = 0;
reg_r(gspca_dev->dev, 0x8611, &value, 1); reg_r(gspca_dev, 0x8611, 1);
tot += value; tot += gspca_dev->usb_buf[0];
reg_r(gspca_dev->dev, 0x8612, &value, 1); reg_r(gspca_dev, 0x8612, 1);
tot += value; tot += gspca_dev->usb_buf[0];
reg_r(gspca_dev->dev, 0x8613, &value, 1); reg_r(gspca_dev, 0x8613, 1);
tot += value; tot += gspca_dev->usb_buf[0];
reg_r(gspca_dev->dev, 0x8614, &value, 1); reg_r(gspca_dev, 0x8614, 1);
tot += value; tot += gspca_dev->usb_buf[0];
sd->brightness = tot >> 2; sd->brightness = tot >> 2;
break; break;
default: default:
@ -893,20 +901,19 @@ static void getbrightness(struct gspca_dev *gspca_dev)
static void getcontrast(struct gspca_dev *gspca_dev) static void getcontrast(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
__u8 value;
__u16 tot; __u16 tot;
switch (sd->chip_revision) { switch (sd->chip_revision) {
case Rev072A: case Rev072A:
tot = 0; tot = 0;
reg_r(gspca_dev->dev, 0x8651, &value, 1); reg_r(gspca_dev, 0x8651, 1);
tot += value; tot += gspca_dev->usb_buf[0];
reg_r(gspca_dev->dev, 0x8652, &value, 1); reg_r(gspca_dev, 0x8652, 1);
tot += value; tot += gspca_dev->usb_buf[0];
reg_r(gspca_dev->dev, 0x8653, &value, 1); reg_r(gspca_dev, 0x8653, 1);
tot += value; tot += gspca_dev->usb_buf[0];
reg_r(gspca_dev->dev, 0x8654, &value, 1); reg_r(gspca_dev, 0x8654, 1);
tot += value; tot += gspca_dev->usb_buf[0];
sd->contrast = tot << 6; sd->contrast = tot << 6;
break; break;
default: default:

View File

@ -23,8 +23,8 @@
#include "gspca.h" #include "gspca.h"
#include "jpeg.h" #include "jpeg.h"
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.5"; static const char version[] = "2.1.7";
MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver");
@ -127,7 +127,7 @@ static struct v4l2_pix_format vga_mode[] = {
/* -- read a register -- */ /* -- read a register -- */
static int reg_r(struct gspca_dev *gspca_dev, static int reg_r(struct gspca_dev *gspca_dev,
__u16 index, __u8 *buf) __u16 index)
{ {
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
int ret; int ret;
@ -137,11 +137,13 @@ static int reg_r(struct gspca_dev *gspca_dev,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x00, 0x00,
index, index,
buf, 1, gspca_dev->usb_buf, 1,
500); 500);
if (ret < 0) if (ret < 0) {
PDEBUG(D_ERR, "reg_r err %d", ret); PDEBUG(D_ERR, "reg_r err %d", ret);
return ret; return ret;
}
return gspca_dev->usb_buf[0];
} }
/* -- write a register -- */ /* -- write a register -- */
@ -164,58 +166,55 @@ static int reg_w(struct gspca_dev *gspca_dev,
return ret; return ret;
} }
/* -- get a value -- */ /* -- get a bulk value (4 bytes) -- */
static int rcv_val(struct gspca_dev *gspca_dev, static int rcv_val(struct gspca_dev *gspca_dev,
int ads, int ads)
int len)
{ {
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
int alen, ret; int alen, ret;
unsigned char bulk_buf[4];
reg_w(gspca_dev, 0x634, (ads >> 16) & 0xff); reg_w(gspca_dev, 0x634, (ads >> 16) & 0xff);
reg_w(gspca_dev, 0x635, (ads >> 8) & 0xff); reg_w(gspca_dev, 0x635, (ads >> 8) & 0xff);
reg_w(gspca_dev, 0x636, ads & 0xff); reg_w(gspca_dev, 0x636, ads & 0xff);
reg_w(gspca_dev, 0x637, 0); reg_w(gspca_dev, 0x637, 0);
reg_w(gspca_dev, 0x638, len & 0xff); reg_w(gspca_dev, 0x638, 4); /* len & 0xff */
reg_w(gspca_dev, 0x639, len >> 8); reg_w(gspca_dev, 0x639, 0); /* len >> 8 */
reg_w(gspca_dev, 0x63a, 0); reg_w(gspca_dev, 0x63a, 0);
reg_w(gspca_dev, 0x63b, 0); reg_w(gspca_dev, 0x63b, 0);
reg_w(gspca_dev, 0x630, 5); reg_w(gspca_dev, 0x630, 5);
if (len > sizeof bulk_buf)
return -1;
ret = usb_bulk_msg(dev, ret = usb_bulk_msg(dev,
usb_rcvbulkpipe(dev, 5), usb_rcvbulkpipe(dev, 5),
bulk_buf, gspca_dev->usb_buf,
len, 4, /* length */
&alen, &alen,
500); /* timeout in milliseconds */ 500); /* timeout in milliseconds */
return ret; return ret;
} }
/* -- send a value -- */ /* -- send a bulk value -- */
static int snd_val(struct gspca_dev *gspca_dev, static int snd_val(struct gspca_dev *gspca_dev,
int ads, int ads,
unsigned int val) unsigned int val)
{ {
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
int alen, ret; int alen, ret;
__u8 value, seq; __u8 seq = 0;
unsigned char bulk_buf[4];
if (ads == 0x003f08) { if (ads == 0x003f08) {
ret = reg_r(gspca_dev, 0x0704, &value); ret = reg_r(gspca_dev, 0x0704);
if (ret < 0) if (ret < 0)
goto ko; goto ko;
ret = reg_r(gspca_dev, 0x0705, &seq); ret = reg_r(gspca_dev, 0x0705);
if (ret < 0) if (ret < 0)
goto ko; goto ko;
ret = reg_r(gspca_dev, 0x0650, &value); seq = ret; /* keep the sequence number */
ret = reg_r(gspca_dev, 0x0650);
if (ret < 0) if (ret < 0)
goto ko; goto ko;
reg_w(gspca_dev, 0x654, seq); reg_w(gspca_dev, 0x654, seq);
} else } else {
reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff); reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff);
}
reg_w(gspca_dev, 0x655, (ads >> 8) & 0xff); reg_w(gspca_dev, 0x655, (ads >> 8) & 0xff);
reg_w(gspca_dev, 0x656, ads & 0xff); reg_w(gspca_dev, 0x656, ads & 0xff);
reg_w(gspca_dev, 0x657, 0); reg_w(gspca_dev, 0x657, 0);
@ -224,13 +223,13 @@ static int snd_val(struct gspca_dev *gspca_dev,
reg_w(gspca_dev, 0x65a, 0); reg_w(gspca_dev, 0x65a, 0);
reg_w(gspca_dev, 0x65b, 0); reg_w(gspca_dev, 0x65b, 0);
reg_w(gspca_dev, 0x650, 5); reg_w(gspca_dev, 0x650, 5);
bulk_buf[0] = (val >> 24) & 0xff; gspca_dev->usb_buf[0] = val >> 24;
bulk_buf[1] = (val >> 16) & 0xff; gspca_dev->usb_buf[1] = val >> 16;
bulk_buf[2] = (val >> 8) & 0xff; gspca_dev->usb_buf[2] = val >> 8;
bulk_buf[3] = val & 0xff; gspca_dev->usb_buf[3] = val;
ret = usb_bulk_msg(dev, ret = usb_bulk_msg(dev,
usb_sndbulkpipe(dev, 6), usb_sndbulkpipe(dev, 6),
bulk_buf, gspca_dev->usb_buf,
4, 4,
&alen, &alen,
500); /* timeout in milliseconds */ 500); /* timeout in milliseconds */
@ -303,7 +302,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->dev_name = (char *) id->driver_info; cam->dev_name = (char *) id->driver_info;
cam->epaddr = 0x02; cam->epaddr = 0x02;
gspca_dev->cam.cam_mode = vga_mode; gspca_dev->cam.cam_mode = vga_mode;
gspca_dev->cam.nmodes = sizeof vga_mode / sizeof vga_mode[0]; gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
sd->brightness = BRIGHTNESS_DEF; sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF; sd->contrast = CONTRAST_DEF;
sd->colors = COLOR_DEF; sd->colors = COLOR_DEF;
@ -314,16 +313,15 @@ static int sd_config(struct gspca_dev *gspca_dev,
/* this function is called at open time */ /* this function is called at open time */
static int sd_open(struct gspca_dev *gspca_dev) static int sd_open(struct gspca_dev *gspca_dev)
{ {
__u8 value;
int ret; int ret;
/* check if the device responds */ /* check if the device responds */
usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
ret = reg_r(gspca_dev, 0x0740, &value); ret = reg_r(gspca_dev, 0x0740);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (value != 0xff) { if (ret != 0xff) {
PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", value); PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", ret);
return -1; return -1;
} }
return 0; return 0;
@ -332,7 +330,6 @@ static int sd_open(struct gspca_dev *gspca_dev)
/* -- start the camera -- */ /* -- start the camera -- */
static void sd_start(struct gspca_dev *gspca_dev) static void sd_start(struct gspca_dev *gspca_dev)
{ {
__u8 dum;
int ret, value; int ret, value;
/* work on alternate 1 */ /* work on alternate 1 */
@ -355,11 +352,11 @@ static void sd_start(struct gspca_dev *gspca_dev)
gspca_dev->iface, gspca_dev->alt); gspca_dev->iface, gspca_dev->alt);
goto out; goto out;
} }
ret = reg_r(gspca_dev, 0x0630, &dum); ret = reg_r(gspca_dev, 0x0630);
if (ret < 0) if (ret < 0)
goto out; goto out;
rcv_val(gspca_dev, 0x000020, 4); /* << (value ff ff ff ff) */ rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */
ret = reg_r(gspca_dev, 0x0650, &dum); ret = reg_r(gspca_dev, 0x0650);
if (ret < 0) if (ret < 0)
goto out; goto out;
snd_val(gspca_dev, 0x000020, 0xffffffff); snd_val(gspca_dev, 0x000020, 0xffffffff);
@ -389,14 +386,13 @@ out:
static void sd_stopN(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
__u8 value;
set_par(gspca_dev, 0x02000000); set_par(gspca_dev, 0x02000000);
set_par(gspca_dev, 0x02000000); set_par(gspca_dev, 0x02000000);
usb_set_interface(dev, gspca_dev->iface, 1); usb_set_interface(dev, gspca_dev->iface, 1);
reg_r(gspca_dev, 0x0630, &value); reg_r(gspca_dev, 0x0630);
rcv_val(gspca_dev, 0x000020, 4); /* << (value ff ff ff ff) */ rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */
reg_r(gspca_dev, 0x0650, &value); reg_r(gspca_dev, 0x0650);
snd_val(gspca_dev, 0x000020, 0xffffffff); snd_val(gspca_dev, 0x000020, 0xffffffff);
reg_w(gspca_dev, 0x0620, 0); reg_w(gspca_dev, 0x0620, 0);
reg_w(gspca_dev, 0x0630, 0); reg_w(gspca_dev, 0x0630, 0);
@ -538,10 +534,10 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
} }
/* sub-driver description */ /* sub-driver description */
static struct sd_desc sd_desc = { static const struct sd_desc sd_desc = {
.name = MODULE_NAME, .name = MODULE_NAME,
.ctrls = sd_ctrls, .ctrls = sd_ctrls,
.nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0], .nctrls = ARRAY_SIZE(sd_ctrls),
.config = sd_config, .config = sd_config,
.open = sd_open, .open = sd_open,
.start = sd_start, .start = sd_start,
@ -554,7 +550,7 @@ static struct sd_desc sd_desc = {
/* -- module initialisation -- */ /* -- module initialisation -- */
#define DVNM(name) .driver_info = (kernel_ulong_t) name #define DVNM(name) .driver_info = (kernel_ulong_t) name
static __devinitdata struct usb_device_id device_table[] = { static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x05e1, 0x0893), DVNM("Syntek DV4000")}, {USB_DEVICE(0x05e1, 0x0893), DVNM("Syntek DV4000")},
{} {}
}; };

View File

@ -24,8 +24,8 @@
#include "gspca.h" #include "gspca.h"
#include "jpeg.h" #include "jpeg.h"
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.5"; static const char version[] = "2.1.7";
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver"); MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver");
@ -452,7 +452,7 @@ static const __u8 qtable_spca504_default[2][64] = {
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e} 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
}; };
static void spca5xxRegRead(struct usb_device *dev, static void reg_r(struct usb_device *dev,
__u16 req, __u16 req,
__u16 index, __u16 index,
__u8 *buffer, __u16 length) __u8 *buffer, __u16 length)
@ -466,7 +466,7 @@ static void spca5xxRegRead(struct usb_device *dev,
500); 500);
} }
static void spca5xxRegWrite(struct usb_device *dev, static void reg_w(struct usb_device *dev,
__u16 req, __u16 req,
__u16 value, __u16 value,
__u16 index, __u16 index,
@ -480,7 +480,8 @@ static void spca5xxRegWrite(struct usb_device *dev,
500); 500);
} }
static int reg_write(struct usb_device *dev, /* write req / index / value */
static int reg_w_riv(struct usb_device *dev,
__u16 req, __u16 index, __u16 value) __u16 req, __u16 index, __u16 value)
{ {
int ret; int ret;
@ -490,57 +491,56 @@ static int reg_write(struct usb_device *dev,
req, req,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, index, NULL, 0, 500); value, index, NULL, 0, 500);
PDEBUG(D_PACK, "reg write: 0x%02x,0x%02x:0x%02x, 0x%x", PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d",
req, index, value, ret); req, index, value, ret);
if (ret < 0) if (ret < 0)
PDEBUG(D_ERR, "reg write: error %d", ret); PDEBUG(D_ERR, "reg write: error %d", ret);
return ret; return ret;
} }
static int reg_read_info(struct usb_device *dev, /* read 1 byte */
static int reg_r_1(struct gspca_dev *gspca_dev,
__u16 value) /* wValue */ __u16 value) /* wValue */
{ {
int ret; int ret;
__u8 data;
ret = usb_control_msg(dev, ret = usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(dev, 0), usb_rcvctrlpipe(gspca_dev->dev, 0),
0x20, /* request */ 0x20, /* request */
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, value,
0, /* index */ 0, /* index */
&data, 1, gspca_dev->usb_buf, 1,
500); /* timeout */ 500); /* timeout */
if (ret < 0) { if (ret < 0) {
PDEBUG(D_ERR, "reg_read_info err %d", ret); PDEBUG(D_ERR, "reg_r_1 err %d", ret);
return 0; return 0;
} }
return data; return gspca_dev->usb_buf[0];
} }
/* returns: negative is error, pos or zero is data */ /* read 1 or 2 bytes - returns < 0 if error */
static int reg_read(struct usb_device *dev, static int reg_r_12(struct gspca_dev *gspca_dev,
__u16 req, /* bRequest */ __u16 req, /* bRequest */
__u16 index, /* wIndex */ __u16 index, /* wIndex */
__u16 length) /* wLength (1 or 2 only) */ __u16 length) /* wLength (1 or 2 only) */
{ {
int ret; int ret;
__u8 buf[2];
buf[1] = 0; gspca_dev->usb_buf[1] = 0;
ret = usb_control_msg(dev, ret = usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(dev, 0), usb_rcvctrlpipe(gspca_dev->dev, 0),
req, req,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */ 0, /* value */
index, index,
buf, length, gspca_dev->usb_buf, length,
500); 500);
if (ret < 0) { if (ret < 0) {
PDEBUG(D_ERR, "reg_read err %d", ret); PDEBUG(D_ERR, "reg_read err %d", ret);
return -1; return -1;
} }
return (buf[1] << 8) + buf[0]; return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
} }
static int write_vector(struct gspca_dev *gspca_dev, static int write_vector(struct gspca_dev *gspca_dev,
@ -550,7 +550,7 @@ static int write_vector(struct gspca_dev *gspca_dev,
int ret, i = 0; int ret, i = 0;
while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); ret = reg_w_riv(dev, data[i][0], data[i][2], data[i][1]);
if (ret < 0) { if (ret < 0) {
PDEBUG(D_ERR, PDEBUG(D_ERR,
"Register write failed for 0x%x,0x%x,0x%x", "Register write failed for 0x%x,0x%x,0x%x",
@ -573,14 +573,14 @@ static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
/* loop over y components */ /* loop over y components */
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
err = reg_write(dev, request, ybase + i, qtable[0][i]); err = reg_w_riv(dev, request, ybase + i, qtable[0][i]);
if (err < 0) if (err < 0)
return err; return err;
} }
/* loop over c components */ /* loop over c components */
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
err = reg_write(dev, request, cbase + i, qtable[1][i]); err = reg_w_riv(dev, request, cbase + i, qtable[1][i]);
if (err < 0) if (err < 0)
return err; return err;
} }
@ -593,14 +593,14 @@ static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
__u8 notdone; __u8 notdone;
reg_write(dev, req, idx, val); reg_w_riv(dev, req, idx, val);
notdone = reg_read(dev, 0x01, 0x0001, 1); notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
reg_write(dev, req, idx, val); reg_w_riv(dev, req, idx, val);
PDEBUG(D_FRAM, "before wait 0x%x", notdone); PDEBUG(D_FRAM, "before wait 0x%x", notdone);
msleep(200); msleep(200);
notdone = reg_read(dev, 0x01, 0x0001, 1); notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
PDEBUG(D_FRAM, "after wait 0x%x", notdone); PDEBUG(D_FRAM, "after wait 0x%x", notdone);
} }
@ -612,8 +612,8 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
__u8 status; __u8 status;
__u8 endcode; __u8 endcode;
reg_write(dev, req, idx, val); reg_w_riv(dev, req, idx, val);
status = reg_read(dev, 0x01, 0x0001, 1); status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
endcode = stat; endcode = stat;
PDEBUG(D_FRAM, "Status 0x%x Need 0x%x", status, stat); PDEBUG(D_FRAM, "Status 0x%x Need 0x%x", status, stat);
if (!count) if (!count)
@ -622,8 +622,8 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
while (--count > 0) { while (--count > 0) {
msleep(10); msleep(10);
/* gsmart mini2 write a each wait setting 1 ms is enought */ /* gsmart mini2 write a each wait setting 1 ms is enought */
/* reg_write(dev, req, idx, val); */ /* reg_w_riv(dev, req, idx, val); */
status = reg_read(dev, 0x01, 0x0001, 1); status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
if (status == endcode) { if (status == endcode) {
PDEBUG(D_FRAM, "status 0x%x after wait 0x%x", PDEBUG(D_FRAM, "status 0x%x after wait 0x%x",
status, 200 - count); status, 200 - count);
@ -632,34 +632,31 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
} }
} }
static int spca504B_PollingDataReady(struct usb_device *dev) static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
{ {
__u8 DataReady;
int count = 10; int count = 10;
while (--count > 0) { while (--count > 0) {
spca5xxRegRead(dev, 0x21, 0, &DataReady, 1); reg_r(gspca_dev->dev, 0x21, 0, gspca_dev->usb_buf, 1);
if ((DataReady & 0x01) == 0) if ((gspca_dev->usb_buf[0] & 0x01) == 0)
break; break;
msleep(10); msleep(10);
} }
return DataReady; return gspca_dev->usb_buf[0];
} }
static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev) static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
__u8 DataReady;
int count = 50; int count = 50;
while (--count > 0) { while (--count > 0) {
spca5xxRegRead(dev, 0x21, 1, &DataReady, 1); reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1);
if (gspca_dev->usb_buf[0] != 0) {
if (DataReady) { gspca_dev->usb_buf[0] = 0;
DataReady = 0; reg_w(dev, 0x21, 0, 1, gspca_dev->usb_buf, 1);
spca5xxRegWrite(dev, 0x21, 0, 1, &DataReady, 1); reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1);
spca5xxRegRead(dev, 0x21, 1, &DataReady, 1); spca504B_PollingDataReady(gspca_dev);
spca504B_PollingDataReady(dev);
break; break;
} }
msleep(10); msleep(10);
@ -669,14 +666,15 @@ static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
static void spca50x_GetFirmware(struct gspca_dev *gspca_dev) static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
__u8 FW[5]; __u8 *data;
__u8 ProductInfo[64];
spca5xxRegRead(dev, 0x20, 0, FW, 5); data = kmalloc(64, GFP_KERNEL);
reg_r(dev, 0x20, 0, data, 5);
PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ", PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ",
FW[0], FW[1], FW[2], FW[3], FW[4]); data[0], data[1], data[2], data[3], data[4]);
spca5xxRegRead(dev, 0x23, 0, ProductInfo, 64); reg_r(dev, 0x23, 0, data, 64);
spca5xxRegRead(dev, 0x23, 1, ProductInfo, 64); reg_r(dev, 0x23, 1, data, 64);
kfree(data);
} }
static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
@ -691,32 +689,35 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
Type = 0; Type = 0;
switch (sd->bridge) { switch (sd->bridge) {
case BRIDGE_SPCA533: case BRIDGE_SPCA533:
spca5xxRegWrite(dev, 0x31, 0, 0, NULL, 0); reg_w(dev, 0x31, 0, 0, NULL, 0);
spca504B_WaitCmdStatus(gspca_dev); spca504B_WaitCmdStatus(gspca_dev);
rc = spca504B_PollingDataReady(dev); rc = spca504B_PollingDataReady(gspca_dev);
spca50x_GetFirmware(gspca_dev); spca50x_GetFirmware(gspca_dev);
Type = 2; gspca_dev->usb_buf[0] = 2; /* type */
spca5xxRegWrite(dev, 0x24, 0, 8, &Type, 1); reg_w(dev, 0x24, 0, 8, gspca_dev->usb_buf, 1);
spca5xxRegRead(dev, 0x24, 8, &Type, 1); reg_r(dev, 0x24, 8, gspca_dev->usb_buf, 1);
spca5xxRegWrite(dev, 0x25, 0, 4, &Size, 1); gspca_dev->usb_buf[0] = Size;
spca5xxRegRead(dev, 0x25, 4, &Size, 1); reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1);
rc = spca504B_PollingDataReady(dev); reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1); /* size */
rc = spca504B_PollingDataReady(gspca_dev);
/* Init the cam width height with some values get on init ? */ /* Init the cam width height with some values get on init ? */
spca5xxRegWrite(dev, 0x31, 0, 4, NULL, 0); reg_w(dev, 0x31, 0, 4, NULL, 0);
spca504B_WaitCmdStatus(gspca_dev); spca504B_WaitCmdStatus(gspca_dev);
rc = spca504B_PollingDataReady(dev); rc = spca504B_PollingDataReady(gspca_dev);
break; break;
default: default:
/* case BRIDGE_SPCA504B: */ /* case BRIDGE_SPCA504B: */
/* case BRIDGE_SPCA536: */ /* case BRIDGE_SPCA536: */
gspca_dev->usb_buf[0] = Size;
reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1);
reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1); /* size */
Type = 6; Type = 6;
spca5xxRegWrite(dev, 0x25, 0, 4, &Size, 1); gspca_dev->usb_buf[0] = Type;
spca5xxRegRead(dev, 0x25, 4, &Size, 1); reg_w(dev, 0x27, 0, 0, gspca_dev->usb_buf, 1);
spca5xxRegWrite(dev, 0x27, 0, 0, &Type, 1); reg_r(dev, 0x27, 0, gspca_dev->usb_buf, 1); /* type */
spca5xxRegRead(dev, 0x27, 0, &Type, 1); rc = spca504B_PollingDataReady(gspca_dev);
rc = spca504B_PollingDataReady(dev);
break; break;
case BRIDGE_SPCA504: case BRIDGE_SPCA504:
Size += 3; Size += 3;
@ -733,21 +734,20 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
break; break;
case BRIDGE_SPCA504C: case BRIDGE_SPCA504C:
/* capture mode */ /* capture mode */
reg_write(dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x0); reg_w_riv(dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
reg_write(dev, 0x20, 0x01, 0x0500 | (Size & 0x0f)); reg_w_riv(dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
break; break;
} }
} }
static void spca504_wait_status(struct gspca_dev *gspca_dev) static void spca504_wait_status(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev;
int cnt; int cnt;
cnt = 256; cnt = 256;
while (--cnt > 0) { while (--cnt > 0) {
/* With this we get the status, when return 0 it's all ok */ /* With this we get the status, when return 0 it's all ok */
if (reg_read(dev, 0x06, 0x00, 1) == 0) if (reg_r_12(gspca_dev, 0x06, 0x00, 1) == 0)
return; return;
msleep(10); msleep(10);
} }
@ -756,11 +756,11 @@ static void spca504_wait_status(struct gspca_dev *gspca_dev)
static void spca504B_setQtable(struct gspca_dev *gspca_dev) static void spca504B_setQtable(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
__u8 Data = 3;
spca5xxRegWrite(dev, 0x26, 0, 0, &Data, 1); gspca_dev->usb_buf[0] = 3;
spca5xxRegRead(dev, 0x26, 0, &Data, 1); reg_w(dev, 0x26, 0, 0, gspca_dev->usb_buf, 1);
spca504B_PollingDataReady(dev); reg_r(dev, 0x26, 0, gspca_dev->usb_buf, 1);
spca504B_PollingDataReady(gspca_dev);
} }
static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev) static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev)
@ -777,24 +777,24 @@ static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev)
default: default:
/* case BRIDGE_SPCA533: */ /* case BRIDGE_SPCA533: */
/* case BRIDGE_SPCA504B: */ /* case BRIDGE_SPCA504B: */
spca5xxRegWrite(dev, 0, 0, 0x21a7, NULL, 0); /* brightness */ reg_w(dev, 0, 0, 0x21a7, NULL, 0); /* brightness */
spca5xxRegWrite(dev, 0, 0x20, 0x21a8, NULL, 0); /* contrast */ reg_w(dev, 0, 0x20, 0x21a8, NULL, 0); /* contrast */
spca5xxRegWrite(dev, 0, 0, 0x21ad, NULL, 0); /* hue */ reg_w(dev, 0, 0, 0x21ad, NULL, 0); /* hue */
spca5xxRegWrite(dev, 0, 1, 0x21ac, NULL, 0); /* sat/hue */ reg_w(dev, 0, 1, 0x21ac, NULL, 0); /* sat/hue */
spca5xxRegWrite(dev, 0, 0x20, 0x21ae, NULL, 0); /* saturation */ reg_w(dev, 0, 0x20, 0x21ae, NULL, 0); /* saturation */
spca5xxRegWrite(dev, 0, 0, 0x21a3, NULL, 0); /* gamma */ reg_w(dev, 0, 0, 0x21a3, NULL, 0); /* gamma */
break; break;
case BRIDGE_SPCA536: case BRIDGE_SPCA536:
spca5xxRegWrite(dev, 0, 0, 0x20f0, NULL, 0); reg_w(dev, 0, 0, 0x20f0, NULL, 0);
spca5xxRegWrite(dev, 0, 0x21, 0x20f1, NULL, 0); reg_w(dev, 0, 0x21, 0x20f1, NULL, 0);
spca5xxRegWrite(dev, 0, 0x40, 0x20f5, NULL, 0); reg_w(dev, 0, 0x40, 0x20f5, NULL, 0);
spca5xxRegWrite(dev, 0, 1, 0x20f4, NULL, 0); reg_w(dev, 0, 1, 0x20f4, NULL, 0);
spca5xxRegWrite(dev, 0, 0x40, 0x20f6, NULL, 0); reg_w(dev, 0, 0x40, 0x20f6, NULL, 0);
spca5xxRegWrite(dev, 0, 0, 0x2089, NULL, 0); reg_w(dev, 0, 0, 0x2089, NULL, 0);
break; break;
} }
if (pollreg) if (pollreg)
spca504B_PollingDataReady(dev); spca504B_PollingDataReady(gspca_dev);
} }
/* this function is called at probe time */ /* this function is called at probe time */
@ -872,7 +872,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
case 0x504a: case 0x504a:
/* try to get the firmware as some cam answer 2.0.1.2.2 /* try to get the firmware as some cam answer 2.0.1.2.2
* and should be a spca504b then overwrite that setting */ * and should be a spca504b then overwrite that setting */
spca5xxRegRead(dev, 0x20, 0, &fw, 1); reg_r(dev, 0x20, 0, gspca_dev->usb_buf, 1);
fw = gspca_dev->usb_buf[0];
if (fw == 1) { if (fw == 1) {
sd->subtype = AiptekMiniPenCam13; sd->subtype = AiptekMiniPenCam13;
sd->bridge = BRIDGE_SPCA504; sd->bridge = BRIDGE_SPCA504;
@ -1048,38 +1049,37 @@ static int sd_open(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
int rc; int rc;
__u8 Data;
__u8 i; __u8 i;
__u8 info[6]; __u8 info[6];
int err_code; int err_code;
switch (sd->bridge) { switch (sd->bridge) {
case BRIDGE_SPCA504B: case BRIDGE_SPCA504B:
spca5xxRegWrite(dev, 0x1d, 0, 0, NULL, 0); reg_w(dev, 0x1d, 0, 0, NULL, 0);
spca5xxRegWrite(dev, 0, 1, 0x2306, NULL, 0); reg_w(dev, 0, 1, 0x2306, NULL, 0);
spca5xxRegWrite(dev, 0, 0, 0x0d04, NULL, 0); reg_w(dev, 0, 0, 0x0d04, NULL, 0);
spca5xxRegWrite(dev, 0, 0, 0x2000, NULL, 0); reg_w(dev, 0, 0, 0x2000, NULL, 0);
spca5xxRegWrite(dev, 0, 0x13, 0x2301, NULL, 0); reg_w(dev, 0, 0x13, 0x2301, NULL, 0);
spca5xxRegWrite(dev, 0, 0, 0x2306, NULL, 0); reg_w(dev, 0, 0, 0x2306, NULL, 0);
/* fall thru */ /* fall thru */
case BRIDGE_SPCA533: case BRIDGE_SPCA533:
rc = spca504B_PollingDataReady(dev); rc = spca504B_PollingDataReady(gspca_dev);
spca50x_GetFirmware(gspca_dev); spca50x_GetFirmware(gspca_dev);
break; break;
case BRIDGE_SPCA536: case BRIDGE_SPCA536:
spca50x_GetFirmware(gspca_dev); spca50x_GetFirmware(gspca_dev);
spca5xxRegRead(dev, 0x00, 0x5002, &Data, 1); reg_r(dev, 0x00, 0x5002, gspca_dev->usb_buf, 1);
Data = 0; gspca_dev->usb_buf[0] = 0;
spca5xxRegWrite(dev, 0x24, 0, 0, &Data, 1); reg_w(dev, 0x24, 0, 0, gspca_dev->usb_buf, 1);
spca5xxRegRead(dev, 0x24, 0, &Data, 1); reg_r(dev, 0x24, 0, gspca_dev->usb_buf, 1);
rc = spca504B_PollingDataReady(dev); rc = spca504B_PollingDataReady(gspca_dev);
spca5xxRegWrite(dev, 0x34, 0, 0, NULL, 0); reg_w(dev, 0x34, 0, 0, NULL, 0);
spca504B_WaitCmdStatus(gspca_dev); spca504B_WaitCmdStatus(gspca_dev);
break; break;
case BRIDGE_SPCA504C: /* pccam600 */ case BRIDGE_SPCA504C: /* pccam600 */
PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)"); PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)");
reg_write(dev, 0xe0, 0x0000, 0x0000); reg_w_riv(dev, 0xe0, 0x0000, 0x0000);
reg_write(dev, 0xe0, 0x0000, 0x0001); /* reset */ reg_w_riv(dev, 0xe0, 0x0000, 0x0001); /* reset */
spca504_wait_status(gspca_dev); spca504_wait_status(gspca_dev);
if (sd->subtype == LogitechClickSmart420) if (sd->subtype == LogitechClickSmart420)
write_vector(gspca_dev, write_vector(gspca_dev,
@ -1100,7 +1100,7 @@ static int sd_open(struct gspca_dev *gspca_dev)
if (sd->subtype == AiptekMiniPenCam13) { if (sd->subtype == AiptekMiniPenCam13) {
/*****************************/ /*****************************/
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
info[i] = reg_read_info(dev, i); info[i] = reg_r_1(gspca_dev, i);
PDEBUG(D_STREAM, PDEBUG(D_STREAM,
"Read info: %d %d %d %d %d %d." "Read info: %d %d %d %d %d %d."
" Should be 1,0,2,2,0,0", " Should be 1,0,2,2,0,0",
@ -1126,14 +1126,14 @@ static int sd_open(struct gspca_dev *gspca_dev)
6, 0, 0x86, 1); */ 6, 0, 0x86, 1); */
/* spca504A_acknowledged_command (gspca_dev, 0x24, /* spca504A_acknowledged_command (gspca_dev, 0x24,
0, 0, 0x9D, 1); */ 0, 0, 0x9D, 1); */
reg_write(dev, 0x0, 0x270c, 0x5); /* L92 sno1t.txt */ reg_w_riv(dev, 0x0, 0x270c, 0x05); /* L92 sno1t.txt */
reg_write(dev, 0x0, 0x2310, 0x5); reg_w_riv(dev, 0x0, 0x2310, 0x05);
spca504A_acknowledged_command(gspca_dev, 0x01, spca504A_acknowledged_command(gspca_dev, 0x01,
0x0f, 0, 0xff, 0); 0x0f, 0, 0xff, 0);
} }
/* setup qtable */ /* setup qtable */
reg_write(dev, 0, 0x2000, 0); reg_w_riv(dev, 0, 0x2000, 0);
reg_write(dev, 0, 0x2883, 1); reg_w_riv(dev, 0, 0x2883, 1);
err_code = spca50x_setup_qtable(gspca_dev, err_code = spca50x_setup_qtable(gspca_dev,
0x00, 0x2800, 0x00, 0x2800,
0x2840, 0x2840,
@ -1166,20 +1166,20 @@ static void sd_start(struct gspca_dev *gspca_dev)
/* case BRIDGE_SPCA536: */ /* case BRIDGE_SPCA536: */
if (sd->subtype == MegapixV4 || if (sd->subtype == MegapixV4 ||
sd->subtype == LogitechClickSmart820) { sd->subtype == LogitechClickSmart820) {
spca5xxRegWrite(dev, 0xf0, 0, 0, NULL, 0); reg_w(dev, 0xf0, 0, 0, NULL, 0);
spca504B_WaitCmdStatus(gspca_dev); spca504B_WaitCmdStatus(gspca_dev);
spca5xxRegRead(dev, 0xf0, 4, NULL, 0); reg_r(dev, 0xf0, 4, NULL, 0);
spca504B_WaitCmdStatus(gspca_dev); spca504B_WaitCmdStatus(gspca_dev);
} else { } else {
spca5xxRegWrite(dev, 0x31, 0, 4, NULL, 0); reg_w(dev, 0x31, 0, 4, NULL, 0);
spca504B_WaitCmdStatus(gspca_dev); spca504B_WaitCmdStatus(gspca_dev);
rc = spca504B_PollingDataReady(dev); rc = spca504B_PollingDataReady(gspca_dev);
} }
break; break;
case BRIDGE_SPCA504: case BRIDGE_SPCA504:
if (sd->subtype == AiptekMiniPenCam13) { if (sd->subtype == AiptekMiniPenCam13) {
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
info[i] = reg_read_info(dev, i); info[i] = reg_r_1(gspca_dev, i);
PDEBUG(D_STREAM, PDEBUG(D_STREAM,
"Read info: %d %d %d %d %d %d." "Read info: %d %d %d %d %d %d."
" Should be 1,0,2,2,0,0", " Should be 1,0,2,2,0,0",
@ -1197,7 +1197,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
} else { } else {
spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
info[i] = reg_read_info(dev, i); info[i] = reg_r_1(gspca_dev, i);
PDEBUG(D_STREAM, PDEBUG(D_STREAM,
"Read info: %d %d %d %d %d %d." "Read info: %d %d %d %d %d %d."
" Should be 1,0,2,2,0,0", " Should be 1,0,2,2,0,0",
@ -1207,8 +1207,8 @@ static void sd_start(struct gspca_dev *gspca_dev)
spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
} }
spca504B_SetSizeType(gspca_dev); spca504B_SetSizeType(gspca_dev);
reg_write(dev, 0x0, 0x270c, 0x5); /* L92 sno1t.txt */ reg_w_riv(dev, 0x0, 0x270c, 0x05); /* L92 sno1t.txt */
reg_write(dev, 0x0, 0x2310, 0x5); reg_w_riv(dev, 0x0, 0x2310, 0x05);
break; break;
case BRIDGE_SPCA504C: case BRIDGE_SPCA504C:
if (sd->subtype == LogitechClickSmart420) { if (sd->subtype == LogitechClickSmart420) {
@ -1217,13 +1217,13 @@ static void sd_start(struct gspca_dev *gspca_dev)
} else { } else {
write_vector(gspca_dev, spca504_pccam600_init_data); write_vector(gspca_dev, spca504_pccam600_init_data);
} }
enable = (sd->autogain ? 0x4 : 0x1); enable = (sd->autogain ? 0x04 : 0x01);
reg_write(dev, 0x0c, 0x0000, enable); /* auto exposure */ reg_w_riv(dev, 0x0c, 0x0000, enable); /* auto exposure */
reg_write(dev, 0xb0, 0x0000, enable); /* auto whiteness */ reg_w_riv(dev, 0xb0, 0x0000, enable); /* auto whiteness */
/* set default exposure compensation and whiteness balance */ /* set default exposure compensation and whiteness balance */
reg_write(dev, 0x30, 0x0001, 800); /* ~ 20 fps */ reg_w_riv(dev, 0x30, 0x0001, 800); /* ~ 20 fps */
reg_write(dev, 0x30, 0x0002, 1600); reg_w_riv(dev, 0x30, 0x0002, 1600);
spca504B_SetSizeType(gspca_dev); spca504B_SetSizeType(gspca_dev);
break; break;
} }
@ -1240,13 +1240,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
/* case BRIDGE_SPCA533: */ /* case BRIDGE_SPCA533: */
/* case BRIDGE_SPCA536: */ /* case BRIDGE_SPCA536: */
/* case BRIDGE_SPCA504B: */ /* case BRIDGE_SPCA504B: */
spca5xxRegWrite(dev, 0x31, 0, 0, NULL, 0); reg_w(dev, 0x31, 0, 0, NULL, 0);
spca504B_WaitCmdStatus(gspca_dev); spca504B_WaitCmdStatus(gspca_dev);
spca504B_PollingDataReady(dev); spca504B_PollingDataReady(gspca_dev);
break; break;
case BRIDGE_SPCA504: case BRIDGE_SPCA504:
case BRIDGE_SPCA504C: case BRIDGE_SPCA504C:
reg_write(dev, 0x00, 0x2000, 0x0000); reg_w_riv(dev, 0x00, 0x2000, 0x0000);
if (sd->subtype == AiptekMiniPenCam13) { if (sd->subtype == AiptekMiniPenCam13) {
/* spca504a aiptek */ /* spca504a aiptek */
@ -1258,7 +1258,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
0x0f, 0x00, 0xff, 1); 0x0f, 0x00, 0xff, 1);
} else { } else {
spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
reg_write(dev, 0x01, 0x000f, 0x0); reg_w_riv(dev, 0x01, 0x000f, 0x00);
} }
break; break;
} }
@ -1383,10 +1383,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
/* case BRIDGE_SPCA504B: */ /* case BRIDGE_SPCA504B: */
/* case BRIDGE_SPCA504: */ /* case BRIDGE_SPCA504: */
/* case BRIDGE_SPCA504C: */ /* case BRIDGE_SPCA504C: */
reg_write(dev, 0x0, 0x21a7, sd->brightness); reg_w_riv(dev, 0x0, 0x21a7, sd->brightness);
break; break;
case BRIDGE_SPCA536: case BRIDGE_SPCA536:
reg_write(dev, 0x0, 0x20f0, sd->brightness); reg_w_riv(dev, 0x0, 0x20f0, sd->brightness);
break; break;
} }
} }
@ -1394,7 +1394,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
static void getbrightness(struct gspca_dev *gspca_dev) static void getbrightness(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
__u16 brightness = 0; __u16 brightness = 0;
switch (sd->bridge) { switch (sd->bridge) {
@ -1403,10 +1402,10 @@ static void getbrightness(struct gspca_dev *gspca_dev)
/* case BRIDGE_SPCA504B: */ /* case BRIDGE_SPCA504B: */
/* case BRIDGE_SPCA504: */ /* case BRIDGE_SPCA504: */
/* case BRIDGE_SPCA504C: */ /* case BRIDGE_SPCA504C: */
brightness = reg_read(dev, 0x0, 0x21a7, 2); brightness = reg_r_12(gspca_dev, 0x00, 0x21a7, 2);
break; break;
case BRIDGE_SPCA536: case BRIDGE_SPCA536:
brightness = reg_read(dev, 0x0, 0x20f0, 2); brightness = reg_r_12(gspca_dev, 0x00, 0x20f0, 2);
break; break;
} }
sd->brightness = ((brightness & 0xff) - 128) % 255; sd->brightness = ((brightness & 0xff) - 128) % 255;
@ -1423,10 +1422,10 @@ static void setcontrast(struct gspca_dev *gspca_dev)
/* case BRIDGE_SPCA504B: */ /* case BRIDGE_SPCA504B: */
/* case BRIDGE_SPCA504: */ /* case BRIDGE_SPCA504: */
/* case BRIDGE_SPCA504C: */ /* case BRIDGE_SPCA504C: */
reg_write(dev, 0x0, 0x21a8, sd->contrast); reg_w_riv(dev, 0x0, 0x21a8, sd->contrast);
break; break;
case BRIDGE_SPCA536: case BRIDGE_SPCA536:
reg_write(dev, 0x0, 0x20f1, sd->contrast); reg_w_riv(dev, 0x0, 0x20f1, sd->contrast);
break; break;
} }
} }
@ -1434,7 +1433,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
static void getcontrast(struct gspca_dev *gspca_dev) static void getcontrast(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
switch (sd->bridge) { switch (sd->bridge) {
default: default:
@ -1442,10 +1440,10 @@ static void getcontrast(struct gspca_dev *gspca_dev)
/* case BRIDGE_SPCA504B: */ /* case BRIDGE_SPCA504B: */
/* case BRIDGE_SPCA504: */ /* case BRIDGE_SPCA504: */
/* case BRIDGE_SPCA504C: */ /* case BRIDGE_SPCA504C: */
sd->contrast = reg_read(dev, 0x0, 0x21a8, 2); sd->contrast = reg_r_12(gspca_dev, 0x00, 0x21a8, 2);
break; break;
case BRIDGE_SPCA536: case BRIDGE_SPCA536:
sd->contrast = reg_read(dev, 0x0, 0x20f1, 2); sd->contrast = reg_r_12(gspca_dev, 0x00, 0x20f1, 2);
break; break;
} }
} }
@ -1461,10 +1459,10 @@ static void setcolors(struct gspca_dev *gspca_dev)
/* case BRIDGE_SPCA504B: */ /* case BRIDGE_SPCA504B: */
/* case BRIDGE_SPCA504: */ /* case BRIDGE_SPCA504: */
/* case BRIDGE_SPCA504C: */ /* case BRIDGE_SPCA504C: */
reg_write(dev, 0x0, 0x21ae, sd->colors); reg_w_riv(dev, 0x0, 0x21ae, sd->colors);
break; break;
case BRIDGE_SPCA536: case BRIDGE_SPCA536:
reg_write(dev, 0x0, 0x20f6, sd->colors); reg_w_riv(dev, 0x0, 0x20f6, sd->colors);
break; break;
} }
} }
@ -1472,7 +1470,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
static void getcolors(struct gspca_dev *gspca_dev) static void getcolors(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
switch (sd->bridge) { switch (sd->bridge) {
default: default:
@ -1480,10 +1477,10 @@ static void getcolors(struct gspca_dev *gspca_dev)
/* case BRIDGE_SPCA504B: */ /* case BRIDGE_SPCA504B: */
/* case BRIDGE_SPCA504: */ /* case BRIDGE_SPCA504: */
/* case BRIDGE_SPCA504C: */ /* case BRIDGE_SPCA504C: */
sd->colors = reg_read(dev, 0x0, 0x21ae, 2) >> 1; sd->colors = reg_r_12(gspca_dev, 0x00, 0x21ae, 2) >> 1;
break; break;
case BRIDGE_SPCA536: case BRIDGE_SPCA536:
sd->colors = reg_read(dev, 0x0, 0x20f6, 2) >> 1; sd->colors = reg_r_12(gspca_dev, 0x00, 0x20f6, 2) >> 1;
break; break;
} }
} }

View File

@ -26,8 +26,8 @@
#define MODULE_NAME "t613" #define MODULE_NAME "t613"
#include "gspca.h" #include "gspca.h"
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.5"; static const char version[] = "2.1.7";
#define MAX_GAMMA 0x10 /* 0 to 15 */ #define MAX_GAMMA 0x10 /* 0 to 15 */
@ -365,48 +365,49 @@ static const __u8 tas5130a_sensor_init[][8] = {
{}, {},
}; };
static void t16RegRead(struct usb_device *dev, /* read 1 byte */
__u16 index, __u8 *buffer, __u16 length) static int reg_r_1(struct gspca_dev *gspca_dev,
__u16 index)
{ {
usb_control_msg(dev, usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(dev, 0), usb_rcvctrlpipe(gspca_dev->dev, 0),
0, /* request */ 0, /* request */
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */ 0, /* value */
index, buffer, length, 500); index,
gspca_dev->usb_buf, 1, 500);
return gspca_dev->usb_buf[0];
} }
static void t16RegWrite(struct usb_device *dev, static void reg_w(struct gspca_dev *gspca_dev,
__u16 value, __u16 value,
__u16 index, __u16 index,
const __u8 *buffer, __u16 len) const __u8 *buffer, __u16 len)
{ {
if (buffer == NULL) { if (buffer == NULL) {
usb_control_msg(dev, usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(dev, 0), usb_sndctrlpipe(gspca_dev->dev, 0),
0, 0,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
value, index, value, index,
NULL, 0, 500); NULL, 0, 500);
return; return;
} }
if (len < 16) { if (len <= sizeof gspca_dev->usb_buf) {
__u8 tmpbuf[16]; memcpy(gspca_dev->usb_buf, buffer, len);
usb_control_msg(gspca_dev->dev,
memcpy(tmpbuf, buffer, len); usb_sndctrlpipe(gspca_dev->dev, 0),
usb_control_msg(dev,
usb_sndctrlpipe(dev, 0),
0, 0,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
value, index, value, index,
tmpbuf, len, 500); gspca_dev->usb_buf, len, 500);
} else { } else {
__u8 *tmpbuf; __u8 *tmpbuf;
tmpbuf = kmalloc(len, GFP_KERNEL); tmpbuf = kmalloc(len, GFP_KERNEL);
memcpy(tmpbuf, buffer, len); memcpy(tmpbuf, buffer, len);
usb_control_msg(dev, usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(dev, 0), usb_sndctrlpipe(gspca_dev->dev, 0),
0, 0,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
value, index, value, index,
@ -443,8 +444,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
static int init_default_parameters(struct gspca_dev *gspca_dev) static int init_default_parameters(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev;
/* some of this registers are not really neded, because /* some of this registers are not really neded, because
* they are overriden by setbrigthness, setcontrast, etc, * they are overriden by setbrigthness, setcontrast, etc,
* but wont hurt anyway, and can help someone with similar webcam * but wont hurt anyway, and can help someone with similar webcam
@ -509,49 +508,49 @@ static int init_default_parameters(struct gspca_dev *gspca_dev)
static const __u8 nset10[6] = static const __u8 nset10[6] =
{ 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 }; { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 };
t16RegWrite(dev, 0x01, 0x0000, n1, 0x06); reg_w(gspca_dev, 0x01, 0x0000, n1, 0x06);
t16RegWrite(dev, 0x01, 0x0000, nset, 0x06); reg_w(gspca_dev, 0x01, 0x0000, nset, 0x06);
t16RegRead(dev, 0x0063, &test_byte, 1); reg_r_1(gspca_dev, 0x0063);
t16RegWrite(dev, 0x01, 0x0000, n2, 0x02); reg_w(gspca_dev, 0x01, 0x0000, n2, 0x02);
while (read_indexs[i] != 0x00) { while (read_indexs[i] != 0x00) {
t16RegRead(dev, read_indexs[i], &test_byte, 1); test_byte = reg_r_1(gspca_dev, read_indexs[i]);
PDEBUG(D_CONF, "Reg 0x%x => 0x%x", read_indexs[i], PDEBUG(D_CONF, "Reg 0x%02x => 0x%02x", read_indexs[i],
test_byte); test_byte);
i++; i++;
} }
t16RegWrite(dev, 0x01, 0x0000, n3, 0x06); reg_w(gspca_dev, 0x01, 0x0000, n3, 0x06);
t16RegWrite(dev, 0x01, 0x0000, n4, 0x46); reg_w(gspca_dev, 0x01, 0x0000, n4, 0x46);
t16RegRead(dev, 0x0080, &test_byte, 1); reg_r_1(gspca_dev, 0x0080);
t16RegWrite(dev, 0x00, 0x2c80, NULL, 0); reg_w(gspca_dev, 0x00, 0x2c80, NULL, 0);
t16RegWrite(dev, 0x01, 0x0000, nset2, 0x14); reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14);
t16RegWrite(dev, 0x01, 0x0000, nset3, 0x12); reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12);
t16RegWrite(dev, 0x01, 0x0000, nset4, 0x12); reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12);
t16RegWrite(dev, 0x00, 0x3880, NULL, 0); reg_w(gspca_dev, 0x00, 0x3880, NULL, 0);
t16RegWrite(dev, 0x00, 0x3880, NULL, 0); reg_w(gspca_dev, 0x00, 0x3880, NULL, 0);
t16RegWrite(dev, 0x00, 0x338e, NULL, 0); reg_w(gspca_dev, 0x00, 0x338e, NULL, 0);
t16RegWrite(dev, 0x01, 0x0000, nset5, 0x04); reg_w(gspca_dev, 0x01, 0x0000, nset5, 0x04);
t16RegWrite(dev, 0x00, 0x00a9, NULL, 0); reg_w(gspca_dev, 0x00, 0x00a9, NULL, 0);
t16RegWrite(dev, 0x01, 0x0000, nset6, 0x22); reg_w(gspca_dev, 0x01, 0x0000, nset6, 0x22);
t16RegWrite(dev, 0x00, 0x86bb, NULL, 0); reg_w(gspca_dev, 0x00, 0x86bb, NULL, 0);
t16RegWrite(dev, 0x00, 0x4aa6, NULL, 0); reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0);
t16RegWrite(dev, 0x01, 0x0000, missing, 0x08); reg_w(gspca_dev, 0x01, 0x0000, missing, 0x08);
t16RegWrite(dev, 0x00, 0x2087, NULL, 0); reg_w(gspca_dev, 0x00, 0x2087, NULL, 0);
t16RegWrite(dev, 0x00, 0x2088, NULL, 0); reg_w(gspca_dev, 0x00, 0x2088, NULL, 0);
t16RegWrite(dev, 0x00, 0x2089, NULL, 0); reg_w(gspca_dev, 0x00, 0x2089, NULL, 0);
t16RegWrite(dev, 0x01, 0x0000, nset7, 0x04); reg_w(gspca_dev, 0x01, 0x0000, nset7, 0x04);
t16RegWrite(dev, 0x01, 0x0000, nset10, 0x06); reg_w(gspca_dev, 0x01, 0x0000, nset10, 0x06);
t16RegWrite(dev, 0x01, 0x0000, nset8, 0x06); reg_w(gspca_dev, 0x01, 0x0000, nset8, 0x06);
t16RegWrite(dev, 0x01, 0x0000, nset9, 0x04); reg_w(gspca_dev, 0x01, 0x0000, nset9, 0x04);
t16RegWrite(dev, 0x00, 0x2880, NULL, 0); reg_w(gspca_dev, 0x00, 0x2880, NULL, 0);
t16RegWrite(dev, 0x01, 0x0000, nset2, 0x14); reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14);
t16RegWrite(dev, 0x01, 0x0000, nset3, 0x12); reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12);
t16RegWrite(dev, 0x01, 0x0000, nset4, 0x12); reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12);
return 0; return 0;
} }
@ -559,7 +558,6 @@ static int init_default_parameters(struct gspca_dev *gspca_dev)
static void setbrightness(struct gspca_dev *gspca_dev) static void setbrightness(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
unsigned int brightness; unsigned int brightness;
__u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x80 }; __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x80 };
brightness = sd->brightness; brightness = sd->brightness;
@ -571,13 +569,12 @@ static void setbrightness(struct gspca_dev *gspca_dev)
set6[3] = 0x00 + ((brightness - 7) * 0xa); set6[3] = 0x00 + ((brightness - 7) * 0xa);
} }
t16RegWrite(dev, 0x01, 0x0000, set6, 4); reg_w(gspca_dev, 0x01, 0x0000, set6, 4);
} }
static void setflip(struct gspca_dev *gspca_dev) static void setflip(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
__u8 flipcmd[8] = __u8 flipcmd[8] =
{ 0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09 }; { 0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09 };
@ -585,15 +582,14 @@ static void setflip(struct gspca_dev *gspca_dev)
if (sd->mirror == 1) if (sd->mirror == 1)
flipcmd[3] = 0x01; flipcmd[3] = 0x01;
t16RegWrite(dev, 0x01, 0x0000, flipcmd, 8); reg_w(gspca_dev, 0x01, 0x0000, flipcmd, 8);
} }
static void seteffect(struct gspca_dev *gspca_dev) static void seteffect(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
t16RegWrite(dev, 0x01, 0x0000, effects_table[sd->effect], 0x06); reg_w(gspca_dev, 0x01, 0x0000, effects_table[sd->effect], 0x06);
if (sd->effect == 1 || sd->effect == 5) { if (sd->effect == 1 || sd->effect == 5) {
PDEBUG(D_CONF, PDEBUG(D_CONF,
"This effect have been disabled for webcam \"safety\""); "This effect have been disabled for webcam \"safety\"");
@ -601,15 +597,14 @@ static void seteffect(struct gspca_dev *gspca_dev)
} }
if (sd->effect == 1 || sd->effect == 4) if (sd->effect == 1 || sd->effect == 4)
t16RegWrite(dev, 0x00, 0x4aa6, NULL, 0); reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0);
else else
t16RegWrite(dev, 0x00, 0xfaa6, NULL, 0); reg_w(gspca_dev, 0x00, 0xfaa6, NULL, 0);
} }
static void setwhitebalance(struct gspca_dev *gspca_dev) static void setwhitebalance(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
__u8 white_balance[8] = __u8 white_balance[8] =
{ 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 }; { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
@ -617,25 +612,23 @@ static void setwhitebalance(struct gspca_dev *gspca_dev)
if (sd->whitebalance == 1) if (sd->whitebalance == 1)
white_balance[7] = 0x3c; white_balance[7] = 0x3c;
t16RegWrite(dev, 0x01, 0x0000, white_balance, 8); reg_w(gspca_dev, 0x01, 0x0000, white_balance, 8);
} }
static void setlightfreq(struct gspca_dev *gspca_dev) static void setlightfreq(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
__u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 }; __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
if (sd->freq == 2) /* 60hz */ if (sd->freq == 2) /* 60hz */
freq[1] = 0x00; freq[1] = 0x00;
t16RegWrite(dev, 0x1, 0x0000, freq, 0x4); reg_w(gspca_dev, 0x1, 0x0000, freq, 0x4);
} }
static void setcontrast(struct gspca_dev *gspca_dev) static void setcontrast(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
unsigned int contrast = sd->contrast; unsigned int contrast = sd->contrast;
__u16 reg_to_write = 0x00; __u16 reg_to_write = 0x00;
@ -644,17 +637,16 @@ static void setcontrast(struct gspca_dev *gspca_dev)
else else
reg_to_write = (0x00a9 + ((contrast - 7) * 0x200)); reg_to_write = (0x00a9 + ((contrast - 7) * 0x200));
t16RegWrite(dev, 0x00, reg_to_write, NULL, 0); reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
} }
static void setcolors(struct gspca_dev *gspca_dev) static void setcolors(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
__u16 reg_to_write; __u16 reg_to_write;
reg_to_write = 0xc0bb + sd->colors * 0x100; reg_to_write = 0xc0bb + sd->colors * 0x100;
t16RegWrite(dev, 0x00, reg_to_write, NULL, 0); reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
} }
static void setgamma(struct gspca_dev *gspca_dev) static void setgamma(struct gspca_dev *gspca_dev)
@ -664,12 +656,11 @@ static void setgamma(struct gspca_dev *gspca_dev)
static void setsharpness(struct gspca_dev *gspca_dev) static void setsharpness(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
__u16 reg_to_write; __u16 reg_to_write;
reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness; reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
t16RegWrite(dev, 0x00, reg_to_write, NULL, 0); reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
} }
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
@ -837,13 +828,12 @@ static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val) static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
sd->autogain = val; sd->autogain = val;
if (val != 0) if (val != 0)
t16RegWrite(dev, 0x00, 0xf48e, NULL, 0); reg_w(gspca_dev, 0x00, 0xf48e, NULL, 0);
else else
t16RegWrite(dev, 0x00, 0xb48e, NULL, 0); reg_w(gspca_dev, 0x00, 0xb48e, NULL, 0);
return 0; return 0;
} }
@ -857,9 +847,7 @@ static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
static void sd_start(struct gspca_dev *gspca_dev) static void sd_start(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev;
int mode; int mode;
__u8 test_byte;
static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 }; static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 };
__u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 }; __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
@ -886,21 +874,21 @@ static void sd_start(struct gspca_dev *gspca_dev)
break; break;
} }
t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[0], 0x8); reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[0], 0x8);
t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8); reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8);
t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8); reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8);
t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8); reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
t16RegWrite(dev, 0x00, 0x3c80, NULL, 0); reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0);
/* just in case and to keep sync with logs (for mine) */ /* just in case and to keep sync with logs (for mine) */
t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8); reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
t16RegWrite(dev, 0x00, 0x3c80, NULL, 0); reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0);
/* just in case and to keep sync with logs (for mine) */ /* just in case and to keep sync with logs (for mine) */
t16RegWrite(dev, 0x01, 0x0000, t1, 4); reg_w(gspca_dev, 0x01, 0x0000, t1, 4);
t16RegWrite(dev, 0x01, 0x0000, t2, 6); reg_w(gspca_dev, 0x01, 0x0000, t2, 6);
t16RegRead(dev, 0x0012, &test_byte, 0x01); reg_r_1(gspca_dev, 0x0012);
t16RegWrite(dev, 0x01, 0x0000, t3, 0x10); reg_w(gspca_dev, 0x01, 0x0000, t3, 0x10);
t16RegWrite(dev, 0x00, 0x0013, NULL, 0); reg_w(gspca_dev, 0x00, 0x0013, NULL, 0);
t16RegWrite(dev, 0x01, 0x0000, t4, 0x4); reg_w(gspca_dev, 0x01, 0x0000, t4, 0x4);
/* restart on each start, just in case, sometimes regs goes wrong /* restart on each start, just in case, sometimes regs goes wrong
* when using controls from app */ * when using controls from app */
setbrightness(gspca_dev); setbrightness(gspca_dev);

View File

@ -22,8 +22,8 @@
#include "gspca.h" #include "gspca.h"
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.5"; static const char version[] = "2.1.7";
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("TV8532 USB Camera Driver"); MODULE_DESCRIPTION("TV8532 USB Camera Driver");
@ -168,63 +168,74 @@ static const __u32 tv_8532_eeprom_data[] = {
0x0c0509f1, 0 0x0c0509f1, 0
}; };
static void reg_r(struct usb_device *dev, static int reg_r(struct gspca_dev *gspca_dev,
__u16 index, __u8 *buffer) __u16 index)
{ {
usb_control_msg(dev, usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(dev, 0), usb_rcvctrlpipe(gspca_dev->dev, 0),
TV8532_REQ_RegRead, TV8532_REQ_RegRead,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */ 0, /* value */
index, buffer, sizeof(__u8), index, gspca_dev->usb_buf, 1,
500); 500);
return gspca_dev->usb_buf[0];
} }
static void reg_w(struct usb_device *dev, /* write 1 byte */
__u16 index, __u8 *buffer, __u16 length) static void reg_w_1(struct gspca_dev *gspca_dev,
__u16 index, __u8 value)
{ {
usb_control_msg(dev, gspca_dev->usb_buf[0] = value;
usb_sndctrlpipe(dev, 0), usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
TV8532_REQ_RegWrite, TV8532_REQ_RegWrite,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */ 0, /* value */
index, buffer, length, 500); index, gspca_dev->usb_buf, 1, 500);
}
/* write 2 bytes */
static void reg_w_2(struct gspca_dev *gspca_dev,
__u16 index, __u8 val1, __u8 val2)
{
gspca_dev->usb_buf[0] = val1;
gspca_dev->usb_buf[1] = val2;
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
TV8532_REQ_RegWrite,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */
index, gspca_dev->usb_buf, 2, 500);
} }
static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev) static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev)
{ {
int i = 0; int i = 0;
__u8 reg, data0, data1, data2, datacmd; __u8 reg, data0, data1, data2;
struct usb_device *dev = gspca_dev->dev;
datacmd = 0xb0;; reg_w_1(gspca_dev, TV8532_GPIO, 0xb0);
reg_w(dev, TV8532_GPIO, &datacmd, 1); reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Open);
datacmd = TV8532_CMD_EEprom_Open;
reg_w(dev, TV8532_CTRL, &datacmd, 1);
/* msleep(1); */ /* msleep(1); */
while (tv_8532_eeprom_data[i]) { while (tv_8532_eeprom_data[i]) {
reg = (tv_8532_eeprom_data[i] & 0xff000000) >> 24; reg = (tv_8532_eeprom_data[i] & 0xff000000) >> 24;
reg_w(dev, TV8532_EEprom_Add, &reg, 1); reg_w_1(gspca_dev, TV8532_EEprom_Add, reg);
/* msleep(1); */ /* msleep(1); */
data0 = (tv_8532_eeprom_data[i] & 0x000000ff); data0 = (tv_8532_eeprom_data[i] & 0x000000ff);
reg_w(dev, TV8532_EEprom_DataL, &data0, 1); reg_w_1(gspca_dev, TV8532_EEprom_DataL, data0);
/* msleep(1); */ /* msleep(1); */
data1 = (tv_8532_eeprom_data[i] & 0x0000FF00) >> 8; data1 = (tv_8532_eeprom_data[i] & 0x0000ff00) >> 8;
reg_w(dev, TV8532_EEprom_DataM, &data1, 1); reg_w_1(gspca_dev, TV8532_EEprom_DataM, data1);
/* msleep(1); */ /* msleep(1); */
data2 = (tv_8532_eeprom_data[i] & 0x00FF0000) >> 16; data2 = (tv_8532_eeprom_data[i] & 0x00ff0000) >> 16;
reg_w(dev, TV8532_EEprom_DataH, &data2, 1); reg_w_1(gspca_dev, TV8532_EEprom_DataH, data2);
/* msleep(1); */ /* msleep(1); */
datacmd = 0; reg_w_1(gspca_dev, TV8532_EEprom_Write, 0);
reg_w(dev, TV8532_EEprom_Write, &datacmd, 1);
/* msleep(10); */ /* msleep(10); */
i++; i++;
} }
datacmd = i; reg_w_1(gspca_dev, TV8532_EEprom_TableLength, i);
reg_w(dev, TV8532_EEprom_TableLength, &datacmd, 1);
/* msleep(1); */ /* msleep(1); */
datacmd = TV8532_CMD_EEprom_Close; reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Close);
reg_w(dev, TV8532_CTRL, &datacmd, 1);
msleep(10); msleep(10);
} }
@ -250,154 +261,121 @@ static int sd_config(struct gspca_dev *gspca_dev,
static void tv_8532ReadRegisters(struct gspca_dev *gspca_dev) static void tv_8532ReadRegisters(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev;
__u8 data; __u8 data;
/* __u16 vid, pid; */
reg_r(dev, 0x0001, &data); data = reg_r(gspca_dev, 0x0001);
PDEBUG(D_USBI, "register 0x01-> %x", data); PDEBUG(D_USBI, "register 0x01-> %x", data);
reg_r(dev, 0x0002, &data); data = reg_r(gspca_dev, 0x0002);
PDEBUG(D_USBI, "register 0x02-> %x", data); PDEBUG(D_USBI, "register 0x02-> %x", data);
reg_r(dev, TV8532_ADWIDTH_L, &data); reg_r(gspca_dev, TV8532_ADWIDTH_L);
reg_r(dev, TV8532_ADWIDTH_H, &data); reg_r(gspca_dev, TV8532_ADWIDTH_H);
reg_r(dev, TV8532_QUANT_COMP, &data); reg_r(gspca_dev, TV8532_QUANT_COMP);
reg_r(dev, TV8532_MODE_PACKET, &data); reg_r(gspca_dev, TV8532_MODE_PACKET);
reg_r(dev, TV8532_SETCLK, &data); reg_r(gspca_dev, TV8532_SETCLK);
reg_r(dev, TV8532_POINT_L, &data); reg_r(gspca_dev, TV8532_POINT_L);
reg_r(dev, TV8532_POINT_H, &data); reg_r(gspca_dev, TV8532_POINT_H);
reg_r(dev, TV8532_POINTB_L, &data); reg_r(gspca_dev, TV8532_POINTB_L);
reg_r(dev, TV8532_POINTB_H, &data); reg_r(gspca_dev, TV8532_POINTB_H);
reg_r(dev, TV8532_BUDGET_L, &data); reg_r(gspca_dev, TV8532_BUDGET_L);
reg_r(dev, TV8532_BUDGET_H, &data); reg_r(gspca_dev, TV8532_BUDGET_H);
reg_r(dev, TV8532_VID_L, &data); reg_r(gspca_dev, TV8532_VID_L);
reg_r(dev, TV8532_VID_H, &data); reg_r(gspca_dev, TV8532_VID_H);
reg_r(dev, TV8532_PID_L, &data); reg_r(gspca_dev, TV8532_PID_L);
reg_r(dev, TV8532_PID_H, &data); reg_r(gspca_dev, TV8532_PID_H);
reg_r(dev, TV8532_DeviceID, &data); reg_r(gspca_dev, TV8532_DeviceID);
reg_r(dev, TV8532_AD_COLBEGIN_L, &data); reg_r(gspca_dev, TV8532_AD_COLBEGIN_L);
reg_r(dev, TV8532_AD_COLBEGIN_H, &data); reg_r(gspca_dev, TV8532_AD_COLBEGIN_H);
reg_r(dev, TV8532_AD_ROWBEGIN_L, &data); reg_r(gspca_dev, TV8532_AD_ROWBEGIN_L);
reg_r(dev, TV8532_AD_ROWBEGIN_H, &data); reg_r(gspca_dev, TV8532_AD_ROWBEGIN_H);
} }
static void tv_8532_setReg(struct gspca_dev *gspca_dev) static void tv_8532_setReg(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev; reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L,
__u8 data; ADCBEGINL); /* 0x10 */
__u8 value[2] = { 0, 0 }; reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H,
ADCBEGINH); /* also digital gain */
reg_w_1(gspca_dev, TV8532_PART_CTRL,
TV8532_CMD_UPDATE); /* 0x00<-0x84 */
data = ADCBEGINL; reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0a);
reg_w(dev, TV8532_AD_COLBEGIN_L, &data, 1); /* 0x10 */
data = ADCBEGINH; /* also digital gain */
reg_w(dev, TV8532_AD_COLBEGIN_H, &data, 1);
data = TV8532_CMD_UPDATE;
reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */
data = 0x0a;
reg_w(dev, TV8532_GPIO_OE, &data, 1);
/******************************************************/ /******************************************************/
data = ADHEIGHL; reg_w_1(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL); /* 0e */
reg_w(dev, TV8532_ADHEIGHT_L, &data, 1); /* 0e */ reg_w_1(gspca_dev, TV8532_ADHEIGHT_H, ADHEIGHH); /* 0f */
data = ADHEIGHH; reg_w_2(gspca_dev, TV8532_EXPOSURE,
reg_w(dev, TV8532_ADHEIGHT_H, &data, 1); /* 0f */ EXPOL, EXPOH); /* 350d 0x014c; 1c */
value[0] = EXPOL; reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L,
value[1] = EXPOH; /* 350d 0x014c; */ ADCBEGINL); /* 0x10 */
reg_w(dev, TV8532_EXPOSURE, value, 2); /* 1c */ reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H,
data = ADCBEGINL; ADCBEGINH); /* also digital gain */
reg_w(dev, TV8532_AD_COLBEGIN_L, &data, 1); /* 0x10 */ reg_w_1(gspca_dev, TV8532_AD_ROWBEGIN_L,
data = ADCBEGINH; /* also digital gain */ ADRBEGINL); /* 0x14 */
reg_w(dev, TV8532_AD_COLBEGIN_H, &data, 1);
data = ADRBEGINL;
reg_w(dev, TV8532_AD_ROWBEGIN_L, &data, 1); /* 0x14 */
data = 0x00; reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */
reg_w(dev, TV8532_AD_SLOPE, &data, 1); /* 0x91 */ reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x02); /* 0x94 */
data = 0x02;
reg_w(dev, TV8532_AD_BITCTRL, &data, 1); /* 0x94 */
reg_w_1(gspca_dev, TV8532_CTRL,
TV8532_CMD_EEprom_Close); /* 0x01 */
data = TV8532_CMD_EEprom_Close; reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */
reg_w(dev, TV8532_CTRL, &data, 1); /* 0x01 */ reg_w_1(gspca_dev, TV8532_PART_CTRL,
TV8532_CMD_UPDATE); /* 0x00<-0x84 */
data = 0x00;
reg_w(dev, TV8532_AD_SLOPE, &data, 1); /* 0x91 */
data = TV8532_CMD_UPDATE;
reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */
} }
static void tv_8532_PollReg(struct gspca_dev *gspca_dev) static void tv_8532_PollReg(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev;
__u8 data;
int i; int i;
/* strange polling from tgc */ /* strange polling from tgc */
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
data = TESTCLK; /* 0x48; //0x08; */ reg_w_1(gspca_dev, TV8532_SETCLK,
reg_w(dev, TV8532_SETCLK, &data, 1); /* 0x2c */ TESTCLK); /* 0x48; //0x08; 0x2c */
data = TV8532_CMD_UPDATE; reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE);
reg_w(dev, TV8532_PART_CTRL, &data, 1); reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */
data = 0x01;
reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */
} }
} }
/* this function is called at open time */ /* this function is called at open time */
static int sd_open(struct gspca_dev *gspca_dev) static int sd_open(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev; reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
__u8 data; reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
__u8 dataStart;
__u8 value[2];
data = 0x32;
reg_w(dev, TV8532_AD_SLOPE, &data, 1);
data = 0;
reg_w(dev, TV8532_AD_BITCTRL, &data, 1);
tv_8532ReadRegisters(gspca_dev); tv_8532ReadRegisters(gspca_dev);
data = 0x0b; reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
reg_w(dev, TV8532_GPIO_OE, &data, 1); reg_w_2(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL,
value[0] = ADHEIGHL; ADHEIGHH); /* 401d 0x0169; 0e */
value[1] = ADHEIGHH; /* 401d 0x0169; */ reg_w_2(gspca_dev, TV8532_EXPOSURE, EXPOL,
reg_w(dev, TV8532_ADHEIGHT_L, value, 2); /* 0e */ EXPOH); /* 350d 0x014c; 1c */
value[0] = EXPOL; reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */
value[1] = EXPOH; /* 350d 0x014c; */ reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */
reg_w(dev, TV8532_EXPOSURE, value, 2); /* 1c */
data = ADWIDTHL; /* 0x20; */
reg_w(dev, TV8532_ADWIDTH_L, &data, 1); /* 0x0c */
data = ADWIDTHH;
reg_w(dev, TV8532_ADWIDTH_H, &data, 1); /* 0x0d */
/*******************************************************************/ /*******************************************************************/
data = TESTCOMP; /* 0x72 compressed mode */ reg_w_1(gspca_dev, TV8532_QUANT_COMP,
reg_w(dev, TV8532_QUANT_COMP, &data, 1); /* 0x28 */ TESTCOMP); /* 0x72 compressed mode 0x28 */
data = TESTLINE; /* 0x84; // CIF | 4 packet */ reg_w_1(gspca_dev, TV8532_MODE_PACKET,
reg_w(dev, TV8532_MODE_PACKET, &data, 1); /* 0x29 */ TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */
/************************************************/ /************************************************/
data = TESTCLK; /* 0x48; //0x08; */ reg_w_1(gspca_dev, TV8532_SETCLK,
reg_w(dev, TV8532_SETCLK, &data, 1); /* 0x2c */ TESTCLK); /* 0x48; //0x08; 0x2c */
data = TESTPTL; /* 0x38; */ reg_w_1(gspca_dev, TV8532_POINT_L,
reg_w(dev, TV8532_POINT_L, &data, 1); /* 0x2d */ TESTPTL); /* 0x38; 0x2d */
data = TESTPTH; /* 0x04; */ reg_w_1(gspca_dev, TV8532_POINT_H,
reg_w(dev, TV8532_POINT_H, &data, 1); /* 0x2e */ TESTPTH); /* 0x04; 0x2e */
dataStart = TESTPTBL; /* 0x04; */ reg_w_1(gspca_dev, TV8532_POINTB_L,
reg_w(dev, TV8532_POINTB_L, &dataStart, 1); /* 0x2f */ TESTPTBL); /* 0x04; 0x2f */
data = TESTPTBH; /* 0x04; */ reg_w_1(gspca_dev, TV8532_POINTB_H,
reg_w(dev, TV8532_POINTB_H, &data, 1); /* 0x30 */ TESTPTBH); /* 0x04; 0x30 */
data = TV8532_CMD_UPDATE; reg_w_1(gspca_dev, TV8532_PART_CTRL,
reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */ TV8532_CMD_UPDATE); /* 0x00<-0x84 */
/*************************************************/ /*************************************************/
data = 0x01; reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */
reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */
msleep(200); msleep(200);
data = 0x00; reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */
/*************************************************/ /*************************************************/
tv_8532_setReg(gspca_dev); tv_8532_setReg(gspca_dev);
/*************************************************/ /*************************************************/
data = 0x0b; reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
reg_w(dev, TV8532_GPIO_OE, &data, 1);
/*************************************************/ /*************************************************/
tv_8532_setReg(gspca_dev); tv_8532_setReg(gspca_dev);
/*************************************************/ /*************************************************/
@ -408,94 +386,72 @@ static int sd_open(struct gspca_dev *gspca_dev)
static void setbrightness(struct gspca_dev *gspca_dev) static void setbrightness(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
__u8 value[2];
__u8 data;
int brightness = sd->brightness; int brightness = sd->brightness;
value[1] = (brightness >> 8) & 0xff; reg_w_2(gspca_dev, TV8532_EXPOSURE,
value[0] = (brightness) & 0xff; brightness >> 8, brightness); /* 1c */
reg_w(gspca_dev->dev, TV8532_EXPOSURE, value, 2); /* 1c */ reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE);
data = TV8532_CMD_UPDATE;
reg_w(gspca_dev->dev, TV8532_PART_CTRL, &data, 1);
} }
/* -- start the camera -- */ /* -- start the camera -- */
static void sd_start(struct gspca_dev *gspca_dev) static void sd_start(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev; reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
__u8 data; reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
__u8 value[2];
data = 0x32;
reg_w(dev, TV8532_AD_SLOPE, &data, 1);
data = 0;
reg_w(dev, TV8532_AD_BITCTRL, &data, 1);
tv_8532ReadRegisters(gspca_dev); tv_8532ReadRegisters(gspca_dev);
data = 0x0b; reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
reg_w(dev, TV8532_GPIO_OE, &data, 1); reg_w_2(gspca_dev, TV8532_ADHEIGHT_L,
value[0] = ADHEIGHL; ADHEIGHL, ADHEIGHH); /* 401d 0x0169; 0e */
value[1] = ADHEIGHH; /* 401d 0x0169; */ /* reg_w_2(gspca_dev, TV8532_EXPOSURE,
reg_w(dev, TV8532_ADHEIGHT_L, value, 2); /* 0e */ EXPOL, EXPOH); * 350d 0x014c; 1c */
/* value[0] = EXPOL; value[1] =EXPOH; * 350d 0x014c; */
/* reg_w(dev,TV8532_REQ_RegWrite,0,TV8532_EXPOSURE,value,2); * 1c */
setbrightness(gspca_dev); setbrightness(gspca_dev);
data = ADWIDTHL; /* 0x20; */ reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */
reg_w(dev, TV8532_ADWIDTH_L, &data, 1); /* 0x0c */ reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */
data = ADWIDTHH;
reg_w(dev, TV8532_ADWIDTH_H, &data, 1); /* 0x0d */
/************************************************/ /************************************************/
data = TESTCOMP; /* 0x72 compressed mode */ reg_w_1(gspca_dev, TV8532_QUANT_COMP,
reg_w(dev, TV8532_QUANT_COMP, &data, 1); /* 0x28 */ TESTCOMP); /* 0x72 compressed mode 0x28 */
if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
/* 176x144 */ /* 176x144 */
data = QCIFLINE; /* 0x84; // CIF | 4 packet */ reg_w_1(gspca_dev, TV8532_MODE_PACKET,
reg_w(dev, TV8532_MODE_PACKET, &data, 1); /* 0x29 */ QCIFLINE); /* 0x84; // CIF | 4 packet 0x29 */
} else { } else {
/* 352x288 */ /* 352x288 */
data = TESTLINE; /* 0x84; // CIF | 4 packet */ reg_w_1(gspca_dev, TV8532_MODE_PACKET,
reg_w(dev, TV8532_MODE_PACKET, &data, 1); /* 0x29 */ TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */
} }
/************************************************/ /************************************************/
data = TESTCLK; /* 0x48; //0x08; */ reg_w_1(gspca_dev, TV8532_SETCLK,
reg_w(dev, TV8532_SETCLK, &data, 1); /* 0x2c */ TESTCLK); /* 0x48; //0x08; 0x2c */
data = TESTPTL; /* 0x38; */ reg_w_1(gspca_dev, TV8532_POINT_L,
reg_w(dev, TV8532_POINT_L, &data, 1); /* 0x2d */ TESTPTL); /* 0x38; 0x2d */
data = TESTPTH; /* 0x04; */ reg_w_1(gspca_dev, TV8532_POINT_H,
reg_w(dev, TV8532_POINT_H, &data, 1); /* 0x2e */ TESTPTH); /* 0x04; 0x2e */
data = TESTPTBL; /* 0x04; */ reg_w_1(gspca_dev, TV8532_POINTB_L,
reg_w(dev, TV8532_POINTB_L, &data, 1); /* 0x2f */ TESTPTBL); /* 0x04; 0x2f */
data = TESTPTBH; /* 0x04; */ reg_w_1(gspca_dev, TV8532_POINTB_H,
reg_w(dev, TV8532_POINTB_H, &data, 1); /* 0x30 */ TESTPTBH); /* 0x04; 0x30 */
data = TV8532_CMD_UPDATE; reg_w_1(gspca_dev, TV8532_PART_CTRL,
reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */ TV8532_CMD_UPDATE); /* 0x00<-0x84 */
/************************************************/ /************************************************/
data = 0x01; reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */
reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */
msleep(200); msleep(200);
data = 0x00; reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */
/************************************************/ /************************************************/
tv_8532_setReg(gspca_dev); tv_8532_setReg(gspca_dev);
/************************************************/ /************************************************/
data = 0x0b; reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
reg_w(dev, TV8532_GPIO_OE, &data, 1);
/************************************************/ /************************************************/
tv_8532_setReg(gspca_dev); tv_8532_setReg(gspca_dev);
/************************************************/ /************************************************/
tv_8532_PollReg(gspca_dev); tv_8532_PollReg(gspca_dev);
data = 0x00; reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */
} }
static void sd_stopN(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev; reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
__u8 data;
data = 0x0b;
reg_w(dev, TV8532_GPIO_OE, &data, 1);
} }
static void sd_stop0(struct gspca_dev *gspca_dev) static void sd_stop0(struct gspca_dev *gspca_dev)

View File

@ -1227,17 +1227,18 @@ static const struct sensor_info sensor_info_data[] = {
{SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01}, {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01},
}; };
static void reg_r(struct usb_device *dev, /* read 'len' bytes in gspca_dev->usb_buf */
__u16 req, static void reg_r(struct gspca_dev *gspca_dev,
__u16 index, __u16 req,
__u8 *buffer, __u16 length) __u16 index,
__u16 len)
{ {
usb_control_msg(dev, usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(dev, 0), usb_rcvctrlpipe(gspca_dev->dev, 0),
req, req,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1, /* value */ 1, /* value */
index, buffer, length, index, gspca_dev->usb_buf, len,
500); 500);
} }
@ -1254,55 +1255,55 @@ static void reg_w(struct usb_device *dev,
500); 500);
} }
static void vc032x_read_sensor_register(struct usb_device *dev, static void read_sensor_register(struct gspca_dev *gspca_dev,
__u16 address, __u16 *value) __u16 address, __u16 *value)
{ {
struct usb_device *dev = gspca_dev->dev;
__u8 ldata, mdata, hdata; __u8 ldata, mdata, hdata;
__u8 tmpvalue = 0;
int retry = 50; int retry = 50;
ldata = 0;
mdata = 0;
hdata = 0;
*value = 0; *value = 0;
reg_r(dev, 0xa1, 0xb33f, &tmpvalue, 1); reg_r(gspca_dev, 0xa1, 0xb33f, 1);
/*PDEBUG(D_PROBE, " I2c Bus Busy Wait 0x%02X ", tmpvalue); */ /*PDEBUG(D_PROBE, " I2c Bus Busy Wait 0x%02X ", tmpvalue); */
if (!(tmpvalue & 0x02)) { if (!(gspca_dev->usb_buf[0] & 0x02)) {
PDEBUG(D_ERR, "I2c Bus Busy Wait %d", tmpvalue & 0x02); PDEBUG(D_ERR, "I2c Bus Busy Wait %d",
gspca_dev->usb_buf[0] & 0x02);
return; return;
} }
reg_w(dev, 0xa0, address, 0xb33a); reg_w(dev, 0xa0, address, 0xb33a);
reg_w(dev, 0xa0, 0x02, 0xb339); reg_w(dev, 0xa0, 0x02, 0xb339);
tmpvalue = 0; reg_r(gspca_dev, 0xa1, 0xb33b, 1);
reg_r(dev, 0xa1, 0xb33b, &tmpvalue, 1); while (retry-- && gspca_dev->usb_buf[0]) {
while (retry-- && tmpvalue) { reg_r(gspca_dev, 0xa1, 0xb33b, 1);
reg_r(dev, 0xa1, 0xb33b, &tmpvalue, 1);
/* PDEBUG(D_PROBE, "Read again 0xb33b %d", tmpvalue); */ /* PDEBUG(D_PROBE, "Read again 0xb33b %d", tmpvalue); */
msleep(1); msleep(1);
} }
reg_r(dev, 0xa1, 0xb33e, &hdata, 1); reg_r(gspca_dev, 0xa1, 0xb33e, 1);
reg_r(dev, 0xa1, 0xb33d, &mdata, 1); hdata = gspca_dev->usb_buf[0];
reg_r(dev, 0xa1, 0xb33c, &ldata, 1); reg_r(gspca_dev, 0xa1, 0xb33d, 1);
mdata = gspca_dev->usb_buf[0];
reg_r(gspca_dev, 0xa1, 0xb33c, 1);
ldata = gspca_dev->usb_buf[0];
PDEBUG(D_PROBE, "Read Sensor h (0x%02X) m (0x%02X) l (0x%02X)", PDEBUG(D_PROBE, "Read Sensor h (0x%02X) m (0x%02X) l (0x%02X)",
hdata, mdata, ldata); hdata, mdata, ldata);
tmpvalue = 0; reg_r(gspca_dev, 0xa1, 0xb334, 1);
reg_r(dev, 0xa1, 0xb334, &tmpvalue, 1); if (gspca_dev->usb_buf[0] == 0x02)
if (tmpvalue == 0x02)
*value = (ldata << 8) + mdata; *value = (ldata << 8) + mdata;
else else
*value = ldata; *value = ldata;
} }
static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
int i; int i;
__u8 data;
__u16 value; __u16 value;
const struct sensor_info *ptsensor_info; const struct sensor_info *ptsensor_info;
reg_r(dev, 0xa1, 0xbfcf, &data, 1); reg_r(gspca_dev, 0xa1, 0xbfcf, 1);
PDEBUG(D_PROBE, "check sensor header %d", data); PDEBUG(D_PROBE, "check sensor header %d", gspca_dev->usb_buf[0]);
for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) { for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) {
ptsensor_info = &sensor_info_data[i]; ptsensor_info = &sensor_info_data[i];
reg_w(dev, 0xa0, 0x02, 0xb334); reg_w(dev, 0xa0, 0x02, 0xb334);
@ -1315,7 +1316,7 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
"check sensor VC032X -> %d Add -> ox%02X!", "check sensor VC032X -> %d Add -> ox%02X!",
i, ptsensor_info->I2cAdd); */ i, ptsensor_info->I2cAdd); */
reg_w(dev, 0xa0, ptsensor_info->op, 0xb301); reg_w(dev, 0xa0, ptsensor_info->op, 0xb301);
vc032x_read_sensor_register(dev, ptsensor_info->IdAdd, &value); read_sensor_register(gspca_dev, ptsensor_info->IdAdd, &value);
if (value == ptsensor_info->VpId) { if (value == ptsensor_info->VpId) {
/* PDEBUG(D_PROBE, "find sensor VC032X -> ox%04X!", /* PDEBUG(D_PROBE, "find sensor VC032X -> ox%04X!",
ptsensor_info->VpId); */ ptsensor_info->VpId); */
@ -1325,14 +1326,14 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
return -1; return -1;
} }
static __u8 i2c_write(struct usb_device *dev, static __u8 i2c_write(struct gspca_dev *gspca_dev,
__u8 reg, const __u8 *val, __u8 size) __u8 reg, const __u8 *val, __u8 size)
{ {
__u8 retbyte; struct usb_device *dev = gspca_dev->dev;
if (size > 3 || size < 1) if (size > 3 || size < 1)
return -EINVAL; return -EINVAL;
reg_r(dev, 0xa1, 0xb33f, &retbyte, 1); reg_r(gspca_dev, 0xa1, 0xb33f, 1);
reg_w(dev, 0xa0, size, 0xb334); reg_w(dev, 0xa0, size, 0xb334);
reg_w(dev, 0xa0, reg, 0xb33a); reg_w(dev, 0xa0, reg, 0xb33a);
switch (size) { switch (size) {
@ -1353,8 +1354,8 @@ static __u8 i2c_write(struct usb_device *dev,
return -EINVAL; return -EINVAL;
} }
reg_w(dev, 0xa0, 0x01, 0xb339); reg_w(dev, 0xa0, 0x01, 0xb339);
reg_r(dev, 0xa1, 0xb33b, &retbyte, 1); reg_r(gspca_dev, 0xa1, 0xb33b, 1);
return retbyte == 0; return gspca_dev->usb_buf[0] == 0;
} }
static void put_tab_to_reg(struct gspca_dev *gspca_dev, static void put_tab_to_reg(struct gspca_dev *gspca_dev,
@ -1382,10 +1383,10 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
((data[i][0])<<8) | data[i][1]); ((data[i][0])<<8) | data[i][1]);
break; break;
case 0xaa: /* i2c op */ case 0xaa: /* i2c op */
i2c_write(dev, data[i][1], &data[i][2], 1); i2c_write(gspca_dev, data[i][1], &data[i][2], 1);
break; break;
case 0xbb: /* i2c op */ case 0xbb: /* i2c op */
i2c_write(dev, data[i][0], &data[i][1], 2); i2c_write(gspca_dev, data[i][0], &data[i][1], 2);
break; break;
case 0xdd: case 0xdd:
msleep(data[i][2] + 10); msleep(data[i][2] + 10);
@ -1417,7 +1418,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
struct cam *cam; struct cam *cam;
__u8 tmp2[4];
int sensor; int sensor;
__u16 product; __u16 product;
@ -1488,10 +1488,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->lightfreq = FREQ_DEF; sd->lightfreq = FREQ_DEF;
if (sd->bridge == BRIDGE_VC0321) { if (sd->bridge == BRIDGE_VC0321) {
reg_r(dev, 0x8a, 0, tmp2, 3); reg_r(gspca_dev, 0x8a, 0, 3);
reg_w(dev, 0x87, 0x00, 0x0f0f); reg_w(dev, 0x87, 0x00, 0x0f0f);
reg_r(dev, 0x8b, 0, tmp2, 3); reg_r(gspca_dev, 0x8b, 0, 3);
reg_w(dev, 0x88, 0x00, 0x0202); reg_w(dev, 0x88, 0x00, 0x0202);
} }
return 0; return 0;
@ -1525,7 +1525,6 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
static void sd_start(struct gspca_dev *gspca_dev) static void sd_start(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
/* __u8 tmp2; */
const __u8 *GammaT = NULL; const __u8 *GammaT = NULL;
const __u8 *MatrixT = NULL; const __u8 *MatrixT = NULL;
int mode; int mode;
@ -1627,7 +1626,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb824); reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb824);
*/ */
/* Only works for HV7131R ?? /* Only works for HV7131R ??
reg_r (gspca_dev->dev, 0xa1, 0xb881, &tmp2, 1); reg_r (gspca_dev, 0xa1, 0xb881, 1);
reg_w(gspca_dev->dev, 0xa0, 0xfe01, 0xb881); reg_w(gspca_dev->dev, 0xa0, 0xfe01, 0xb881);
reg_w(gspca_dev->dev, 0xa0, 0x79, 0xb801); reg_w(gspca_dev->dev, 0xa0, 0x79, 0xb801);
*/ */

View File

@ -24,8 +24,8 @@
#include "gspca.h" #include "gspca.h"
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.5"; static const char version[] = "2.1.7";
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>, " MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>, "
"Serge A. Suchkov <Serge.A.S@tochka.ru>"); "Serge A. Suchkov <Serge.A.S@tochka.ru>");
@ -6214,23 +6214,27 @@ static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = {
{} {}
}; };
static void reg_r_i(struct usb_device *dev, static int reg_r_i(struct gspca_dev *gspca_dev,
__u16 index, __u8 *buffer) __u16 index)
{ {
usb_control_msg(dev, usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(dev, 0), usb_rcvctrlpipe(gspca_dev->dev, 0),
0xa1, 0xa1,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x01, /* value */ 0x01, /* value */
index, buffer, 1, index, gspca_dev->usb_buf, 1,
500); 500);
return gspca_dev->usb_buf[0];
} }
static void reg_r(struct usb_device *dev, static int reg_r(struct gspca_dev *gspca_dev,
__u16 index, __u8 *buffer) __u16 index)
{ {
reg_r_i(dev, index, buffer); int ret;
PDEBUG(D_USBI, "reg r [%04x] -> %02x", index, *buffer);
ret = reg_r_i(gspca_dev, index);
PDEBUG(D_USBI, "reg r [%04x] -> %02x", index, ret);
return ret;
} }
static void reg_w_i(struct usb_device *dev, static void reg_w_i(struct usb_device *dev,
@ -6253,55 +6257,54 @@ static void reg_w(struct usb_device *dev,
reg_w_i(dev, value, index); reg_w_i(dev, value, index);
} }
static __u16 i2c_read(struct usb_device *dev, __u8 reg) static __u16 i2c_read(struct gspca_dev *gspca_dev,
__u8 reg)
{ {
__u8 retbyte; __u8 retbyte;
__u8 retval[2]; __u8 retval[2];
reg_w_i(dev, reg, 0x92); reg_w_i(gspca_dev->dev, reg, 0x92);
reg_w_i(dev, 0x02, 0x90); /* <- read command */ reg_w_i(gspca_dev->dev, 0x02, 0x90); /* <- read command */
msleep(25); msleep(25);
reg_r_i(dev, 0x0091, &retbyte); /* read status */ retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */
reg_r_i(dev, 0x0095, &retval[0]); /* read Lowbyte */ retval[0] = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */
reg_r_i(dev, 0x0096, &retval[1]); /* read Hightbyte */ retval[1] = reg_r_i(gspca_dev, 0x0096); /* read Hightbyte */
PDEBUG(D_USBO, "i2c r [%02x] -> (%02x) %02x%02x", PDEBUG(D_USBO, "i2c r [%02x] -> (%02x) %02x%02x",
reg, retbyte, retval[1], retval[0]); reg, retbyte, retval[1], retval[0]);
return (retval[1] << 8) | retval[0]; return (retval[1] << 8) | retval[0];
} }
static __u8 i2c_write(struct usb_device *dev, static __u8 i2c_write(struct gspca_dev *gspca_dev,
__u8 reg, __u8 reg,
__u8 valL, __u8 valL,
__u8 valH) __u8 valH)
{ {
__u8 retbyte; __u8 retbyte;
reg_w_i(dev, reg, 0x92); reg_w_i(gspca_dev->dev, reg, 0x92);
reg_w_i(dev, valL, 0x93); reg_w_i(gspca_dev->dev, valL, 0x93);
reg_w_i(dev, valH, 0x94); reg_w_i(gspca_dev->dev, valH, 0x94);
reg_w_i(dev, 0x01, 0x90); /* <- write command */ reg_w_i(gspca_dev->dev, 0x01, 0x90); /* <- write command */
msleep(5); msleep(5);
reg_r_i(dev, 0x0091, &retbyte); /* read status */ retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */
PDEBUG(D_USBO, "i2c w [%02x] %02x%02x (%02x)", PDEBUG(D_USBO, "i2c w [%02x] %02x%02x (%02x)",
reg, valH, valL, retbyte); reg, valH, valL, retbyte);
return retbyte; return retbyte;
} }
static void usb_exchange(struct usb_device *dev, static void usb_exchange(struct gspca_dev *gspca_dev,
const struct usb_action *action) const struct usb_action *action)
{ {
__u8 buffread;
while (action->req) { while (action->req) {
switch (action->req) { switch (action->req) {
case 0xa0: /* write register */ case 0xa0: /* write register */
reg_w(dev, action->val, action->idx); reg_w(gspca_dev->dev, action->val, action->idx);
break; break;
case 0xa1: /* read status */ case 0xa1: /* read status */
reg_r(dev, action->idx, &buffread); reg_r(gspca_dev, action->idx);
break; break;
case 0xaa: case 0xaa:
i2c_write(dev, i2c_write(gspca_dev,
action->val, /* reg */ action->val, /* reg */
action->idx & 0xff, /* valL */ action->idx & 0xff, /* valL */
action->idx >> 8); /* valH */ action->idx >> 8); /* valH */
@ -6376,7 +6379,6 @@ static void setsharpness(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
int sharpness; int sharpness;
__u8 retbyte;
static const __u8 sharpness_tb[][2] = { static const __u8 sharpness_tb[][2] = {
{0x02, 0x03}, {0x02, 0x03},
{0x04, 0x07}, {0x04, 0x07},
@ -6386,9 +6388,9 @@ static void setsharpness(struct gspca_dev *gspca_dev)
sharpness = sd->sharpness; sharpness = sd->sharpness;
reg_w(dev, sharpness_tb[sharpness][0], 0x01c6); reg_w(dev, sharpness_tb[sharpness][0], 0x01c6);
reg_r(dev, 0x01c8, &retbyte); reg_r(gspca_dev, 0x01c8);
reg_r(dev, 0x01c9, &retbyte); reg_r(gspca_dev, 0x01c9);
reg_r(dev, 0x01ca, &retbyte); reg_r(gspca_dev, 0x01ca);
reg_w(dev, sharpness_tb[sharpness][1], 0x01cb); reg_w(dev, sharpness_tb[sharpness][1], 0x01cb);
} }
@ -6398,7 +6400,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
const __u8 *Tgamma, *Tgradient; const __u8 *Tgamma, *Tgradient;
int g, i, k; int g, i, k;
static const __u8 kgamma_tb[16] = /* delta for contrast */ static const __u8 kgamma_tb[16] = /* delta for contrast */
{0x15, 0x0d, 0x0a, 0x09, 0x08, 0x08, 0x08, 0x08, {0x15, 0x0d, 0x0a, 0x09, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
static const __u8 kgrad_tb[16] = static const __u8 kgrad_tb[16] =
@ -6623,7 +6625,7 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
i++; /* 640x480 */ i++; /* 640x480 */
zc3_freq = freq_tb[(int) sd->sensor][i]; zc3_freq = freq_tb[(int) sd->sensor][i];
if (zc3_freq != NULL) { if (zc3_freq != NULL) {
usb_exchange(gspca_dev->dev, zc3_freq); usb_exchange(gspca_dev, zc3_freq);
switch (sd->sensor) { switch (sd->sensor) {
case SENSOR_GC0305: case SENSOR_GC0305:
if (mode /* if 320x240 */ if (mode /* if 320x240 */
@ -6687,44 +6689,45 @@ static void start_2wr_probe(struct usb_device *dev, int sensor)
/* msleep(2); */ /* msleep(2); */
} }
static int sif_probe(struct usb_device *dev) static int sif_probe(struct gspca_dev *gspca_dev)
{ {
__u16 checkword; __u16 checkword;
start_2wr_probe(dev, 0x0f); /* PAS106 */ start_2wr_probe(gspca_dev->dev, 0x0f); /* PAS106 */
reg_w(dev, 0x08, 0x008d); reg_w(gspca_dev->dev, 0x08, 0x008d);
msleep(150); msleep(150);
checkword = ((i2c_read(dev, 0x00) & 0x0f) << 4) checkword = ((i2c_read(gspca_dev, 0x00) & 0x0f) << 4)
| ((i2c_read(dev, 0x01) & 0xf0) >> 4); | ((i2c_read(gspca_dev, 0x01) & 0xf0) >> 4);
PDEBUG(D_PROBE, "probe sif 0x%04x", checkword); PDEBUG(D_PROBE, "probe sif 0x%04x", checkword);
if (checkword == 0x0007) { if (checkword == 0x0007) {
send_unknown(dev, SENSOR_PAS106); send_unknown(gspca_dev->dev, SENSOR_PAS106);
return 0x0f; /* PAS106 */ return 0x0f; /* PAS106 */
} }
return -1; return -1;
} }
static int vga_2wr_probe(struct usb_device *dev) static int vga_2wr_probe(struct gspca_dev *gspca_dev)
{ {
struct usb_device *dev = gspca_dev->dev;
__u8 retbyte; __u8 retbyte;
__u16 checkword; __u16 checkword;
start_2wr_probe(dev, 0x00); /* HV7131B */ start_2wr_probe(dev, 0x00); /* HV7131B */
i2c_write(dev, 0x01, 0xaa, 0x00); i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
retbyte = i2c_read(dev, 0x01); retbyte = i2c_read(gspca_dev, 0x01);
if (retbyte != 0) if (retbyte != 0)
return 0x00; /* HV7131B */ return 0x00; /* HV7131B */
start_2wr_probe(dev, 0x04); /* CS2102 */ start_2wr_probe(dev, 0x04); /* CS2102 */
i2c_write(dev, 0x01, 0xaa, 0x00); i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
retbyte = i2c_read(dev, 0x01); retbyte = i2c_read(gspca_dev, 0x01);
if (retbyte != 0) if (retbyte != 0)
return 0x04; /* CS2102 */ return 0x04; /* CS2102 */
start_2wr_probe(dev, 0x06); /* OmniVision */ start_2wr_probe(dev, 0x06); /* OmniVision */
reg_w(dev, 0x08, 0x8d); reg_w(dev, 0x08, 0x8d);
i2c_write(dev, 0x11, 0xaa, 0x00); i2c_write(gspca_dev, 0x11, 0xaa, 0x00);
retbyte = i2c_read(dev, 0x11); retbyte = i2c_read(gspca_dev, 0x11);
if (retbyte != 0) { if (retbyte != 0) {
/* (should have returned 0xaa) --> Omnivision? */ /* (should have returned 0xaa) --> Omnivision? */
/* reg_r 0x10 -> 0x06 --> */ /* reg_r 0x10 -> 0x06 --> */
@ -6732,45 +6735,45 @@ static int vga_2wr_probe(struct usb_device *dev)
} }
start_2wr_probe(dev, 0x08); /* HDCS2020 */ start_2wr_probe(dev, 0x08); /* HDCS2020 */
i2c_write(dev, 0x15, 0xaa, 0x00); i2c_write(gspca_dev, 0x15, 0xaa, 0x00);
retbyte = i2c_read(dev, 0x15); retbyte = i2c_read(gspca_dev, 0x15);
if (retbyte != 0) if (retbyte != 0)
return 0x08; /* HDCS2020 */ return 0x08; /* HDCS2020 */
start_2wr_probe(dev, 0x0a); /* PB0330 */ start_2wr_probe(dev, 0x0a); /* PB0330 */
i2c_write(dev, 0x07, 0xaa, 0xaa); i2c_write(gspca_dev, 0x07, 0xaa, 0xaa);
retbyte = i2c_read(dev, 0x07); retbyte = i2c_read(gspca_dev, 0x07);
if (retbyte != 0) if (retbyte != 0)
return 0x0a; /* PB0330 */ return 0x0a; /* PB0330 */
retbyte = i2c_read(dev, 0x03); retbyte = i2c_read(gspca_dev, 0x03);
if (retbyte != 0) if (retbyte != 0)
return 0x0a; /* PB0330 ?? */ return 0x0a; /* PB0330 ?? */
retbyte = i2c_read(dev, 0x04); retbyte = i2c_read(gspca_dev, 0x04);
if (retbyte != 0) if (retbyte != 0)
return 0x0a; /* PB0330 ?? */ return 0x0a; /* PB0330 ?? */
start_2wr_probe(dev, 0x0c); /* ICM105A */ start_2wr_probe(dev, 0x0c); /* ICM105A */
i2c_write(dev, 0x01, 0x11, 0x00); i2c_write(gspca_dev, 0x01, 0x11, 0x00);
retbyte = i2c_read(dev, 0x01); retbyte = i2c_read(gspca_dev, 0x01);
if (retbyte != 0) if (retbyte != 0)
return 0x0c; /* ICM105A */ return 0x0c; /* ICM105A */
start_2wr_probe(dev, 0x0e); /* PAS202BCB */ start_2wr_probe(dev, 0x0e); /* PAS202BCB */
reg_w(dev, 0x08, 0x8d); reg_w(dev, 0x08, 0x8d);
i2c_write(dev, 0x03, 0xaa, 0x00); i2c_write(gspca_dev, 0x03, 0xaa, 0x00);
msleep(500); msleep(500);
retbyte = i2c_read(dev, 0x03); retbyte = i2c_read(gspca_dev, 0x03);
if (retbyte != 0) if (retbyte != 0)
return 0x0e; /* PAS202BCB */ return 0x0e; /* PAS202BCB */
start_2wr_probe(dev, 0x02); /* ?? */ start_2wr_probe(dev, 0x02); /* ?? */
i2c_write(dev, 0x01, 0xaa, 0x00); i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
retbyte = i2c_read(dev, 0x01); retbyte = i2c_read(gspca_dev, 0x01);
if (retbyte != 0) if (retbyte != 0)
return 0x02; /* ?? */ return 0x02; /* ?? */
ov_check: ov_check:
reg_r(dev, 0x0010, &retbyte); /* ?? */ reg_r(gspca_dev, 0x0010); /* ?? */
reg_r(dev, 0x0010, &retbyte); reg_r(gspca_dev, 0x0010);
reg_w(dev, 0x01, 0x0000); reg_w(dev, 0x01, 0x0000);
reg_w(dev, 0x01, 0x0001); reg_w(dev, 0x01, 0x0001);
@ -6779,10 +6782,10 @@ ov_check:
reg_w(dev, 0x08, 0x008d); reg_w(dev, 0x08, 0x008d);
msleep(500); msleep(500);
reg_w(dev, 0x01, 0x0012); reg_w(dev, 0x01, 0x0012);
i2c_write(dev, 0x12, 0x80, 0x00); /* sensor reset */ i2c_write(gspca_dev, 0x12, 0x80, 0x00); /* sensor reset */
retbyte = i2c_read(dev, 0x0a); retbyte = i2c_read(gspca_dev, 0x0a);
checkword = retbyte << 8; checkword = retbyte << 8;
retbyte = i2c_read(dev, 0x0b); retbyte = i2c_read(gspca_dev, 0x0b);
checkword |= retbyte; checkword |= retbyte;
PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", checkword); PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", checkword);
switch (checkword) { switch (checkword) {
@ -6821,7 +6824,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
/*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/ /*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/
reg_w(dev, 0x02, 0x0010); reg_w(dev, 0x02, 0x0010);
reg_r(dev, 0x10, &retbyte); reg_r(gspca_dev, 0x10);
reg_w(dev, 0x01, 0x0000); reg_w(dev, 0x01, 0x0000);
reg_w(dev, 0x00, 0x0010); reg_w(dev, 0x00, 0x0010);
reg_w(dev, 0x01, 0x0001); reg_w(dev, 0x01, 0x0001);
@ -6829,23 +6832,23 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x03, 0x0012); reg_w(dev, 0x03, 0x0012);
reg_w(dev, 0x01, 0x0012); reg_w(dev, 0x01, 0x0012);
reg_w(dev, 0x05, 0x0012); reg_w(dev, 0x05, 0x0012);
retbyte = i2c_read(dev, 0x14); retbyte = i2c_read(gspca_dev, 0x14);
if (retbyte != 0) if (retbyte != 0)
return 0x11; /* HV7131R */ return 0x11; /* HV7131R */
retbyte = i2c_read(dev, 0x15); retbyte = i2c_read(gspca_dev, 0x15);
if (retbyte != 0) if (retbyte != 0)
return 0x11; /* HV7131R */ return 0x11; /* HV7131R */
retbyte = i2c_read(dev, 0x16); retbyte = i2c_read(gspca_dev, 0x16);
if (retbyte != 0) if (retbyte != 0)
return 0x11; /* HV7131R */ return 0x11; /* HV7131R */
reg_w(dev, 0x02, 0x0010); reg_w(dev, 0x02, 0x0010);
reg_r(dev, 0x000b, &retbyte); retbyte = reg_r(gspca_dev, 0x000b);
checkword = retbyte << 8; checkword = retbyte << 8;
reg_r(dev, 0x000a, &retbyte); retbyte = reg_r(gspca_dev, 0x000a);
checkword |= retbyte; checkword |= retbyte;
PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", checkword); PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", checkword);
reg_r(dev, 0x0010, &retbyte); reg_r(gspca_dev, 0x0010);
/* this is tested only once anyway */ /* this is tested only once anyway */
i = 0; i = 0;
while (chipset_revision_sensor[i].revision) { while (chipset_revision_sensor[i].revision) {
@ -6863,7 +6866,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x0a, 0x0010); reg_w(dev, 0x0a, 0x0010);
reg_w(dev, 0x03, 0x0012); reg_w(dev, 0x03, 0x0012);
reg_w(dev, 0x01, 0x0012); reg_w(dev, 0x01, 0x0012);
retbyte = i2c_read(dev, 0x00); retbyte = i2c_read(gspca_dev, 0x00);
if (retbyte != 0) { if (retbyte != 0) {
PDEBUG(D_PROBE, "probe 3wr vga type 0a ?"); PDEBUG(D_PROBE, "probe 3wr vga type 0a ?");
return 0x0a; /* ?? */ return 0x0a; /* ?? */
@ -6876,7 +6879,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x03, 0x0012); reg_w(dev, 0x03, 0x0012);
msleep(2); msleep(2);
reg_w(dev, 0x01, 0x0012); reg_w(dev, 0x01, 0x0012);
retbyte = i2c_read(dev, 0x00); retbyte = i2c_read(gspca_dev, 0x00);
if (retbyte != 0) { if (retbyte != 0) {
PDEBUG(D_PROBE, "probe 3wr vga type %02x", retbyte); PDEBUG(D_PROBE, "probe 3wr vga type %02x", retbyte);
send_unknown(dev, SENSOR_GC0305); send_unknown(dev, SENSOR_GC0305);
@ -6890,8 +6893,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x06, 0x0010); reg_w(dev, 0x06, 0x0010);
reg_w(dev, 0x01, 0x0012); reg_w(dev, 0x01, 0x0012);
reg_w(dev, 0x05, 0x0012); reg_w(dev, 0x05, 0x0012);
if (i2c_read(dev, 0x1c) == 0x7f /* OV7610 - manufacturer ID */ if (i2c_read(gspca_dev, 0x1c) == 0x7f /* OV7610 - manufacturer ID */
&& i2c_read(dev, 0x1d) == 0xa2) { && i2c_read(gspca_dev, 0x1d) == 0xa2) {
send_unknown(dev, SENSOR_OV7620); send_unknown(dev, SENSOR_OV7620);
return 0x06; /* OmniVision confirm ? */ return 0x06; /* OmniVision confirm ? */
} }
@ -6905,13 +6908,13 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
/* msleep(150); */ /* msleep(150); */
reg_w(dev, 0x01, 0x12); reg_w(dev, 0x01, 0x12);
reg_w(dev, 0x05, 0x12); reg_w(dev, 0x05, 0x12);
retbyte = i2c_read(dev, 0x00); /* ID 0 */ retbyte = i2c_read(gspca_dev, 0x00); /* ID 0 */
checkword = retbyte << 8; checkword = retbyte << 8;
retbyte = i2c_read(dev, 0x01); /* ID 1 */ retbyte = i2c_read(gspca_dev, 0x01); /* ID 1 */
checkword |= retbyte; checkword |= retbyte;
PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", checkword); PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", checkword);
if (checkword == 0x2030) { if (checkword == 0x2030) {
retbyte = i2c_read(dev, 0x02); /* revision number */ retbyte = i2c_read(gspca_dev, 0x02); /* revision number */
PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte); PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte);
send_unknown(dev, SENSOR_PO2030); send_unknown(dev, SENSOR_PO2030);
return checkword; return checkword;
@ -6925,7 +6928,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x01, 0x12); reg_w(dev, 0x01, 0x12);
reg_w(dev, 0x05, 0x01); reg_w(dev, 0x05, 0x01);
reg_w(dev, 0xd3, 0x8b); reg_w(dev, 0xd3, 0x8b);
retbyte = i2c_read(dev, 0x01); retbyte = i2c_read(gspca_dev, 0x01);
if (retbyte != 0) { if (retbyte != 0) {
PDEBUG(D_PROBE, "probe 3wr vga type 0a ?"); PDEBUG(D_PROBE, "probe 3wr vga type 0a ?");
return 0x0a; /* ?? */ return 0x0a; /* ?? */
@ -6936,7 +6939,6 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
static int zcxx_probeSensor(struct gspca_dev *gspca_dev) static int zcxx_probeSensor(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
int sensor, sensor2; int sensor, sensor2;
switch (sd->sensor) { switch (sd->sensor) {
@ -6944,7 +6946,7 @@ static int zcxx_probeSensor(struct gspca_dev *gspca_dev)
case SENSOR_TAS5130C_VF0250: case SENSOR_TAS5130C_VF0250:
return -1; /* don't probe */ return -1; /* don't probe */
} }
sensor = vga_2wr_probe(dev); sensor = vga_2wr_probe(gspca_dev);
if (sensor >= 0) { if (sensor >= 0) {
if (sensor < 0x7600) if (sensor < 0x7600)
return sensor; return sensor;
@ -6956,7 +6958,7 @@ static int zcxx_probeSensor(struct gspca_dev *gspca_dev)
return sensor; return sensor;
return sensor2; return sensor2;
} }
return sif_probe(dev); return sif_probe(gspca_dev);
} }
/* this function is called at probe time */ /* this function is called at probe time */
@ -6966,7 +6968,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam; struct cam *cam;
int sensor; int sensor;
__u8 bsensor;
int vga = 1; /* 1: vga, 0: sif */ int vga = 1; /* 1: vga, 0: sif */
static const __u8 gamma[SENSOR_MAX] = { static const __u8 gamma[SENSOR_MAX] = {
5, /* SENSOR_CS2102 0 */ 5, /* SENSOR_CS2102 0 */
@ -7122,7 +7123,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
reg_w(gspca_dev->dev, 0x02, 0x0010); reg_w(gspca_dev->dev, 0x02, 0x0010);
else else
reg_w(gspca_dev->dev, sensor & 0x0f, 0x0010); reg_w(gspca_dev->dev, sensor & 0x0f, 0x0010);
reg_r(gspca_dev->dev, 0x0010, &bsensor); reg_r(gspca_dev, 0x0010);
} }
cam = &gspca_dev->cam; cam = &gspca_dev->cam;
@ -7163,7 +7164,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
const struct usb_action *zc3_init; const struct usb_action *zc3_init;
int mode; int mode;
__u8 retbyte;
static const struct usb_action *init_tb[SENSOR_MAX][2] = { static const struct usb_action *init_tb[SENSOR_MAX][2] = {
{cs2102_InitialScale, cs2102_Initial}, /* 0 */ {cs2102_InitialScale, cs2102_Initial}, /* 0 */
{cs2102K_InitialScale, cs2102K_Initial}, /* 1 */ {cs2102K_InitialScale, cs2102K_Initial}, /* 1 */
@ -7194,7 +7194,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
zcxx_probeSensor(gspca_dev); zcxx_probeSensor(gspca_dev);
break; break;
case SENSOR_PAS106: case SENSOR_PAS106:
usb_exchange(dev, pas106b_Initial_com); usb_exchange(gspca_dev, pas106b_Initial_com);
break; break;
case SENSOR_PB0330: case SENSOR_PB0330:
if (mode) { if (mode) {
@ -7210,14 +7210,14 @@ static void sd_start(struct gspca_dev *gspca_dev)
} }
break; break;
} }
usb_exchange(dev, zc3_init); usb_exchange(gspca_dev, zc3_init);
switch (sd->sensor) { switch (sd->sensor) {
case SENSOR_GC0305: case SENSOR_GC0305:
case SENSOR_OV7620: case SENSOR_OV7620:
case SENSOR_PO2030: case SENSOR_PO2030:
msleep(100); /* ?? */ msleep(100); /* ?? */
reg_r(dev, 0x0002, &retbyte); /* --> 0x40 */ reg_r(gspca_dev, 0x0002); /* --> 0x40 */
reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
reg_w(dev, 0x15, 0x01ae); reg_w(dev, 0x15, 0x01ae);
reg_w(dev, 0x0d, 0x003a); reg_w(dev, 0x0d, 0x003a);
@ -7230,11 +7230,11 @@ static void sd_start(struct gspca_dev *gspca_dev)
setbrightness(gspca_dev); setbrightness(gspca_dev);
switch (sd->sensor) { switch (sd->sensor) {
case SENSOR_OV7620: case SENSOR_OV7620:
reg_r(dev, 0x0008, &retbyte); reg_r(gspca_dev, 0x0008);
reg_w(dev, 0x00, 0x0008); reg_w(dev, 0x00, 0x0008);
break; break;
case SENSOR_GC0305: case SENSOR_GC0305:
reg_r(dev, 0x0008, &retbyte); reg_r(gspca_dev, 0x0008);
/* fall thru */ /* fall thru */
case SENSOR_PO2030: case SENSOR_PO2030:
reg_w(dev, 0x03, 0x0008); reg_w(dev, 0x03, 0x0008);
@ -7259,7 +7259,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
setmatrix(gspca_dev); /* one more time? */ setmatrix(gspca_dev); /* one more time? */
switch (sd->sensor) { switch (sd->sensor) {
case SENSOR_OV7620: case SENSOR_OV7620:
reg_r(dev, 0x0180, &retbyte); /* from win */ reg_r(gspca_dev, 0x0180); /* from win */
reg_w(dev, 0x00, 0x0180); reg_w(dev, 0x00, 0x0180);
break; break;
default: default:
@ -7277,7 +7277,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
break; break;
case SENSOR_PO2030: case SENSOR_PO2030:
reg_w(dev, 0x40, 0x0117); /* (from win traces) */ reg_w(dev, 0x40, 0x0117); /* (from win traces) */
reg_r(dev, 0x0180, &retbyte); reg_r(gspca_dev, 0x0180);
break; break;
} }
@ -7289,22 +7289,23 @@ static void sd_start(struct gspca_dev *gspca_dev)
reg_w(dev, 0x15, 0x01ae); reg_w(dev, 0x15, 0x01ae);
reg_w(dev, 0x40, 0x0180); reg_w(dev, 0x40, 0x0180);
reg_w(dev, 0x40, 0x0117); reg_w(dev, 0x40, 0x0117);
reg_r(dev, 0x0180, &retbyte); reg_r(gspca_dev, 0x0180);
sd->autogain = 1; sd->autogain = 1;
setautogain(gspca_dev); setautogain(gspca_dev);
break; break;
case SENSOR_OV7620: case SENSOR_OV7620:
i2c_read(dev, 0x13); /*fixme: returns 0xa3 */ i2c_read(gspca_dev, 0x13); /*fixme: returns 0xa3 */
i2c_write(dev, 0x13, 0xa3, 0x00); /*fixme: same to send? */ i2c_write(gspca_dev, 0x13, 0xa3, 0x00);
/*fixme: returned value to send? */
reg_w(dev, 0x40, 0x0117); /* (from win traces) */ reg_w(dev, 0x40, 0x0117); /* (from win traces) */
reg_r(dev, 0x0180, &retbyte); reg_r(gspca_dev, 0x0180);
setautogain(gspca_dev); setautogain(gspca_dev);
msleep(500); msleep(500);
break; break;
case SENSOR_PO2030: case SENSOR_PO2030:
msleep(500); msleep(500);
reg_r(dev, 0x0008, &retbyte); reg_r(gspca_dev, 0x0008);
reg_r(dev, 0x0007, &retbyte); reg_r(gspca_dev, 0x0007);
reg_w(dev, 0x00, 0x0007); /* (from win traces) */ reg_w(dev, 0x00, 0x0007); /* (from win traces) */
reg_w(dev, 0x02, 0x0008); reg_w(dev, 0x02, 0x0008);
break; break;