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