V4L/DVB (13567): gspca - sunplus/stk014: Propagate errors to higher level.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Jean-Francois Moine 2009-12-02 14:39:53 -03:00 committed by Mauro Carvalho Chehab
parent 8c4ebae45f
commit ecb7768686
2 changed files with 168 additions and 175 deletions

View File

@ -126,12 +126,14 @@ static const struct v4l2_pix_format vga_mode[] = {
};
/* -- read a register -- */
static int reg_r(struct gspca_dev *gspca_dev,
static u8 reg_r(struct gspca_dev *gspca_dev,
__u16 index)
{
struct usb_device *dev = gspca_dev->dev;
int ret;
if (gspca_dev->usb_err < 0)
return 0;
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
0x00,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
@ -141,18 +143,21 @@ static int reg_r(struct gspca_dev *gspca_dev,
500);
if (ret < 0) {
PDEBUG(D_ERR, "reg_r err %d", ret);
return ret;
gspca_dev->usb_err = ret;
return 0;
}
return gspca_dev->usb_buf[0];
}
/* -- write a register -- */
static int reg_w(struct gspca_dev *gspca_dev,
static void reg_w(struct gspca_dev *gspca_dev,
__u16 index, __u16 value)
{
struct usb_device *dev = gspca_dev->dev;
int ret;
if (gspca_dev->usb_err < 0)
return;
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
0x01,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
@ -161,13 +166,14 @@ static int reg_w(struct gspca_dev *gspca_dev,
NULL,
0,
500);
if (ret < 0)
if (ret < 0) {
PDEBUG(D_ERR, "reg_w err %d", ret);
return ret;
gspca_dev->usb_err = ret;
}
}
/* -- get a bulk value (4 bytes) -- */
static int rcv_val(struct gspca_dev *gspca_dev,
static void rcv_val(struct gspca_dev *gspca_dev,
int ads)
{
struct usb_device *dev = gspca_dev->dev;
@ -182,17 +188,22 @@ static int rcv_val(struct gspca_dev *gspca_dev,
reg_w(gspca_dev, 0x63a, 0);
reg_w(gspca_dev, 0x63b, 0);
reg_w(gspca_dev, 0x630, 5);
if (gspca_dev->usb_err < 0)
return;
ret = usb_bulk_msg(dev,
usb_rcvbulkpipe(dev, 0x05),
gspca_dev->usb_buf,
4, /* length */
&alen,
500); /* timeout in milliseconds */
return ret;
if (ret < 0) {
PDEBUG(D_ERR, "rcv_val err %d", ret);
gspca_dev->usb_err = ret;
}
}
/* -- send a bulk value -- */
static int snd_val(struct gspca_dev *gspca_dev,
static void snd_val(struct gspca_dev *gspca_dev,
int ads,
unsigned int val)
{
@ -201,16 +212,9 @@ static int snd_val(struct gspca_dev *gspca_dev,
__u8 seq = 0;
if (ads == 0x003f08) {
ret = reg_r(gspca_dev, 0x0704);
if (ret < 0)
goto ko;
ret = reg_r(gspca_dev, 0x0705);
if (ret < 0)
goto ko;
seq = ret; /* keep the sequence number */
ret = reg_r(gspca_dev, 0x0650);
if (ret < 0)
goto ko;
reg_r(gspca_dev, 0x0704);
seq = reg_r(gspca_dev, 0x0705);
reg_r(gspca_dev, 0x0650);
reg_w(gspca_dev, 0x654, seq);
} else {
reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff);
@ -223,6 +227,8 @@ static int snd_val(struct gspca_dev *gspca_dev,
reg_w(gspca_dev, 0x65a, 0);
reg_w(gspca_dev, 0x65b, 0);
reg_w(gspca_dev, 0x650, 5);
if (gspca_dev->usb_err < 0)
return;
gspca_dev->usb_buf[0] = val >> 24;
gspca_dev->usb_buf[1] = val >> 16;
gspca_dev->usb_buf[2] = val >> 8;
@ -233,24 +239,23 @@ static int snd_val(struct gspca_dev *gspca_dev,
4,
&alen,
500); /* timeout in milliseconds */
if (ret < 0)
goto ko;
if (ret < 0) {
PDEBUG(D_ERR, "snd_val err %d", ret);
gspca_dev->usb_err = ret;
} else {
if (ads == 0x003f08) {
seq += 4;
seq &= 0x3f;
reg_w(gspca_dev, 0x705, seq);
}
return ret;
ko:
PDEBUG(D_ERR, "snd_val err %d", ret);
return ret;
}
}
/* set a camera parameter */
static int set_par(struct gspca_dev *gspca_dev,
static void set_par(struct gspca_dev *gspca_dev,
int parval)
{
return snd_val(gspca_dev, 0x003f08, parval);
snd_val(gspca_dev, 0x003f08, parval);
}
static void setbrightness(struct gspca_dev *gspca_dev)
@ -311,18 +316,18 @@ static int sd_config(struct gspca_dev *gspca_dev,
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
int ret;
u8 ret;
/* check if the device responds */
usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
ret = reg_r(gspca_dev, 0x0740);
if (ret < 0)
return ret;
if (gspca_dev->usb_err >= 0) {
if (ret != 0xff) {
PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", ret);
return -1;
gspca_dev->usb_err = -EIO;
}
return 0;
}
return gspca_dev->usb_err;
}
/* -- start the camera -- */
@ -357,15 +362,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
if (ret < 0) {
PDEBUG(D_ERR|D_STREAM, "set intf %d %d failed",
gspca_dev->iface, gspca_dev->alt);
gspca_dev->usb_err = ret;
goto out;
}
ret = reg_r(gspca_dev, 0x0630);
if (ret < 0)
goto out;
reg_r(gspca_dev, 0x0630);
rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */
ret = reg_r(gspca_dev, 0x0650);
if (ret < 0)
goto out;
reg_r(gspca_dev, 0x0650);
snd_val(gspca_dev, 0x000020, 0xffffffff);
reg_w(gspca_dev, 0x0620, 0);
reg_w(gspca_dev, 0x0630, 0);
@ -384,11 +386,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* start the video flow */
set_par(gspca_dev, 0x01000000);
set_par(gspca_dev, 0x01000000);
PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt);
return 0;
if (gspca_dev->usb_err >= 0)
PDEBUG(D_STREAM, "camera started alt: 0x%02x",
gspca_dev->alt);
out:
PDEBUG(D_ERR|D_STREAM, "camera start err %d", ret);
return ret;
return gspca_dev->usb_err;
}
static void sd_stopN(struct gspca_dev *gspca_dev)
@ -456,7 +458,7 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
sd->brightness = val;
if (gspca_dev->streaming)
setbrightness(gspca_dev);
return 0;
return gspca_dev->usb_err;
}
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
@ -474,7 +476,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
sd->contrast = val;
if (gspca_dev->streaming)
setcontrast(gspca_dev);
return 0;
return gspca_dev->usb_err;
}
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
@ -492,7 +494,7 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
sd->colors = val;
if (gspca_dev->streaming)
setcolors(gspca_dev);
return 0;
return gspca_dev->usb_err;
}
static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
@ -510,7 +512,7 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
sd->lightfreq = val;
if (gspca_dev->streaming)
setfreq(gspca_dev);
return 0;
return gspca_dev->usb_err;
}
static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
@ -552,7 +554,7 @@ static int sd_set_jcomp(struct gspca_dev *gspca_dev,
sd->quality = jcomp->quality;
if (gspca_dev->streaming)
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
return 0;
return gspca_dev->usb_err;
}
static int sd_get_jcomp(struct gspca_dev *gspca_dev,

View File

@ -460,13 +460,17 @@ static void reg_r(struct gspca_dev *gspca_dev,
u16 index,
u16 len)
{
int ret;
#ifdef GSPCA_DEBUG
if (len > USB_BUF_SZ) {
err("reg_r: buffer overflow");
return;
}
#endif
usb_control_msg(gspca_dev->dev,
if (gspca_dev->usb_err < 0)
return;
ret = usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
req,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
@ -474,6 +478,10 @@ static void reg_r(struct gspca_dev *gspca_dev,
index,
len ? gspca_dev->usb_buf : NULL, len,
500);
if (ret < 0) {
PDEBUG(D_ERR, "reg_r err %d", ret);
gspca_dev->usb_err = ret;
}
}
/* write one byte */
@ -483,40 +491,55 @@ static void reg_w_1(struct gspca_dev *gspca_dev,
u16 index,
u16 byte)
{
int ret;
if (gspca_dev->usb_err < 0)
return;
gspca_dev->usb_buf[0] = byte;
usb_control_msg(gspca_dev->dev,
ret = usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
req,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, index,
gspca_dev->usb_buf, 1,
500);
if (ret < 0) {
PDEBUG(D_ERR, "reg_w_1 err %d", ret);
gspca_dev->usb_err = ret;
}
}
/* write req / index / value */
static int reg_w_riv(struct usb_device *dev,
static void reg_w_riv(struct gspca_dev *gspca_dev,
u8 req, u16 index, u16 value)
{
struct usb_device *dev = gspca_dev->dev;
int ret;
if (gspca_dev->usb_err < 0)
return;
ret = usb_control_msg(dev,
usb_sndctrlpipe(dev, 0),
req,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, index, NULL, 0, 500);
PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d",
req, index, value, ret);
if (ret < 0)
PDEBUG(D_ERR, "reg write: error %d", ret);
return ret;
if (ret < 0) {
PDEBUG(D_ERR, "reg_w_riv err %d", ret);
gspca_dev->usb_err = ret;
return;
}
PDEBUG(D_USBO, "reg_w_riv: 0x%02x,0x%04x:0x%04x",
req, index, value);
}
/* read 1 byte */
static int reg_r_1(struct gspca_dev *gspca_dev,
static u8 reg_r_1(struct gspca_dev *gspca_dev,
u16 value) /* wValue */
{
int ret;
if (gspca_dev->usb_err < 0)
return 0;
ret = usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
0x20, /* request */
@ -527,19 +550,22 @@ static int reg_r_1(struct gspca_dev *gspca_dev,
500); /* timeout */
if (ret < 0) {
PDEBUG(D_ERR, "reg_r_1 err %d", ret);
gspca_dev->usb_err = ret;
return 0;
}
return gspca_dev->usb_buf[0];
}
/* read 1 or 2 bytes - returns < 0 if error */
static int reg_r_12(struct gspca_dev *gspca_dev,
/* read 1 or 2 bytes */
static u16 reg_r_12(struct gspca_dev *gspca_dev,
u8 req, /* bRequest */
u16 index, /* wIndex */
u16 length) /* wLength (1 or 2 only) */
{
int ret;
if (gspca_dev->usb_err < 0)
return 0;
gspca_dev->usb_buf[1] = 0;
ret = usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
@ -550,62 +576,44 @@ static int reg_r_12(struct gspca_dev *gspca_dev,
gspca_dev->usb_buf, length,
500);
if (ret < 0) {
PDEBUG(D_ERR, "reg_read err %d", ret);
return -1;
PDEBUG(D_ERR, "reg_r_12 err %d", ret);
gspca_dev->usb_err = ret;
return 0;
}
return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
}
static int write_vector(struct gspca_dev *gspca_dev,
static void write_vector(struct gspca_dev *gspca_dev,
const struct cmd *data, int ncmds)
{
struct usb_device *dev = gspca_dev->dev;
int ret;
while (--ncmds >= 0) {
ret = reg_w_riv(dev, data->req, data->idx, data->val);
if (ret < 0) {
PDEBUG(D_ERR,
"Register write failed for 0x%02x, 0x%04x, 0x%04x",
data->req, data->val, data->idx);
return ret;
}
reg_w_riv(gspca_dev, data->req, data->idx, data->val);
data++;
}
return 0;
}
static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
static void setup_qtable(struct gspca_dev *gspca_dev,
const u8 qtable[2][64])
{
struct usb_device *dev = gspca_dev->dev;
int i, err;
int i;
/* loop over y components */
for (i = 0; i < 64; i++) {
err = reg_w_riv(dev, 0x00, 0x2800 + i, qtable[0][i]);
if (err < 0)
return err;
}
for (i = 0; i < 64; i++)
reg_w_riv(gspca_dev, 0x00, 0x2800 + i, qtable[0][i]);
/* loop over c components */
for (i = 0; i < 64; i++) {
err = reg_w_riv(dev, 0x00, 0x2840 + i, qtable[1][i]);
if (err < 0)
return err;
}
return 0;
for (i = 0; i < 64; i++)
reg_w_riv(gspca_dev, 0x00, 0x2840 + i, qtable[1][i]);
}
static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
u8 req, u16 idx, u16 val)
{
struct usb_device *dev = gspca_dev->dev;
int notdone;
u16 notdone;
reg_w_riv(dev, req, idx, val);
reg_w_riv(gspca_dev, req, idx, val);
notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
reg_w_riv(dev, req, idx, val);
reg_w_riv(gspca_dev, req, idx, val);
PDEBUG(D_FRAM, "before wait 0x%04x", notdone);
@ -616,23 +624,22 @@ static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
u8 req,
u16 idx, u16 val, u8 stat, u8 count)
u16 idx, u16 val, u16 endcode, u8 count)
{
struct usb_device *dev = gspca_dev->dev;
int status;
u8 endcode;
u16 status;
reg_w_riv(dev, req, idx, val);
reg_w_riv(gspca_dev, req, idx, val);
status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
endcode = stat;
PDEBUG(D_FRAM, "Status 0x%x Need 0x%04x", status, stat);
if (gspca_dev->usb_err < 0)
return;
PDEBUG(D_FRAM, "Status 0x%04x Need 0x%04x", status, endcode);
if (!count)
return;
count = 200;
while (--count > 0) {
msleep(10);
/* gsmart mini2 write a each wait setting 1 ms is enough */
/* reg_w_riv(dev, req, idx, val); */
/* reg_w_riv(gspca_dev, req, idx, val); */
status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
if (status == endcode) {
PDEBUG(D_FRAM, "status 0x%04x after wait %d",
@ -642,7 +649,7 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
}
}
static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
static void spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
{
int count = 10;
@ -652,7 +659,6 @@ static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
break;
msleep(10);
}
return gspca_dev->usb_buf[0];
}
static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
@ -686,28 +692,26 @@ static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
u8 Size;
int rc;
Size = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
switch (sd->bridge) {
case BRIDGE_SPCA533:
reg_w_riv(dev, 0x31, 0, 0);
reg_w_riv(gspca_dev, 0x31, 0, 0);
spca504B_WaitCmdStatus(gspca_dev);
rc = spca504B_PollingDataReady(gspca_dev);
spca504B_PollingDataReady(gspca_dev);
spca50x_GetFirmware(gspca_dev);
reg_w_1(gspca_dev, 0x24, 0, 8, 2); /* type */
reg_r(gspca_dev, 0x24, 8, 1);
reg_w_1(gspca_dev, 0x25, 0, 4, Size);
reg_r(gspca_dev, 0x25, 4, 1); /* size */
rc = spca504B_PollingDataReady(gspca_dev);
spca504B_PollingDataReady(gspca_dev);
/* Init the cam width height with some values get on init ? */
reg_w_riv(dev, 0x31, 0, 0x04);
reg_w_riv(gspca_dev, 0x31, 0, 0x04);
spca504B_WaitCmdStatus(gspca_dev);
rc = spca504B_PollingDataReady(gspca_dev);
spca504B_PollingDataReady(gspca_dev);
break;
default:
/* case BRIDGE_SPCA504B: */
@ -716,7 +720,7 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
reg_r(gspca_dev, 0x25, 4, 1); /* size */
reg_w_1(gspca_dev, 0x27, 0, 0, 6);
reg_r(gspca_dev, 0x27, 0, 1); /* type */
rc = spca504B_PollingDataReady(gspca_dev);
spca504B_PollingDataReady(gspca_dev);
break;
case BRIDGE_SPCA504:
Size += 3;
@ -733,8 +737,8 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
break;
case BRIDGE_SPCA504C:
/* capture mode */
reg_w_riv(dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
reg_w_riv(dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
reg_w_riv(gspca_dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
reg_w_riv(gspca_dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
break;
}
}
@ -762,37 +766,33 @@ static void spca504B_setQtable(struct gspca_dev *gspca_dev)
static void setbrightness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
u16 reg;
reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7;
reg_w_riv(dev, 0x00, reg, sd->brightness);
reg_w_riv(gspca_dev, 0x00, reg, sd->brightness);
}
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
u16 reg;
reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8;
reg_w_riv(dev, 0x00, reg, sd->contrast);
reg_w_riv(gspca_dev, 0x00, reg, sd->contrast);
}
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
u16 reg;
reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae;
reg_w_riv(dev, 0x00, reg, sd->colors);
reg_w_riv(gspca_dev, 0x00, reg, sd->colors);
}
static void init_ctl_reg(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
int pollreg = 1;
setbrightness(gspca_dev);
@ -807,14 +807,14 @@ static void init_ctl_reg(struct gspca_dev *gspca_dev)
default:
/* case BRIDGE_SPCA533: */
/* case BRIDGE_SPCA504B: */
reg_w_riv(dev, 0, 0x00, 0x21ad); /* hue */
reg_w_riv(dev, 0, 0x01, 0x21ac); /* sat/hue */
reg_w_riv(dev, 0, 0x00, 0x21a3); /* gamma */
reg_w_riv(gspca_dev, 0, 0x00, 0x21ad); /* hue */
reg_w_riv(gspca_dev, 0, 0x01, 0x21ac); /* sat/hue */
reg_w_riv(gspca_dev, 0, 0x00, 0x21a3); /* gamma */
break;
case BRIDGE_SPCA536:
reg_w_riv(dev, 0, 0x40, 0x20f5);
reg_w_riv(dev, 0, 0x01, 0x20f4);
reg_w_riv(dev, 0, 0x00, 0x2089);
reg_w_riv(gspca_dev, 0, 0x40, 0x20f5);
reg_w_riv(gspca_dev, 0, 0x01, 0x20f4);
reg_w_riv(gspca_dev, 0, 0x00, 0x2089);
break;
}
if (pollreg)
@ -881,18 +881,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
static int sd_init(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
int i, err_code;
int i;
u8 info[6];
switch (sd->bridge) {
case BRIDGE_SPCA504B:
reg_w_riv(dev, 0x1d, 0x00, 0);
reg_w_riv(dev, 0, 0x01, 0x2306);
reg_w_riv(dev, 0, 0x00, 0x0d04);
reg_w_riv(dev, 0, 0x00, 0x2000);
reg_w_riv(dev, 0, 0x13, 0x2301);
reg_w_riv(dev, 0, 0x00, 0x2306);
reg_w_riv(gspca_dev, 0x1d, 0x00, 0);
reg_w_riv(gspca_dev, 0, 0x01, 0x2306);
reg_w_riv(gspca_dev, 0, 0x00, 0x0d04);
reg_w_riv(gspca_dev, 0, 0x00, 0x2000);
reg_w_riv(gspca_dev, 0, 0x13, 0x2301);
reg_w_riv(gspca_dev, 0, 0x00, 0x2306);
/* fall thru */
case BRIDGE_SPCA533:
spca504B_PollingDataReady(gspca_dev);
@ -904,13 +903,13 @@ static int sd_init(struct gspca_dev *gspca_dev)
reg_w_1(gspca_dev, 0x24, 0, 0, 0);
reg_r(gspca_dev, 0x24, 0, 1);
spca504B_PollingDataReady(gspca_dev);
reg_w_riv(dev, 0x34, 0, 0);
reg_w_riv(gspca_dev, 0x34, 0, 0);
spca504B_WaitCmdStatus(gspca_dev);
break;
case BRIDGE_SPCA504C: /* pccam600 */
PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)");
reg_w_riv(dev, 0xe0, 0x0000, 0x0000);
reg_w_riv(dev, 0xe0, 0x0000, 0x0001); /* reset */
reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0000);
reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0001); /* reset */
spca504_wait_status(gspca_dev);
if (sd->subtype == LogitechClickSmart420)
write_vector(gspca_dev,
@ -919,12 +918,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
else
write_vector(gspca_dev, spca504_pccam600_open_data,
ARRAY_SIZE(spca504_pccam600_open_data));
err_code = spca50x_setup_qtable(gspca_dev,
qtable_creative_pccam);
if (err_code < 0) {
PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed");
return err_code;
}
setup_qtable(gspca_dev, qtable_creative_pccam);
break;
default:
/* case BRIDGE_SPCA504: */
@ -958,29 +952,24 @@ static int sd_init(struct gspca_dev *gspca_dev)
6, 0, 0x86, 1); */
/* spca504A_acknowledged_command (gspca_dev, 0x24,
0, 0, 0x9D, 1); */
reg_w_riv(dev, 0x00, 0x270c, 0x05); /* L92 sno1t.txt */
reg_w_riv(dev, 0x00, 0x2310, 0x05);
reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
/* L92 sno1t.txt */
reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
spca504A_acknowledged_command(gspca_dev, 0x01,
0x0f, 0, 0xff, 0);
}
/* setup qtable */
reg_w_riv(dev, 0, 0x2000, 0);
reg_w_riv(dev, 0, 0x2883, 1);
err_code = spca50x_setup_qtable(gspca_dev,
qtable_spca504_default);
if (err_code < 0) {
PDEBUG(D_ERR, "spca50x_setup_qtable failed");
return err_code;
}
reg_w_riv(gspca_dev, 0, 0x2000, 0);
reg_w_riv(gspca_dev, 0, 0x2883, 1);
setup_qtable(gspca_dev, qtable_spca504_default);
break;
}
return 0;
return gspca_dev->usb_err;
}
static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
int enable;
int i;
u8 info[6];
@ -1005,13 +994,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
case MegapixV4:
case LogitechClickSmart820:
case MegaImageVI:
reg_w_riv(dev, 0xf0, 0, 0);
reg_w_riv(gspca_dev, 0xf0, 0, 0);
spca504B_WaitCmdStatus(gspca_dev);
reg_r(gspca_dev, 0xf0, 4, 0);
spca504B_WaitCmdStatus(gspca_dev);
break;
default:
reg_w_riv(dev, 0x31, 0, 0x04);
reg_w_riv(gspca_dev, 0x31, 0, 0x04);
spca504B_WaitCmdStatus(gspca_dev);
spca504B_PollingDataReady(gspca_dev);
break;
@ -1048,8 +1037,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
}
spca504B_SetSizeType(gspca_dev);
reg_w_riv(dev, 0x00, 0x270c, 0x05); /* L92 sno1t.txt */
reg_w_riv(dev, 0x00, 0x2310, 0x05);
reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
/* L92 sno1t.txt */
reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
break;
case BRIDGE_SPCA504C:
if (sd->subtype == LogitechClickSmart420) {
@ -1061,36 +1051,37 @@ static int sd_start(struct gspca_dev *gspca_dev)
ARRAY_SIZE(spca504_pccam600_init_data));
}
enable = (sd->autogain ? 0x04 : 0x01);
reg_w_riv(dev, 0x0c, 0x0000, enable); /* auto exposure */
reg_w_riv(dev, 0xb0, 0x0000, enable); /* auto whiteness */
reg_w_riv(gspca_dev, 0x0c, 0x0000, enable);
/* auto exposure */
reg_w_riv(gspca_dev, 0xb0, 0x0000, enable);
/* auto whiteness */
/* set default exposure compensation and whiteness balance */
reg_w_riv(dev, 0x30, 0x0001, 800); /* ~ 20 fps */
reg_w_riv(dev, 0x30, 0x0002, 1600);
reg_w_riv(gspca_dev, 0x30, 0x0001, 800); /* ~ 20 fps */
reg_w_riv(gspca_dev, 0x30, 0x0002, 1600);
spca504B_SetSizeType(gspca_dev);
break;
}
init_ctl_reg(gspca_dev);
return 0;
return gspca_dev->usb_err;
}
static void sd_stopN(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
switch (sd->bridge) {
default:
/* case BRIDGE_SPCA533: */
/* case BRIDGE_SPCA536: */
/* case BRIDGE_SPCA504B: */
reg_w_riv(dev, 0x31, 0, 0);
reg_w_riv(gspca_dev, 0x31, 0, 0);
spca504B_WaitCmdStatus(gspca_dev);
spca504B_PollingDataReady(gspca_dev);
break;
case BRIDGE_SPCA504:
case BRIDGE_SPCA504C:
reg_w_riv(dev, 0x00, 0x2000, 0x0000);
reg_w_riv(gspca_dev, 0x00, 0x2000, 0x0000);
if (sd->subtype == AiptekMiniPenCam13) {
/* spca504a aiptek */
@ -1102,7 +1093,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
0x0f, 0x00, 0xff, 1);
} else {
spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
reg_w_riv(dev, 0x01, 0x000f, 0x0000);
reg_w_riv(gspca_dev, 0x01, 0x000f, 0x0000);
}
break;
}
@ -1216,7 +1207,7 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
sd->brightness = val;
if (gspca_dev->streaming)
setbrightness(gspca_dev);
return 0;
return gspca_dev->usb_err;
}
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
@ -1234,7 +1225,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
sd->contrast = val;
if (gspca_dev->streaming)
setcontrast(gspca_dev);
return 0;
return gspca_dev->usb_err;
}
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
@ -1252,7 +1243,7 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
sd->colors = val;
if (gspca_dev->streaming)
setcolors(gspca_dev);
return 0;
return gspca_dev->usb_err;
}
static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
@ -1292,7 +1283,7 @@ static int sd_set_jcomp(struct gspca_dev *gspca_dev,
sd->quality = jcomp->quality;
if (gspca_dev->streaming)
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
return 0;
return gspca_dev->usb_err;
}
static int sd_get_jcomp(struct gspca_dev *gspca_dev,