Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ecb77686 authored by Jean-Francois Moine's avatar Jean-Francois Moine Committed by Mauro Carvalho Chehab
Browse files

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

parent 8c4ebae4
Loading
Loading
Loading
Loading
+54 −52
Original line number Diff line number Diff line
@@ -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,
+114 −123
Original line number Diff line number Diff line
@@ -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,