xref: /openbmc/linux/drivers/media/usb/gspca/cpia1.c (revision 3213486f)
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 		gspca_err(gspca_dev, "Unexpected first byte of command: %x\n",
423 			  command[0]);
424 		return -EINVAL;
425 	}
426 
427 retry:
428 	ret = usb_control_msg(gspca_dev->dev, pipe,
429 			      command[1],
430 			      requesttype,
431 			      command[2] | (command[3] << 8),
432 			      command[4] | (command[5] << 8),
433 			      gspca_dev->usb_buf, databytes, 1000);
434 
435 	if (ret < 0)
436 		pr_err("usb_control_msg %02x, error %d\n", command[1], ret);
437 
438 	if (ret == -EPIPE && retries > 0) {
439 		retries--;
440 		goto retry;
441 	}
442 
443 	return (ret < 0) ? ret : 0;
444 }
445 
446 /* send an arbitrary command to the camera */
447 static int do_command(struct gspca_dev *gspca_dev, u16 command,
448 		      u8 a, u8 b, u8 c, u8 d)
449 {
450 	struct sd *sd = (struct sd *) gspca_dev;
451 	int ret, datasize;
452 	u8 cmd[8];
453 
454 	switch (command) {
455 	case CPIA_COMMAND_GetCPIAVersion:
456 	case CPIA_COMMAND_GetPnPID:
457 	case CPIA_COMMAND_GetCameraStatus:
458 	case CPIA_COMMAND_GetVPVersion:
459 	case CPIA_COMMAND_GetColourParams:
460 	case CPIA_COMMAND_GetColourBalance:
461 	case CPIA_COMMAND_GetExposure:
462 		datasize = 8;
463 		break;
464 	case CPIA_COMMAND_ReadMCPorts:
465 	case CPIA_COMMAND_ReadVCRegs:
466 		datasize = 4;
467 		break;
468 	default:
469 		datasize = 0;
470 		break;
471 	}
472 
473 	cmd[0] = command >> 8;
474 	cmd[1] = command & 0xff;
475 	cmd[2] = a;
476 	cmd[3] = b;
477 	cmd[4] = c;
478 	cmd[5] = d;
479 	cmd[6] = datasize;
480 	cmd[7] = 0;
481 
482 	ret = cpia_usb_transferCmd(gspca_dev, cmd);
483 	if (ret)
484 		return ret;
485 
486 	switch (command) {
487 	case CPIA_COMMAND_GetCPIAVersion:
488 		sd->params.version.firmwareVersion = gspca_dev->usb_buf[0];
489 		sd->params.version.firmwareRevision = gspca_dev->usb_buf[1];
490 		sd->params.version.vcVersion = gspca_dev->usb_buf[2];
491 		sd->params.version.vcRevision = gspca_dev->usb_buf[3];
492 		break;
493 	case CPIA_COMMAND_GetPnPID:
494 		sd->params.pnpID.vendor =
495 			gspca_dev->usb_buf[0] | (gspca_dev->usb_buf[1] << 8);
496 		sd->params.pnpID.product =
497 			gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
498 		sd->params.pnpID.deviceRevision =
499 			gspca_dev->usb_buf[4] | (gspca_dev->usb_buf[5] << 8);
500 		break;
501 	case CPIA_COMMAND_GetCameraStatus:
502 		sd->params.status.systemState = gspca_dev->usb_buf[0];
503 		sd->params.status.grabState = gspca_dev->usb_buf[1];
504 		sd->params.status.streamState = gspca_dev->usb_buf[2];
505 		sd->params.status.fatalError = gspca_dev->usb_buf[3];
506 		sd->params.status.cmdError = gspca_dev->usb_buf[4];
507 		sd->params.status.debugFlags = gspca_dev->usb_buf[5];
508 		sd->params.status.vpStatus = gspca_dev->usb_buf[6];
509 		sd->params.status.errorCode = gspca_dev->usb_buf[7];
510 		break;
511 	case CPIA_COMMAND_GetVPVersion:
512 		sd->params.vpVersion.vpVersion = gspca_dev->usb_buf[0];
513 		sd->params.vpVersion.vpRevision = gspca_dev->usb_buf[1];
514 		sd->params.vpVersion.cameraHeadID =
515 			gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
516 		break;
517 	case CPIA_COMMAND_GetColourParams:
518 		sd->params.colourParams.brightness = gspca_dev->usb_buf[0];
519 		sd->params.colourParams.contrast = gspca_dev->usb_buf[1];
520 		sd->params.colourParams.saturation = gspca_dev->usb_buf[2];
521 		break;
522 	case CPIA_COMMAND_GetColourBalance:
523 		sd->params.colourBalance.redGain = gspca_dev->usb_buf[0];
524 		sd->params.colourBalance.greenGain = gspca_dev->usb_buf[1];
525 		sd->params.colourBalance.blueGain = gspca_dev->usb_buf[2];
526 		break;
527 	case CPIA_COMMAND_GetExposure:
528 		sd->params.exposure.gain = gspca_dev->usb_buf[0];
529 		sd->params.exposure.fineExp = gspca_dev->usb_buf[1];
530 		sd->params.exposure.coarseExpLo = gspca_dev->usb_buf[2];
531 		sd->params.exposure.coarseExpHi = gspca_dev->usb_buf[3];
532 		sd->params.exposure.redComp = gspca_dev->usb_buf[4];
533 		sd->params.exposure.green1Comp = gspca_dev->usb_buf[5];
534 		sd->params.exposure.green2Comp = gspca_dev->usb_buf[6];
535 		sd->params.exposure.blueComp = gspca_dev->usb_buf[7];
536 		break;
537 
538 	case CPIA_COMMAND_ReadMCPorts:
539 		/* test button press */
540 		a = ((gspca_dev->usb_buf[1] & 0x02) == 0);
541 		if (a != sd->params.qx3.button) {
542 #if IS_ENABLED(CONFIG_INPUT)
543 			input_report_key(gspca_dev->input_dev, KEY_CAMERA, a);
544 			input_sync(gspca_dev->input_dev);
545 #endif
546 			sd->params.qx3.button = a;
547 		}
548 		if (sd->params.qx3.button) {
549 			/* button pressed - unlock the latch */
550 			ret = do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
551 				   3, 0xdf, 0xdf, 0);
552 			if (ret)
553 				return ret;
554 			ret = do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
555 				   3, 0xff, 0xff, 0);
556 			if (ret)
557 				return ret;
558 		}
559 
560 		/* test whether microscope is cradled */
561 		sd->params.qx3.cradled = ((gspca_dev->usb_buf[2] & 0x40) == 0);
562 		break;
563 	}
564 
565 	return 0;
566 }
567 
568 /* send a command to the camera with an additional data transaction */
569 static int do_command_extended(struct gspca_dev *gspca_dev, u16 command,
570 			       u8 a, u8 b, u8 c, u8 d,
571 			       u8 e, u8 f, u8 g, u8 h,
572 			       u8 i, u8 j, u8 k, u8 l)
573 {
574 	u8 cmd[8];
575 
576 	cmd[0] = command >> 8;
577 	cmd[1] = command & 0xff;
578 	cmd[2] = a;
579 	cmd[3] = b;
580 	cmd[4] = c;
581 	cmd[5] = d;
582 	cmd[6] = 8;
583 	cmd[7] = 0;
584 	gspca_dev->usb_buf[0] = e;
585 	gspca_dev->usb_buf[1] = f;
586 	gspca_dev->usb_buf[2] = g;
587 	gspca_dev->usb_buf[3] = h;
588 	gspca_dev->usb_buf[4] = i;
589 	gspca_dev->usb_buf[5] = j;
590 	gspca_dev->usb_buf[6] = k;
591 	gspca_dev->usb_buf[7] = l;
592 
593 	return cpia_usb_transferCmd(gspca_dev, cmd);
594 }
595 
596 /*  find_over_exposure
597  *  Finds a suitable value of OverExposure for use with SetFlickerCtrl
598  *  Some calculation is required because this value changes with the brightness
599  *  set with SetColourParameters
600  *
601  *  Parameters: Brightness - last brightness value set with SetColourParameters
602  *
603  *  Returns: OverExposure value to use with SetFlickerCtrl
604  */
605 #define FLICKER_MAX_EXPOSURE                    250
606 #define FLICKER_ALLOWABLE_OVER_EXPOSURE         146
607 #define FLICKER_BRIGHTNESS_CONSTANT             59
608 static int find_over_exposure(int brightness)
609 {
610 	int MaxAllowableOverExposure, OverExposure;
611 
612 	MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness -
613 				   FLICKER_BRIGHTNESS_CONSTANT;
614 
615 	if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE)
616 		OverExposure = MaxAllowableOverExposure;
617 	else
618 		OverExposure = FLICKER_ALLOWABLE_OVER_EXPOSURE;
619 
620 	return OverExposure;
621 }
622 #undef FLICKER_MAX_EXPOSURE
623 #undef FLICKER_ALLOWABLE_OVER_EXPOSURE
624 #undef FLICKER_BRIGHTNESS_CONSTANT
625 
626 /* initialise cam_data structure  */
627 static void reset_camera_params(struct gspca_dev *gspca_dev)
628 {
629 	struct sd *sd = (struct sd *) gspca_dev;
630 	struct cam_params *params = &sd->params;
631 
632 	/* The following parameter values are the defaults from
633 	 * "Software Developer's Guide for CPiA Cameras".  Any changes
634 	 * to the defaults are noted in comments. */
635 	params->colourParams.brightness = BRIGHTNESS_DEF;
636 	params->colourParams.contrast = CONTRAST_DEF;
637 	params->colourParams.saturation = SATURATION_DEF;
638 	params->exposure.gainMode = 4;
639 	params->exposure.expMode = 2;		/* AEC */
640 	params->exposure.compMode = 1;
641 	params->exposure.centreWeight = 1;
642 	params->exposure.gain = 0;
643 	params->exposure.fineExp = 0;
644 	params->exposure.coarseExpLo = 185;
645 	params->exposure.coarseExpHi = 0;
646 	params->exposure.redComp = COMP_RED;
647 	params->exposure.green1Comp = COMP_GREEN1;
648 	params->exposure.green2Comp = COMP_GREEN2;
649 	params->exposure.blueComp = COMP_BLUE;
650 	params->colourBalance.balanceMode = 2;	/* ACB */
651 	params->colourBalance.redGain = 32;
652 	params->colourBalance.greenGain = 6;
653 	params->colourBalance.blueGain = 92;
654 	params->apcor.gain1 = 0x18;
655 	params->apcor.gain2 = 0x16;
656 	params->apcor.gain4 = 0x24;
657 	params->apcor.gain8 = 0x34;
658 	params->vlOffset.gain1 = 20;
659 	params->vlOffset.gain2 = 24;
660 	params->vlOffset.gain4 = 26;
661 	params->vlOffset.gain8 = 26;
662 	params->compressionParams.hysteresis = 3;
663 	params->compressionParams.threshMax = 11;
664 	params->compressionParams.smallStep = 1;
665 	params->compressionParams.largeStep = 3;
666 	params->compressionParams.decimationHysteresis = 2;
667 	params->compressionParams.frDiffStepThresh = 5;
668 	params->compressionParams.qDiffStepThresh = 3;
669 	params->compressionParams.decimationThreshMod = 2;
670 	/* End of default values from Software Developer's Guide */
671 
672 	/* Set Sensor FPS to 15fps. This seems better than 30fps
673 	 * for indoor lighting. */
674 	params->sensorFps.divisor = 1;
675 	params->sensorFps.baserate = 1;
676 
677 	params->flickerControl.flickerMode = 0;
678 	params->flickerControl.disabled = 1;
679 	params->flickerControl.coarseJump =
680 		flicker_jumps[sd->mainsFreq]
681 			     [params->sensorFps.baserate]
682 			     [params->sensorFps.divisor];
683 	params->flickerControl.allowableOverExposure =
684 		find_over_exposure(params->colourParams.brightness);
685 
686 	params->yuvThreshold.yThreshold = 6; /* From windows driver */
687 	params->yuvThreshold.uvThreshold = 6; /* From windows driver */
688 
689 	params->format.subSample = SUBSAMPLE_420;
690 	params->format.yuvOrder = YUVORDER_YUYV;
691 
692 	params->compression.mode = CPIA_COMPRESSION_AUTO;
693 	params->compression.decimation = NO_DECIMATION;
694 
695 	params->compressionTarget.frTargeting = COMP_TARGET_DEF;
696 	params->compressionTarget.targetFR = 15; /* From windows driver */
697 	params->compressionTarget.targetQ = 5; /* From windows driver */
698 
699 	params->qx3.qx3_detected = 0;
700 	params->qx3.toplight = 0;
701 	params->qx3.bottomlight = 0;
702 	params->qx3.button = 0;
703 	params->qx3.cradled = 0;
704 }
705 
706 static void printstatus(struct gspca_dev *gspca_dev, struct cam_params *params)
707 {
708 	gspca_dbg(gspca_dev, D_PROBE, "status: %02x %02x %02x %02x %02x %02x %02x %02x\n",
709 		  params->status.systemState, params->status.grabState,
710 		  params->status.streamState, params->status.fatalError,
711 		  params->status.cmdError, params->status.debugFlags,
712 		  params->status.vpStatus, params->status.errorCode);
713 }
714 
715 static int goto_low_power(struct gspca_dev *gspca_dev)
716 {
717 	struct sd *sd = (struct sd *) gspca_dev;
718 	int ret;
719 
720 	ret = do_command(gspca_dev, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0);
721 	if (ret)
722 		return ret;
723 
724 	ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
725 	if (ret)
726 		return ret;
727 
728 	if (sd->params.status.systemState != LO_POWER_STATE) {
729 		if (sd->params.status.systemState != WARM_BOOT_STATE) {
730 			gspca_err(gspca_dev, "unexpected state after lo power cmd: %02x\n",
731 				  sd->params.status.systemState);
732 			printstatus(gspca_dev, &sd->params);
733 		}
734 		return -EIO;
735 	}
736 
737 	gspca_dbg(gspca_dev, D_CONF, "camera now in LOW power state\n");
738 	return 0;
739 }
740 
741 static int goto_high_power(struct gspca_dev *gspca_dev)
742 {
743 	struct sd *sd = (struct sd *) gspca_dev;
744 	int ret;
745 
746 	ret = do_command(gspca_dev, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0);
747 	if (ret)
748 		return ret;
749 
750 	msleep_interruptible(40);	/* windows driver does it too */
751 
752 	if (signal_pending(current))
753 		return -EINTR;
754 
755 	ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
756 	if (ret)
757 		return ret;
758 
759 	if (sd->params.status.systemState != HI_POWER_STATE) {
760 		gspca_err(gspca_dev, "unexpected state after hi power cmd: %02x\n",
761 			  sd->params.status.systemState);
762 		printstatus(gspca_dev, &sd->params);
763 		return -EIO;
764 	}
765 
766 	gspca_dbg(gspca_dev, D_CONF, "camera now in HIGH power state\n");
767 	return 0;
768 }
769 
770 static int get_version_information(struct gspca_dev *gspca_dev)
771 {
772 	int ret;
773 
774 	/* GetCPIAVersion */
775 	ret = do_command(gspca_dev, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0);
776 	if (ret)
777 		return ret;
778 
779 	/* GetPnPID */
780 	return do_command(gspca_dev, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0);
781 }
782 
783 static int save_camera_state(struct gspca_dev *gspca_dev)
784 {
785 	int ret;
786 
787 	ret = do_command(gspca_dev, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
788 	if (ret)
789 		return ret;
790 
791 	return do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
792 }
793 
794 static int command_setformat(struct gspca_dev *gspca_dev)
795 {
796 	struct sd *sd = (struct sd *) gspca_dev;
797 	int ret;
798 
799 	ret = do_command(gspca_dev, CPIA_COMMAND_SetFormat,
800 			 sd->params.format.videoSize,
801 			 sd->params.format.subSample,
802 			 sd->params.format.yuvOrder, 0);
803 	if (ret)
804 		return ret;
805 
806 	return do_command(gspca_dev, CPIA_COMMAND_SetROI,
807 			  sd->params.roi.colStart, sd->params.roi.colEnd,
808 			  sd->params.roi.rowStart, sd->params.roi.rowEnd);
809 }
810 
811 static int command_setcolourparams(struct gspca_dev *gspca_dev)
812 {
813 	struct sd *sd = (struct sd *) gspca_dev;
814 	return do_command(gspca_dev, CPIA_COMMAND_SetColourParams,
815 			  sd->params.colourParams.brightness,
816 			  sd->params.colourParams.contrast,
817 			  sd->params.colourParams.saturation, 0);
818 }
819 
820 static int command_setapcor(struct gspca_dev *gspca_dev)
821 {
822 	struct sd *sd = (struct sd *) gspca_dev;
823 	return do_command(gspca_dev, CPIA_COMMAND_SetApcor,
824 			  sd->params.apcor.gain1,
825 			  sd->params.apcor.gain2,
826 			  sd->params.apcor.gain4,
827 			  sd->params.apcor.gain8);
828 }
829 
830 static int command_setvloffset(struct gspca_dev *gspca_dev)
831 {
832 	struct sd *sd = (struct sd *) gspca_dev;
833 	return do_command(gspca_dev, CPIA_COMMAND_SetVLOffset,
834 			  sd->params.vlOffset.gain1,
835 			  sd->params.vlOffset.gain2,
836 			  sd->params.vlOffset.gain4,
837 			  sd->params.vlOffset.gain8);
838 }
839 
840 static int command_setexposure(struct gspca_dev *gspca_dev)
841 {
842 	struct sd *sd = (struct sd *) gspca_dev;
843 	int ret;
844 
845 	ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
846 				  sd->params.exposure.gainMode,
847 				  1,
848 				  sd->params.exposure.compMode,
849 				  sd->params.exposure.centreWeight,
850 				  sd->params.exposure.gain,
851 				  sd->params.exposure.fineExp,
852 				  sd->params.exposure.coarseExpLo,
853 				  sd->params.exposure.coarseExpHi,
854 				  sd->params.exposure.redComp,
855 				  sd->params.exposure.green1Comp,
856 				  sd->params.exposure.green2Comp,
857 				  sd->params.exposure.blueComp);
858 	if (ret)
859 		return ret;
860 
861 	if (sd->params.exposure.expMode != 1) {
862 		ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
863 					  0,
864 					  sd->params.exposure.expMode,
865 					  0, 0,
866 					  sd->params.exposure.gain,
867 					  sd->params.exposure.fineExp,
868 					  sd->params.exposure.coarseExpLo,
869 					  sd->params.exposure.coarseExpHi,
870 					  0, 0, 0, 0);
871 	}
872 
873 	return ret;
874 }
875 
876 static int command_setcolourbalance(struct gspca_dev *gspca_dev)
877 {
878 	struct sd *sd = (struct sd *) gspca_dev;
879 
880 	if (sd->params.colourBalance.balanceMode == 1) {
881 		int ret;
882 
883 		ret = do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
884 				 1,
885 				 sd->params.colourBalance.redGain,
886 				 sd->params.colourBalance.greenGain,
887 				 sd->params.colourBalance.blueGain);
888 		if (ret)
889 			return ret;
890 
891 		return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
892 				  3, 0, 0, 0);
893 	}
894 	if (sd->params.colourBalance.balanceMode == 2) {
895 		return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
896 				  2, 0, 0, 0);
897 	}
898 	if (sd->params.colourBalance.balanceMode == 3) {
899 		return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
900 				  3, 0, 0, 0);
901 	}
902 
903 	return -EINVAL;
904 }
905 
906 static int command_setcompressiontarget(struct gspca_dev *gspca_dev)
907 {
908 	struct sd *sd = (struct sd *) gspca_dev;
909 
910 	return do_command(gspca_dev, CPIA_COMMAND_SetCompressionTarget,
911 			  sd->params.compressionTarget.frTargeting,
912 			  sd->params.compressionTarget.targetFR,
913 			  sd->params.compressionTarget.targetQ, 0);
914 }
915 
916 static int command_setyuvtresh(struct gspca_dev *gspca_dev)
917 {
918 	struct sd *sd = (struct sd *) gspca_dev;
919 
920 	return do_command(gspca_dev, CPIA_COMMAND_SetYUVThresh,
921 			  sd->params.yuvThreshold.yThreshold,
922 			  sd->params.yuvThreshold.uvThreshold, 0, 0);
923 }
924 
925 static int command_setcompressionparams(struct gspca_dev *gspca_dev)
926 {
927 	struct sd *sd = (struct sd *) gspca_dev;
928 
929 	return do_command_extended(gspca_dev,
930 			    CPIA_COMMAND_SetCompressionParams,
931 			    0, 0, 0, 0,
932 			    sd->params.compressionParams.hysteresis,
933 			    sd->params.compressionParams.threshMax,
934 			    sd->params.compressionParams.smallStep,
935 			    sd->params.compressionParams.largeStep,
936 			    sd->params.compressionParams.decimationHysteresis,
937 			    sd->params.compressionParams.frDiffStepThresh,
938 			    sd->params.compressionParams.qDiffStepThresh,
939 			    sd->params.compressionParams.decimationThreshMod);
940 }
941 
942 static int command_setcompression(struct gspca_dev *gspca_dev)
943 {
944 	struct sd *sd = (struct sd *) gspca_dev;
945 
946 	return do_command(gspca_dev, CPIA_COMMAND_SetCompression,
947 			  sd->params.compression.mode,
948 			  sd->params.compression.decimation, 0, 0);
949 }
950 
951 static int command_setsensorfps(struct gspca_dev *gspca_dev)
952 {
953 	struct sd *sd = (struct sd *) gspca_dev;
954 
955 	return do_command(gspca_dev, CPIA_COMMAND_SetSensorFPS,
956 			  sd->params.sensorFps.divisor,
957 			  sd->params.sensorFps.baserate, 0, 0);
958 }
959 
960 static int command_setflickerctrl(struct gspca_dev *gspca_dev)
961 {
962 	struct sd *sd = (struct sd *) gspca_dev;
963 
964 	return do_command(gspca_dev, CPIA_COMMAND_SetFlickerCtrl,
965 			  sd->params.flickerControl.flickerMode,
966 			  sd->params.flickerControl.coarseJump,
967 			  sd->params.flickerControl.allowableOverExposure,
968 			  0);
969 }
970 
971 static int command_setecptiming(struct gspca_dev *gspca_dev)
972 {
973 	struct sd *sd = (struct sd *) gspca_dev;
974 
975 	return do_command(gspca_dev, CPIA_COMMAND_SetECPTiming,
976 			  sd->params.ecpTiming, 0, 0, 0);
977 }
978 
979 static int command_pause(struct gspca_dev *gspca_dev)
980 {
981 	return do_command(gspca_dev, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
982 }
983 
984 static int command_resume(struct gspca_dev *gspca_dev)
985 {
986 	struct sd *sd = (struct sd *) gspca_dev;
987 
988 	return do_command(gspca_dev, CPIA_COMMAND_InitStreamCap,
989 			  0, sd->params.streamStartLine, 0, 0);
990 }
991 
992 static int command_setlights(struct gspca_dev *gspca_dev)
993 {
994 	struct sd *sd = (struct sd *) gspca_dev;
995 	int ret, p1, p2;
996 
997 	p1 = (sd->params.qx3.bottomlight == 0) << 1;
998 	p2 = (sd->params.qx3.toplight == 0) << 3;
999 
1000 	ret = do_command(gspca_dev, CPIA_COMMAND_WriteVCReg,
1001 			 0x90, 0x8f, 0x50, 0);
1002 	if (ret)
1003 		return ret;
1004 
1005 	return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0,
1006 			  p1 | p2 | 0xe0, 0);
1007 }
1008 
1009 static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply)
1010 {
1011 	/* Everything in here is from the Windows driver */
1012 /* define for compgain calculation */
1013 #if 0
1014 #define COMPGAIN(base, curexp, newexp) \
1015     (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
1016 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1017     (u16)((float)curexp * (float)(u8)(curcomp + 128) / \
1018     (float)(u8)(basecomp - 128))
1019 #else
1020   /* equivalent functions without floating point math */
1021 #define COMPGAIN(base, curexp, newexp) \
1022     (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2 * newexp)))
1023 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1024     (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
1025 #endif
1026 
1027 	struct sd *sd = (struct sd *) gspca_dev;
1028 	int currentexp = sd->params.exposure.coarseExpLo +
1029 			 sd->params.exposure.coarseExpHi * 256;
1030 	int ret, startexp;
1031 
1032 	if (on) {
1033 		int cj = sd->params.flickerControl.coarseJump;
1034 		sd->params.flickerControl.flickerMode = 1;
1035 		sd->params.flickerControl.disabled = 0;
1036 		if (sd->params.exposure.expMode != 2) {
1037 			sd->params.exposure.expMode = 2;
1038 			sd->exposure_status = EXPOSURE_NORMAL;
1039 		}
1040 		currentexp = currentexp << sd->params.exposure.gain;
1041 		sd->params.exposure.gain = 0;
1042 		/* round down current exposure to nearest value */
1043 		startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj;
1044 		if (startexp < 1)
1045 			startexp = 1;
1046 		startexp = (startexp * cj) - 1;
1047 		if (FIRMWARE_VERSION(1, 2))
1048 			while (startexp > MAX_EXP_102)
1049 				startexp -= cj;
1050 		else
1051 			while (startexp > MAX_EXP)
1052 				startexp -= cj;
1053 		sd->params.exposure.coarseExpLo = startexp & 0xff;
1054 		sd->params.exposure.coarseExpHi = startexp >> 8;
1055 		if (currentexp > startexp) {
1056 			if (currentexp > (2 * startexp))
1057 				currentexp = 2 * startexp;
1058 			sd->params.exposure.redComp =
1059 				COMPGAIN(COMP_RED, currentexp, startexp);
1060 			sd->params.exposure.green1Comp =
1061 				COMPGAIN(COMP_GREEN1, currentexp, startexp);
1062 			sd->params.exposure.green2Comp =
1063 				COMPGAIN(COMP_GREEN2, currentexp, startexp);
1064 			sd->params.exposure.blueComp =
1065 				COMPGAIN(COMP_BLUE, currentexp, startexp);
1066 		} else {
1067 			sd->params.exposure.redComp = COMP_RED;
1068 			sd->params.exposure.green1Comp = COMP_GREEN1;
1069 			sd->params.exposure.green2Comp = COMP_GREEN2;
1070 			sd->params.exposure.blueComp = COMP_BLUE;
1071 		}
1072 		if (FIRMWARE_VERSION(1, 2))
1073 			sd->params.exposure.compMode = 0;
1074 		else
1075 			sd->params.exposure.compMode = 1;
1076 
1077 		sd->params.apcor.gain1 = 0x18;
1078 		sd->params.apcor.gain2 = 0x18;
1079 		sd->params.apcor.gain4 = 0x16;
1080 		sd->params.apcor.gain8 = 0x14;
1081 	} else {
1082 		sd->params.flickerControl.flickerMode = 0;
1083 		sd->params.flickerControl.disabled = 1;
1084 		/* Average equivalent coarse for each comp channel */
1085 		startexp = EXP_FROM_COMP(COMP_RED,
1086 				sd->params.exposure.redComp, currentexp);
1087 		startexp += EXP_FROM_COMP(COMP_GREEN1,
1088 				sd->params.exposure.green1Comp, currentexp);
1089 		startexp += EXP_FROM_COMP(COMP_GREEN2,
1090 				sd->params.exposure.green2Comp, currentexp);
1091 		startexp += EXP_FROM_COMP(COMP_BLUE,
1092 				sd->params.exposure.blueComp, currentexp);
1093 		startexp = startexp >> 2;
1094 		while (startexp > MAX_EXP && sd->params.exposure.gain <
1095 		       sd->params.exposure.gainMode - 1) {
1096 			startexp = startexp >> 1;
1097 			++sd->params.exposure.gain;
1098 		}
1099 		if (FIRMWARE_VERSION(1, 2) && startexp > MAX_EXP_102)
1100 			startexp = MAX_EXP_102;
1101 		if (startexp > MAX_EXP)
1102 			startexp = MAX_EXP;
1103 		sd->params.exposure.coarseExpLo = startexp & 0xff;
1104 		sd->params.exposure.coarseExpHi = startexp >> 8;
1105 		sd->params.exposure.redComp = COMP_RED;
1106 		sd->params.exposure.green1Comp = COMP_GREEN1;
1107 		sd->params.exposure.green2Comp = COMP_GREEN2;
1108 		sd->params.exposure.blueComp = COMP_BLUE;
1109 		sd->params.exposure.compMode = 1;
1110 		sd->params.apcor.gain1 = 0x18;
1111 		sd->params.apcor.gain2 = 0x16;
1112 		sd->params.apcor.gain4 = 0x24;
1113 		sd->params.apcor.gain8 = 0x34;
1114 	}
1115 	sd->params.vlOffset.gain1 = 20;
1116 	sd->params.vlOffset.gain2 = 24;
1117 	sd->params.vlOffset.gain4 = 26;
1118 	sd->params.vlOffset.gain8 = 26;
1119 
1120 	if (apply) {
1121 		ret = command_setexposure(gspca_dev);
1122 		if (ret)
1123 			return ret;
1124 
1125 		ret = command_setapcor(gspca_dev);
1126 		if (ret)
1127 			return ret;
1128 
1129 		ret = command_setvloffset(gspca_dev);
1130 		if (ret)
1131 			return ret;
1132 
1133 		ret = command_setflickerctrl(gspca_dev);
1134 		if (ret)
1135 			return ret;
1136 	}
1137 
1138 	return 0;
1139 #undef EXP_FROM_COMP
1140 #undef COMPGAIN
1141 }
1142 
1143 /* monitor the exposure and adjust the sensor frame rate if needed */
1144 static void monitor_exposure(struct gspca_dev *gspca_dev)
1145 {
1146 	struct sd *sd = (struct sd *) gspca_dev;
1147 	u8 exp_acc, bcomp, cmd[8];
1148 	int ret, light_exp, dark_exp, very_dark_exp;
1149 	int old_exposure, new_exposure, framerate;
1150 	int setfps = 0, setexp = 0, setflicker = 0;
1151 
1152 	/* get necessary stats and register settings from camera */
1153 	/* do_command can't handle this, so do it ourselves */
1154 	cmd[0] = CPIA_COMMAND_ReadVPRegs >> 8;
1155 	cmd[1] = CPIA_COMMAND_ReadVPRegs & 0xff;
1156 	cmd[2] = 30;
1157 	cmd[3] = 4;
1158 	cmd[4] = 9;
1159 	cmd[5] = 8;
1160 	cmd[6] = 8;
1161 	cmd[7] = 0;
1162 	ret = cpia_usb_transferCmd(gspca_dev, cmd);
1163 	if (ret) {
1164 		pr_err("ReadVPRegs(30,4,9,8) - failed: %d\n", ret);
1165 		return;
1166 	}
1167 	exp_acc = gspca_dev->usb_buf[0];
1168 	bcomp = gspca_dev->usb_buf[1];
1169 
1170 	light_exp = sd->params.colourParams.brightness +
1171 		    TC - 50 + EXP_ACC_LIGHT;
1172 	if (light_exp > 255)
1173 		light_exp = 255;
1174 	dark_exp = sd->params.colourParams.brightness +
1175 		   TC - 50 - EXP_ACC_DARK;
1176 	if (dark_exp < 0)
1177 		dark_exp = 0;
1178 	very_dark_exp = dark_exp / 2;
1179 
1180 	old_exposure = sd->params.exposure.coarseExpHi * 256 +
1181 		       sd->params.exposure.coarseExpLo;
1182 
1183 	if (!sd->params.flickerControl.disabled) {
1184 		/* Flicker control on */
1185 		int max_comp = FIRMWARE_VERSION(1, 2) ? MAX_COMP :
1186 							HIGH_COMP_102;
1187 		bcomp += 128;	/* decode */
1188 		if (bcomp >= max_comp && exp_acc < dark_exp) {
1189 			/* dark */
1190 			if (exp_acc < very_dark_exp) {
1191 				/* very dark */
1192 				if (sd->exposure_status == EXPOSURE_VERY_DARK)
1193 					++sd->exposure_count;
1194 				else {
1195 					sd->exposure_status =
1196 						EXPOSURE_VERY_DARK;
1197 					sd->exposure_count = 1;
1198 				}
1199 			} else {
1200 				/* just dark */
1201 				if (sd->exposure_status == EXPOSURE_DARK)
1202 					++sd->exposure_count;
1203 				else {
1204 					sd->exposure_status = EXPOSURE_DARK;
1205 					sd->exposure_count = 1;
1206 				}
1207 			}
1208 		} else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1209 			/* light */
1210 			if (old_exposure <= VERY_LOW_EXP) {
1211 				/* very light */
1212 				if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1213 					++sd->exposure_count;
1214 				else {
1215 					sd->exposure_status =
1216 						EXPOSURE_VERY_LIGHT;
1217 					sd->exposure_count = 1;
1218 				}
1219 			} else {
1220 				/* just light */
1221 				if (sd->exposure_status == EXPOSURE_LIGHT)
1222 					++sd->exposure_count;
1223 				else {
1224 					sd->exposure_status = EXPOSURE_LIGHT;
1225 					sd->exposure_count = 1;
1226 				}
1227 			}
1228 		} else {
1229 			/* not dark or light */
1230 			sd->exposure_status = EXPOSURE_NORMAL;
1231 		}
1232 	} else {
1233 		/* Flicker control off */
1234 		if (old_exposure >= MAX_EXP && exp_acc < dark_exp) {
1235 			/* dark */
1236 			if (exp_acc < very_dark_exp) {
1237 				/* very dark */
1238 				if (sd->exposure_status == EXPOSURE_VERY_DARK)
1239 					++sd->exposure_count;
1240 				else {
1241 					sd->exposure_status =
1242 						EXPOSURE_VERY_DARK;
1243 					sd->exposure_count = 1;
1244 				}
1245 			} else {
1246 				/* just dark */
1247 				if (sd->exposure_status == EXPOSURE_DARK)
1248 					++sd->exposure_count;
1249 				else {
1250 					sd->exposure_status = EXPOSURE_DARK;
1251 					sd->exposure_count = 1;
1252 				}
1253 			}
1254 		} else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1255 			/* light */
1256 			if (old_exposure <= VERY_LOW_EXP) {
1257 				/* very light */
1258 				if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1259 					++sd->exposure_count;
1260 				else {
1261 					sd->exposure_status =
1262 						EXPOSURE_VERY_LIGHT;
1263 					sd->exposure_count = 1;
1264 				}
1265 			} else {
1266 				/* just light */
1267 				if (sd->exposure_status == EXPOSURE_LIGHT)
1268 					++sd->exposure_count;
1269 				else {
1270 					sd->exposure_status = EXPOSURE_LIGHT;
1271 					sd->exposure_count = 1;
1272 				}
1273 			}
1274 		} else {
1275 			/* not dark or light */
1276 			sd->exposure_status = EXPOSURE_NORMAL;
1277 		}
1278 	}
1279 
1280 	framerate = atomic_read(&sd->fps);
1281 	if (framerate > 30 || framerate < 1)
1282 		framerate = 1;
1283 
1284 	if (!sd->params.flickerControl.disabled) {
1285 		/* Flicker control on */
1286 		if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1287 		     sd->exposure_status == EXPOSURE_DARK) &&
1288 		    sd->exposure_count >= DARK_TIME * framerate &&
1289 		    sd->params.sensorFps.divisor < 2) {
1290 
1291 			/* dark for too long */
1292 			++sd->params.sensorFps.divisor;
1293 			setfps = 1;
1294 
1295 			sd->params.flickerControl.coarseJump =
1296 				flicker_jumps[sd->mainsFreq]
1297 					     [sd->params.sensorFps.baserate]
1298 					     [sd->params.sensorFps.divisor];
1299 			setflicker = 1;
1300 
1301 			new_exposure = sd->params.flickerControl.coarseJump-1;
1302 			while (new_exposure < old_exposure / 2)
1303 				new_exposure +=
1304 					sd->params.flickerControl.coarseJump;
1305 			sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1306 			sd->params.exposure.coarseExpHi = new_exposure >> 8;
1307 			setexp = 1;
1308 			sd->exposure_status = EXPOSURE_NORMAL;
1309 			gspca_dbg(gspca_dev, D_CONF, "Automatically decreasing sensor_fps\n");
1310 
1311 		} else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1312 			    sd->exposure_status == EXPOSURE_LIGHT) &&
1313 			   sd->exposure_count >= LIGHT_TIME * framerate &&
1314 			   sd->params.sensorFps.divisor > 0) {
1315 
1316 			/* light for too long */
1317 			int max_exp = FIRMWARE_VERSION(1, 2) ? MAX_EXP_102 :
1318 							       MAX_EXP;
1319 			--sd->params.sensorFps.divisor;
1320 			setfps = 1;
1321 
1322 			sd->params.flickerControl.coarseJump =
1323 				flicker_jumps[sd->mainsFreq]
1324 					     [sd->params.sensorFps.baserate]
1325 					     [sd->params.sensorFps.divisor];
1326 			setflicker = 1;
1327 
1328 			new_exposure = sd->params.flickerControl.coarseJump-1;
1329 			while (new_exposure < 2 * old_exposure &&
1330 			       new_exposure +
1331 			       sd->params.flickerControl.coarseJump < max_exp)
1332 				new_exposure +=
1333 					sd->params.flickerControl.coarseJump;
1334 			sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1335 			sd->params.exposure.coarseExpHi = new_exposure >> 8;
1336 			setexp = 1;
1337 			sd->exposure_status = EXPOSURE_NORMAL;
1338 			gspca_dbg(gspca_dev, D_CONF, "Automatically increasing sensor_fps\n");
1339 		}
1340 	} else {
1341 		/* Flicker control off */
1342 		if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1343 		     sd->exposure_status == EXPOSURE_DARK) &&
1344 		    sd->exposure_count >= DARK_TIME * framerate &&
1345 		    sd->params.sensorFps.divisor < 2) {
1346 
1347 			/* dark for too long */
1348 			++sd->params.sensorFps.divisor;
1349 			setfps = 1;
1350 
1351 			if (sd->params.exposure.gain > 0) {
1352 				--sd->params.exposure.gain;
1353 				setexp = 1;
1354 			}
1355 			sd->exposure_status = EXPOSURE_NORMAL;
1356 			gspca_dbg(gspca_dev, D_CONF, "Automatically decreasing sensor_fps\n");
1357 
1358 		} else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1359 			    sd->exposure_status == EXPOSURE_LIGHT) &&
1360 			   sd->exposure_count >= LIGHT_TIME * framerate &&
1361 			   sd->params.sensorFps.divisor > 0) {
1362 
1363 			/* light for too long */
1364 			--sd->params.sensorFps.divisor;
1365 			setfps = 1;
1366 
1367 			if (sd->params.exposure.gain <
1368 			    sd->params.exposure.gainMode - 1) {
1369 				++sd->params.exposure.gain;
1370 				setexp = 1;
1371 			}
1372 			sd->exposure_status = EXPOSURE_NORMAL;
1373 			gspca_dbg(gspca_dev, D_CONF, "Automatically increasing sensor_fps\n");
1374 		}
1375 	}
1376 
1377 	if (setexp)
1378 		command_setexposure(gspca_dev);
1379 
1380 	if (setfps)
1381 		command_setsensorfps(gspca_dev);
1382 
1383 	if (setflicker)
1384 		command_setflickerctrl(gspca_dev);
1385 }
1386 
1387 /*-----------------------------------------------------------------*/
1388 /* if flicker is switched off, this function switches it back on.It checks,
1389    however, that conditions are suitable before restarting it.
1390    This should only be called for firmware version 1.2.
1391 
1392    It also adjust the colour balance when an exposure step is detected - as
1393    long as flicker is running
1394 */
1395 static void restart_flicker(struct gspca_dev *gspca_dev)
1396 {
1397 	struct sd *sd = (struct sd *) gspca_dev;
1398 	int cam_exposure, old_exp;
1399 
1400 	if (!FIRMWARE_VERSION(1, 2))
1401 		return;
1402 
1403 	cam_exposure = atomic_read(&sd->cam_exposure);
1404 
1405 	if (sd->params.flickerControl.flickerMode == 0 ||
1406 	    cam_exposure == 0)
1407 		return;
1408 
1409 	old_exp = sd->params.exposure.coarseExpLo +
1410 		  sd->params.exposure.coarseExpHi*256;
1411 	/*
1412 	  see how far away camera exposure is from a valid
1413 	  flicker exposure value
1414 	*/
1415 	cam_exposure %= sd->params.flickerControl.coarseJump;
1416 	if (!sd->params.flickerControl.disabled &&
1417 	    cam_exposure <= sd->params.flickerControl.coarseJump - 3) {
1418 		/* Flicker control auto-disabled */
1419 		sd->params.flickerControl.disabled = 1;
1420 	}
1421 
1422 	if (sd->params.flickerControl.disabled &&
1423 	    old_exp > sd->params.flickerControl.coarseJump +
1424 		      ROUND_UP_EXP_FOR_FLICKER) {
1425 		/* exposure is now high enough to switch
1426 		   flicker control back on */
1427 		set_flicker(gspca_dev, 1, 1);
1428 	}
1429 }
1430 
1431 /* this function is called at probe time */
1432 static int sd_config(struct gspca_dev *gspca_dev,
1433 			const struct usb_device_id *id)
1434 {
1435 	struct sd *sd = (struct sd *) gspca_dev;
1436 	struct cam *cam;
1437 	int ret;
1438 
1439 	sd->mainsFreq = FREQ_DEF == V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
1440 	reset_camera_params(gspca_dev);
1441 
1442 	gspca_dbg(gspca_dev, D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)\n",
1443 		  id->idVendor, id->idProduct);
1444 
1445 	cam = &gspca_dev->cam;
1446 	cam->cam_mode = mode;
1447 	cam->nmodes = ARRAY_SIZE(mode);
1448 
1449 	ret = goto_low_power(gspca_dev);
1450 	if (ret)
1451 		gspca_err(gspca_dev, "Cannot go to low power mode: %d\n",
1452 			  ret);
1453 	/* Check the firmware version. */
1454 	sd->params.version.firmwareVersion = 0;
1455 	get_version_information(gspca_dev);
1456 	if (sd->params.version.firmwareVersion != 1) {
1457 		gspca_err(gspca_dev, "only firmware version 1 is supported (got: %d)\n",
1458 			  sd->params.version.firmwareVersion);
1459 		return -ENODEV;
1460 	}
1461 
1462 	/* A bug in firmware 1-02 limits gainMode to 2 */
1463 	if (sd->params.version.firmwareRevision <= 2 &&
1464 	    sd->params.exposure.gainMode > 2) {
1465 		sd->params.exposure.gainMode = 2;
1466 	}
1467 
1468 	/* set QX3 detected flag */
1469 	sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 &&
1470 				       sd->params.pnpID.product == 0x0001);
1471 	return 0;
1472 }
1473 
1474 /* -- start the camera -- */
1475 static int sd_start(struct gspca_dev *gspca_dev)
1476 {
1477 	struct sd *sd = (struct sd *) gspca_dev;
1478 	int priv, ret;
1479 
1480 	/* Start the camera in low power mode */
1481 	if (goto_low_power(gspca_dev)) {
1482 		if (sd->params.status.systemState != WARM_BOOT_STATE) {
1483 			gspca_err(gspca_dev, "unexpected systemstate: %02x\n",
1484 				  sd->params.status.systemState);
1485 			printstatus(gspca_dev, &sd->params);
1486 			return -ENODEV;
1487 		}
1488 
1489 		/* FIXME: this is just dirty trial and error */
1490 		ret = goto_high_power(gspca_dev);
1491 		if (ret)
1492 			return ret;
1493 
1494 		ret = do_command(gspca_dev, CPIA_COMMAND_DiscardFrame,
1495 				 0, 0, 0, 0);
1496 		if (ret)
1497 			return ret;
1498 
1499 		ret = goto_low_power(gspca_dev);
1500 		if (ret)
1501 			return ret;
1502 	}
1503 
1504 	/* procedure described in developer's guide p3-28 */
1505 
1506 	/* Check the firmware version. */
1507 	sd->params.version.firmwareVersion = 0;
1508 	get_version_information(gspca_dev);
1509 
1510 	/* The fatal error checking should be done after
1511 	 * the camera powers up (developer's guide p 3-38) */
1512 
1513 	/* Set streamState before transition to high power to avoid bug
1514 	 * in firmware 1-02 */
1515 	ret = do_command(gspca_dev, CPIA_COMMAND_ModifyCameraStatus,
1516 			 STREAMSTATE, 0, STREAM_NOT_READY, 0);
1517 	if (ret)
1518 		return ret;
1519 
1520 	/* GotoHiPower */
1521 	ret = goto_high_power(gspca_dev);
1522 	if (ret)
1523 		return ret;
1524 
1525 	/* Check the camera status */
1526 	ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1527 	if (ret)
1528 		return ret;
1529 
1530 	if (sd->params.status.fatalError) {
1531 		gspca_err(gspca_dev, "fatal_error: %04x, vp_status: %04x\n",
1532 			  sd->params.status.fatalError,
1533 			  sd->params.status.vpStatus);
1534 		return -EIO;
1535 	}
1536 
1537 	/* VPVersion can't be retrieved before the camera is in HiPower,
1538 	 * so get it here instead of in get_version_information. */
1539 	ret = do_command(gspca_dev, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0);
1540 	if (ret)
1541 		return ret;
1542 
1543 	/* Determine video mode settings */
1544 	sd->params.streamStartLine = 120;
1545 
1546 	priv = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1547 	if (priv & 0x01) { /* crop */
1548 		sd->params.roi.colStart = 2;
1549 		sd->params.roi.rowStart = 6;
1550 	} else {
1551 		sd->params.roi.colStart = 0;
1552 		sd->params.roi.rowStart = 0;
1553 	}
1554 
1555 	if (priv & 0x02) { /* quarter */
1556 		sd->params.format.videoSize = VIDEOSIZE_QCIF;
1557 		sd->params.roi.colStart /= 2;
1558 		sd->params.roi.rowStart /= 2;
1559 		sd->params.streamStartLine /= 2;
1560 	} else
1561 		sd->params.format.videoSize = VIDEOSIZE_CIF;
1562 
1563 	sd->params.roi.colEnd = sd->params.roi.colStart +
1564 				(gspca_dev->pixfmt.width >> 3);
1565 	sd->params.roi.rowEnd = sd->params.roi.rowStart +
1566 				(gspca_dev->pixfmt.height >> 2);
1567 
1568 	/* And now set the camera to a known state */
1569 	ret = do_command(gspca_dev, CPIA_COMMAND_SetGrabMode,
1570 			 CPIA_GRAB_CONTINEOUS, 0, 0, 0);
1571 	if (ret)
1572 		return ret;
1573 	/* We start with compression disabled, as we need one uncompressed
1574 	   frame to handle later compressed frames */
1575 	ret = do_command(gspca_dev, CPIA_COMMAND_SetCompression,
1576 			 CPIA_COMPRESSION_NONE,
1577 			 NO_DECIMATION, 0, 0);
1578 	if (ret)
1579 		return ret;
1580 	ret = command_setcompressiontarget(gspca_dev);
1581 	if (ret)
1582 		return ret;
1583 	ret = command_setcolourparams(gspca_dev);
1584 	if (ret)
1585 		return ret;
1586 	ret = command_setformat(gspca_dev);
1587 	if (ret)
1588 		return ret;
1589 	ret = command_setyuvtresh(gspca_dev);
1590 	if (ret)
1591 		return ret;
1592 	ret = command_setecptiming(gspca_dev);
1593 	if (ret)
1594 		return ret;
1595 	ret = command_setcompressionparams(gspca_dev);
1596 	if (ret)
1597 		return ret;
1598 	ret = command_setexposure(gspca_dev);
1599 	if (ret)
1600 		return ret;
1601 	ret = command_setcolourbalance(gspca_dev);
1602 	if (ret)
1603 		return ret;
1604 	ret = command_setsensorfps(gspca_dev);
1605 	if (ret)
1606 		return ret;
1607 	ret = command_setapcor(gspca_dev);
1608 	if (ret)
1609 		return ret;
1610 	ret = command_setflickerctrl(gspca_dev);
1611 	if (ret)
1612 		return ret;
1613 	ret = command_setvloffset(gspca_dev);
1614 	if (ret)
1615 		return ret;
1616 
1617 	/* Start stream */
1618 	ret = command_resume(gspca_dev);
1619 	if (ret)
1620 		return ret;
1621 
1622 	/* Wait 6 frames before turning compression on for the sensor to get
1623 	   all settings and AEC/ACB to settle */
1624 	sd->first_frame = 6;
1625 	sd->exposure_status = EXPOSURE_NORMAL;
1626 	sd->exposure_count = 0;
1627 	atomic_set(&sd->cam_exposure, 0);
1628 	atomic_set(&sd->fps, 0);
1629 
1630 	return 0;
1631 }
1632 
1633 static void sd_stopN(struct gspca_dev *gspca_dev)
1634 {
1635 	struct sd *sd __maybe_unused = (struct sd *) gspca_dev;
1636 
1637 	command_pause(gspca_dev);
1638 
1639 	/* save camera state for later open (developers guide ch 3.5.3) */
1640 	save_camera_state(gspca_dev);
1641 
1642 	/* GotoLoPower */
1643 	goto_low_power(gspca_dev);
1644 
1645 	/* Update the camera status */
1646 	do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1647 
1648 #if IS_ENABLED(CONFIG_INPUT)
1649 	/* If the last button state is pressed, release it now! */
1650 	if (sd->params.qx3.button) {
1651 		/* The camera latch will hold the pressed state until we reset
1652 		   the latch, so we do not reset sd->params.qx3.button now, to
1653 		   avoid a false keypress being reported the next sd_start */
1654 		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1655 		input_sync(gspca_dev->input_dev);
1656 	}
1657 #endif
1658 }
1659 
1660 /* this function is called at probe and resume time */
1661 static int sd_init(struct gspca_dev *gspca_dev)
1662 {
1663 	struct sd *sd = (struct sd *) gspca_dev;
1664 	int ret;
1665 
1666 	/* Start / Stop the camera to make sure we are talking to
1667 	   a supported camera, and to get some information from it
1668 	   to print. */
1669 	ret = sd_start(gspca_dev);
1670 	if (ret)
1671 		return ret;
1672 
1673 	/* Ensure the QX3 illuminators' states are restored upon resume,
1674 	   or disable the illuminator controls, if this isn't a QX3 */
1675 	if (sd->params.qx3.qx3_detected)
1676 		command_setlights(gspca_dev);
1677 
1678 	sd_stopN(gspca_dev);
1679 
1680 	gspca_dbg(gspca_dev, D_PROBE, "CPIA Version:             %d.%02d (%d.%d)\n",
1681 		  sd->params.version.firmwareVersion,
1682 		  sd->params.version.firmwareRevision,
1683 		  sd->params.version.vcVersion,
1684 		  sd->params.version.vcRevision);
1685 	gspca_dbg(gspca_dev, D_PROBE, "CPIA PnP-ID:              %04x:%04x:%04x",
1686 		  sd->params.pnpID.vendor, sd->params.pnpID.product,
1687 		  sd->params.pnpID.deviceRevision);
1688 	gspca_dbg(gspca_dev, D_PROBE, "VP-Version:               %d.%d %04x",
1689 		  sd->params.vpVersion.vpVersion,
1690 		  sd->params.vpVersion.vpRevision,
1691 		  sd->params.vpVersion.cameraHeadID);
1692 
1693 	return 0;
1694 }
1695 
1696 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1697 			u8 *data,
1698 			int len)
1699 {
1700 	struct sd *sd = (struct sd *) gspca_dev;
1701 
1702 	/* Check for SOF */
1703 	if (len >= 64 &&
1704 	    data[0] == MAGIC_0 && data[1] == MAGIC_1 &&
1705 	    data[16] == sd->params.format.videoSize &&
1706 	    data[17] == sd->params.format.subSample &&
1707 	    data[18] == sd->params.format.yuvOrder &&
1708 	    data[24] == sd->params.roi.colStart &&
1709 	    data[25] == sd->params.roi.colEnd &&
1710 	    data[26] == sd->params.roi.rowStart &&
1711 	    data[27] == sd->params.roi.rowEnd) {
1712 		u8 *image;
1713 
1714 		atomic_set(&sd->cam_exposure, data[39] * 2);
1715 		atomic_set(&sd->fps, data[41]);
1716 
1717 		/* Check for proper EOF for last frame */
1718 		image = gspca_dev->image;
1719 		if (image != NULL &&
1720 		    gspca_dev->image_len > 4 &&
1721 		    image[gspca_dev->image_len - 4] == 0xff &&
1722 		    image[gspca_dev->image_len - 3] == 0xff &&
1723 		    image[gspca_dev->image_len - 2] == 0xff &&
1724 		    image[gspca_dev->image_len - 1] == 0xff)
1725 			gspca_frame_add(gspca_dev, LAST_PACKET,
1726 						NULL, 0);
1727 
1728 		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
1729 		return;
1730 	}
1731 
1732 	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1733 }
1734 
1735 static void sd_dq_callback(struct gspca_dev *gspca_dev)
1736 {
1737 	struct sd *sd = (struct sd *) gspca_dev;
1738 
1739 	/* Set the normal compression settings once we have captured a
1740 	   few uncompressed frames (and AEC has hopefully settled) */
1741 	if (sd->first_frame) {
1742 		sd->first_frame--;
1743 		if (sd->first_frame == 0)
1744 			command_setcompression(gspca_dev);
1745 	}
1746 
1747 	/* Switch flicker control back on if it got turned off */
1748 	restart_flicker(gspca_dev);
1749 
1750 	/* If AEC is enabled, monitor the exposure and
1751 	   adjust the sensor frame rate if needed */
1752 	if (sd->params.exposure.expMode == 2)
1753 		monitor_exposure(gspca_dev);
1754 
1755 	/* Update our knowledge of the camera state */
1756 	do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
1757 	do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
1758 }
1759 
1760 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1761 {
1762 	struct gspca_dev *gspca_dev =
1763 		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1764 	struct sd *sd = (struct sd *)gspca_dev;
1765 
1766 	gspca_dev->usb_err = 0;
1767 
1768 	if (!gspca_dev->streaming && ctrl->id != V4L2_CID_POWER_LINE_FREQUENCY)
1769 		return 0;
1770 
1771 	switch (ctrl->id) {
1772 	case V4L2_CID_BRIGHTNESS:
1773 		sd->params.colourParams.brightness = ctrl->val;
1774 		sd->params.flickerControl.allowableOverExposure =
1775 			find_over_exposure(sd->params.colourParams.brightness);
1776 		gspca_dev->usb_err = command_setcolourparams(gspca_dev);
1777 		if (!gspca_dev->usb_err)
1778 			gspca_dev->usb_err = command_setflickerctrl(gspca_dev);
1779 		break;
1780 	case V4L2_CID_CONTRAST:
1781 		sd->params.colourParams.contrast = ctrl->val;
1782 		gspca_dev->usb_err = command_setcolourparams(gspca_dev);
1783 		break;
1784 	case V4L2_CID_SATURATION:
1785 		sd->params.colourParams.saturation = ctrl->val;
1786 		gspca_dev->usb_err = command_setcolourparams(gspca_dev);
1787 		break;
1788 	case V4L2_CID_POWER_LINE_FREQUENCY:
1789 		sd->mainsFreq = ctrl->val == V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
1790 		sd->params.flickerControl.coarseJump =
1791 			flicker_jumps[sd->mainsFreq]
1792 			[sd->params.sensorFps.baserate]
1793 			[sd->params.sensorFps.divisor];
1794 
1795 		gspca_dev->usb_err = set_flicker(gspca_dev,
1796 			ctrl->val != V4L2_CID_POWER_LINE_FREQUENCY_DISABLED,
1797 			gspca_dev->streaming);
1798 		break;
1799 	case V4L2_CID_ILLUMINATORS_1:
1800 		sd->params.qx3.bottomlight = ctrl->val;
1801 		gspca_dev->usb_err = command_setlights(gspca_dev);
1802 		break;
1803 	case V4L2_CID_ILLUMINATORS_2:
1804 		sd->params.qx3.toplight = ctrl->val;
1805 		gspca_dev->usb_err = command_setlights(gspca_dev);
1806 		break;
1807 	case CPIA1_CID_COMP_TARGET:
1808 		sd->params.compressionTarget.frTargeting = ctrl->val;
1809 		gspca_dev->usb_err = command_setcompressiontarget(gspca_dev);
1810 		break;
1811 	}
1812 	return gspca_dev->usb_err;
1813 }
1814 
1815 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1816 	.s_ctrl = sd_s_ctrl,
1817 };
1818 
1819 static int sd_init_controls(struct gspca_dev *gspca_dev)
1820 {
1821 	struct sd *sd = (struct sd *)gspca_dev;
1822 	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1823 	static const char * const comp_target_menu[] = {
1824 		"Quality",
1825 		"Framerate",
1826 		NULL
1827 	};
1828 	static const struct v4l2_ctrl_config comp_target = {
1829 		.ops = &sd_ctrl_ops,
1830 		.id = CPIA1_CID_COMP_TARGET,
1831 		.type = V4L2_CTRL_TYPE_MENU,
1832 		.name = "Compression Target",
1833 		.qmenu = comp_target_menu,
1834 		.max = 1,
1835 		.def = COMP_TARGET_DEF,
1836 	};
1837 
1838 	gspca_dev->vdev.ctrl_handler = hdl;
1839 	v4l2_ctrl_handler_init(hdl, 7);
1840 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1841 			V4L2_CID_BRIGHTNESS, 0, 100, 1, BRIGHTNESS_DEF);
1842 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1843 			V4L2_CID_CONTRAST, 0, 96, 8, CONTRAST_DEF);
1844 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1845 			V4L2_CID_SATURATION, 0, 100, 1, SATURATION_DEF);
1846 	sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
1847 			V4L2_CID_POWER_LINE_FREQUENCY,
1848 			V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
1849 			FREQ_DEF);
1850 	if (sd->params.qx3.qx3_detected) {
1851 		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1852 				V4L2_CID_ILLUMINATORS_1, 0, 1, 1,
1853 				ILLUMINATORS_1_DEF);
1854 		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1855 				V4L2_CID_ILLUMINATORS_2, 0, 1, 1,
1856 				ILLUMINATORS_2_DEF);
1857 	}
1858 	v4l2_ctrl_new_custom(hdl, &comp_target, NULL);
1859 
1860 	if (hdl->error) {
1861 		pr_err("Could not initialize controls\n");
1862 		return hdl->error;
1863 	}
1864 	return 0;
1865 }
1866 
1867 /* sub-driver description */
1868 static const struct sd_desc sd_desc = {
1869 	.name = MODULE_NAME,
1870 	.config = sd_config,
1871 	.init = sd_init,
1872 	.init_controls = sd_init_controls,
1873 	.start = sd_start,
1874 	.stopN = sd_stopN,
1875 	.dq_callback = sd_dq_callback,
1876 	.pkt_scan = sd_pkt_scan,
1877 #if IS_ENABLED(CONFIG_INPUT)
1878 	.other_input = 1,
1879 #endif
1880 };
1881 
1882 /* -- module initialisation -- */
1883 static const struct usb_device_id device_table[] = {
1884 	{USB_DEVICE(0x0553, 0x0002)},
1885 	{USB_DEVICE(0x0813, 0x0001)},
1886 	{}
1887 };
1888 MODULE_DEVICE_TABLE(usb, device_table);
1889 
1890 /* -- device connect -- */
1891 static int sd_probe(struct usb_interface *intf,
1892 			const struct usb_device_id *id)
1893 {
1894 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1895 				THIS_MODULE);
1896 }
1897 
1898 static struct usb_driver sd_driver = {
1899 	.name = MODULE_NAME,
1900 	.id_table = device_table,
1901 	.probe = sd_probe,
1902 	.disconnect = gspca_disconnect,
1903 #ifdef CONFIG_PM
1904 	.suspend = gspca_suspend,
1905 	.resume = gspca_resume,
1906 	.reset_resume = gspca_resume,
1907 #endif
1908 };
1909 
1910 module_usb_driver(sd_driver);
1911