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