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