• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/media/video/gspca/
1/*
2 * cpia CPiA (1) gspca driver
3 *
4 * Copyright (C) 2010 Hans de Goede <hdgoede@redhat.com>
5 *
6 * This module is adapted from the in kernel v4l1 cpia driver which is :
7 *
8 * (C) Copyright 1999-2000 Peter Pregler
9 * (C) Copyright 1999-2000 Scott J. Bertin
10 * (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.com>
11 * (C) Copyright 2000 STMicroelectronics
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 *
27 */
28
29#define MODULE_NAME "cpia1"
30
31#include "gspca.h"
32
33MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>");
34MODULE_DESCRIPTION("Vision CPiA");
35MODULE_LICENSE("GPL");
36
37/* constant value's */
38#define MAGIC_0		0x19
39#define MAGIC_1		0x68
40#define DATA_IN		0xC0
41#define DATA_OUT	0x40
42#define VIDEOSIZE_QCIF	0	/* 176x144 */
43#define VIDEOSIZE_CIF	1	/* 352x288 */
44#define SUBSAMPLE_420	0
45#define SUBSAMPLE_422	1
46#define YUVORDER_YUYV	0
47#define YUVORDER_UYVY	1
48#define NOT_COMPRESSED	0
49#define COMPRESSED	1
50#define NO_DECIMATION	0
51#define DECIMATION_ENAB	1
52#define EOI		0xff	/* End Of Image */
53#define EOL		0xfd	/* End Of Line */
54#define FRAME_HEADER_SIZE	64
55
56/* Image grab modes */
57#define CPIA_GRAB_SINGLE	0
58#define CPIA_GRAB_CONTINEOUS	1
59
60/* Compression parameters */
61#define CPIA_COMPRESSION_NONE	0
62#define CPIA_COMPRESSION_AUTO	1
63#define CPIA_COMPRESSION_MANUAL	2
64#define CPIA_COMPRESSION_TARGET_QUALITY         0
65#define CPIA_COMPRESSION_TARGET_FRAMERATE       1
66
67/* Return offsets for GetCameraState */
68#define SYSTEMSTATE	0
69#define GRABSTATE	1
70#define STREAMSTATE	2
71#define FATALERROR	3
72#define CMDERROR	4
73#define DEBUGFLAGS	5
74#define VPSTATUS	6
75#define ERRORCODE	7
76
77/* SystemState */
78#define UNINITIALISED_STATE	0
79#define PASS_THROUGH_STATE	1
80#define LO_POWER_STATE		2
81#define HI_POWER_STATE		3
82#define WARM_BOOT_STATE		4
83
84/* GrabState */
85#define GRAB_IDLE		0
86#define GRAB_ACTIVE		1
87#define GRAB_DONE		2
88
89/* StreamState */
90#define STREAM_NOT_READY	0
91#define STREAM_READY		1
92#define STREAM_OPEN		2
93#define STREAM_PAUSED		3
94#define STREAM_FINISHED		4
95
96/* Fatal Error, CmdError, and DebugFlags */
97#define CPIA_FLAG	  1
98#define SYSTEM_FLAG	  2
99#define INT_CTRL_FLAG	  4
100#define PROCESS_FLAG	  8
101#define COM_FLAG	 16
102#define VP_CTRL_FLAG	 32
103#define CAPTURE_FLAG	 64
104#define DEBUG_FLAG	128
105
106/* VPStatus */
107#define VP_STATE_OK			0x00
108
109#define VP_STATE_FAILED_VIDEOINIT	0x01
110#define VP_STATE_FAILED_AECACBINIT	0x02
111#define VP_STATE_AEC_MAX		0x04
112#define VP_STATE_ACB_BMAX		0x08
113
114#define VP_STATE_ACB_RMIN		0x10
115#define VP_STATE_ACB_GMIN		0x20
116#define VP_STATE_ACB_RMAX		0x40
117#define VP_STATE_ACB_GMAX		0x80
118
119/* default (minimum) compensation values */
120#define COMP_RED        220
121#define COMP_GREEN1     214
122#define COMP_GREEN2     COMP_GREEN1
123#define COMP_BLUE       230
124
125/* exposure status */
126#define EXPOSURE_VERY_LIGHT 0
127#define EXPOSURE_LIGHT      1
128#define EXPOSURE_NORMAL     2
129#define EXPOSURE_DARK       3
130#define EXPOSURE_VERY_DARK  4
131
132#define CPIA_MODULE_CPIA			(0 << 5)
133#define CPIA_MODULE_SYSTEM			(1 << 5)
134#define CPIA_MODULE_VP_CTRL			(5 << 5)
135#define CPIA_MODULE_CAPTURE			(6 << 5)
136#define CPIA_MODULE_DEBUG			(7 << 5)
137
138#define INPUT (DATA_IN << 8)
139#define OUTPUT (DATA_OUT << 8)
140
141#define CPIA_COMMAND_GetCPIAVersion	(INPUT | CPIA_MODULE_CPIA | 1)
142#define CPIA_COMMAND_GetPnPID		(INPUT | CPIA_MODULE_CPIA | 2)
143#define CPIA_COMMAND_GetCameraStatus	(INPUT | CPIA_MODULE_CPIA | 3)
144#define CPIA_COMMAND_GotoHiPower	(OUTPUT | CPIA_MODULE_CPIA | 4)
145#define CPIA_COMMAND_GotoLoPower	(OUTPUT | CPIA_MODULE_CPIA | 5)
146#define CPIA_COMMAND_GotoSuspend	(OUTPUT | CPIA_MODULE_CPIA | 7)
147#define CPIA_COMMAND_GotoPassThrough	(OUTPUT | CPIA_MODULE_CPIA | 8)
148#define CPIA_COMMAND_ModifyCameraStatus	(OUTPUT | CPIA_MODULE_CPIA | 10)
149
150#define CPIA_COMMAND_ReadVCRegs		(INPUT | CPIA_MODULE_SYSTEM | 1)
151#define CPIA_COMMAND_WriteVCReg		(OUTPUT | CPIA_MODULE_SYSTEM | 2)
152#define CPIA_COMMAND_ReadMCPorts	(INPUT | CPIA_MODULE_SYSTEM | 3)
153#define CPIA_COMMAND_WriteMCPort	(OUTPUT | CPIA_MODULE_SYSTEM | 4)
154#define CPIA_COMMAND_SetBaudRate	(OUTPUT | CPIA_MODULE_SYSTEM | 5)
155#define CPIA_COMMAND_SetECPTiming	(OUTPUT | CPIA_MODULE_SYSTEM | 6)
156#define CPIA_COMMAND_ReadIDATA		(INPUT | CPIA_MODULE_SYSTEM | 7)
157#define CPIA_COMMAND_WriteIDATA		(OUTPUT | CPIA_MODULE_SYSTEM | 8)
158#define CPIA_COMMAND_GenericCall	(OUTPUT | CPIA_MODULE_SYSTEM | 9)
159#define CPIA_COMMAND_I2CStart		(OUTPUT | CPIA_MODULE_SYSTEM | 10)
160#define CPIA_COMMAND_I2CStop		(OUTPUT | CPIA_MODULE_SYSTEM | 11)
161#define CPIA_COMMAND_I2CWrite		(OUTPUT | CPIA_MODULE_SYSTEM | 12)
162#define CPIA_COMMAND_I2CRead		(INPUT | CPIA_MODULE_SYSTEM | 13)
163
164#define CPIA_COMMAND_GetVPVersion	(INPUT | CPIA_MODULE_VP_CTRL | 1)
165#define CPIA_COMMAND_ResetFrameCounter	(INPUT | CPIA_MODULE_VP_CTRL | 2)
166#define CPIA_COMMAND_SetColourParams	(OUTPUT | CPIA_MODULE_VP_CTRL | 3)
167#define CPIA_COMMAND_SetExposure	(OUTPUT | CPIA_MODULE_VP_CTRL | 4)
168#define CPIA_COMMAND_SetColourBalance	(OUTPUT | CPIA_MODULE_VP_CTRL | 6)
169#define CPIA_COMMAND_SetSensorFPS	(OUTPUT | CPIA_MODULE_VP_CTRL | 7)
170#define CPIA_COMMAND_SetVPDefaults	(OUTPUT | CPIA_MODULE_VP_CTRL | 8)
171#define CPIA_COMMAND_SetApcor		(OUTPUT | CPIA_MODULE_VP_CTRL | 9)
172#define CPIA_COMMAND_SetFlickerCtrl	(OUTPUT | CPIA_MODULE_VP_CTRL | 10)
173#define CPIA_COMMAND_SetVLOffset	(OUTPUT | CPIA_MODULE_VP_CTRL | 11)
174#define CPIA_COMMAND_GetColourParams	(INPUT | CPIA_MODULE_VP_CTRL | 16)
175#define CPIA_COMMAND_GetColourBalance	(INPUT | CPIA_MODULE_VP_CTRL | 17)
176#define CPIA_COMMAND_GetExposure	(INPUT | CPIA_MODULE_VP_CTRL | 18)
177#define CPIA_COMMAND_SetSensorMatrix	(OUTPUT | CPIA_MODULE_VP_CTRL | 19)
178#define CPIA_COMMAND_ColourBars		(OUTPUT | CPIA_MODULE_VP_CTRL | 25)
179#define CPIA_COMMAND_ReadVPRegs		(INPUT | CPIA_MODULE_VP_CTRL | 30)
180#define CPIA_COMMAND_WriteVPReg		(OUTPUT | CPIA_MODULE_VP_CTRL | 31)
181
182#define CPIA_COMMAND_GrabFrame		(OUTPUT | CPIA_MODULE_CAPTURE | 1)
183#define CPIA_COMMAND_UploadFrame	(OUTPUT | CPIA_MODULE_CAPTURE | 2)
184#define CPIA_COMMAND_SetGrabMode	(OUTPUT | CPIA_MODULE_CAPTURE | 3)
185#define CPIA_COMMAND_InitStreamCap	(OUTPUT | CPIA_MODULE_CAPTURE | 4)
186#define CPIA_COMMAND_FiniStreamCap	(OUTPUT | CPIA_MODULE_CAPTURE | 5)
187#define CPIA_COMMAND_StartStreamCap	(OUTPUT | CPIA_MODULE_CAPTURE | 6)
188#define CPIA_COMMAND_EndStreamCap	(OUTPUT | CPIA_MODULE_CAPTURE | 7)
189#define CPIA_COMMAND_SetFormat		(OUTPUT | CPIA_MODULE_CAPTURE | 8)
190#define CPIA_COMMAND_SetROI		(OUTPUT | CPIA_MODULE_CAPTURE | 9)
191#define CPIA_COMMAND_SetCompression	(OUTPUT | CPIA_MODULE_CAPTURE | 10)
192#define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
193#define CPIA_COMMAND_SetYUVThresh	(OUTPUT | CPIA_MODULE_CAPTURE | 12)
194#define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
195#define CPIA_COMMAND_DiscardFrame	(OUTPUT | CPIA_MODULE_CAPTURE | 14)
196#define CPIA_COMMAND_GrabReset		(OUTPUT | CPIA_MODULE_CAPTURE | 15)
197
198#define CPIA_COMMAND_OutputRS232	(OUTPUT | CPIA_MODULE_DEBUG | 1)
199#define CPIA_COMMAND_AbortProcess	(OUTPUT | CPIA_MODULE_DEBUG | 4)
200#define CPIA_COMMAND_SetDramPage	(OUTPUT | CPIA_MODULE_DEBUG | 5)
201#define CPIA_COMMAND_StartDramUpload	(OUTPUT | CPIA_MODULE_DEBUG | 6)
202#define CPIA_COMMAND_StartDummyDtream	(OUTPUT | CPIA_MODULE_DEBUG | 8)
203#define CPIA_COMMAND_AbortStream	(OUTPUT | CPIA_MODULE_DEBUG | 9)
204#define CPIA_COMMAND_DownloadDRAM	(OUTPUT | CPIA_MODULE_DEBUG | 10)
205#define CPIA_COMMAND_Null		(OUTPUT | CPIA_MODULE_DEBUG | 11)
206
207#define ROUND_UP_EXP_FOR_FLICKER 15
208
209/* Constants for automatic frame rate adjustment */
210#define MAX_EXP       302
211#define MAX_EXP_102   255
212#define LOW_EXP       140
213#define VERY_LOW_EXP   70
214#define TC             94
215#define	EXP_ACC_DARK   50
216#define	EXP_ACC_LIGHT  90
217#define HIGH_COMP_102 160
218#define MAX_COMP      239
219#define DARK_TIME       3
220#define LIGHT_TIME      3
221
222#define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \
223				sd->params.version.firmwareRevision == (y))
224
225/* Developer's Guide Table 5 p 3-34
226 * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
227static u8 flicker_jumps[2][2][4] =
228{ { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
229  { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
230};
231
232struct cam_params {
233	struct {
234		u8 firmwareVersion;
235		u8 firmwareRevision;
236		u8 vcVersion;
237		u8 vcRevision;
238	} version;
239	struct {
240		u16 vendor;
241		u16 product;
242		u16 deviceRevision;
243	} pnpID;
244	struct {
245		u8 vpVersion;
246		u8 vpRevision;
247		u16 cameraHeadID;
248	} vpVersion;
249	struct {
250		u8 systemState;
251		u8 grabState;
252		u8 streamState;
253		u8 fatalError;
254		u8 cmdError;
255		u8 debugFlags;
256		u8 vpStatus;
257		u8 errorCode;
258	} status;
259	struct {
260		u8 brightness;
261		u8 contrast;
262		u8 saturation;
263	} colourParams;
264	struct {
265		u8 gainMode;
266		u8 expMode;
267		u8 compMode;
268		u8 centreWeight;
269		u8 gain;
270		u8 fineExp;
271		u8 coarseExpLo;
272		u8 coarseExpHi;
273		u8 redComp;
274		u8 green1Comp;
275		u8 green2Comp;
276		u8 blueComp;
277	} exposure;
278	struct {
279		u8 balanceMode;
280		u8 redGain;
281		u8 greenGain;
282		u8 blueGain;
283	} colourBalance;
284	struct {
285		u8 divisor;
286		u8 baserate;
287	} sensorFps;
288	struct {
289		u8 gain1;
290		u8 gain2;
291		u8 gain4;
292		u8 gain8;
293	} apcor;
294	struct {
295		u8 disabled;
296		u8 flickerMode;
297		u8 coarseJump;
298		u8 allowableOverExposure;
299	} flickerControl;
300	struct {
301		u8 gain1;
302		u8 gain2;
303		u8 gain4;
304		u8 gain8;
305	} vlOffset;
306	struct {
307		u8 mode;
308		u8 decimation;
309	} compression;
310	struct {
311		u8 frTargeting;
312		u8 targetFR;
313		u8 targetQ;
314	} compressionTarget;
315	struct {
316		u8 yThreshold;
317		u8 uvThreshold;
318	} yuvThreshold;
319	struct {
320		u8 hysteresis;
321		u8 threshMax;
322		u8 smallStep;
323		u8 largeStep;
324		u8 decimationHysteresis;
325		u8 frDiffStepThresh;
326		u8 qDiffStepThresh;
327		u8 decimationThreshMod;
328	} compressionParams;
329	struct {
330		u8 videoSize;		/* CIF/QCIF */
331		u8 subSample;
332		u8 yuvOrder;
333	} format;
334	struct {                        /* Intel QX3 specific data */
335		u8 qx3_detected;        /* a QX3 is present */
336		u8 toplight;            /* top light lit , R/W */
337		u8 bottomlight;         /* bottom light lit, R/W */
338		u8 button;              /* snapshot button pressed (R/O) */
339		u8 cradled;             /* microscope is in cradle (R/O) */
340	} qx3;
341	struct {
342		u8 colStart;		/* skip first 8*colStart pixels */
343		u8 colEnd;		/* finish at 8*colEnd pixels */
344		u8 rowStart;		/* skip first 4*rowStart lines */
345		u8 rowEnd;		/* finish at 4*rowEnd lines */
346	} roi;
347	u8 ecpTiming;
348	u8 streamStartLine;
349};
350
351/* specific webcam descriptor */
352struct sd {
353	struct gspca_dev gspca_dev;		/* !! must be the first item */
354	struct cam_params params;		/* camera settings */
355
356	atomic_t cam_exposure;
357	atomic_t fps;
358	int exposure_count;
359	u8 exposure_status;
360	u8 mainsFreq;				/* 0 = 50hz, 1 = 60hz */
361	u8 first_frame;
362	u8 freq;
363};
364
365/* V4L2 controls supported by the driver */
366static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
367static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
368static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
369static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
370static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val);
371static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val);
372static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
373static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
374static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val);
375static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val);
376
377static const struct ctrl sd_ctrls[] = {
378	{
379	    {
380		.id      = V4L2_CID_BRIGHTNESS,
381		.type    = V4L2_CTRL_TYPE_INTEGER,
382		.name    = "Brightness",
383		.minimum = 0,
384		.maximum = 100,
385		.step = 1,
386#define BRIGHTNESS_DEF 50
387		.default_value = BRIGHTNESS_DEF,
388		.flags = 0,
389	    },
390	    .set = sd_setbrightness,
391	    .get = sd_getbrightness,
392	},
393	{
394	    {
395		.id      = V4L2_CID_CONTRAST,
396		.type    = V4L2_CTRL_TYPE_INTEGER,
397		.name    = "Contrast",
398		.minimum = 0,
399		.maximum = 96,
400		.step    = 8,
401#define CONTRAST_DEF 48
402		.default_value = CONTRAST_DEF,
403	    },
404	    .set = sd_setcontrast,
405	    .get = sd_getcontrast,
406	},
407	{
408	    {
409		.id      = V4L2_CID_SATURATION,
410		.type    = V4L2_CTRL_TYPE_INTEGER,
411		.name    = "Saturation",
412		.minimum = 0,
413		.maximum = 100,
414		.step    = 1,
415#define SATURATION_DEF 50
416		.default_value = SATURATION_DEF,
417	    },
418	    .set = sd_setsaturation,
419	    .get = sd_getsaturation,
420	},
421	{
422		{
423			.id	 = V4L2_CID_POWER_LINE_FREQUENCY,
424			.type    = V4L2_CTRL_TYPE_MENU,
425			.name    = "Light frequency filter",
426			.minimum = 0,
427			.maximum = 2,	/* 0: 0, 1: 50Hz, 2:60Hz */
428			.step    = 1,
429#define FREQ_DEF 1
430			.default_value = FREQ_DEF,
431		},
432		.set = sd_setfreq,
433		.get = sd_getfreq,
434	},
435	{
436		{
437#define V4L2_CID_COMP_TARGET V4L2_CID_PRIVATE_BASE
438			.id	 = V4L2_CID_COMP_TARGET,
439			.type    = V4L2_CTRL_TYPE_MENU,
440			.name    = "Compression Target",
441			.minimum = 0,
442			.maximum = 1,
443			.step    = 1,
444#define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY
445			.default_value = COMP_TARGET_DEF,
446		},
447		.set = sd_setcomptarget,
448		.get = sd_getcomptarget,
449	},
450};
451
452static const struct v4l2_pix_format mode[] = {
453	{160, 120, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
454		/* The sizeimage is trial and error, as with low framerates
455		   the camera will pad out usb frames, making the image
456		   data larger then strictly necessary */
457		.bytesperline = 160,
458		.sizeimage = 65536,
459		.colorspace = V4L2_COLORSPACE_SRGB,
460		.priv = 3},
461	{176, 144, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
462		.bytesperline = 172,
463		.sizeimage = 65536,
464		.colorspace = V4L2_COLORSPACE_SRGB,
465		.priv = 2},
466	{320, 240, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
467		.bytesperline = 320,
468		.sizeimage = 262144,
469		.colorspace = V4L2_COLORSPACE_SRGB,
470		.priv = 1},
471	{352, 288, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
472		.bytesperline = 352,
473		.sizeimage = 262144,
474		.colorspace = V4L2_COLORSPACE_SRGB,
475		.priv = 0},
476};
477
478/**********************************************************************
479 *
480 * General functions
481 *
482 **********************************************************************/
483
484static int cpia_usb_transferCmd(struct gspca_dev *gspca_dev, u8 *command)
485{
486	u8 requesttype;
487	unsigned int pipe;
488	int ret, databytes = command[6] | (command[7] << 8);
489	/* Sometimes we see spurious EPIPE errors */
490	int retries = 3;
491
492	if (command[0] == DATA_IN) {
493		pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
494		requesttype = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
495	} else if (command[0] == DATA_OUT) {
496		pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
497		requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE;
498	} else {
499		PDEBUG(D_ERR, "Unexpected first byte of command: %x",
500		       command[0]);
501		return -EINVAL;
502	}
503
504retry:
505	ret = usb_control_msg(gspca_dev->dev, pipe,
506			      command[1],
507			      requesttype,
508			      command[2] | (command[3] << 8),
509			      command[4] | (command[5] << 8),
510			      gspca_dev->usb_buf, databytes, 1000);
511
512	if (ret < 0)
513		PDEBUG(D_ERR, "usb_control_msg %02x, error %d", command[1],
514		       ret);
515
516	if (ret == -EPIPE && retries > 0) {
517		retries--;
518		goto retry;
519	}
520
521	return (ret < 0) ? ret : 0;
522}
523
524/* send an arbitrary command to the camera */
525static int do_command(struct gspca_dev *gspca_dev, u16 command,
526		      u8 a, u8 b, u8 c, u8 d)
527{
528	struct sd *sd = (struct sd *) gspca_dev;
529	int ret, datasize;
530	u8 cmd[8];
531
532	switch (command) {
533	case CPIA_COMMAND_GetCPIAVersion:
534	case CPIA_COMMAND_GetPnPID:
535	case CPIA_COMMAND_GetCameraStatus:
536	case CPIA_COMMAND_GetVPVersion:
537	case CPIA_COMMAND_GetColourParams:
538	case CPIA_COMMAND_GetColourBalance:
539	case CPIA_COMMAND_GetExposure:
540		datasize = 8;
541		break;
542	case CPIA_COMMAND_ReadMCPorts:
543	case CPIA_COMMAND_ReadVCRegs:
544		datasize = 4;
545		break;
546	default:
547		datasize = 0;
548		break;
549	}
550
551	cmd[0] = command >> 8;
552	cmd[1] = command & 0xff;
553	cmd[2] = a;
554	cmd[3] = b;
555	cmd[4] = c;
556	cmd[5] = d;
557	cmd[6] = datasize;
558	cmd[7] = 0;
559
560	ret = cpia_usb_transferCmd(gspca_dev, cmd);
561	if (ret)
562		return ret;
563
564	switch (command) {
565	case CPIA_COMMAND_GetCPIAVersion:
566		sd->params.version.firmwareVersion = gspca_dev->usb_buf[0];
567		sd->params.version.firmwareRevision = gspca_dev->usb_buf[1];
568		sd->params.version.vcVersion = gspca_dev->usb_buf[2];
569		sd->params.version.vcRevision = gspca_dev->usb_buf[3];
570		break;
571	case CPIA_COMMAND_GetPnPID:
572		sd->params.pnpID.vendor =
573			gspca_dev->usb_buf[0] | (gspca_dev->usb_buf[1] << 8);
574		sd->params.pnpID.product =
575			gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
576		sd->params.pnpID.deviceRevision =
577			gspca_dev->usb_buf[4] | (gspca_dev->usb_buf[5] << 8);
578		break;
579	case CPIA_COMMAND_GetCameraStatus:
580		sd->params.status.systemState = gspca_dev->usb_buf[0];
581		sd->params.status.grabState = gspca_dev->usb_buf[1];
582		sd->params.status.streamState = gspca_dev->usb_buf[2];
583		sd->params.status.fatalError = gspca_dev->usb_buf[3];
584		sd->params.status.cmdError = gspca_dev->usb_buf[4];
585		sd->params.status.debugFlags = gspca_dev->usb_buf[5];
586		sd->params.status.vpStatus = gspca_dev->usb_buf[6];
587		sd->params.status.errorCode = gspca_dev->usb_buf[7];
588		break;
589	case CPIA_COMMAND_GetVPVersion:
590		sd->params.vpVersion.vpVersion = gspca_dev->usb_buf[0];
591		sd->params.vpVersion.vpRevision = gspca_dev->usb_buf[1];
592		sd->params.vpVersion.cameraHeadID =
593			gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
594		break;
595	case CPIA_COMMAND_GetColourParams:
596		sd->params.colourParams.brightness = gspca_dev->usb_buf[0];
597		sd->params.colourParams.contrast = gspca_dev->usb_buf[1];
598		sd->params.colourParams.saturation = gspca_dev->usb_buf[2];
599		break;
600	case CPIA_COMMAND_GetColourBalance:
601		sd->params.colourBalance.redGain = gspca_dev->usb_buf[0];
602		sd->params.colourBalance.greenGain = gspca_dev->usb_buf[1];
603		sd->params.colourBalance.blueGain = gspca_dev->usb_buf[2];
604		break;
605	case CPIA_COMMAND_GetExposure:
606		sd->params.exposure.gain = gspca_dev->usb_buf[0];
607		sd->params.exposure.fineExp = gspca_dev->usb_buf[1];
608		sd->params.exposure.coarseExpLo = gspca_dev->usb_buf[2];
609		sd->params.exposure.coarseExpHi = gspca_dev->usb_buf[3];
610		sd->params.exposure.redComp = gspca_dev->usb_buf[4];
611		sd->params.exposure.green1Comp = gspca_dev->usb_buf[5];
612		sd->params.exposure.green2Comp = gspca_dev->usb_buf[6];
613		sd->params.exposure.blueComp = gspca_dev->usb_buf[7];
614		break;
615
616	case CPIA_COMMAND_ReadMCPorts:
617		if (!sd->params.qx3.qx3_detected)
618			break;
619		/* test button press */
620		sd->params.qx3.button = ((gspca_dev->usb_buf[1] & 0x02) == 0);
621		if (sd->params.qx3.button) {
622			/* button pressed - unlock the latch */
623			do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
624				   3, 0xDF, 0xDF, 0);
625			do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
626				   3, 0xFF, 0xFF, 0);
627		}
628
629		/* test whether microscope is cradled */
630		sd->params.qx3.cradled = ((gspca_dev->usb_buf[2] & 0x40) == 0);
631		break;
632	}
633
634	return 0;
635}
636
637/* send a command to the camera with an additional data transaction */
638static int do_command_extended(struct gspca_dev *gspca_dev, u16 command,
639			       u8 a, u8 b, u8 c, u8 d,
640			       u8 e, u8 f, u8 g, u8 h,
641			       u8 i, u8 j, u8 k, u8 l)
642{
643	u8 cmd[8];
644
645	cmd[0] = command >> 8;
646	cmd[1] = command & 0xff;
647	cmd[2] = a;
648	cmd[3] = b;
649	cmd[4] = c;
650	cmd[5] = d;
651	cmd[6] = 8;
652	cmd[7] = 0;
653	gspca_dev->usb_buf[0] = e;
654	gspca_dev->usb_buf[1] = f;
655	gspca_dev->usb_buf[2] = g;
656	gspca_dev->usb_buf[3] = h;
657	gspca_dev->usb_buf[4] = i;
658	gspca_dev->usb_buf[5] = j;
659	gspca_dev->usb_buf[6] = k;
660	gspca_dev->usb_buf[7] = l;
661
662	return cpia_usb_transferCmd(gspca_dev, cmd);
663}
664
665/*  find_over_exposure
666 *  Finds a suitable value of OverExposure for use with SetFlickerCtrl
667 *  Some calculation is required because this value changes with the brightness
668 *  set with SetColourParameters
669 *
670 *  Parameters: Brightness - last brightness value set with SetColourParameters
671 *
672 *  Returns: OverExposure value to use with SetFlickerCtrl
673 */
674#define FLICKER_MAX_EXPOSURE                    250
675#define FLICKER_ALLOWABLE_OVER_EXPOSURE         146
676#define FLICKER_BRIGHTNESS_CONSTANT             59
677static int find_over_exposure(int brightness)
678{
679	int MaxAllowableOverExposure, OverExposure;
680
681	MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness -
682				   FLICKER_BRIGHTNESS_CONSTANT;
683
684	if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE)
685		OverExposure = MaxAllowableOverExposure;
686	else
687		OverExposure = FLICKER_ALLOWABLE_OVER_EXPOSURE;
688
689	return OverExposure;
690}
691#undef FLICKER_MAX_EXPOSURE
692#undef FLICKER_ALLOWABLE_OVER_EXPOSURE
693#undef FLICKER_BRIGHTNESS_CONSTANT
694
695/* initialise cam_data structure  */
696static void reset_camera_params(struct gspca_dev *gspca_dev)
697{
698	struct sd *sd = (struct sd *) gspca_dev;
699	struct cam_params *params = &sd->params;
700
701	/* The following parameter values are the defaults from
702	 * "Software Developer's Guide for CPiA Cameras".  Any changes
703	 * to the defaults are noted in comments. */
704	params->colourParams.brightness = BRIGHTNESS_DEF;
705	params->colourParams.contrast = CONTRAST_DEF;
706	params->colourParams.saturation = SATURATION_DEF;
707	params->exposure.gainMode = 4;
708	params->exposure.expMode = 2;		/* AEC */
709	params->exposure.compMode = 1;
710	params->exposure.centreWeight = 1;
711	params->exposure.gain = 0;
712	params->exposure.fineExp = 0;
713	params->exposure.coarseExpLo = 185;
714	params->exposure.coarseExpHi = 0;
715	params->exposure.redComp = COMP_RED;
716	params->exposure.green1Comp = COMP_GREEN1;
717	params->exposure.green2Comp = COMP_GREEN2;
718	params->exposure.blueComp = COMP_BLUE;
719	params->colourBalance.balanceMode = 2;	/* ACB */
720	params->colourBalance.redGain = 32;
721	params->colourBalance.greenGain = 6;
722	params->colourBalance.blueGain = 92;
723	params->apcor.gain1 = 0x18;
724	params->apcor.gain2 = 0x16;
725	params->apcor.gain4 = 0x24;
726	params->apcor.gain8 = 0x34;
727	params->flickerControl.flickerMode = 0;
728	params->flickerControl.disabled = 1;
729
730	params->flickerControl.coarseJump =
731		flicker_jumps[sd->mainsFreq]
732			     [params->sensorFps.baserate]
733			     [params->sensorFps.divisor];
734	params->flickerControl.allowableOverExposure =
735		find_over_exposure(params->colourParams.brightness);
736	params->vlOffset.gain1 = 20;
737	params->vlOffset.gain2 = 24;
738	params->vlOffset.gain4 = 26;
739	params->vlOffset.gain8 = 26;
740	params->compressionParams.hysteresis = 3;
741	params->compressionParams.threshMax = 11;
742	params->compressionParams.smallStep = 1;
743	params->compressionParams.largeStep = 3;
744	params->compressionParams.decimationHysteresis = 2;
745	params->compressionParams.frDiffStepThresh = 5;
746	params->compressionParams.qDiffStepThresh = 3;
747	params->compressionParams.decimationThreshMod = 2;
748	/* End of default values from Software Developer's Guide */
749
750	/* Set Sensor FPS to 15fps. This seems better than 30fps
751	 * for indoor lighting. */
752	params->sensorFps.divisor = 1;
753	params->sensorFps.baserate = 1;
754
755	params->yuvThreshold.yThreshold = 6; /* From windows driver */
756	params->yuvThreshold.uvThreshold = 6; /* From windows driver */
757
758	params->format.subSample = SUBSAMPLE_420;
759	params->format.yuvOrder = YUVORDER_YUYV;
760
761	params->compression.mode = CPIA_COMPRESSION_AUTO;
762	params->compression.decimation = NO_DECIMATION;
763
764	params->compressionTarget.frTargeting = COMP_TARGET_DEF;
765	params->compressionTarget.targetFR = 15; /* From windows driver */
766	params->compressionTarget.targetQ = 5; /* From windows driver */
767
768	params->qx3.qx3_detected = 0;
769	params->qx3.toplight = 0;
770	params->qx3.bottomlight = 0;
771	params->qx3.button = 0;
772	params->qx3.cradled = 0;
773}
774
775static void printstatus(struct cam_params *params)
776{
777	PDEBUG(D_PROBE, "status: %02x %02x %02x %02x %02x %02x %02x %02x",
778	       params->status.systemState, params->status.grabState,
779	       params->status.streamState, params->status.fatalError,
780	       params->status.cmdError, params->status.debugFlags,
781	       params->status.vpStatus, params->status.errorCode);
782}
783
784static int goto_low_power(struct gspca_dev *gspca_dev)
785{
786	struct sd *sd = (struct sd *) gspca_dev;
787	int ret;
788
789	ret = do_command(gspca_dev, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0);
790	if (ret)
791		return ret;
792
793	do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
794	if (ret)
795		return ret;
796
797	if (sd->params.status.systemState != LO_POWER_STATE) {
798		if (sd->params.status.systemState != WARM_BOOT_STATE) {
799			PDEBUG(D_ERR,
800			       "unexpected state after lo power cmd: %02x",
801			       sd->params.status.systemState);
802			printstatus(&sd->params);
803		}
804		return -EIO;
805	}
806
807	PDEBUG(D_CONF, "camera now in LOW power state");
808	return 0;
809}
810
811static int goto_high_power(struct gspca_dev *gspca_dev)
812{
813	struct sd *sd = (struct sd *) gspca_dev;
814	int ret;
815
816	ret = do_command(gspca_dev, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0);
817	if (ret)
818		return ret;
819
820	msleep_interruptible(40);	/* windows driver does it too */
821
822	if (signal_pending(current))
823		return -EINTR;
824
825	do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
826	if (ret)
827		return ret;
828
829	if (sd->params.status.systemState != HI_POWER_STATE) {
830		PDEBUG(D_ERR, "unexpected state after hi power cmd: %02x",
831			       sd->params.status.systemState);
832		printstatus(&sd->params);
833		return -EIO;
834	}
835
836	PDEBUG(D_CONF, "camera now in HIGH power state");
837	return 0;
838}
839
840static int get_version_information(struct gspca_dev *gspca_dev)
841{
842	int ret;
843
844	/* GetCPIAVersion */
845	ret = do_command(gspca_dev, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0);
846	if (ret)
847		return ret;
848
849	/* GetPnPID */
850	return do_command(gspca_dev, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0);
851}
852
853static int save_camera_state(struct gspca_dev *gspca_dev)
854{
855	int ret;
856
857	ret = do_command(gspca_dev, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
858	if (ret)
859		return ret;
860
861	return do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
862}
863
864static int command_setformat(struct gspca_dev *gspca_dev)
865{
866	struct sd *sd = (struct sd *) gspca_dev;
867	int ret;
868
869	ret = do_command(gspca_dev, CPIA_COMMAND_SetFormat,
870			 sd->params.format.videoSize,
871			 sd->params.format.subSample,
872			 sd->params.format.yuvOrder, 0);
873	if (ret)
874		return ret;
875
876	return do_command(gspca_dev, CPIA_COMMAND_SetROI,
877			  sd->params.roi.colStart, sd->params.roi.colEnd,
878			  sd->params.roi.rowStart, sd->params.roi.rowEnd);
879}
880
881static int command_setcolourparams(struct gspca_dev *gspca_dev)
882{
883	struct sd *sd = (struct sd *) gspca_dev;
884	return do_command(gspca_dev, CPIA_COMMAND_SetColourParams,
885			  sd->params.colourParams.brightness,
886			  sd->params.colourParams.contrast,
887			  sd->params.colourParams.saturation, 0);
888}
889
890static int command_setapcor(struct gspca_dev *gspca_dev)
891{
892	struct sd *sd = (struct sd *) gspca_dev;
893	return do_command(gspca_dev, CPIA_COMMAND_SetApcor,
894			  sd->params.apcor.gain1,
895			  sd->params.apcor.gain2,
896			  sd->params.apcor.gain4,
897			  sd->params.apcor.gain8);
898}
899
900static int command_setvloffset(struct gspca_dev *gspca_dev)
901{
902	struct sd *sd = (struct sd *) gspca_dev;
903	return do_command(gspca_dev, CPIA_COMMAND_SetVLOffset,
904			  sd->params.vlOffset.gain1,
905			  sd->params.vlOffset.gain2,
906			  sd->params.vlOffset.gain4,
907			  sd->params.vlOffset.gain8);
908}
909
910static int command_setexposure(struct gspca_dev *gspca_dev)
911{
912	struct sd *sd = (struct sd *) gspca_dev;
913	int ret;
914
915	ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
916				  sd->params.exposure.gainMode,
917				  1,
918				  sd->params.exposure.compMode,
919				  sd->params.exposure.centreWeight,
920				  sd->params.exposure.gain,
921				  sd->params.exposure.fineExp,
922				  sd->params.exposure.coarseExpLo,
923				  sd->params.exposure.coarseExpHi,
924				  sd->params.exposure.redComp,
925				  sd->params.exposure.green1Comp,
926				  sd->params.exposure.green2Comp,
927				  sd->params.exposure.blueComp);
928	if (ret)
929		return ret;
930
931	if (sd->params.exposure.expMode != 1) {
932		ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
933					  0,
934					  sd->params.exposure.expMode,
935					  0, 0,
936					  sd->params.exposure.gain,
937					  sd->params.exposure.fineExp,
938					  sd->params.exposure.coarseExpLo,
939					  sd->params.exposure.coarseExpHi,
940					  0, 0, 0, 0);
941	}
942
943	return ret;
944}
945
946static int command_setcolourbalance(struct gspca_dev *gspca_dev)
947{
948	struct sd *sd = (struct sd *) gspca_dev;
949
950	if (sd->params.colourBalance.balanceMode == 1) {
951		int ret;
952
953		ret = do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
954				 1,
955				 sd->params.colourBalance.redGain,
956				 sd->params.colourBalance.greenGain,
957				 sd->params.colourBalance.blueGain);
958		if (ret)
959			return ret;
960
961		return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
962				  3, 0, 0, 0);
963	}
964	if (sd->params.colourBalance.balanceMode == 2) {
965		return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
966				  2, 0, 0, 0);
967	}
968	if (sd->params.colourBalance.balanceMode == 3) {
969		return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
970				  3, 0, 0, 0);
971	}
972
973	return -EINVAL;
974}
975
976static int command_setcompressiontarget(struct gspca_dev *gspca_dev)
977{
978	struct sd *sd = (struct sd *) gspca_dev;
979
980	return do_command(gspca_dev, CPIA_COMMAND_SetCompressionTarget,
981			  sd->params.compressionTarget.frTargeting,
982			  sd->params.compressionTarget.targetFR,
983			  sd->params.compressionTarget.targetQ, 0);
984}
985
986static int command_setyuvtresh(struct gspca_dev *gspca_dev)
987{
988	struct sd *sd = (struct sd *) gspca_dev;
989
990	return do_command(gspca_dev, CPIA_COMMAND_SetYUVThresh,
991			  sd->params.yuvThreshold.yThreshold,
992			  sd->params.yuvThreshold.uvThreshold, 0, 0);
993}
994
995static int command_setcompressionparams(struct gspca_dev *gspca_dev)
996{
997	struct sd *sd = (struct sd *) gspca_dev;
998
999	return do_command_extended(gspca_dev,
1000			    CPIA_COMMAND_SetCompressionParams,
1001			    0, 0, 0, 0,
1002			    sd->params.compressionParams.hysteresis,
1003			    sd->params.compressionParams.threshMax,
1004			    sd->params.compressionParams.smallStep,
1005			    sd->params.compressionParams.largeStep,
1006			    sd->params.compressionParams.decimationHysteresis,
1007			    sd->params.compressionParams.frDiffStepThresh,
1008			    sd->params.compressionParams.qDiffStepThresh,
1009			    sd->params.compressionParams.decimationThreshMod);
1010}
1011
1012static int command_setcompression(struct gspca_dev *gspca_dev)
1013{
1014	struct sd *sd = (struct sd *) gspca_dev;
1015
1016	return do_command(gspca_dev, CPIA_COMMAND_SetCompression,
1017			  sd->params.compression.mode,
1018			  sd->params.compression.decimation, 0, 0);
1019}
1020
1021static int command_setsensorfps(struct gspca_dev *gspca_dev)
1022{
1023	struct sd *sd = (struct sd *) gspca_dev;
1024
1025	return do_command(gspca_dev, CPIA_COMMAND_SetSensorFPS,
1026			  sd->params.sensorFps.divisor,
1027			  sd->params.sensorFps.baserate, 0, 0);
1028}
1029
1030static int command_setflickerctrl(struct gspca_dev *gspca_dev)
1031{
1032	struct sd *sd = (struct sd *) gspca_dev;
1033
1034	return do_command(gspca_dev, CPIA_COMMAND_SetFlickerCtrl,
1035			  sd->params.flickerControl.flickerMode,
1036			  sd->params.flickerControl.coarseJump,
1037			  sd->params.flickerControl.allowableOverExposure,
1038			  0);
1039}
1040
1041static int command_setecptiming(struct gspca_dev *gspca_dev)
1042{
1043	struct sd *sd = (struct sd *) gspca_dev;
1044
1045	return do_command(gspca_dev, CPIA_COMMAND_SetECPTiming,
1046			  sd->params.ecpTiming, 0, 0, 0);
1047}
1048
1049static int command_pause(struct gspca_dev *gspca_dev)
1050{
1051	return do_command(gspca_dev, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
1052}
1053
1054static int command_resume(struct gspca_dev *gspca_dev)
1055{
1056	struct sd *sd = (struct sd *) gspca_dev;
1057
1058	return do_command(gspca_dev, CPIA_COMMAND_InitStreamCap,
1059			  0, sd->params.streamStartLine, 0, 0);
1060}
1061
1062
1063static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply)
1064{
1065	/* Everything in here is from the Windows driver */
1066/* define for compgain calculation */
1067  /* equivalent functions without floating point math */
1068#define COMPGAIN(base, curexp, newexp) \
1069    (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2 * newexp)))
1070#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1071    (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
1072
1073	struct sd *sd = (struct sd *) gspca_dev;
1074	int currentexp = sd->params.exposure.coarseExpLo +
1075			 sd->params.exposure.coarseExpHi * 256;
1076	int ret, startexp;
1077
1078	if (on) {
1079		int cj = sd->params.flickerControl.coarseJump;
1080		sd->params.flickerControl.flickerMode = 1;
1081		sd->params.flickerControl.disabled = 0;
1082		if (sd->params.exposure.expMode != 2) {
1083			sd->params.exposure.expMode = 2;
1084			sd->exposure_status = EXPOSURE_NORMAL;
1085		}
1086		currentexp = currentexp << sd->params.exposure.gain;
1087		sd->params.exposure.gain = 0;
1088		/* round down current exposure to nearest value */
1089		startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj;
1090		if (startexp < 1)
1091			startexp = 1;
1092		startexp = (startexp * cj) - 1;
1093		if (FIRMWARE_VERSION(1, 2))
1094			while (startexp > MAX_EXP_102)
1095				startexp -= cj;
1096		else
1097			while (startexp > MAX_EXP)
1098				startexp -= cj;
1099		sd->params.exposure.coarseExpLo = startexp & 0xff;
1100		sd->params.exposure.coarseExpHi = startexp >> 8;
1101		if (currentexp > startexp) {
1102			if (currentexp > (2 * startexp))
1103				currentexp = 2 * startexp;
1104			sd->params.exposure.redComp =
1105				COMPGAIN(COMP_RED, currentexp, startexp);
1106			sd->params.exposure.green1Comp =
1107				COMPGAIN(COMP_GREEN1, currentexp, startexp);
1108			sd->params.exposure.green2Comp =
1109				COMPGAIN(COMP_GREEN2, currentexp, startexp);
1110			sd->params.exposure.blueComp =
1111				COMPGAIN(COMP_BLUE, currentexp, startexp);
1112		} else {
1113			sd->params.exposure.redComp = COMP_RED;
1114			sd->params.exposure.green1Comp = COMP_GREEN1;
1115			sd->params.exposure.green2Comp = COMP_GREEN2;
1116			sd->params.exposure.blueComp = COMP_BLUE;
1117		}
1118		if (FIRMWARE_VERSION(1, 2))
1119			sd->params.exposure.compMode = 0;
1120		else
1121			sd->params.exposure.compMode = 1;
1122
1123		sd->params.apcor.gain1 = 0x18;
1124		sd->params.apcor.gain2 = 0x18;
1125		sd->params.apcor.gain4 = 0x16;
1126		sd->params.apcor.gain8 = 0x14;
1127	} else {
1128		sd->params.flickerControl.flickerMode = 0;
1129		sd->params.flickerControl.disabled = 1;
1130		/* Average equivalent coarse for each comp channel */
1131		startexp = EXP_FROM_COMP(COMP_RED,
1132				sd->params.exposure.redComp, currentexp);
1133		startexp += EXP_FROM_COMP(COMP_GREEN1,
1134				sd->params.exposure.green1Comp, currentexp);
1135		startexp += EXP_FROM_COMP(COMP_GREEN2,
1136				sd->params.exposure.green2Comp, currentexp);
1137		startexp += EXP_FROM_COMP(COMP_BLUE,
1138				sd->params.exposure.blueComp, currentexp);
1139		startexp = startexp >> 2;
1140		while (startexp > MAX_EXP && sd->params.exposure.gain <
1141		       sd->params.exposure.gainMode - 1) {
1142			startexp = startexp >> 1;
1143			++sd->params.exposure.gain;
1144		}
1145		if (FIRMWARE_VERSION(1, 2) && startexp > MAX_EXP_102)
1146			startexp = MAX_EXP_102;
1147		if (startexp > MAX_EXP)
1148			startexp = MAX_EXP;
1149		sd->params.exposure.coarseExpLo = startexp & 0xff;
1150		sd->params.exposure.coarseExpHi = startexp >> 8;
1151		sd->params.exposure.redComp = COMP_RED;
1152		sd->params.exposure.green1Comp = COMP_GREEN1;
1153		sd->params.exposure.green2Comp = COMP_GREEN2;
1154		sd->params.exposure.blueComp = COMP_BLUE;
1155		sd->params.exposure.compMode = 1;
1156		sd->params.apcor.gain1 = 0x18;
1157		sd->params.apcor.gain2 = 0x16;
1158		sd->params.apcor.gain4 = 0x24;
1159		sd->params.apcor.gain8 = 0x34;
1160	}
1161	sd->params.vlOffset.gain1 = 20;
1162	sd->params.vlOffset.gain2 = 24;
1163	sd->params.vlOffset.gain4 = 26;
1164	sd->params.vlOffset.gain8 = 26;
1165
1166	if (apply) {
1167		ret = command_setexposure(gspca_dev);
1168		if (ret)
1169			return ret;
1170
1171		ret = command_setapcor(gspca_dev);
1172		if (ret)
1173			return ret;
1174
1175		ret = command_setvloffset(gspca_dev);
1176		if (ret)
1177			return ret;
1178
1179		ret = command_setflickerctrl(gspca_dev);
1180		if (ret)
1181			return ret;
1182	}
1183
1184	return 0;
1185#undef EXP_FROM_COMP
1186#undef COMPGAIN
1187}
1188
1189/* monitor the exposure and adjust the sensor frame rate if needed */
1190static void monitor_exposure(struct gspca_dev *gspca_dev)
1191{
1192	struct sd *sd = (struct sd *) gspca_dev;
1193	u8 exp_acc, bcomp, gain, coarseL, cmd[8];
1194	int ret, light_exp, dark_exp, very_dark_exp;
1195	int old_exposure, new_exposure, framerate;
1196	int setfps = 0, setexp = 0, setflicker = 0;
1197
1198	/* get necessary stats and register settings from camera */
1199	/* do_command can't handle this, so do it ourselves */
1200	cmd[0] = CPIA_COMMAND_ReadVPRegs >> 8;
1201	cmd[1] = CPIA_COMMAND_ReadVPRegs & 0xff;
1202	cmd[2] = 30;
1203	cmd[3] = 4;
1204	cmd[4] = 9;
1205	cmd[5] = 8;
1206	cmd[6] = 8;
1207	cmd[7] = 0;
1208	ret = cpia_usb_transferCmd(gspca_dev, cmd);
1209	if (ret) {
1210		PDEBUG(D_ERR, "ReadVPRegs(30,4,9,8) - failed: %d", ret);
1211		return;
1212	}
1213	exp_acc = gspca_dev->usb_buf[0];
1214	bcomp = gspca_dev->usb_buf[1];
1215	gain = gspca_dev->usb_buf[2];
1216	coarseL = gspca_dev->usb_buf[3];
1217
1218	light_exp = sd->params.colourParams.brightness +
1219		    TC - 50 + EXP_ACC_LIGHT;
1220	if (light_exp > 255)
1221		light_exp = 255;
1222	dark_exp = sd->params.colourParams.brightness +
1223		   TC - 50 - EXP_ACC_DARK;
1224	if (dark_exp < 0)
1225		dark_exp = 0;
1226	very_dark_exp = dark_exp / 2;
1227
1228	old_exposure = sd->params.exposure.coarseExpHi * 256 +
1229		       sd->params.exposure.coarseExpLo;
1230
1231	if (!sd->params.flickerControl.disabled) {
1232		/* Flicker control on */
1233		int max_comp = FIRMWARE_VERSION(1, 2) ? MAX_COMP :
1234							HIGH_COMP_102;
1235		bcomp += 128;	/* decode */
1236		if (bcomp >= max_comp && exp_acc < dark_exp) {
1237			/* dark */
1238			if (exp_acc < very_dark_exp) {
1239				/* very dark */
1240				if (sd->exposure_status == EXPOSURE_VERY_DARK)
1241					++sd->exposure_count;
1242				else {
1243					sd->exposure_status =
1244						EXPOSURE_VERY_DARK;
1245					sd->exposure_count = 1;
1246				}
1247			} else {
1248				/* just dark */
1249				if (sd->exposure_status == EXPOSURE_DARK)
1250					++sd->exposure_count;
1251				else {
1252					sd->exposure_status = EXPOSURE_DARK;
1253					sd->exposure_count = 1;
1254				}
1255			}
1256		} else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1257			/* light */
1258			if (old_exposure <= VERY_LOW_EXP) {
1259				/* very light */
1260				if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1261					++sd->exposure_count;
1262				else {
1263					sd->exposure_status =
1264						EXPOSURE_VERY_LIGHT;
1265					sd->exposure_count = 1;
1266				}
1267			} else {
1268				/* just light */
1269				if (sd->exposure_status == EXPOSURE_LIGHT)
1270					++sd->exposure_count;
1271				else {
1272					sd->exposure_status = EXPOSURE_LIGHT;
1273					sd->exposure_count = 1;
1274				}
1275			}
1276		} else {
1277			/* not dark or light */
1278			sd->exposure_status = EXPOSURE_NORMAL;
1279		}
1280	} else {
1281		/* Flicker control off */
1282		if (old_exposure >= MAX_EXP && exp_acc < dark_exp) {
1283			/* dark */
1284			if (exp_acc < very_dark_exp) {
1285				/* very dark */
1286				if (sd->exposure_status == EXPOSURE_VERY_DARK)
1287					++sd->exposure_count;
1288				else {
1289					sd->exposure_status =
1290						EXPOSURE_VERY_DARK;
1291					sd->exposure_count = 1;
1292				}
1293			} else {
1294				/* just dark */
1295				if (sd->exposure_status == EXPOSURE_DARK)
1296					++sd->exposure_count;
1297				else {
1298					sd->exposure_status = EXPOSURE_DARK;
1299					sd->exposure_count = 1;
1300				}
1301			}
1302		} else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1303			/* light */
1304			if (old_exposure <= VERY_LOW_EXP) {
1305				/* very light */
1306				if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1307					++sd->exposure_count;
1308				else {
1309					sd->exposure_status =
1310						EXPOSURE_VERY_LIGHT;
1311					sd->exposure_count = 1;
1312				}
1313			} else {
1314				/* just light */
1315				if (sd->exposure_status == EXPOSURE_LIGHT)
1316					++sd->exposure_count;
1317				else {
1318					sd->exposure_status = EXPOSURE_LIGHT;
1319					sd->exposure_count = 1;
1320				}
1321			}
1322		} else {
1323			/* not dark or light */
1324			sd->exposure_status = EXPOSURE_NORMAL;
1325		}
1326	}
1327
1328	framerate = atomic_read(&sd->fps);
1329	if (framerate > 30 || framerate < 1)
1330		framerate = 1;
1331
1332	if (!sd->params.flickerControl.disabled) {
1333		/* Flicker control on */
1334		if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1335		     sd->exposure_status == EXPOSURE_DARK) &&
1336		    sd->exposure_count >= DARK_TIME * framerate &&
1337		    sd->params.sensorFps.divisor < 3) {
1338
1339			/* dark for too long */
1340			++sd->params.sensorFps.divisor;
1341			setfps = 1;
1342
1343			sd->params.flickerControl.coarseJump =
1344				flicker_jumps[sd->mainsFreq]
1345					     [sd->params.sensorFps.baserate]
1346					     [sd->params.sensorFps.divisor];
1347			setflicker = 1;
1348
1349			new_exposure = sd->params.flickerControl.coarseJump-1;
1350			while (new_exposure < old_exposure / 2)
1351				new_exposure +=
1352					sd->params.flickerControl.coarseJump;
1353			sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1354			sd->params.exposure.coarseExpHi = new_exposure >> 8;
1355			setexp = 1;
1356			sd->exposure_status = EXPOSURE_NORMAL;
1357			PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
1358
1359		} else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1360			    sd->exposure_status == EXPOSURE_LIGHT) &&
1361			   sd->exposure_count >= LIGHT_TIME * framerate &&
1362			   sd->params.sensorFps.divisor > 0) {
1363
1364			/* light for too long */
1365			int max_exp = FIRMWARE_VERSION(1, 2) ? MAX_EXP_102 :
1366							       MAX_EXP;
1367			--sd->params.sensorFps.divisor;
1368			setfps = 1;
1369
1370			sd->params.flickerControl.coarseJump =
1371				flicker_jumps[sd->mainsFreq]
1372					     [sd->params.sensorFps.baserate]
1373					     [sd->params.sensorFps.divisor];
1374			setflicker = 1;
1375
1376			new_exposure = sd->params.flickerControl.coarseJump-1;
1377			while (new_exposure < 2 * old_exposure &&
1378			       new_exposure +
1379			       sd->params.flickerControl.coarseJump < max_exp)
1380				new_exposure +=
1381					sd->params.flickerControl.coarseJump;
1382			sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1383			sd->params.exposure.coarseExpHi = new_exposure >> 8;
1384			setexp = 1;
1385			sd->exposure_status = EXPOSURE_NORMAL;
1386			PDEBUG(D_CONF, "Automatically increasing sensor_fps");
1387		}
1388	} else {
1389		/* Flicker control off */
1390		if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1391		     sd->exposure_status == EXPOSURE_DARK) &&
1392		    sd->exposure_count >= DARK_TIME * framerate &&
1393		    sd->params.sensorFps.divisor < 3) {
1394
1395			/* dark for too long */
1396			++sd->params.sensorFps.divisor;
1397			setfps = 1;
1398
1399			if (sd->params.exposure.gain > 0) {
1400				--sd->params.exposure.gain;
1401				setexp = 1;
1402			}
1403			sd->exposure_status = EXPOSURE_NORMAL;
1404			PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
1405
1406		} else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1407			    sd->exposure_status == EXPOSURE_LIGHT) &&
1408			   sd->exposure_count >= LIGHT_TIME * framerate &&
1409			   sd->params.sensorFps.divisor > 0) {
1410
1411			/* light for too long */
1412			--sd->params.sensorFps.divisor;
1413			setfps = 1;
1414
1415			if (sd->params.exposure.gain <
1416			    sd->params.exposure.gainMode - 1) {
1417				++sd->params.exposure.gain;
1418				setexp = 1;
1419			}
1420			sd->exposure_status = EXPOSURE_NORMAL;
1421			PDEBUG(D_CONF, "Automatically increasing sensor_fps");
1422		}
1423	}
1424
1425	if (setexp)
1426		command_setexposure(gspca_dev);
1427
1428	if (setfps)
1429		command_setsensorfps(gspca_dev);
1430
1431	if (setflicker)
1432		command_setflickerctrl(gspca_dev);
1433}
1434
1435/*-----------------------------------------------------------------*/
1436/* if flicker is switched off, this function switches it back on.It checks,
1437   however, that conditions are suitable before restarting it.
1438   This should only be called for firmware version 1.2.
1439
1440   It also adjust the colour balance when an exposure step is detected - as
1441   long as flicker is running
1442*/
1443static void restart_flicker(struct gspca_dev *gspca_dev)
1444{
1445	struct sd *sd = (struct sd *) gspca_dev;
1446	int cam_exposure, old_exp;
1447
1448	if (!FIRMWARE_VERSION(1, 2))
1449		return;
1450
1451	cam_exposure = atomic_read(&sd->cam_exposure);
1452
1453	if (sd->params.flickerControl.flickerMode == 0 ||
1454	    cam_exposure == 0)
1455		return;
1456
1457	old_exp = sd->params.exposure.coarseExpLo +
1458		  sd->params.exposure.coarseExpHi*256;
1459	/*
1460	  see how far away camera exposure is from a valid
1461	  flicker exposure value
1462	*/
1463	cam_exposure %= sd->params.flickerControl.coarseJump;
1464	if (!sd->params.flickerControl.disabled &&
1465	    cam_exposure <= sd->params.flickerControl.coarseJump - 3) {
1466		/* Flicker control auto-disabled */
1467		sd->params.flickerControl.disabled = 1;
1468	}
1469
1470	if (sd->params.flickerControl.disabled &&
1471	    old_exp > sd->params.flickerControl.coarseJump +
1472		      ROUND_UP_EXP_FOR_FLICKER) {
1473		/* exposure is now high enough to switch
1474		   flicker control back on */
1475		set_flicker(gspca_dev, 1, 1);
1476	}
1477}
1478
1479/* this function is called at probe time */
1480static int sd_config(struct gspca_dev *gspca_dev,
1481			const struct usb_device_id *id)
1482{
1483	struct cam *cam;
1484
1485	reset_camera_params(gspca_dev);
1486
1487	PDEBUG(D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)",
1488	       id->idVendor, id->idProduct);
1489
1490	cam = &gspca_dev->cam;
1491	cam->cam_mode = mode;
1492	cam->nmodes = ARRAY_SIZE(mode);
1493
1494	sd_setfreq(gspca_dev, FREQ_DEF);
1495
1496	return 0;
1497}
1498
1499/* -- start the camera -- */
1500static int sd_start(struct gspca_dev *gspca_dev)
1501{
1502	struct sd *sd = (struct sd *) gspca_dev;
1503	int priv, ret;
1504
1505	/* Start the camera in low power mode */
1506	if (goto_low_power(gspca_dev)) {
1507		if (sd->params.status.systemState != WARM_BOOT_STATE) {
1508			PDEBUG(D_ERR, "unexpected systemstate: %02x",
1509			       sd->params.status.systemState);
1510			printstatus(&sd->params);
1511			return -ENODEV;
1512		}
1513
1514		ret = goto_high_power(gspca_dev);
1515		if (ret)
1516			return ret;
1517
1518		ret = do_command(gspca_dev, CPIA_COMMAND_DiscardFrame,
1519				 0, 0, 0, 0);
1520		if (ret)
1521			return ret;
1522
1523		ret = goto_low_power(gspca_dev);
1524		if (ret)
1525			return ret;
1526	}
1527
1528	/* procedure described in developer's guide p3-28 */
1529
1530	/* Check the firmware version. */
1531	sd->params.version.firmwareVersion = 0;
1532	get_version_information(gspca_dev);
1533	if (sd->params.version.firmwareVersion != 1) {
1534		PDEBUG(D_ERR, "only firmware version 1 is supported (got: %d)",
1535		       sd->params.version.firmwareVersion);
1536		return -ENODEV;
1537	}
1538
1539	/* A bug in firmware 1-02 limits gainMode to 2 */
1540	if (sd->params.version.firmwareRevision <= 2 &&
1541	    sd->params.exposure.gainMode > 2) {
1542		sd->params.exposure.gainMode = 2;
1543	}
1544
1545	/* set QX3 detected flag */
1546	sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 &&
1547				       sd->params.pnpID.product == 0x0001);
1548
1549	/* The fatal error checking should be done after
1550	 * the camera powers up (developer's guide p 3-38) */
1551
1552	/* Set streamState before transition to high power to avoid bug
1553	 * in firmware 1-02 */
1554	ret = do_command(gspca_dev, CPIA_COMMAND_ModifyCameraStatus,
1555			 STREAMSTATE, 0, STREAM_NOT_READY, 0);
1556	if (ret)
1557		return ret;
1558
1559	/* GotoHiPower */
1560	ret = goto_high_power(gspca_dev);
1561	if (ret)
1562		return ret;
1563
1564	/* Check the camera status */
1565	ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1566	if (ret)
1567		return ret;
1568
1569	if (sd->params.status.fatalError) {
1570		PDEBUG(D_ERR, "fatal_error: %04x, vp_status: %04x",
1571		       sd->params.status.fatalError,
1572		       sd->params.status.vpStatus);
1573		return -EIO;
1574	}
1575
1576	/* VPVersion can't be retrieved before the camera is in HiPower,
1577	 * so get it here instead of in get_version_information. */
1578	ret = do_command(gspca_dev, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0);
1579	if (ret)
1580		return ret;
1581
1582	/* Determine video mode settings */
1583	sd->params.streamStartLine = 120;
1584
1585	priv = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1586	if (priv & 0x01) { /* crop */
1587		sd->params.roi.colStart = 2;
1588		sd->params.roi.rowStart = 6;
1589	} else {
1590		sd->params.roi.colStart = 0;
1591		sd->params.roi.rowStart = 0;
1592	}
1593
1594	if (priv & 0x02) { /* quarter */
1595		sd->params.format.videoSize = VIDEOSIZE_QCIF;
1596		sd->params.roi.colStart /= 2;
1597		sd->params.roi.rowStart /= 2;
1598		sd->params.streamStartLine /= 2;
1599	} else
1600		sd->params.format.videoSize = VIDEOSIZE_CIF;
1601
1602	sd->params.roi.colEnd = sd->params.roi.colStart +
1603				(gspca_dev->width >> 3);
1604	sd->params.roi.rowEnd = sd->params.roi.rowStart +
1605				(gspca_dev->height >> 2);
1606
1607	/* And now set the camera to a known state */
1608	ret = do_command(gspca_dev, CPIA_COMMAND_SetGrabMode,
1609			 CPIA_GRAB_CONTINEOUS, 0, 0, 0);
1610	if (ret)
1611		return ret;
1612	/* We start with compression disabled, as we need one uncompressed
1613	   frame to handle later compressed frames */
1614	ret = do_command(gspca_dev, CPIA_COMMAND_SetCompression,
1615			 CPIA_COMPRESSION_NONE,
1616			 NO_DECIMATION, 0, 0);
1617	if (ret)
1618		return ret;
1619	ret = command_setcompressiontarget(gspca_dev);
1620	if (ret)
1621		return ret;
1622	ret = command_setcolourparams(gspca_dev);
1623	if (ret)
1624		return ret;
1625	ret = command_setformat(gspca_dev);
1626	if (ret)
1627		return ret;
1628	ret = command_setyuvtresh(gspca_dev);
1629	if (ret)
1630		return ret;
1631	ret = command_setecptiming(gspca_dev);
1632	if (ret)
1633		return ret;
1634	ret = command_setcompressionparams(gspca_dev);
1635	if (ret)
1636		return ret;
1637	ret = command_setexposure(gspca_dev);
1638	if (ret)
1639		return ret;
1640	ret = command_setcolourbalance(gspca_dev);
1641	if (ret)
1642		return ret;
1643	ret = command_setsensorfps(gspca_dev);
1644	if (ret)
1645		return ret;
1646	ret = command_setapcor(gspca_dev);
1647	if (ret)
1648		return ret;
1649	ret = command_setflickerctrl(gspca_dev);
1650	if (ret)
1651		return ret;
1652	ret = command_setvloffset(gspca_dev);
1653	if (ret)
1654		return ret;
1655
1656	/* Start stream */
1657	ret = command_resume(gspca_dev);
1658	if (ret)
1659		return ret;
1660
1661	/* Wait 6 frames before turning compression on for the sensor to get
1662	   all settings and AEC/ACB to settle */
1663	sd->first_frame = 6;
1664	sd->exposure_status = EXPOSURE_NORMAL;
1665	sd->exposure_count = 0;
1666	atomic_set(&sd->cam_exposure, 0);
1667	atomic_set(&sd->fps, 0);
1668
1669	return 0;
1670}
1671
1672static void sd_stopN(struct gspca_dev *gspca_dev)
1673{
1674	command_pause(gspca_dev);
1675
1676	/* save camera state for later open (developers guide ch 3.5.3) */
1677	save_camera_state(gspca_dev);
1678
1679	/* GotoLoPower */
1680	goto_low_power(gspca_dev);
1681
1682	/* Update the camera status */
1683	do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1684}
1685
1686/* this function is called at probe and resume time */
1687static int sd_init(struct gspca_dev *gspca_dev)
1688{
1689	struct sd *sd = (struct sd *) gspca_dev;
1690	int ret;
1691
1692	/* Start / Stop the camera to make sure we are talking to
1693	   a supported camera, and to get some information from it
1694	   to print. */
1695	ret = sd_start(gspca_dev);
1696	if (ret)
1697		return ret;
1698
1699	sd_stopN(gspca_dev);
1700
1701	PDEBUG(D_PROBE, "CPIA Version:             %d.%02d (%d.%d)",
1702			sd->params.version.firmwareVersion,
1703			sd->params.version.firmwareRevision,
1704			sd->params.version.vcVersion,
1705			sd->params.version.vcRevision);
1706	PDEBUG(D_PROBE, "CPIA PnP-ID:              %04x:%04x:%04x",
1707			sd->params.pnpID.vendor, sd->params.pnpID.product,
1708			sd->params.pnpID.deviceRevision);
1709	PDEBUG(D_PROBE, "VP-Version:               %d.%d %04x",
1710			sd->params.vpVersion.vpVersion,
1711			sd->params.vpVersion.vpRevision,
1712			sd->params.vpVersion.cameraHeadID);
1713
1714	return 0;
1715}
1716
1717static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1718			u8 *data,
1719			int len)
1720{
1721	struct sd *sd = (struct sd *) gspca_dev;
1722
1723	/* Check for SOF */
1724	if (len >= 64 &&
1725	    data[0] == MAGIC_0 && data[1] == MAGIC_1 &&
1726	    data[16] == sd->params.format.videoSize &&
1727	    data[17] == sd->params.format.subSample &&
1728	    data[18] == sd->params.format.yuvOrder &&
1729	    data[24] == sd->params.roi.colStart &&
1730	    data[25] == sd->params.roi.colEnd &&
1731	    data[26] == sd->params.roi.rowStart &&
1732	    data[27] == sd->params.roi.rowEnd) {
1733		u8 *image;
1734
1735		atomic_set(&sd->cam_exposure, data[39] * 2);
1736		atomic_set(&sd->fps, data[41]);
1737
1738		/* Check for proper EOF for last frame */
1739		image = gspca_dev->image;
1740		if (image != NULL &&
1741		    gspca_dev->image_len > 4 &&
1742		    image[gspca_dev->image_len - 4] == 0xff &&
1743		    image[gspca_dev->image_len - 3] == 0xff &&
1744		    image[gspca_dev->image_len - 2] == 0xff &&
1745		    image[gspca_dev->image_len - 1] == 0xff)
1746			gspca_frame_add(gspca_dev, LAST_PACKET,
1747						NULL, 0);
1748
1749		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
1750		return;
1751	}
1752
1753	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1754}
1755
1756static void sd_dq_callback(struct gspca_dev *gspca_dev)
1757{
1758	struct sd *sd = (struct sd *) gspca_dev;
1759
1760	/* Set the normal compression settings once we have captured a
1761	   few uncompressed frames (and AEC has hopefully settled) */
1762	if (sd->first_frame) {
1763		sd->first_frame--;
1764		if (sd->first_frame == 0)
1765			command_setcompression(gspca_dev);
1766	}
1767
1768	/* Switch flicker control back on if it got turned off */
1769	restart_flicker(gspca_dev);
1770
1771	/* If AEC is enabled, monitor the exposure and
1772	   adjust the sensor frame rate if needed */
1773	if (sd->params.exposure.expMode == 2)
1774		monitor_exposure(gspca_dev);
1775
1776	/* Update our knowledge of the camera state */
1777	do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
1778	if (sd->params.qx3.qx3_detected)
1779		do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
1780}
1781
1782static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1783{
1784	struct sd *sd = (struct sd *) gspca_dev;
1785	int ret;
1786
1787	sd->params.colourParams.brightness = val;
1788	sd->params.flickerControl.allowableOverExposure =
1789		find_over_exposure(sd->params.colourParams.brightness);
1790	if (gspca_dev->streaming) {
1791		ret = command_setcolourparams(gspca_dev);
1792		if (ret)
1793			return ret;
1794		return command_setflickerctrl(gspca_dev);
1795	}
1796	return 0;
1797}
1798
1799static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1800{
1801	struct sd *sd = (struct sd *) gspca_dev;
1802
1803	*val = sd->params.colourParams.brightness;
1804	return 0;
1805}
1806
1807static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1808{
1809	struct sd *sd = (struct sd *) gspca_dev;
1810
1811	sd->params.colourParams.contrast = val;
1812	if (gspca_dev->streaming)
1813		return command_setcolourparams(gspca_dev);
1814
1815	return 0;
1816}
1817
1818static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1819{
1820	struct sd *sd = (struct sd *) gspca_dev;
1821
1822	*val = sd->params.colourParams.contrast;
1823	return 0;
1824}
1825
1826static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val)
1827{
1828	struct sd *sd = (struct sd *) gspca_dev;
1829
1830	sd->params.colourParams.saturation = val;
1831	if (gspca_dev->streaming)
1832		return command_setcolourparams(gspca_dev);
1833
1834	return 0;
1835}
1836
1837static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val)
1838{
1839	struct sd *sd = (struct sd *) gspca_dev;
1840
1841	*val = sd->params.colourParams.saturation;
1842	return 0;
1843}
1844
1845static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1846{
1847	struct sd *sd = (struct sd *) gspca_dev;
1848	int on;
1849
1850	switch (val) {
1851	case 0:		/* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1852		on = 0;
1853		break;
1854	case 1:		/* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1855		on = 1;
1856		sd->mainsFreq = 0;
1857		break;
1858	case 2:		/* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1859		on = 1;
1860		sd->mainsFreq = 1;
1861		break;
1862	default:
1863		return -EINVAL;
1864	}
1865
1866	sd->freq = val;
1867	sd->params.flickerControl.coarseJump =
1868		flicker_jumps[sd->mainsFreq]
1869			     [sd->params.sensorFps.baserate]
1870			     [sd->params.sensorFps.divisor];
1871
1872	return set_flicker(gspca_dev, on, gspca_dev->streaming);
1873}
1874
1875static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1876{
1877	struct sd *sd = (struct sd *) gspca_dev;
1878
1879	*val = sd->freq;
1880	return 0;
1881}
1882
1883static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val)
1884{
1885	struct sd *sd = (struct sd *) gspca_dev;
1886
1887	sd->params.compressionTarget.frTargeting = val;
1888	if (gspca_dev->streaming)
1889		return command_setcompressiontarget(gspca_dev);
1890
1891	return 0;
1892}
1893
1894static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val)
1895{
1896	struct sd *sd = (struct sd *) gspca_dev;
1897
1898	*val = sd->params.compressionTarget.frTargeting;
1899	return 0;
1900}
1901
1902static int sd_querymenu(struct gspca_dev *gspca_dev,
1903			struct v4l2_querymenu *menu)
1904{
1905	switch (menu->id) {
1906	case V4L2_CID_POWER_LINE_FREQUENCY:
1907		switch (menu->index) {
1908		case 0:		/* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1909			strcpy((char *) menu->name, "NoFliker");
1910			return 0;
1911		case 1:		/* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1912			strcpy((char *) menu->name, "50 Hz");
1913			return 0;
1914		case 2:		/* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1915			strcpy((char *) menu->name, "60 Hz");
1916			return 0;
1917		}
1918		break;
1919	case V4L2_CID_COMP_TARGET:
1920		switch (menu->index) {
1921		case CPIA_COMPRESSION_TARGET_QUALITY:
1922			strcpy((char *) menu->name, "Quality");
1923			return 0;
1924		case CPIA_COMPRESSION_TARGET_FRAMERATE:
1925			strcpy((char *) menu->name, "Framerate");
1926			return 0;
1927		}
1928		break;
1929	}
1930	return -EINVAL;
1931}
1932
1933/* sub-driver description */
1934static const struct sd_desc sd_desc = {
1935	.name = MODULE_NAME,
1936	.ctrls = sd_ctrls,
1937	.nctrls = ARRAY_SIZE(sd_ctrls),
1938	.config = sd_config,
1939	.init = sd_init,
1940	.start = sd_start,
1941	.stopN = sd_stopN,
1942	.dq_callback = sd_dq_callback,
1943	.pkt_scan = sd_pkt_scan,
1944	.querymenu = sd_querymenu,
1945};
1946
1947/* -- module initialisation -- */
1948static const __devinitdata struct usb_device_id device_table[] = {
1949	{USB_DEVICE(0x0553, 0x0002)},
1950	{USB_DEVICE(0x0813, 0x0001)},
1951	{}
1952};
1953MODULE_DEVICE_TABLE(usb, device_table);
1954
1955/* -- device connect -- */
1956static int sd_probe(struct usb_interface *intf,
1957			const struct usb_device_id *id)
1958{
1959	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1960				THIS_MODULE);
1961}
1962
1963static struct usb_driver sd_driver = {
1964	.name = MODULE_NAME,
1965	.id_table = device_table,
1966	.probe = sd_probe,
1967	.disconnect = gspca_disconnect,
1968#ifdef CONFIG_PM
1969	.suspend = gspca_suspend,
1970	.resume = gspca_resume,
1971#endif
1972};
1973
1974/* -- module insert / remove -- */
1975static int __init sd_mod_init(void)
1976{
1977	int ret;
1978	ret = usb_register(&sd_driver);
1979	if (ret < 0)
1980		return ret;
1981	PDEBUG(D_PROBE, "registered");
1982	return 0;
1983}
1984static void __exit sd_mod_exit(void)
1985{
1986	usb_deregister(&sd_driver);
1987	PDEBUG(D_PROBE, "deregistered");
1988}
1989
1990module_init(sd_mod_init);
1991module_exit(sd_mod_exit);
1992