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