spca561.c revision 6a709749228c5f76f128c69c16f39a52d639bd96
16a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/*
26a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * Sunplus spca561 subdriver
36a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine *
46a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr
56a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine *
66a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
76a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine *
86a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * This program is free software; you can redistribute it and/or modify
96a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * it under the terms of the GNU General Public License as published by
106a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * the Free Software Foundation; either version 2 of the License, or
116a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * any later version.
126a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine *
136a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * This program is distributed in the hope that it will be useful,
146a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * but WITHOUT ANY WARRANTY; without even the implied warranty of
156a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
166a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * GNU General Public License for more details.
176a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine *
186a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * You should have received a copy of the GNU General Public License
196a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * along with this program; if not, write to the Free Software
206a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
216a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine */
226a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
236a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define MODULE_NAME "spca561"
246a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
256a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#include "gspca.h"
266a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
276a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois MoineMODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
286a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois MoineMODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver");
296a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois MoineMODULE_LICENSE("GPL");
306a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
316a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/* specific webcam descriptor */
326a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestruct sd {
336a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	struct gspca_dev gspca_dev;	/* !! must be the first item */
346a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
357879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	__u16 contrast;			/* rev72a only */
367879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine#define CONTRAST_MIN 0x0000
377879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine#define CONTRAST_DEF 0x2000
387879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine#define CONTRAST_MAX 0x3fff
397879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
407879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	__u16 exposure;			/* rev12a only */
413a1ea7050345734acc3a33b2b00a611b9b7bf640Jean-Francois Moine#define EXPOSURE_MIN 0
423a1ea7050345734acc3a33b2b00a611b9b7bf640Jean-Francois Moine#define EXPOSURE_DEF 200
433a1ea7050345734acc3a33b2b00a611b9b7bf640Jean-Francois Moine#define EXPOSURE_MAX 762
447879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
457879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	__u8 brightness;		/* rev72a only */
467879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine#define BRIGHTNESS_MIN 0
477879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine#define BRIGHTNESS_DEF 32
487879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine#define BRIGHTNESS_MAX 63
497879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
507879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	__u8 white;			/* rev12a only */
513a1ea7050345734acc3a33b2b00a611b9b7bf640Jean-Francois Moine#define WHITE_MIN 1
527879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine#define WHITE_DEF 0x40
537879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine#define WHITE_MAX 0x7f
547879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
556a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	__u8 autogain;
567879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine#define AUTOGAIN_MIN 0
577879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine#define AUTOGAIN_DEF 1
587879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine#define AUTOGAIN_MAX 1
597879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
607879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	__u8 gain;			/* rev12a only */
617879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine#define GAIN_MIN 0x0
627879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine#define GAIN_DEF 0x24
637879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine#define GAIN_MAX 0x24
646a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
65d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine#define EXPO12A_DEF 3
66d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	__u8 expo12a;		/* expo/gain? for rev 12a */
67d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine
686a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	__u8 chip_revision;
697879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine#define Rev012A 0
707879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine#define Rev072A 1
717879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
726a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	signed char ag_cnt;
736a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define AG_CNT_START 13
746a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine};
756a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
76c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moinestatic struct v4l2_pix_format sif_mode[] = {
77c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine	{160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
78c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine		.bytesperline = 160,
79c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine		.sizeimage = 160 * 120,
80c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine		.colorspace = V4L2_COLORSPACE_SRGB,
81c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine		.priv = 3},
82c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine	{176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
83c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine		.bytesperline = 176,
84c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine		.sizeimage = 176 * 144,
85c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine		.colorspace = V4L2_COLORSPACE_SRGB,
86c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine		.priv = 2},
87c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine	{320, 240, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
88c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine		.bytesperline = 320,
89c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine		.sizeimage = 320 * 240 * 4 / 8,
90c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine		.colorspace = V4L2_COLORSPACE_SRGB,
91c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine		.priv = 1},
92c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine	{352, 288, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
93c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine		.bytesperline = 352,
94c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine		.sizeimage = 352 * 288 * 4 / 8,
95c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine		.colorspace = V4L2_COLORSPACE_SRGB,
96c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine		.priv = 0},
976a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine};
986a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
996a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/*
1006a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * Initialization data
1016a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * I'm not very sure how to split initialization from open data
1026a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * chunks. For now, we'll consider everything as initialization
1036a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine */
1046a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/* Frame packet header offsets for the spca561 */
1056a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_SNAP 1
1066a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_TYPE 2
1076a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_COMPRESS 3
1086a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_FRAMSEQ   4
1096a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_GPIO 5
1106a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_USBBUFF 6
1116a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_WIN2GRAVE 7
1126a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_WIN2RAVE 8
1136a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_WIN2BAVE 9
1146a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_WIN2GBAVE 10
1156a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_WIN1GRAVE 11
1166a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_WIN1RAVE 12
1176a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_WIN1BAVE 13
1186a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_WIN1GBAVE 14
1196a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_FREQ 15
1206a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_VSYNC 16
1216a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_DATA 1
1226a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_INDEX_I2C_BASE 0x8800
1236a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_SNAPBIT 0x20
1246a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_SNAPCTRL 0x40
1256a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
1267879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moinestatic void reg_w_val(struct usb_device *dev, __u16 index, __u8 value)
1276a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
1286a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	int ret;
1296a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
1306a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1316a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			      0,		/* request */
1326a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			      USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1336a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			      value, index, NULL, 0, 500);
1346a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value);
1356a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	if (ret < 0)
1366a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		PDEBUG(D_ERR, "reg write: error %d", ret);
1376a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
1386a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
139a5ae2062252e697d38e53dbbeb91460252208914Jean-Francois Moinestatic void write_vector(struct gspca_dev *gspca_dev,
140a5ae2062252e697d38e53dbbeb91460252208914Jean-Francois Moine			const __u16 data[][2])
1416a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
1426a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	struct usb_device *dev = gspca_dev->dev;
1436a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	int i;
1446a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
1456a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	i = 0;
1466a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	while (data[i][1] != 0) {
1476a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		reg_w_val(dev, data[i][1], data[i][0]);
1486a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		i++;
1496a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	}
1506a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
1516a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
152739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine/* read 'len' bytes to gspca_dev->usb_buf */
153739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moinestatic void reg_r(struct gspca_dev *gspca_dev,
154739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine		  __u16 index, __u16 length)
1556a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
156739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine	usb_control_msg(gspca_dev->dev,
157739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine			usb_rcvctrlpipe(gspca_dev->dev, 0),
1586a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			0,			/* request */
1596a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1606a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			0,			/* value */
161739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine			index, gspca_dev->usb_buf, length, 500);
1626a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
1636a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
164739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moinestatic void reg_w_buf(struct gspca_dev *gspca_dev,
165a5ae2062252e697d38e53dbbeb91460252208914Jean-Francois Moine		      __u16 index, const __u8 *buffer, __u16 len)
1666a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
167739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine	memcpy(gspca_dev->usb_buf, buffer, len);
168739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine	usb_control_msg(gspca_dev->dev,
169739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine			usb_sndctrlpipe(gspca_dev->dev, 0),
1706a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			0,			/* request */
1716a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1726a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			0,			/* value */
173739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine			index, gspca_dev->usb_buf, len, 500);
1746a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
1756a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
1766a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg)
1776a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
1786a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	int retry = 60;
1796a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	__u8 DataLow;
1806a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	__u8 DataHight;
1816a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
1826a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	DataLow = valeur;
1836a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	DataHight = valeur >> 8;
1847879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_w_val(gspca_dev->dev, 0x8801, reg);
1857879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_w_val(gspca_dev->dev, 0x8805, DataLow);
1867879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_w_val(gspca_dev->dev, 0x8800, DataHight);
1876a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	while (retry--) {
188739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine		reg_r(gspca_dev, 0x8803, 1);
189739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine		if (!gspca_dev->usb_buf[0])
1906a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			break;
1916a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	}
1926a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
1936a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
1946a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
1956a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
1966a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	int retry = 60;
1976a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	__u8 value;
1986a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	__u8 vallsb;
1996a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
2007879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_w_val(gspca_dev->dev, 0x8804, 0x92);
2017879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_w_val(gspca_dev->dev, 0x8801, reg);
2027879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_w_val(gspca_dev->dev, 0x8802, (mode | 0x01));
2036a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	while (retry--) {
204739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine		reg_r(gspca_dev, 0x8803, 1);
205739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine		if (!gspca_dev->usb_buf)
2066a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			break;
2076a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	}
2086a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	if (retry == 0)
2096a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		return -1;
210739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine	reg_r(gspca_dev, 0x8800, 1);
211739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine	value = gspca_dev->usb_buf[0];
212739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine	reg_r(gspca_dev, 0x8805, 1);
213739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine	vallsb = gspca_dev->usb_buf[0];
2146a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	return ((int) value << 8) | vallsb;
2156a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
2166a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
217a5ae2062252e697d38e53dbbeb91460252208914Jean-Francois Moinestatic const __u16 spca561_init_data[][2] = {
2186a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8114},	/* Software GPIO output data */
2196a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0001, 0x8114},	/* Software GPIO output data */
2206a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8112},	/* Some kind of reset */
2216a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0003, 0x8701},	/* PCLK clock delay adjustment */
2226a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0001, 0x8703},	/* HSYNC from cmos inverted */
2236a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0011, 0x8118},	/* Enable and conf sensor */
2246a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0001, 0x8118},	/* Conf sensor */
2256a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0092, 0x8804},	/* I know nothing about these */
2266a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0010, 0x8802},	/* 0x88xx registers, so I won't */
2276a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	/***************/
2286a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x000d, 0x8805},	/* sensor default setting */
2296a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0001, 0x8801},	/* 1 <- 0x0d */
2306a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
2316a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0018, 0x8805},
2326a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0002, 0x8801},	/* 2 <- 0x18 */
2336a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
2346a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0065, 0x8805},
2356a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0004, 0x8801},	/* 4 <- 0x01 0x65 */
2366a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0001, 0x8800},
2376a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0021, 0x8805},
2386a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0005, 0x8801},	/* 5 <- 0x21 */
2396a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
2406a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x00aa, 0x8805},
2416a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0007, 0x8801},	/* 7 <- 0xaa */
2426a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
2436a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0004, 0x8805},
2446a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0020, 0x8801},	/* 0x20 <- 0x15 0x04 */
2456a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0015, 0x8800},
2466a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0002, 0x8805},
2476a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0039, 0x8801},	/* 0x39 <- 0x02 */
2486a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
2496a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0010, 0x8805},
2506a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0035, 0x8801},	/* 0x35 <- 0x10 */
2516a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
2526a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0049, 0x8805},
2536a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0009, 0x8801},	/* 0x09 <- 0x10 0x49 */
2546a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0010, 0x8800},
2556a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x000b, 0x8805},
2566a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0028, 0x8801},	/* 0x28 <- 0x0b */
2576a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
2586a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x000f, 0x8805},
2596a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x003b, 0x8801},	/* 0x3b <- 0x0f */
2606a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
2616a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8805},
2626a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x003c, 0x8801},	/* 0x3c <- 0x00 */
2636a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
2646a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	/***************/
2656a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0018, 0x8601},	/* Pixel/line selection for color separation */
2666a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8602},	/* Optical black level for user setting */
2676a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0060, 0x8604},	/* Optical black horizontal offset */
2686a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0002, 0x8605},	/* Optical black vertical offset */
2696a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8603},	/* Non-automatic optical black level */
2706a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0002, 0x865b},	/* Horizontal offset for valid pixels */
2716a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x865f},	/* Vertical valid pixels window (x2) */
2726a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x00b0, 0x865d},	/* Horizontal valid pixels window (x2) */
2736a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0090, 0x865e},	/* Vertical valid lines window (x2) */
2746a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x00e0, 0x8406},	/* Memory buffer threshold */
2756a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8660},	/* Compensation memory stuff */
2766a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0002, 0x8201},	/* Output address for r/w serial EEPROM */
2776a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0008, 0x8200},	/* Clear valid bit for serial EEPROM */
2786a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0001, 0x8200},	/* OprMode to be executed by hardware */
2796a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0007, 0x8201},	/* Output address for r/w serial EEPROM */
2806a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0008, 0x8200},	/* Clear valid bit for serial EEPROM */
2816a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0001, 0x8200},	/* OprMode to be executed by hardware */
2826a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0010, 0x8660},	/* Compensation memory stuff */
2836a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0018, 0x8660},	/* Compensation memory stuff */
2846a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
2856a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0004, 0x8611},	/* R offset for white balance */
2866a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0004, 0x8612},	/* Gr offset for white balance */
2876a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0007, 0x8613},	/* B offset for white balance */
2886a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8614},	/* Gb offset for white balance */
2896a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x008c, 0x8651},	/* R gain for white balance */
2906a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x008c, 0x8652},	/* Gr gain for white balance */
2916a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x00b5, 0x8653},	/* B gain for white balance */
2926a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x008c, 0x8654},	/* Gb gain for white balance */
2936a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0002, 0x8502},	/* Maximum average bit rate stuff */
2946a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
2956a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0011, 0x8802},
2966a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0087, 0x8700},	/* Set master clock (96Mhz????) */
2976a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0081, 0x8702},	/* Master clock output enable */
2986a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
2996a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8500},	/* Set image type (352x288 no compression) */
3006a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	/* Originally was 0x0010 (352x288 compression) */
3016a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
3026a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0002, 0x865b},	/* Horizontal offset for valid pixels */
3036a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0003, 0x865c},	/* Vertical offset for valid lines */
3046a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	/***************//* sensor active */
3056a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0003, 0x8801},	/* 0x03 <- 0x01 0x21 //289 */
3066a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0021, 0x8805},
3076a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0001, 0x8800},
3086a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0004, 0x8801},	/* 0x04 <- 0x01 0x65 //357 */
3096a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0065, 0x8805},
3106a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0001, 0x8800},
3116a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0005, 0x8801},	/* 0x05 <- 0x2f */
3126a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x002f, 0x8805},
3136a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
3146a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0006, 0x8801},	/* 0x06 <- 0 */
3156a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8805},
3166a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
3176a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x000a, 0x8801},	/* 0x0a <- 2 */
3186a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0002, 0x8805},
3196a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
3206a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0009, 0x8801},	/* 0x09 <- 0x1061 */
3216a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0061, 0x8805},
3226a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0010, 0x8800},
3236a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0035, 0x8801},	/* 0x35 <-0x14 */
3246a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0014, 0x8805},
3256a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
3266a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0030, 0x8112},	/* ISO and drop packet enable */
3276a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8112},	/* Some kind of reset ???? */
3286a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0009, 0x8118},	/* Enable sensor and set standby */
3296a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8114},	/* Software GPIO output data */
3306a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8114},	/* Software GPIO output data */
3316a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0001, 0x8114},	/* Software GPIO output data */
3326a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8112},	/* Some kind of reset ??? */
3336a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0003, 0x8701},
3346a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0001, 0x8703},
3356a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0011, 0x8118},
3366a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0001, 0x8118},
3376a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	/***************/
3386a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0092, 0x8804},
3396a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0010, 0x8802},
3406a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x000d, 0x8805},
3416a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0001, 0x8801},
3426a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
3436a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0018, 0x8805},
3446a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0002, 0x8801},
3456a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
3466a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0065, 0x8805},
3476a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0004, 0x8801},
3486a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0001, 0x8800},
3496a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0021, 0x8805},
3506a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0005, 0x8801},
3516a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
3526a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x00aa, 0x8805},
3536a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0007, 0x8801},	/* mode 0xaa */
3546a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
3556a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0004, 0x8805},
3566a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0020, 0x8801},
3576a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0015, 0x8800},	/* mode 0x0415 */
3586a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0002, 0x8805},
3596a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0039, 0x8801},
3606a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
3616a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0010, 0x8805},
3626a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0035, 0x8801},
3636a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
3646a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0049, 0x8805},
3656a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0009, 0x8801},
3666a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0010, 0x8800},
3676a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x000b, 0x8805},
3686a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0028, 0x8801},
3696a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
3706a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x000f, 0x8805},
3716a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x003b, 0x8801},
3726a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
3736a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8805},
3746a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x003c, 0x8801},
3756a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
3766a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0002, 0x8502},
3776a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0039, 0x8801},
3786a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8805},
3796a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
3806a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
3816a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0087, 0x8700},	/* overwrite by start */
3826a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0081, 0x8702},
3836a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8500},
3846a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/*	{0x0010, 0x8500},  -- Previous line was this */
3856a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0002, 0x865b},
3866a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0003, 0x865c},
3876a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	/***************/
3886a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0003, 0x8801},	/* 0x121-> 289 */
3896a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0021, 0x8805},
3906a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0001, 0x8800},
3916a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0004, 0x8801},	/* 0x165 -> 357 */
3926a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0065, 0x8805},
3936a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0001, 0x8800},
3946a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0005, 0x8801},	/* 0x2f //blanking control colonne */
3956a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x002f, 0x8805},
3966a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
3976a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0006, 0x8801},	/* 0x00 //blanking mode row */
3986a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8805},
3996a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
4006a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x000a, 0x8801},	/* 0x01 //0x02 */
4016a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0001, 0x8805},
4026a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
4036a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0009, 0x8801},	/* 0x1061 - setexposure times && pixel clock
4046a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine				 * 0001 0 | 000 0110 0001 */
4056a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0061, 0x8805},	/* 61 31 */
4066a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0008, 0x8800},	/* 08 */
4076a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0035, 0x8801},	/* 0x14 - set gain general */
4086a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x001f, 0x8805},	/* 0x14 */
4096a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0000, 0x8800},
4106c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	{0x000e, 0x8112},	/* white balance - was 30 */
4116a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{}
4126a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine};
4136a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
4146a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
4156a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/******************** QC Express etch2 stuff ********************/
416a5ae2062252e697d38e53dbbeb91460252208914Jean-Francois Moinestatic const __u16 Pb100_1map8300[][2] = {
4176a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	/* reg, value */
4186a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x8320, 0x3304},
4196a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
4206a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x8303, 0x0125},	/* image area */
4216a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x8304, 0x0169},
4226a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x8328, 0x000b},
4237879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	{0x833c, 0x0001},		/*fixme: win:07*/
4246a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
4257879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	{0x832f, 0x1904},		/*fixme: was 0419*/
4266a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x8307, 0x00aa},
4276a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x8301, 0x0003},
4286a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x8302, 0x000e},
4296a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{}
4306a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine};
431a5ae2062252e697d38e53dbbeb91460252208914Jean-Francois Moinestatic const __u16 Pb100_2map8300[][2] = {
4326a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	/* reg, value */
4336a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x8339, 0x0000},
4346a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x8307, 0x00aa},
4356a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{}
4366a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine};
4376a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
438a5ae2062252e697d38e53dbbeb91460252208914Jean-Francois Moinestatic const __u16 spca561_161rev12A_data1[][2] = {
4396c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	{0x29, 0x8118},		/* white balance - was 21 */
4406c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	{0x08, 0x8114},		/* white balance - was 01 */
4416c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	{0x0e, 0x8112},		/* white balance - was 00 */
4426c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	{0x00, 0x8102},		/* white balance - new */
4436a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x92, 0x8804},
4446a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x04, 0x8802},		/* windows uses 08 */
4456a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{}
4466a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine};
447a5ae2062252e697d38e53dbbeb91460252208914Jean-Francois Moinestatic const __u16 spca561_161rev12A_data2[][2] = {
4486a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x21, 0x8118},
4496a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x10, 0x8500},
4506a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x07, 0x8601},
4516a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x07, 0x8602},
4526a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x04, 0x8501},
4536a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x21, 0x8118},
4546a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
4556a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x07, 0x8201},		/* windows uses 02 */
4566a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x08, 0x8200},
4576a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x01, 0x8200},
4586a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
4596a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x00, 0x8114},
4606a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x01, 0x8114},		/* windows uses 00 */
4616a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
4626a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x90, 0x8604},
4636a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x00, 0x8605},
4646a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0xb0, 0x8603},
4656a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
4666a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	/* sensor gains */
4676c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	{0x07, 0x8601},		/* white balance - new */
4686c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	{0x07, 0x8602},		/* white balance - new */
4696a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x00, 0x8610},		/* *red */
4706a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x00, 0x8611},		/* 3f   *green */
4716a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x00, 0x8612},		/* green *blue */
4726a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x00, 0x8613},		/* blue *green */
4736c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	{0x43, 0x8614},		/* green *red - white balance - was 0x35 */
4746c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	{0x40, 0x8615},		/* 40   *green - white balance - was 0x35 */
4756c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	{0x71, 0x8616},		/* 7a   *blue - white balance - was 0x35 */
4766c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	{0x40, 0x8617},		/* 40   *green - white balance - was 0x35 */
4776a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
4786a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x0c, 0x8620},		/* 0c */
4796a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0xc8, 0x8631},		/* c8 */
4806a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0xc8, 0x8634},		/* c8 */
4816a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x23, 0x8635},		/* 23 */
4826a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x1f, 0x8636},		/* 1f */
4836a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0xdd, 0x8637},		/* dd */
4846a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0xe1, 0x8638},		/* e1 */
4856a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x1d, 0x8639},		/* 1d */
4866a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x21, 0x863a},		/* 21 */
4876a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0xe3, 0x863b},		/* e3 */
4886a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0xdf, 0x863c},		/* df */
4896a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0xf0, 0x8505},
4906a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{0x32, 0x850a},
4917879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/*	{0x99, 0x8700},		 * - white balance - new (removed) */
4926a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{}
4936a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine};
4946a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
4956a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic void sensor_mapwrite(struct gspca_dev *gspca_dev,
496a5ae2062252e697d38e53dbbeb91460252208914Jean-Francois Moine			    const __u16 sensormap[][2])
4976a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
4986a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	int i = 0;
4996a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	__u8 usbval[2];
5006a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
5016a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	while (sensormap[i][0]) {
5026a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		usbval[0] = sensormap[i][1];
5036a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		usbval[1] = sensormap[i][1] >> 8;
504739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine		reg_w_buf(gspca_dev, sensormap[i][0], usbval, 2);
5056a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		i++;
5066a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	}
5076a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
5086a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic void init_161rev12A(struct gspca_dev *gspca_dev)
5096a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
5107879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/*	sensor_reset(gspca_dev);	(not in win) */
5116a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	write_vector(gspca_dev, spca561_161rev12A_data1);
5126a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	sensor_mapwrite(gspca_dev, Pb100_1map8300);
5137879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/*fixme: should be in sd_start*/
5146a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	write_vector(gspca_dev, spca561_161rev12A_data2);
5156a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	sensor_mapwrite(gspca_dev, Pb100_2map8300);
5166a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
5176a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
5186a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/* this function is called at probe time */
5196a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic int sd_config(struct gspca_dev *gspca_dev,
5206a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		     const struct usb_device_id *id)
5216a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
5226a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
5236a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	struct cam *cam;
5246a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	__u16 vendor, product;
5256a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	__u8 data1, data2;
5266a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
5276a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	/* Read frm global register the USB product and vendor IDs, just to
5286a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	 * prove that we can communicate with the device.  This works, which
5296a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	 * confirms at we are communicating properly and that the device
5306a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	 * is a 561. */
531739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine	reg_r(gspca_dev, 0x8104, 1);
532739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine	data1 = gspca_dev->usb_buf[0];
533739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine	reg_r(gspca_dev, 0x8105, 1);
534739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine	data2 = gspca_dev->usb_buf[0];
5356a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	vendor = (data2 << 8) | data1;
536739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine	reg_r(gspca_dev, 0x8106, 1);
537739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine	data1 = gspca_dev->usb_buf[0];
538739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine	reg_r(gspca_dev, 0x8107, 1);
539739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine	data2 = gspca_dev->usb_buf[0];
5406a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	product = (data2 << 8) | data1;
5416a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	if (vendor != id->idVendor || product != id->idProduct) {
5426a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		PDEBUG(D_PROBE, "Bad vendor / product from device");
5436a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		return -EINVAL;
5446a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	}
5459d64fdb15b1b9ce9144cfde4001e9194ccde42d1Jean-Francois Moine
5466a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	cam = &gspca_dev->cam;
5476a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	cam->epaddr = 0x01;
5486a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	gspca_dev->nbalt = 7 + 1;	/* choose alternate 7 first */
5496a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	cam->cam_mode = sif_mode;
5507879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	cam->nmodes = ARRAY_SIZE(sif_mode);
5519d64fdb15b1b9ce9144cfde4001e9194ccde42d1Jean-Francois Moine
5529d64fdb15b1b9ce9144cfde4001e9194ccde42d1Jean-Francois Moine	sd->chip_revision = id->driver_info;
5536c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	sd->brightness = BRIGHTNESS_DEF;
5546c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	sd->contrast = CONTRAST_DEF;
5556c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	sd->white = WHITE_DEF;
5567879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	sd->exposure = EXPOSURE_DEF;
5577879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	sd->autogain = AUTOGAIN_DEF;
5587879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	sd->gain = GAIN_DEF;
559d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	sd->expo12a = EXPO12A_DEF;
5606a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	return 0;
5616a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
5626a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
5636a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/* this function is called at open time */
5647879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moinestatic int sd_open_12a(struct gspca_dev *gspca_dev)
5656a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
5667879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	PDEBUG(D_STREAM, "Chip revision: 012a");
5677879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	init_161rev12A(gspca_dev);
5687879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	return 0;
5697879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine}
5707879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moinestatic int sd_open_72a(struct gspca_dev *gspca_dev)
5717879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine{
5727879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	PDEBUG(D_STREAM, "Chip revision: 072a");
5737879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	write_vector(gspca_dev, spca561_init_data);
5746a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	return 0;
5756a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
5766a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
5776a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic void setcontrast(struct gspca_dev *gspca_dev)
5786a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
5796a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
5806a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	struct usb_device *dev = gspca_dev->dev;
5816a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	__u8 lowb;
5826a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
5836a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	switch (sd->chip_revision) {
5846a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	case Rev072A:
5856a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		lowb = sd->contrast >> 8;
5867879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		reg_w_val(dev, 0x8651, lowb);
5877879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		reg_w_val(dev, 0x8652, lowb);
5887879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		reg_w_val(dev, 0x8653, lowb);
5897879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		reg_w_val(dev, 0x8654, lowb);
5906a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		break;
5916c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	default: {
5926c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine/*	case Rev012A: { */
5937879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		static const __u8 Reg8391[] =
5947879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine			{ 0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00 };
5957879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
596739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine		reg_w_buf(gspca_dev, 0x8391, Reg8391, 8);
597739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine		reg_w_buf(gspca_dev, 0x8390, Reg8391, 8);
5986a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		break;
5996a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	    }
6006a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	}
6016a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
6026a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
6037879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/* rev12a only */
6046c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moinestatic void setwhite(struct gspca_dev *gspca_dev)
6056c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine{
6066c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
6076c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	__u16 white;
6086c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	__u8 reg8614, reg8616;
6096c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine
6107879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	white = sd->white;
6117879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	/* try to emulate MS-win as possible */
612d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	reg8616 = 0x90 - white * 5 / 8;
6137879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_w_val(gspca_dev->dev, 0x8616, reg8616);
614d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	reg8614 = 0x20 + white * 3 / 8;
6157879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_w_val(gspca_dev->dev, 0x8614, reg8614);
6167879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine}
6177879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
6187879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/* rev 12a only */
6197879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moinestatic void setexposure(struct gspca_dev *gspca_dev)
6207879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine{
6217879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
6223a1ea7050345734acc3a33b2b00a611b9b7bf640Jean-Francois Moine	int expo;
623d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	__u8 data[2];
6247879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
6253a1ea7050345734acc3a33b2b00a611b9b7bf640Jean-Francois Moine	expo = sd->exposure + 0x20a8;	/* from test */
6263a1ea7050345734acc3a33b2b00a611b9b7bf640Jean-Francois Moine	data[0] = expo;
6273a1ea7050345734acc3a33b2b00a611b9b7bf640Jean-Francois Moine	data[1] = expo >> 8;
628d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	reg_w_buf(gspca_dev, 0x8309, data, 2);
6297879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine}
6307879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
6317879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/* rev 12a only */
6327879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moinestatic void setgain(struct gspca_dev *gspca_dev)
6337879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine{
6347879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
635d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	__u8 data[2];
6367879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
637d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	data[0] = sd->gain;
638d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	data[1] = 0;
639d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	reg_w_buf(gspca_dev, 0x8335, data, 2);
6406c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine}
6416c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine
642cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moinestatic void setautogain(struct gspca_dev *gspca_dev)
643cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine{
644cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
645cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine
646d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	if (sd->autogain)
647d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine		sd->ag_cnt = AG_CNT_START;
648d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	else
649d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine		sd->ag_cnt = -1;
650cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine}
651cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine
6527879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moinestatic void sd_start_12a(struct gspca_dev *gspca_dev)
6536a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
6546a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	struct usb_device *dev = gspca_dev->dev;
6556a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	int Clck;
6566a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	__u8 Reg8307[] = { 0xaa, 0x00 };
6576a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	int mode;
6586a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
659c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
6607879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	switch (mode) {
6617879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	case 0:
6627879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	case 1:
6637879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		Clck = 0x8a;
6647879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		break;
6657879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	case 2:
6667879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		Clck = 0x85;
6676a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		break;
6686a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	default:
6697879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		Clck = 0x83;
6707879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		break;
6717879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	}
6727879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	if (mode <= 1) {
6737879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		/* Use compression on 320x240 and above */
6747879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		reg_w_val(dev, 0x8500, 0x10 | mode);
6757879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	} else {
6767879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		/* I couldn't get the compression to work below 320x240
6777879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		 * Fortunately at these resolutions the bandwidth
6787879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		 * is sufficient to push raw frames at ~20fps */
6797879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		reg_w_val(dev, 0x8500, mode);
6807879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	}		/* -- qq@kuku.eu.org */
6817879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_w_buf(gspca_dev, 0x8307, Reg8307, 2);
6827879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_w_val(gspca_dev->dev, 0x8700, Clck);
6837879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine					/* 0x8f 0x85 0x27 clock */
6847879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
6857879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_w_val(gspca_dev->dev, 0x850b, 0x03);
6867879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	setcontrast(gspca_dev);
6877879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	setwhite(gspca_dev);
688d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	setautogain(gspca_dev);
6897879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine}
6907879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moinestatic void sd_start_72a(struct gspca_dev *gspca_dev)
6917879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine{
6927879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	struct usb_device *dev = gspca_dev->dev;
6937879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	int Clck;
6947879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	int mode;
6957879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
6967879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
6977879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	switch (mode) {
6987879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	default:
6997879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/*	case 0:
7007879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	case 1: */
7017879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		Clck = 0x25;
7027879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		break;
7037879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	case 2:
7047879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		Clck = 0x22;
7057879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		break;
7067879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	case 3:
7077879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		Clck = 0x21;
7086a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		break;
7096a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	}
7107879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_w_val(dev, 0x8500, mode);	/* mode */
7117879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_w_val(dev, 0x8700, Clck);	/* 0x27 clock */
7127879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_w_val(dev, 0x8112, 0x10 | 0x20);
7137879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	setautogain(gspca_dev);
7146a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
7156a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
7166a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic void sd_stopN(struct gspca_dev *gspca_dev)
7176a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
718d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
719d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine
720d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	if (sd->chip_revision == Rev012A) {
721d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine		reg_w_val(gspca_dev->dev, 0x8112, 0x0e);
722d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	} else {
723d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine		reg_w_val(gspca_dev->dev, 0x8112, 0x20);
724d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine/*		reg_w_val(gspca_dev->dev, 0x8102, 0x00); ?? */
725d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	}
7266a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
7276a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
7286a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic void sd_stop0(struct gspca_dev *gspca_dev)
7296a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
730d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
731d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine
732d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	if (sd->chip_revision == Rev012A) {
733d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine		reg_w_val(gspca_dev->dev, 0x8118, 0x29);
734d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine		reg_w_val(gspca_dev->dev, 0x8114, 0x08);
735d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	}
7366a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
7376a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
7386a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/* this function is called at close time */
7396a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic void sd_close(struct gspca_dev *gspca_dev)
7406a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
7416a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	reg_w_val(gspca_dev->dev, 0x8114, 0);
7426a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
7436a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
744cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moinestatic void do_autogain(struct gspca_dev *gspca_dev)
7456a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
7466a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
747cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine	int expotimes;
748cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine	int pixelclk;
749cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine	int gainG;
7506a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	__u8 R, Gr, Gb, B;
7516a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	int y;
7526a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	__u8 luma_mean = 110;
7536a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	__u8 luma_delta = 20;
7546a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	__u8 spring = 4;
755d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine	__u8 reg8339[2];
7566a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
757cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine	if (sd->ag_cnt < 0)
758cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine		return;
759cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine	if (--sd->ag_cnt >= 0)
760cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine		return;
761cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine	sd->ag_cnt = AG_CNT_START;
762cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine
7636a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	switch (sd->chip_revision) {
7646a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	case Rev072A:
765739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine		reg_r(gspca_dev, 0x8621, 1);
766739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine		Gr = gspca_dev->usb_buf[0];
767739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine		reg_r(gspca_dev, 0x8622, 1);
768739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine		R = gspca_dev->usb_buf[0];
769739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine		reg_r(gspca_dev, 0x8623, 1);
770739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine		B = gspca_dev->usb_buf[0];
771739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine		reg_r(gspca_dev, 0x8624, 1);
772739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine		Gb = gspca_dev->usb_buf[0];
7736a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8;
7746a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		/* u= (128*B-(43*(Gr+Gb+R))) >> 8; */
7756a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		/* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */
7766a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		/* PDEBUG(D_CONF,"reading Y %d U %d V %d ",y,u,v); */
7776a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
7786a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		if (y < luma_mean - luma_delta ||
7796a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		    y > luma_mean + luma_delta) {
7806a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			expotimes = i2c_read(gspca_dev, 0x09, 0x10);
7816a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			pixelclk = 0x0800;
7826a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			expotimes = expotimes & 0x07ff;
7836a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			/* PDEBUG(D_PACK,
7846a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine				"Exposition Times 0x%03X Clock 0x%04X ",
7856a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine				expotimes,pixelclk); */
7866a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			gainG = i2c_read(gspca_dev, 0x35, 0x10);
7876a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			/* PDEBUG(D_PACK,
7886a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine				"reading Gain register %d", gainG); */
7896a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
7906a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			expotimes += (luma_mean - y) >> spring;
7916a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			gainG += (luma_mean - y) / 50;
7926a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			/* PDEBUG(D_PACK,
7936a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine				"compute expotimes %d gain %d",
7946a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine				expotimes,gainG); */
7956a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
7966a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			if (gainG > 0x3f)
7976a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine				gainG = 0x3f;
7986a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			else if (gainG < 4)
7996a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine				gainG = 3;
8006a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			i2c_write(gspca_dev, gainG, 0x35);
8016a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
8026a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			if (expotimes >= 0x0256)
8036a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine				expotimes = 0x0256;
8046a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			else if (expotimes < 4)
8056a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine				expotimes = 3;
8066a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			i2c_write(gspca_dev, expotimes | pixelclk, 0x09);
8076a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		}
8086a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		break;
8096a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	case Rev012A:
810d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine		reg_r(gspca_dev, 0x8330, 2);
811d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine		if (gspca_dev->usb_buf[1] > 0x08) {
812d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine			reg8339[0] = ++sd->expo12a;
813d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine			reg8339[1] = 0;
814d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine			reg_w_buf(gspca_dev, 0x8339, reg8339, 2);
815d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine		} else if (gspca_dev->usb_buf[1] < 0x02) {
816d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine			reg8339[0] = --sd->expo12a;
817d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine			reg8339[1] = 0;
818d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine			reg_w_buf(gspca_dev, 0x8339, reg8339, 2);
819d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine		}
8206a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		break;
8216a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	}
8226a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
8236a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
8246a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic void sd_pkt_scan(struct gspca_dev *gspca_dev,
8256a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			struct gspca_frame *frame, /* target */
8266a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			__u8 *data,		/* isoc packet */
8276a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			int len)		/* iso packet length */
8286a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
8296a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	switch (data[0]) {
8306a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	case 0:		/* start of frame */
8316a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
8326a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine					data, 0);
8336a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		data += SPCA561_OFFSET_DATA;
8346a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		len -= SPCA561_OFFSET_DATA;
8356a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		if (data[1] & 0x10) {
8366a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			/* compressed bayer */
8376a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			gspca_frame_add(gspca_dev, FIRST_PACKET,
8386a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine					frame, data, len);
8396a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		} else {
84054ab92ca05550550bcec2462de2605f35d079b66Hans de Goede			/* raw bayer (with a header, which we skip) */
8416a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			data += 20;
8426a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			len -= 20;
8436a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			gspca_frame_add(gspca_dev, FIRST_PACKET,
8446a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine						frame, data, len);
8456a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		}
8466a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		return;
8476a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	case 0xff:		/* drop */
8486a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/*		gspca_dev->last_packet_type = DISCARD_PACKET; */
8496a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		return;
8506a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	}
8516a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	data++;
8526a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	len--;
8536a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
8546a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
8556a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
8567879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/* rev 72a only */
8576a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic void setbrightness(struct gspca_dev *gspca_dev)
8586a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
8596a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
8606a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	__u8 value;
8616a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
8627879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	value = sd->brightness;
8637879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_w_val(gspca_dev->dev, 0x8611, value);
8647879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_w_val(gspca_dev->dev, 0x8612, value);
8657879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_w_val(gspca_dev->dev, 0x8613, value);
8667879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_w_val(gspca_dev->dev, 0x8614, value);
8676a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
8686a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
8696a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic void getbrightness(struct gspca_dev *gspca_dev)
8706a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
8716a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
8726a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	__u16 tot;
8736a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
8747879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	tot = 0;
8757879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_r(gspca_dev, 0x8611, 1);
8767879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	tot += gspca_dev->usb_buf[0];
8777879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_r(gspca_dev, 0x8612, 1);
8787879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	tot += gspca_dev->usb_buf[0];
8797879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_r(gspca_dev, 0x8613, 1);
8807879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	tot += gspca_dev->usb_buf[0];
8817879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_r(gspca_dev, 0x8614, 1);
8827879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	tot += gspca_dev->usb_buf[0];
8837879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	sd->brightness = tot >> 2;
8846a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
8856a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
8867879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/* rev72a only */
8876a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic void getcontrast(struct gspca_dev *gspca_dev)
8886a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
8896a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
8906a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	__u16 tot;
8916a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
8927879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	tot = 0;
8937879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_r(gspca_dev, 0x8651, 1);
8947879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	tot += gspca_dev->usb_buf[0];
8957879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_r(gspca_dev, 0x8652, 1);
8967879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	tot += gspca_dev->usb_buf[0];
8977879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_r(gspca_dev, 0x8653, 1);
8987879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	tot += gspca_dev->usb_buf[0];
8997879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	reg_r(gspca_dev, 0x8654, 1);
9007879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	tot += gspca_dev->usb_buf[0];
9017879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	sd->contrast = tot << 6;
9026a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	PDEBUG(D_CONF, "get contrast %d", sd->contrast);
9036a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
9046a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
9057879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/* rev 72a only */
9066a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
9076a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
9086a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
9096a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
9106a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	sd->brightness = val;
9116a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	if (gspca_dev->streaming)
9126a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		setbrightness(gspca_dev);
9136a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	return 0;
9146a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
9156a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
9166a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
9176a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
9186a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
9196a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
9206a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	getbrightness(gspca_dev);
9216a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	*val = sd->brightness;
9226a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	return 0;
9236a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
9246a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
9257879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/* rev 72a only */
9266a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
9276a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
9286a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
9296a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
9306a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	sd->contrast = val;
9316a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	if (gspca_dev->streaming)
9326a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		setcontrast(gspca_dev);
9336a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	return 0;
9346a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
9356a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
9366a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
9376a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
9386a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
9396a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
9406a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	getcontrast(gspca_dev);
9416a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	*val = sd->contrast;
9426a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	return 0;
9436a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
9446a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
9456a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
9466a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
9476a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
9486a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
9496a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	sd->autogain = val;
950cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine	if (gspca_dev->streaming)
951cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine		setautogain(gspca_dev);
9526a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	return 0;
9536a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
9546a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
9556a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
9566a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
9576a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
9586a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
9596a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	*val = sd->autogain;
9606a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	return 0;
9616a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
9626a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
9637879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/* rev12a only */
9646c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moinestatic int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val)
9656c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine{
9666c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
9676c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine
9686c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	sd->white = val;
9696c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	if (gspca_dev->streaming)
9706c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine		setwhite(gspca_dev);
9716c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	return 0;
9726c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine}
9736c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine
9746c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moinestatic int sd_getwhite(struct gspca_dev *gspca_dev, __s32 *val)
9756c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine{
9766c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
9776c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine
9786c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	*val = sd->white;
9796c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine	return 0;
9806c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine}
9816c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine
9827879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/* rev12a only */
9837879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moinestatic int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
9847879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine{
9857879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
9867879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
9877879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	sd->exposure = val;
9887879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	if (gspca_dev->streaming)
9897879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		setexposure(gspca_dev);
9907879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	return 0;
9917879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine}
9927879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
9937879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moinestatic int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
9947879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine{
9957879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
9967879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
9977879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	*val = sd->exposure;
9987879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	return 0;
9997879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine}
10007879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
10017879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/* rev12a only */
10027879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moinestatic int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
10037879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine{
10047879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
10057879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
10067879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	sd->gain = val;
10077879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	if (gspca_dev->streaming)
10087879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		setgain(gspca_dev);
10097879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	return 0;
10107879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine}
10117879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
10127879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moinestatic int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
10137879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine{
10147879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	struct sd *sd = (struct sd *) gspca_dev;
10157879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
10167879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	*val = sd->gain;
10177879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	return 0;
10187879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine}
10197879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
10207879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/* control tables */
10217879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moinestatic struct ctrl sd_ctrls_12a[] = {
10227879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	{
10237879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    {
10247879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.id = V4L2_CID_DO_WHITE_BALANCE,
10257879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.type = V4L2_CTRL_TYPE_INTEGER,
10267879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.name = "While Balance",
10277879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.minimum = WHITE_MIN,
10287879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.maximum = WHITE_MAX,
10297879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.step = 1,
10307879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.default_value = WHITE_DEF,
10317879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    },
10327879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    .set = sd_setwhite,
10337879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    .get = sd_getwhite,
10347879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	},
10357879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	{
10367879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    {
10377879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.id = V4L2_CID_EXPOSURE,
10387879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.type = V4L2_CTRL_TYPE_INTEGER,
10397879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.name = "Exposure",
10407879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.minimum = EXPOSURE_MIN,
10417879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.maximum = EXPOSURE_MAX,
10427879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.step = 1,
10437879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.default_value = EXPOSURE_DEF,
10447879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    },
10457879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    .set = sd_setexposure,
10467879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    .get = sd_getexposure,
10477879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	},
10487879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	{
10497879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    {
10507879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.id = V4L2_CID_AUTOGAIN,
10517879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.type = V4L2_CTRL_TYPE_BOOLEAN,
10527879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.name = "Auto Gain",
10537879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.minimum = AUTOGAIN_MIN,
10547879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.maximum = AUTOGAIN_MAX,
10557879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.step = 1,
10567879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.default_value = AUTOGAIN_DEF,
10577879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    },
10587879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    .set = sd_setautogain,
10597879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    .get = sd_getautogain,
10607879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	},
10617879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	{
10627879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    {
10637879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.id = V4L2_CID_GAIN,
10647879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.type = V4L2_CTRL_TYPE_INTEGER,
10657879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.name = "Gain",
10667879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.minimum = GAIN_MIN,
10677879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.maximum = GAIN_MAX,
10687879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.step = 1,
10697879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.default_value = GAIN_DEF,
10707879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    },
10717879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    .set = sd_setgain,
10727879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    .get = sd_getgain,
10737879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	},
10747879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine};
10757879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
10767879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moinestatic struct ctrl sd_ctrls_72a[] = {
10777879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	{
10787879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	   {
10797879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.id = V4L2_CID_BRIGHTNESS,
10807879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.type = V4L2_CTRL_TYPE_INTEGER,
10817879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.name = "Brightness",
10827879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.minimum = BRIGHTNESS_MIN,
10837879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.maximum = BRIGHTNESS_MAX,
10847879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.step = 1,
10857879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.default_value = BRIGHTNESS_DEF,
10867879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    },
10877879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    .set = sd_setbrightness,
10887879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    .get = sd_getbrightness,
10897879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	},
10907879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	{
10917879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    {
10927879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.id = V4L2_CID_CONTRAST,
10937879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.type = V4L2_CTRL_TYPE_INTEGER,
10947879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.name = "Contrast",
10957879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.minimum = CONTRAST_MIN,
10967879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.maximum = CONTRAST_MAX,
10977879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.step = 1,
10987879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.default_value = CONTRAST_DEF,
10997879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    },
11007879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    .set = sd_setcontrast,
11017879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    .get = sd_getcontrast,
11027879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	},
11037879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	{
11047879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    {
11057879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.id = V4L2_CID_AUTOGAIN,
11067879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.type = V4L2_CTRL_TYPE_BOOLEAN,
11077879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.name = "Auto Gain",
11087879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.minimum = AUTOGAIN_MIN,
11097879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.maximum = AUTOGAIN_MAX,
11107879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.step = 1,
11117879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine		.default_value = AUTOGAIN_DEF,
11127879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    },
11137879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    .set = sd_setautogain,
11147879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	    .get = sd_getautogain,
11157879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	},
11167879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine};
11177879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine
11186a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/* sub-driver description */
11197879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moinestatic const struct sd_desc sd_desc_12a = {
11206a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	.name = MODULE_NAME,
11217879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	.ctrls = sd_ctrls_12a,
11227879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	.nctrls = ARRAY_SIZE(sd_ctrls_12a),
11236a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	.config = sd_config,
11247879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	.open = sd_open_12a,
11257879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	.start = sd_start_12a,
11267879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	.stopN = sd_stopN,
11277879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	.stop0 = sd_stop0,
11287879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	.close = sd_close,
11297879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	.pkt_scan = sd_pkt_scan,
11307879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/*	.dq_callback = do_autogain,	 * fixme */
11317879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine};
11327879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moinestatic const struct sd_desc sd_desc_72a = {
11337879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	.name = MODULE_NAME,
11347879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	.ctrls = sd_ctrls_72a,
11357879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	.nctrls = ARRAY_SIZE(sd_ctrls_72a),
11367879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	.config = sd_config,
11377879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	.open = sd_open_72a,
11387879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	.start = sd_start_72a,
11396a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	.stopN = sd_stopN,
11406a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	.stop0 = sd_stop0,
11416a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	.close = sd_close,
11426a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	.pkt_scan = sd_pkt_scan,
1143cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine	.dq_callback = do_autogain,
11446a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine};
11457879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moinestatic const struct sd_desc *sd_desc[2] = {
11467879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	&sd_desc_12a,
11477879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	&sd_desc_72a
11487879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine};
11496a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
11506a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/* -- module initialisation -- */
1151a5ae2062252e697d38e53dbbeb91460252208914Jean-Francois Moinestatic const __devinitdata struct usb_device_id device_table[] = {
115287581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine	{USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},
115387581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine	{USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},
115487581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine	{USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},
115587581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine	{USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A},
115687581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine	{USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A},
115787581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine	{USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A},
115887581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine	{USB_DEVICE(0x046d, 0x092b), .driver_info = Rev012A},
115987581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine	{USB_DEVICE(0x046d, 0x092c), .driver_info = Rev012A},
116087581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine	{USB_DEVICE(0x046d, 0x092d), .driver_info = Rev012A},
116187581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine	{USB_DEVICE(0x046d, 0x092e), .driver_info = Rev012A},
116287581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine	{USB_DEVICE(0x046d, 0x092f), .driver_info = Rev012A},
116387581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine	{USB_DEVICE(0x04fc, 0x0561), .driver_info = Rev072A},
116487581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine	{USB_DEVICE(0x060b, 0xa001), .driver_info = Rev072A},
116587581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine	{USB_DEVICE(0x10fd, 0x7e50), .driver_info = Rev072A},
116687581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine	{USB_DEVICE(0xabcd, 0xcdee), .driver_info = Rev072A},
11676a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	{}
11686a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine};
11696a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
11706a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois MoineMODULE_DEVICE_TABLE(usb, device_table);
11716a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
11726a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/* -- device connect -- */
11736a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic int sd_probe(struct usb_interface *intf,
11746a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		    const struct usb_device_id *id)
11756a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
11767879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine	return gspca_dev_probe(intf, id,
11777879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine				sd_desc[id->driver_info],
11787879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine				sizeof(struct sd),
11796a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine			       THIS_MODULE);
11806a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
11816a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
11826a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic struct usb_driver sd_driver = {
11836a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	.name = MODULE_NAME,
11846a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	.id_table = device_table,
11856a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	.probe = sd_probe,
11866a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	.disconnect = gspca_disconnect,
11876a709749228c5f76f128c69c16f39a52d639bd96Jean-Francois Moine#ifdef CONFIG_PM
11886a709749228c5f76f128c69c16f39a52d639bd96Jean-Francois Moine	.suspend = gspca_suspend,
11896a709749228c5f76f128c69c16f39a52d639bd96Jean-Francois Moine	.resume = gspca_resume,
11906a709749228c5f76f128c69c16f39a52d639bd96Jean-Francois Moine#endif
11916a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine};
11926a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
11936a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/* -- module insert / remove -- */
11946a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic int __init sd_mod_init(void)
11956a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
11966a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	if (usb_register(&sd_driver) < 0)
11976a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine		return -1;
119810b0e96ed9a1ce0412ef981cf6250f9de3c80b02Jean-Francois Moine	PDEBUG(D_PROBE, "registered");
11996a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	return 0;
12006a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
12016a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic void __exit sd_mod_exit(void)
12026a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{
12036a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	usb_deregister(&sd_driver);
12046a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine	PDEBUG(D_PROBE, "deregistered");
12056a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}
12066a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine
12076a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinemodule_init(sd_mod_init);
12086a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinemodule_exit(sd_mod_exit);
1209