• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/media/video/gspca/
1/*
2 * Sunplus spca561 subdriver
3 *
4 * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr
5 *
6 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#define MODULE_NAME "spca561"
24
25#include <linux/input.h>
26#include "gspca.h"
27
28MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
29MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver");
30MODULE_LICENSE("GPL");
31
32/* specific webcam descriptor */
33struct sd {
34	struct gspca_dev gspca_dev;	/* !! must be the first item */
35
36	__u16 exposure;			/* rev12a only */
37#define EXPOSURE_MIN 1
38#define EXPOSURE_DEF 700		/* == 10 fps */
39#define EXPOSURE_MAX (2047 + 325)	/* see setexposure */
40
41	__u8 contrast;			/* rev72a only */
42#define CONTRAST_MIN 0x00
43#define CONTRAST_DEF 0x20
44#define CONTRAST_MAX 0x3f
45
46	__u8 brightness;		/* rev72a only */
47#define BRIGHTNESS_MIN 0
48#define BRIGHTNESS_DEF 0x20
49#define BRIGHTNESS_MAX 0x3f
50
51	__u8 white;
52#define HUE_MIN 1
53#define HUE_DEF 0x40
54#define HUE_MAX 0x7f
55
56	__u8 autogain;
57#define AUTOGAIN_MIN 0
58#define AUTOGAIN_DEF 1
59#define AUTOGAIN_MAX 1
60
61	__u8 gain;			/* rev12a only */
62#define GAIN_MIN 0
63#define GAIN_DEF 63
64#define GAIN_MAX 255
65
66#define EXPO12A_DEF 3
67	__u8 expo12a;		/* expo/gain? for rev 12a */
68
69	__u8 chip_revision;
70#define Rev012A 0
71#define Rev072A 1
72
73	signed char ag_cnt;
74#define AG_CNT_START 13
75};
76
77static const struct v4l2_pix_format sif_012a_mode[] = {
78	{160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
79		.bytesperline = 160,
80		.sizeimage = 160 * 120,
81		.colorspace = V4L2_COLORSPACE_SRGB,
82		.priv = 3},
83	{176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
84		.bytesperline = 176,
85		.sizeimage = 176 * 144,
86		.colorspace = V4L2_COLORSPACE_SRGB,
87		.priv = 2},
88	{320, 240, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
89		.bytesperline = 320,
90		.sizeimage = 320 * 240 * 4 / 8,
91		.colorspace = V4L2_COLORSPACE_SRGB,
92		.priv = 1},
93	{352, 288, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
94		.bytesperline = 352,
95		.sizeimage = 352 * 288 * 4 / 8,
96		.colorspace = V4L2_COLORSPACE_SRGB,
97		.priv = 0},
98};
99
100static const struct v4l2_pix_format sif_072a_mode[] = {
101	{160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
102		.bytesperline = 160,
103		.sizeimage = 160 * 120,
104		.colorspace = V4L2_COLORSPACE_SRGB,
105		.priv = 3},
106	{176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
107		.bytesperline = 176,
108		.sizeimage = 176 * 144,
109		.colorspace = V4L2_COLORSPACE_SRGB,
110		.priv = 2},
111	{320, 240, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
112		.bytesperline = 320,
113		.sizeimage = 320 * 240,
114		.colorspace = V4L2_COLORSPACE_SRGB,
115		.priv = 1},
116	{352, 288, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
117		.bytesperline = 352,
118		.sizeimage = 352 * 288,
119		.colorspace = V4L2_COLORSPACE_SRGB,
120		.priv = 0},
121};
122
123/*
124 * Initialization data
125 * I'm not very sure how to split initialization from open data
126 * chunks. For now, we'll consider everything as initialization
127 */
128/* Frame packet header offsets for the spca561 */
129#define SPCA561_OFFSET_SNAP 1
130#define SPCA561_OFFSET_TYPE 2
131#define SPCA561_OFFSET_COMPRESS 3
132#define SPCA561_OFFSET_FRAMSEQ   4
133#define SPCA561_OFFSET_GPIO 5
134#define SPCA561_OFFSET_USBBUFF 6
135#define SPCA561_OFFSET_WIN2GRAVE 7
136#define SPCA561_OFFSET_WIN2RAVE 8
137#define SPCA561_OFFSET_WIN2BAVE 9
138#define SPCA561_OFFSET_WIN2GBAVE 10
139#define SPCA561_OFFSET_WIN1GRAVE 11
140#define SPCA561_OFFSET_WIN1RAVE 12
141#define SPCA561_OFFSET_WIN1BAVE 13
142#define SPCA561_OFFSET_WIN1GBAVE 14
143#define SPCA561_OFFSET_FREQ 15
144#define SPCA561_OFFSET_VSYNC 16
145#define SPCA561_INDEX_I2C_BASE 0x8800
146#define SPCA561_SNAPBIT 0x20
147#define SPCA561_SNAPCTRL 0x40
148
149static const u16 rev72a_reset[][2] = {
150	{0x0000, 0x8114},	/* Software GPIO output data */
151	{0x0001, 0x8114},	/* Software GPIO output data */
152	{0x0000, 0x8112},	/* Some kind of reset */
153	{}
154};
155static const __u16 rev72a_init_data1[][2] = {
156	{0x0003, 0x8701},	/* PCLK clock delay adjustment */
157	{0x0001, 0x8703},	/* HSYNC from cmos inverted */
158	{0x0011, 0x8118},	/* Enable and conf sensor */
159	{0x0001, 0x8118},	/* Conf sensor */
160	{0x0092, 0x8804},	/* I know nothing about these */
161	{0x0010, 0x8802},	/* 0x88xx registers, so I won't */
162	{}
163};
164static const u16 rev72a_init_sensor1[][2] = {
165	{0x0001, 0x000d},
166	{0x0002, 0x0018},
167	{0x0004, 0x0165},
168	{0x0005, 0x0021},
169	{0x0007, 0x00aa},
170	{0x0020, 0x1504},
171	{0x0039, 0x0002},
172	{0x0035, 0x0010},
173	{0x0009, 0x1049},
174	{0x0028, 0x000b},
175	{0x003b, 0x000f},
176	{0x003c, 0x0000},
177	{}
178};
179static const __u16 rev72a_init_data2[][2] = {
180	{0x0018, 0x8601},	/* Pixel/line selection for color separation */
181	{0x0000, 0x8602},	/* Optical black level for user setting */
182	{0x0060, 0x8604},	/* Optical black horizontal offset */
183	{0x0002, 0x8605},	/* Optical black vertical offset */
184	{0x0000, 0x8603},	/* Non-automatic optical black level */
185	{0x0002, 0x865b},	/* Horizontal offset for valid pixels */
186	{0x0000, 0x865f},	/* Vertical valid pixels window (x2) */
187	{0x00b0, 0x865d},	/* Horizontal valid pixels window (x2) */
188	{0x0090, 0x865e},	/* Vertical valid lines window (x2) */
189	{0x00e0, 0x8406},	/* Memory buffer threshold */
190	{0x0000, 0x8660},	/* Compensation memory stuff */
191	{0x0002, 0x8201},	/* Output address for r/w serial EEPROM */
192	{0x0008, 0x8200},	/* Clear valid bit for serial EEPROM */
193	{0x0001, 0x8200},	/* OprMode to be executed by hardware */
194/* from ms-win */
195	{0x0000, 0x8611},	/* R offset for white balance */
196	{0x00fd, 0x8612},	/* Gr offset for white balance */
197	{0x0003, 0x8613},	/* B offset for white balance */
198	{0x0000, 0x8614},	/* Gb offset for white balance */
199/* from ms-win */
200	{0x0035, 0x8651},	/* R gain for white balance */
201	{0x0040, 0x8652},	/* Gr gain for white balance */
202	{0x005f, 0x8653},	/* B gain for white balance */
203	{0x0040, 0x8654},	/* Gb gain for white balance */
204	{0x0002, 0x8502},	/* Maximum average bit rate stuff */
205	{0x0011, 0x8802},
206
207	{0x0087, 0x8700},	/* Set master clock (96Mhz????) */
208	{0x0081, 0x8702},	/* Master clock output enable */
209
210	{0x0000, 0x8500},	/* Set image type (352x288 no compression) */
211	/* Originally was 0x0010 (352x288 compression) */
212
213	{0x0002, 0x865b},	/* Horizontal offset for valid pixels */
214	{0x0003, 0x865c},	/* Vertical offset for valid lines */
215	{}
216};
217static const u16 rev72a_init_sensor2[][2] = {
218	{0x0003, 0x0121},
219	{0x0004, 0x0165},
220	{0x0005, 0x002f},	/* blanking control column */
221	{0x0006, 0x0000},	/* blanking mode row*/
222	{0x000a, 0x0002},
223	{0x0009, 0x1061},	/* setexposure times && pixel clock
224				 * 0001 0 | 000 0110 0001 */
225	{0x0035, 0x0014},
226	{}
227};
228
229/******************** QC Express etch2 stuff ********************/
230static const __u16 Pb100_1map8300[][2] = {
231	/* reg, value */
232	{0x8320, 0x3304},
233
234	{0x8303, 0x0125},	/* image area */
235	{0x8304, 0x0169},
236	{0x8328, 0x000b},
237	{0x833c, 0x0001},
238
239	{0x832f, 0x1904},
240	{0x8307, 0x00aa},
241	{0x8301, 0x0003},
242	{0x8302, 0x000e},
243	{}
244};
245static const __u16 Pb100_2map8300[][2] = {
246	/* reg, value */
247	{0x8339, 0x0000},
248	{0x8307, 0x00aa},
249	{}
250};
251
252static const __u16 spca561_161rev12A_data1[][2] = {
253	{0x29, 0x8118},		/* Control register (various enable bits) */
254	{0x08, 0x8114},		/* GPIO: Led off */
255	{0x0e, 0x8112},		/* 0x0e stream off 0x3e stream on */
256	{0x00, 0x8102},		/* white balance - new */
257	{0x92, 0x8804},
258	{0x04, 0x8802},		/* windows uses 08 */
259	{}
260};
261static const __u16 spca561_161rev12A_data2[][2] = {
262	{0x21, 0x8118},
263	{0x10, 0x8500},
264	{0x07, 0x8601},
265	{0x07, 0x8602},
266	{0x04, 0x8501},
267
268	{0x07, 0x8201},		/* windows uses 02 */
269	{0x08, 0x8200},
270	{0x01, 0x8200},
271
272	{0x90, 0x8604},
273	{0x00, 0x8605},
274	{0xb0, 0x8603},
275
276	/* sensor gains */
277	{0x07, 0x8601},		/* white balance - new */
278	{0x07, 0x8602},		/* white balance - new */
279	{0x00, 0x8610},		/* *red */
280	{0x00, 0x8611},		/* 3f   *green */
281	{0x00, 0x8612},		/* green *blue */
282	{0x00, 0x8613},		/* blue *green */
283	{0x43, 0x8614},		/* green *red - white balance - was 0x35 */
284	{0x40, 0x8615},		/* 40   *green - white balance - was 0x35 */
285	{0x71, 0x8616},		/* 7a   *blue - white balance - was 0x35 */
286	{0x40, 0x8617},		/* 40   *green - white balance - was 0x35 */
287
288	{0x0c, 0x8620},		/* 0c */
289	{0xc8, 0x8631},		/* c8 */
290	{0xc8, 0x8634},		/* c8 */
291	{0x23, 0x8635},		/* 23 */
292	{0x1f, 0x8636},		/* 1f */
293	{0xdd, 0x8637},		/* dd */
294	{0xe1, 0x8638},		/* e1 */
295	{0x1d, 0x8639},		/* 1d */
296	{0x21, 0x863a},		/* 21 */
297	{0xe3, 0x863b},		/* e3 */
298	{0xdf, 0x863c},		/* df */
299	{0xf0, 0x8505},
300	{0x32, 0x850a},
301/*	{0x99, 0x8700},		 * - white balance - new (removed) */
302	/* HDG we used to do this in stop0, making the init state and the state
303	   after a start / stop different, so do this here instead. */
304	{0x29, 0x8118},
305	{}
306};
307
308static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value)
309{
310	int ret;
311
312	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
313			      0,		/* request */
314			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
315			      value, index, NULL, 0, 500);
316	PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value);
317	if (ret < 0)
318		PDEBUG(D_ERR, "reg write: error %d", ret);
319}
320
321static void write_vector(struct gspca_dev *gspca_dev,
322			const __u16 data[][2])
323{
324	struct usb_device *dev = gspca_dev->dev;
325	int i;
326
327	i = 0;
328	while (data[i][1] != 0) {
329		reg_w_val(dev, data[i][1], data[i][0]);
330		i++;
331	}
332}
333
334/* read 'len' bytes to gspca_dev->usb_buf */
335static void reg_r(struct gspca_dev *gspca_dev,
336		  __u16 index, __u16 length)
337{
338	usb_control_msg(gspca_dev->dev,
339			usb_rcvctrlpipe(gspca_dev->dev, 0),
340			0,			/* request */
341			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
342			0,			/* value */
343			index, gspca_dev->usb_buf, length, 500);
344}
345
346/* write 'len' bytes from gspca_dev->usb_buf */
347static void reg_w_buf(struct gspca_dev *gspca_dev,
348		      __u16 index, __u16 len)
349{
350	usb_control_msg(gspca_dev->dev,
351			usb_sndctrlpipe(gspca_dev->dev, 0),
352			0,			/* request */
353			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
354			0,			/* value */
355			index, gspca_dev->usb_buf, len, 500);
356}
357
358static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg)
359{
360	int retry = 60;
361
362	reg_w_val(gspca_dev->dev, 0x8801, reg);
363	reg_w_val(gspca_dev->dev, 0x8805, value);
364	reg_w_val(gspca_dev->dev, 0x8800, value >> 8);
365	do {
366		reg_r(gspca_dev, 0x8803, 1);
367		if (!gspca_dev->usb_buf[0])
368			return;
369		msleep(10);
370	} while (--retry);
371}
372
373static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
374{
375	int retry = 60;
376	__u8 value;
377
378	reg_w_val(gspca_dev->dev, 0x8804, 0x92);
379	reg_w_val(gspca_dev->dev, 0x8801, reg);
380	reg_w_val(gspca_dev->dev, 0x8802, mode | 0x01);
381	do {
382		reg_r(gspca_dev, 0x8803, 1);
383		if (!gspca_dev->usb_buf[0]) {
384			reg_r(gspca_dev, 0x8800, 1);
385			value = gspca_dev->usb_buf[0];
386			reg_r(gspca_dev, 0x8805, 1);
387			return ((int) value << 8) | gspca_dev->usb_buf[0];
388		}
389		msleep(10);
390	} while (--retry);
391	return -1;
392}
393
394static void sensor_mapwrite(struct gspca_dev *gspca_dev,
395			    const __u16 (*sensormap)[2])
396{
397	while ((*sensormap)[0]) {
398		gspca_dev->usb_buf[0] = (*sensormap)[1];
399		gspca_dev->usb_buf[1] = (*sensormap)[1] >> 8;
400		reg_w_buf(gspca_dev, (*sensormap)[0], 2);
401		sensormap++;
402	}
403}
404
405static void write_sensor_72a(struct gspca_dev *gspca_dev,
406			    const __u16 (*sensor)[2])
407{
408	while ((*sensor)[0]) {
409		i2c_write(gspca_dev, (*sensor)[1], (*sensor)[0]);
410		sensor++;
411	}
412}
413
414static void init_161rev12A(struct gspca_dev *gspca_dev)
415{
416	write_vector(gspca_dev, spca561_161rev12A_data1);
417	sensor_mapwrite(gspca_dev, Pb100_1map8300);
418	write_vector(gspca_dev, spca561_161rev12A_data2);
419	sensor_mapwrite(gspca_dev, Pb100_2map8300);
420}
421
422/* this function is called at probe time */
423static int sd_config(struct gspca_dev *gspca_dev,
424		     const struct usb_device_id *id)
425{
426	struct sd *sd = (struct sd *) gspca_dev;
427	struct cam *cam;
428	__u16 vendor, product;
429	__u8 data1, data2;
430
431	/* Read frm global register the USB product and vendor IDs, just to
432	 * prove that we can communicate with the device.  This works, which
433	 * confirms at we are communicating properly and that the device
434	 * is a 561. */
435	reg_r(gspca_dev, 0x8104, 1);
436	data1 = gspca_dev->usb_buf[0];
437	reg_r(gspca_dev, 0x8105, 1);
438	data2 = gspca_dev->usb_buf[0];
439	vendor = (data2 << 8) | data1;
440	reg_r(gspca_dev, 0x8106, 1);
441	data1 = gspca_dev->usb_buf[0];
442	reg_r(gspca_dev, 0x8107, 1);
443	data2 = gspca_dev->usb_buf[0];
444	product = (data2 << 8) | data1;
445	if (vendor != id->idVendor || product != id->idProduct) {
446		PDEBUG(D_PROBE, "Bad vendor / product from device");
447		return -EINVAL;
448	}
449
450	cam = &gspca_dev->cam;
451	gspca_dev->nbalt = 7 + 1;	/* choose alternate 7 first */
452
453	sd->chip_revision = id->driver_info;
454	if (sd->chip_revision == Rev012A) {
455		cam->cam_mode = sif_012a_mode;
456		cam->nmodes = ARRAY_SIZE(sif_012a_mode);
457	} else {
458		cam->cam_mode = sif_072a_mode;
459		cam->nmodes = ARRAY_SIZE(sif_072a_mode);
460	}
461	sd->brightness = BRIGHTNESS_DEF;
462	sd->contrast = CONTRAST_DEF;
463	sd->white = HUE_DEF;
464	sd->exposure = EXPOSURE_DEF;
465	sd->autogain = AUTOGAIN_DEF;
466	sd->gain = GAIN_DEF;
467	sd->expo12a = EXPO12A_DEF;
468	return 0;
469}
470
471/* this function is called at probe and resume time */
472static int sd_init_12a(struct gspca_dev *gspca_dev)
473{
474	PDEBUG(D_STREAM, "Chip revision: 012a");
475	init_161rev12A(gspca_dev);
476	return 0;
477}
478static int sd_init_72a(struct gspca_dev *gspca_dev)
479{
480	PDEBUG(D_STREAM, "Chip revision: 072a");
481	write_vector(gspca_dev, rev72a_reset);
482	msleep(200);
483	write_vector(gspca_dev, rev72a_init_data1);
484	write_sensor_72a(gspca_dev, rev72a_init_sensor1);
485	write_vector(gspca_dev, rev72a_init_data2);
486	write_sensor_72a(gspca_dev, rev72a_init_sensor2);
487	reg_w_val(gspca_dev->dev, 0x8112, 0x30);
488	return 0;
489}
490
491/* rev 72a only */
492static void setbrightness(struct gspca_dev *gspca_dev)
493{
494	struct sd *sd = (struct sd *) gspca_dev;
495	struct usb_device *dev = gspca_dev->dev;
496	__u8 value;
497
498	value = sd->brightness;
499
500	/* offsets for white balance */
501	reg_w_val(dev, 0x8611, value);		/* R */
502	reg_w_val(dev, 0x8612, value);		/* Gr */
503	reg_w_val(dev, 0x8613, value);		/* B */
504	reg_w_val(dev, 0x8614, value);		/* Gb */
505}
506
507static void setwhite(struct gspca_dev *gspca_dev)
508{
509	struct sd *sd = (struct sd *) gspca_dev;
510	__u16 white;
511	__u8 blue, red;
512	__u16 reg;
513
514	/* try to emulate MS-win as possible */
515	white = sd->white;
516	red = 0x20 + white * 3 / 8;
517	blue = 0x90 - white * 5 / 8;
518	if (sd->chip_revision == Rev012A) {
519		reg = 0x8614;
520	} else {
521		reg = 0x8651;
522		red += sd->contrast - 0x20;
523		blue += sd->contrast - 0x20;
524	}
525	reg_w_val(gspca_dev->dev, reg, red);
526	reg_w_val(gspca_dev->dev, reg + 2, blue);
527}
528
529static void setcontrast(struct gspca_dev *gspca_dev)
530{
531	struct sd *sd = (struct sd *) gspca_dev;
532	struct usb_device *dev = gspca_dev->dev;
533	__u8 value;
534
535	if (sd->chip_revision != Rev072A)
536		return;
537	value = sd->contrast + 0x20;
538
539	/* gains for white balance */
540	setwhite(gspca_dev);
541/*	reg_w_val(dev, 0x8651, value);		 * R - done by setwhite */
542	reg_w_val(dev, 0x8652, value);		/* Gr */
543/*	reg_w_val(dev, 0x8653, value);		 * B - done by setwhite */
544	reg_w_val(dev, 0x8654, value);		/* Gb */
545}
546
547/* rev 12a only */
548static void setexposure(struct gspca_dev *gspca_dev)
549{
550	struct sd *sd = (struct sd *) gspca_dev;
551	int i, expo = 0;
552
553	/* Register 0x8309 controls exposure for the spca561,
554	   the basic exposure setting goes from 1-2047, where 1 is completely
555	   dark and 2047 is very bright. It not only influences exposure but
556	   also the framerate (to allow for longer exposure) from 1 - 300 it
557	   only raises the exposure time then from 300 - 600 it halves the
558	   framerate to be able to further raise the exposure time and for every
559	   300 more it halves the framerate again. This allows for a maximum
560	   exposure time of circa 0.2 - 0.25 seconds (30 / (2000/3000) fps).
561	   Sometimes this is not enough, the 1-2047 uses bits 0-10, bits 11-12
562	   configure a divider for the base framerate which us used at the
563	   exposure setting of 1-300. These bits configure the base framerate
564	   according to the following formula: fps = 60 / (value + 2) */
565
566	/* We choose to use the high bits setting the fixed framerate divisor
567	   asap, as setting high basic exposure setting without the fixed
568	   divider in combination with high gains makes the cam stop */
569	int table[] =  { 0, 450, 550, 625, EXPOSURE_MAX };
570
571	for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
572		if (sd->exposure <= table[i + 1]) {
573			expo  = sd->exposure - table[i];
574			if (i)
575				expo += 300;
576			expo |= i << 11;
577			break;
578		}
579	}
580
581	gspca_dev->usb_buf[0] = expo;
582	gspca_dev->usb_buf[1] = expo >> 8;
583	reg_w_buf(gspca_dev, 0x8309, 2);
584}
585
586/* rev 12a only */
587static void setgain(struct gspca_dev *gspca_dev)
588{
589	struct sd *sd = (struct sd *) gspca_dev;
590
591	/* gain reg low 6 bits  0-63 gain, bit 6 and 7, both double the
592	   sensitivity when set, so 31 + one of them set == 63, and 15
593	   with both of them set == 63 */
594	if (sd->gain < 64)
595		gspca_dev->usb_buf[0] = sd->gain;
596	else if (sd->gain < 128)
597		gspca_dev->usb_buf[0] = (sd->gain / 2) | 0x40;
598	else
599		gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xC0;
600
601	gspca_dev->usb_buf[1] = 0;
602	reg_w_buf(gspca_dev, 0x8335, 2);
603}
604
605static void setautogain(struct gspca_dev *gspca_dev)
606{
607	struct sd *sd = (struct sd *) gspca_dev;
608
609	if (sd->autogain)
610		sd->ag_cnt = AG_CNT_START;
611	else
612		sd->ag_cnt = -1;
613}
614
615static int sd_start_12a(struct gspca_dev *gspca_dev)
616{
617	struct usb_device *dev = gspca_dev->dev;
618	int mode;
619	static const __u8 Reg8391[8] =
620		{0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00};
621
622	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
623	if (mode <= 1) {
624		/* Use compression on 320x240 and above */
625		reg_w_val(dev, 0x8500, 0x10 | mode);
626	} else {
627		/* I couldn't get the compression to work below 320x240
628		 * Fortunately at these resolutions the bandwidth
629		 * is sufficient to push raw frames at ~20fps */
630		reg_w_val(dev, 0x8500, mode);
631	}		/* -- qq@kuku.eu.org */
632
633	gspca_dev->usb_buf[0] = 0xaa;
634	gspca_dev->usb_buf[1] = 0x00;
635	reg_w_buf(gspca_dev, 0x8307, 2);
636	/* clock - lower 0x8X values lead to fps > 30 */
637	reg_w_val(gspca_dev->dev, 0x8700, 0x8a);
638					/* 0x8f 0x85 0x27 clock */
639	reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
640	reg_w_val(gspca_dev->dev, 0x850b, 0x03);
641	memcpy(gspca_dev->usb_buf, Reg8391, 8);
642	reg_w_buf(gspca_dev, 0x8391, 8);
643	reg_w_buf(gspca_dev, 0x8390, 8);
644	setwhite(gspca_dev);
645	setgain(gspca_dev);
646	setexposure(gspca_dev);
647
648	/* Led ON (bit 3 -> 0 */
649	reg_w_val(gspca_dev->dev, 0x8114, 0x00);
650	return 0;
651}
652static int sd_start_72a(struct gspca_dev *gspca_dev)
653{
654	struct usb_device *dev = gspca_dev->dev;
655	int Clck;
656	int mode;
657
658	write_vector(gspca_dev, rev72a_reset);
659	msleep(200);
660	write_vector(gspca_dev, rev72a_init_data1);
661	write_sensor_72a(gspca_dev, rev72a_init_sensor1);
662
663	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
664	switch (mode) {
665	default:
666	case 0:
667		Clck = 0x27;		/* ms-win 0x87 */
668		break;
669	case 1:
670		Clck = 0x25;
671		break;
672	case 2:
673		Clck = 0x22;
674		break;
675	case 3:
676		Clck = 0x21;
677		break;
678	}
679	reg_w_val(dev, 0x8700, Clck);	/* 0x27 clock */
680	reg_w_val(dev, 0x8702, 0x81);
681	reg_w_val(dev, 0x8500, mode);	/* mode */
682	write_sensor_72a(gspca_dev, rev72a_init_sensor2);
683	setcontrast(gspca_dev);
684	setautogain(gspca_dev);
685	reg_w_val(dev, 0x8112, 0x10 | 0x20);
686	return 0;
687}
688
689static void sd_stopN(struct gspca_dev *gspca_dev)
690{
691	struct sd *sd = (struct sd *) gspca_dev;
692
693	if (sd->chip_revision == Rev012A) {
694		reg_w_val(gspca_dev->dev, 0x8112, 0x0e);
695		/* Led Off (bit 3 -> 1 */
696		reg_w_val(gspca_dev->dev, 0x8114, 0x08);
697	} else {
698		reg_w_val(gspca_dev->dev, 0x8112, 0x20);
699/*		reg_w_val(gspca_dev->dev, 0x8102, 0x00); ?? */
700	}
701}
702
703static void do_autogain(struct gspca_dev *gspca_dev)
704{
705	struct sd *sd = (struct sd *) gspca_dev;
706	int expotimes;
707	int pixelclk;
708	int gainG;
709	__u8 R, Gr, Gb, B;
710	int y;
711	__u8 luma_mean = 110;
712	__u8 luma_delta = 20;
713	__u8 spring = 4;
714
715	if (sd->ag_cnt < 0)
716		return;
717	if (--sd->ag_cnt >= 0)
718		return;
719	sd->ag_cnt = AG_CNT_START;
720
721	switch (sd->chip_revision) {
722	case Rev072A:
723		reg_r(gspca_dev, 0x8621, 1);
724		Gr = gspca_dev->usb_buf[0];
725		reg_r(gspca_dev, 0x8622, 1);
726		R = gspca_dev->usb_buf[0];
727		reg_r(gspca_dev, 0x8623, 1);
728		B = gspca_dev->usb_buf[0];
729		reg_r(gspca_dev, 0x8624, 1);
730		Gb = gspca_dev->usb_buf[0];
731		y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8;
732		/* u= (128*B-(43*(Gr+Gb+R))) >> 8; */
733		/* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */
734		/* PDEBUG(D_CONF,"reading Y %d U %d V %d ",y,u,v); */
735
736		if (y < luma_mean - luma_delta ||
737		    y > luma_mean + luma_delta) {
738			expotimes = i2c_read(gspca_dev, 0x09, 0x10);
739			pixelclk = 0x0800;
740			expotimes = expotimes & 0x07ff;
741			/* PDEBUG(D_PACK,
742				"Exposition Times 0x%03X Clock 0x%04X ",
743				expotimes,pixelclk); */
744			gainG = i2c_read(gspca_dev, 0x35, 0x10);
745			/* PDEBUG(D_PACK,
746				"reading Gain register %d", gainG); */
747
748			expotimes += (luma_mean - y) >> spring;
749			gainG += (luma_mean - y) / 50;
750			/* PDEBUG(D_PACK,
751				"compute expotimes %d gain %d",
752				expotimes,gainG); */
753
754			if (gainG > 0x3f)
755				gainG = 0x3f;
756			else if (gainG < 3)
757				gainG = 3;
758			i2c_write(gspca_dev, gainG, 0x35);
759
760			if (expotimes > 0x0256)
761				expotimes = 0x0256;
762			else if (expotimes < 3)
763				expotimes = 3;
764			i2c_write(gspca_dev, expotimes | pixelclk, 0x09);
765		}
766		break;
767	}
768}
769
770static void sd_pkt_scan(struct gspca_dev *gspca_dev,
771			u8 *data,		/* isoc packet */
772			int len)		/* iso packet length */
773{
774	struct sd *sd = (struct sd *) gspca_dev;
775
776	len--;
777	switch (*data++) {			/* sequence number */
778	case 0:					/* start of frame */
779		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
780
781		/* This should never happen */
782		if (len < 2) {
783			PDEBUG(D_ERR, "Short SOF packet, ignoring");
784			gspca_dev->last_packet_type = DISCARD_PACKET;
785			return;
786		}
787
788#ifdef CONFIG_INPUT
789		if (data[0] & 0x20) {
790			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
791			input_sync(gspca_dev->input_dev);
792			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
793			input_sync(gspca_dev->input_dev);
794		}
795#endif
796
797		if (data[1] & 0x10) {
798			/* compressed bayer */
799			gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
800		} else {
801			/* raw bayer (with a header, which we skip) */
802			if (sd->chip_revision == Rev012A) {
803				data += 20;
804				len -= 20;
805			} else {
806				data += 16;
807				len -= 16;
808			}
809			gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
810		}
811		return;
812	case 0xff:			/* drop (empty mpackets) */
813		return;
814	}
815	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
816}
817
818/* rev 72a only */
819static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
820{
821	struct sd *sd = (struct sd *) gspca_dev;
822
823	sd->brightness = val;
824	if (gspca_dev->streaming)
825		setbrightness(gspca_dev);
826	return 0;
827}
828
829static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
830{
831	struct sd *sd = (struct sd *) gspca_dev;
832
833	*val = sd->brightness;
834	return 0;
835}
836
837/* rev 72a only */
838static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
839{
840	struct sd *sd = (struct sd *) gspca_dev;
841
842	sd->contrast = val;
843	if (gspca_dev->streaming)
844		setcontrast(gspca_dev);
845	return 0;
846}
847
848static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
849{
850	struct sd *sd = (struct sd *) gspca_dev;
851
852	*val = sd->contrast;
853	return 0;
854}
855
856static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
857{
858	struct sd *sd = (struct sd *) gspca_dev;
859
860	sd->autogain = val;
861	if (gspca_dev->streaming)
862		setautogain(gspca_dev);
863	return 0;
864}
865
866static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
867{
868	struct sd *sd = (struct sd *) gspca_dev;
869
870	*val = sd->autogain;
871	return 0;
872}
873
874static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val)
875{
876	struct sd *sd = (struct sd *) gspca_dev;
877
878	sd->white = val;
879	if (gspca_dev->streaming)
880		setwhite(gspca_dev);
881	return 0;
882}
883
884static int sd_getwhite(struct gspca_dev *gspca_dev, __s32 *val)
885{
886	struct sd *sd = (struct sd *) gspca_dev;
887
888	*val = sd->white;
889	return 0;
890}
891
892/* rev12a only */
893static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
894{
895	struct sd *sd = (struct sd *) gspca_dev;
896
897	sd->exposure = val;
898	if (gspca_dev->streaming)
899		setexposure(gspca_dev);
900	return 0;
901}
902
903static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
904{
905	struct sd *sd = (struct sd *) gspca_dev;
906
907	*val = sd->exposure;
908	return 0;
909}
910
911/* rev12a only */
912static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
913{
914	struct sd *sd = (struct sd *) gspca_dev;
915
916	sd->gain = val;
917	if (gspca_dev->streaming)
918		setgain(gspca_dev);
919	return 0;
920}
921
922static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
923{
924	struct sd *sd = (struct sd *) gspca_dev;
925
926	*val = sd->gain;
927	return 0;
928}
929
930/* control tables */
931static const struct ctrl sd_ctrls_12a[] = {
932	{
933	    {
934		.id = V4L2_CID_HUE,
935		.type = V4L2_CTRL_TYPE_INTEGER,
936		.name = "Hue",
937		.minimum = HUE_MIN,
938		.maximum = HUE_MAX,
939		.step = 1,
940		.default_value = HUE_DEF,
941	    },
942	    .set = sd_setwhite,
943	    .get = sd_getwhite,
944	},
945	{
946	    {
947		.id = V4L2_CID_EXPOSURE,
948		.type = V4L2_CTRL_TYPE_INTEGER,
949		.name = "Exposure",
950		.minimum = EXPOSURE_MIN,
951		.maximum = EXPOSURE_MAX,
952		.step = 1,
953		.default_value = EXPOSURE_DEF,
954	    },
955	    .set = sd_setexposure,
956	    .get = sd_getexposure,
957	},
958	{
959	    {
960		.id = V4L2_CID_GAIN,
961		.type = V4L2_CTRL_TYPE_INTEGER,
962		.name = "Gain",
963		.minimum = GAIN_MIN,
964		.maximum = GAIN_MAX,
965		.step = 1,
966		.default_value = GAIN_DEF,
967	    },
968	    .set = sd_setgain,
969	    .get = sd_getgain,
970	},
971};
972
973static const struct ctrl sd_ctrls_72a[] = {
974	{
975	    {
976		.id = V4L2_CID_HUE,
977		.type = V4L2_CTRL_TYPE_INTEGER,
978		.name = "Hue",
979		.minimum = HUE_MIN,
980		.maximum = HUE_MAX,
981		.step = 1,
982		.default_value = HUE_DEF,
983	    },
984	    .set = sd_setwhite,
985	    .get = sd_getwhite,
986	},
987	{
988	   {
989		.id = V4L2_CID_BRIGHTNESS,
990		.type = V4L2_CTRL_TYPE_INTEGER,
991		.name = "Brightness",
992		.minimum = BRIGHTNESS_MIN,
993		.maximum = BRIGHTNESS_MAX,
994		.step = 1,
995		.default_value = BRIGHTNESS_DEF,
996	    },
997	    .set = sd_setbrightness,
998	    .get = sd_getbrightness,
999	},
1000	{
1001	    {
1002		.id = V4L2_CID_CONTRAST,
1003		.type = V4L2_CTRL_TYPE_INTEGER,
1004		.name = "Contrast",
1005		.minimum = CONTRAST_MIN,
1006		.maximum = CONTRAST_MAX,
1007		.step = 1,
1008		.default_value = CONTRAST_DEF,
1009	    },
1010	    .set = sd_setcontrast,
1011	    .get = sd_getcontrast,
1012	},
1013	{
1014	    {
1015		.id = V4L2_CID_AUTOGAIN,
1016		.type = V4L2_CTRL_TYPE_BOOLEAN,
1017		.name = "Auto Gain",
1018		.minimum = AUTOGAIN_MIN,
1019		.maximum = AUTOGAIN_MAX,
1020		.step = 1,
1021		.default_value = AUTOGAIN_DEF,
1022	    },
1023	    .set = sd_setautogain,
1024	    .get = sd_getautogain,
1025	},
1026};
1027
1028/* sub-driver description */
1029static const struct sd_desc sd_desc_12a = {
1030	.name = MODULE_NAME,
1031	.ctrls = sd_ctrls_12a,
1032	.nctrls = ARRAY_SIZE(sd_ctrls_12a),
1033	.config = sd_config,
1034	.init = sd_init_12a,
1035	.start = sd_start_12a,
1036	.stopN = sd_stopN,
1037	.pkt_scan = sd_pkt_scan,
1038#ifdef CONFIG_INPUT
1039	.other_input = 1,
1040#endif
1041};
1042static const struct sd_desc sd_desc_72a = {
1043	.name = MODULE_NAME,
1044	.ctrls = sd_ctrls_72a,
1045	.nctrls = ARRAY_SIZE(sd_ctrls_72a),
1046	.config = sd_config,
1047	.init = sd_init_72a,
1048	.start = sd_start_72a,
1049	.stopN = sd_stopN,
1050	.pkt_scan = sd_pkt_scan,
1051	.dq_callback = do_autogain,
1052#ifdef CONFIG_INPUT
1053	.other_input = 1,
1054#endif
1055};
1056static const struct sd_desc *sd_desc[2] = {
1057	&sd_desc_12a,
1058	&sd_desc_72a
1059};
1060
1061/* -- module initialisation -- */
1062static const __devinitdata struct usb_device_id device_table[] = {
1063	{USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},
1064	{USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},
1065	{USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},
1066	{USB_DEVICE(0x0461, 0x0815), .driver_info = Rev072A},
1067	{USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A},
1068	{USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A},
1069	{USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A},
1070	{USB_DEVICE(0x046d, 0x092b), .driver_info = Rev012A},
1071	{USB_DEVICE(0x046d, 0x092c), .driver_info = Rev012A},
1072	{USB_DEVICE(0x046d, 0x092d), .driver_info = Rev012A},
1073	{USB_DEVICE(0x046d, 0x092e), .driver_info = Rev012A},
1074	{USB_DEVICE(0x046d, 0x092f), .driver_info = Rev012A},
1075	{USB_DEVICE(0x04fc, 0x0561), .driver_info = Rev072A},
1076	{USB_DEVICE(0x060b, 0xa001), .driver_info = Rev072A},
1077	{USB_DEVICE(0x10fd, 0x7e50), .driver_info = Rev072A},
1078	{USB_DEVICE(0xabcd, 0xcdee), .driver_info = Rev072A},
1079	{}
1080};
1081
1082MODULE_DEVICE_TABLE(usb, device_table);
1083
1084/* -- device connect -- */
1085static int sd_probe(struct usb_interface *intf,
1086		    const struct usb_device_id *id)
1087{
1088	return gspca_dev_probe(intf, id,
1089				sd_desc[id->driver_info],
1090				sizeof(struct sd),
1091			       THIS_MODULE);
1092}
1093
1094static struct usb_driver sd_driver = {
1095	.name = MODULE_NAME,
1096	.id_table = device_table,
1097	.probe = sd_probe,
1098	.disconnect = gspca_disconnect,
1099#ifdef CONFIG_PM
1100	.suspend = gspca_suspend,
1101	.resume = gspca_resume,
1102#endif
1103};
1104
1105/* -- module insert / remove -- */
1106static int __init sd_mod_init(void)
1107{
1108	int ret;
1109	ret = usb_register(&sd_driver);
1110	if (ret < 0)
1111		return ret;
1112	PDEBUG(D_PROBE, "registered");
1113	return 0;
1114}
1115static void __exit sd_mod_exit(void)
1116{
1117	usb_deregister(&sd_driver);
1118	PDEBUG(D_PROBE, "deregistered");
1119}
1120
1121module_init(sd_mod_init);
1122module_exit(sd_mod_exit);
1123