xref: /openbmc/linux/drivers/media/usb/gspca/cpia1.c (revision 54d8c1d3)
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 #include <linux/bitops.h>
22 
23 #include "gspca.h"
24 
25 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
26 MODULE_DESCRIPTION("Vision CPiA");
27 MODULE_LICENSE("GPL");
28 
29 /* constant value's */
30 #define MAGIC_0		0x19
31 #define MAGIC_1		0x68
32 #define DATA_IN		0xc0
33 #define DATA_OUT	0x40
34 #define VIDEOSIZE_QCIF	0	/* 176x144 */
35 #define VIDEOSIZE_CIF	1	/* 352x288 */
36 #define SUBSAMPLE_420	0
37 #define SUBSAMPLE_422	1
38 #define YUVORDER_YUYV	0
39 #define YUVORDER_UYVY	1
40 #define NOT_COMPRESSED	0
41 #define COMPRESSED	1
42 #define NO_DECIMATION	0
43 #define DECIMATION_ENAB	1
44 #define EOI		0xff	/* End Of Image */
45 #define EOL		0xfd	/* End Of Line */
46 #define FRAME_HEADER_SIZE	64
47 
48 /* Image grab modes */
49 #define CPIA_GRAB_SINGLE	0
50 #define CPIA_GRAB_CONTINEOUS	1
51 
52 /* Compression parameters */
53 #define CPIA_COMPRESSION_NONE	0
54 #define CPIA_COMPRESSION_AUTO	1
55 #define CPIA_COMPRESSION_MANUAL	2
56 #define CPIA_COMPRESSION_TARGET_QUALITY         0
57 #define CPIA_COMPRESSION_TARGET_FRAMERATE       1
58 
59 /* Return offsets for GetCameraState */
60 #define SYSTEMSTATE	0
61 #define GRABSTATE	1
62 #define STREAMSTATE	2
63 #define FATALERROR	3
64 #define CMDERROR	4
65 #define DEBUGFLAGS	5
66 #define VPSTATUS	6
67 #define ERRORCODE	7
68 
69 /* SystemState */
70 #define UNINITIALISED_STATE	0
71 #define PASS_THROUGH_STATE	1
72 #define LO_POWER_STATE		2
73 #define HI_POWER_STATE		3
74 #define WARM_BOOT_STATE		4
75 
76 /* GrabState */
77 #define GRAB_IDLE		0
78 #define GRAB_ACTIVE		1
79 #define GRAB_DONE		2
80 
81 /* StreamState */
82 #define STREAM_NOT_READY	0
83 #define STREAM_READY		1
84 #define STREAM_OPEN		2
85 #define STREAM_PAUSED		3
86 #define STREAM_FINISHED		4
87 
88 /* Fatal Error, CmdError, and DebugFlags */
89 #define CPIA_FLAG	  1
90 #define SYSTEM_FLAG	  2
91 #define INT_CTRL_FLAG	  4
92 #define PROCESS_FLAG	  8
93 #define COM_FLAG	 16
94 #define VP_CTRL_FLAG	 32
95 #define CAPTURE_FLAG	 64
96 #define DEBUG_FLAG	128
97 
98 /* VPStatus */
99 #define VP_STATE_OK			0x00
100 
101 #define VP_STATE_FAILED_VIDEOINIT	0x01
102 #define VP_STATE_FAILED_AECACBINIT	0x02
103 #define VP_STATE_AEC_MAX		0x04
104 #define VP_STATE_ACB_BMAX		0x08
105 
106 #define VP_STATE_ACB_RMIN		0x10
107 #define VP_STATE_ACB_GMIN		0x20
108 #define VP_STATE_ACB_RMAX		0x40
109 #define VP_STATE_ACB_GMAX		0x80
110 
111 /* default (minimum) compensation values */
112 #define COMP_RED        220
113 #define COMP_GREEN1     214
114 #define COMP_GREEN2     COMP_GREEN1
115 #define COMP_BLUE       230
116 
117 /* exposure status */
118 #define EXPOSURE_VERY_LIGHT 0
119 #define EXPOSURE_LIGHT      1
120 #define EXPOSURE_NORMAL     2
121 #define EXPOSURE_DARK       3
122 #define EXPOSURE_VERY_DARK  4
123 
124 #define CPIA_MODULE_CPIA			(0 << 5)
125 #define CPIA_MODULE_SYSTEM			(1 << 5)
126 #define CPIA_MODULE_VP_CTRL			(5 << 5)
127 #define CPIA_MODULE_CAPTURE			(6 << 5)
128 #define CPIA_MODULE_DEBUG			(7 << 5)
129 
130 #define INPUT (DATA_IN << 8)
131 #define OUTPUT (DATA_OUT << 8)
132 
133 #define CPIA_COMMAND_GetCPIAVersion	(INPUT | CPIA_MODULE_CPIA | 1)
134 #define CPIA_COMMAND_GetPnPID		(INPUT | CPIA_MODULE_CPIA | 2)
135 #define CPIA_COMMAND_GetCameraStatus	(INPUT | CPIA_MODULE_CPIA | 3)
136 #define CPIA_COMMAND_GotoHiPower	(OUTPUT | CPIA_MODULE_CPIA | 4)
137 #define CPIA_COMMAND_GotoLoPower	(OUTPUT | CPIA_MODULE_CPIA | 5)
138 #define CPIA_COMMAND_GotoSuspend	(OUTPUT | CPIA_MODULE_CPIA | 7)
139 #define CPIA_COMMAND_GotoPassThrough	(OUTPUT | CPIA_MODULE_CPIA | 8)
140 #define CPIA_COMMAND_ModifyCameraStatus	(OUTPUT | CPIA_MODULE_CPIA | 10)
141 
142 #define CPIA_COMMAND_ReadVCRegs		(INPUT | CPIA_MODULE_SYSTEM | 1)
143 #define CPIA_COMMAND_WriteVCReg		(OUTPUT | CPIA_MODULE_SYSTEM | 2)
144 #define CPIA_COMMAND_ReadMCPorts	(INPUT | CPIA_MODULE_SYSTEM | 3)
145 #define CPIA_COMMAND_WriteMCPort	(OUTPUT | CPIA_MODULE_SYSTEM | 4)
146 #define CPIA_COMMAND_SetBaudRate	(OUTPUT | CPIA_MODULE_SYSTEM | 5)
147 #define CPIA_COMMAND_SetECPTiming	(OUTPUT | CPIA_MODULE_SYSTEM | 6)
148 #define CPIA_COMMAND_ReadIDATA		(INPUT | CPIA_MODULE_SYSTEM | 7)
149 #define CPIA_COMMAND_WriteIDATA		(OUTPUT | CPIA_MODULE_SYSTEM | 8)
150 #define CPIA_COMMAND_GenericCall	(OUTPUT | CPIA_MODULE_SYSTEM | 9)
151 #define CPIA_COMMAND_I2CStart		(OUTPUT | CPIA_MODULE_SYSTEM | 10)
152 #define CPIA_COMMAND_I2CStop		(OUTPUT | CPIA_MODULE_SYSTEM | 11)
153 #define CPIA_COMMAND_I2CWrite		(OUTPUT | CPIA_MODULE_SYSTEM | 12)
154 #define CPIA_COMMAND_I2CRead		(INPUT | CPIA_MODULE_SYSTEM | 13)
155 
156 #define CPIA_COMMAND_GetVPVersion	(INPUT | CPIA_MODULE_VP_CTRL | 1)
157 #define CPIA_COMMAND_ResetFrameCounter	(INPUT | CPIA_MODULE_VP_CTRL | 2)
158 #define CPIA_COMMAND_SetColourParams	(OUTPUT | CPIA_MODULE_VP_CTRL | 3)
159 #define CPIA_COMMAND_SetExposure	(OUTPUT | CPIA_MODULE_VP_CTRL | 4)
160 #define CPIA_COMMAND_SetColourBalance	(OUTPUT | CPIA_MODULE_VP_CTRL | 6)
161 #define CPIA_COMMAND_SetSensorFPS	(OUTPUT | CPIA_MODULE_VP_CTRL | 7)
162 #define CPIA_COMMAND_SetVPDefaults	(OUTPUT | CPIA_MODULE_VP_CTRL | 8)
163 #define CPIA_COMMAND_SetApcor		(OUTPUT | CPIA_MODULE_VP_CTRL | 9)
164 #define CPIA_COMMAND_SetFlickerCtrl	(OUTPUT | CPIA_MODULE_VP_CTRL | 10)
165 #define CPIA_COMMAND_SetVLOffset	(OUTPUT | CPIA_MODULE_VP_CTRL | 11)
166 #define CPIA_COMMAND_GetColourParams	(INPUT | CPIA_MODULE_VP_CTRL | 16)
167 #define CPIA_COMMAND_GetColourBalance	(INPUT | CPIA_MODULE_VP_CTRL | 17)
168 #define CPIA_COMMAND_GetExposure	(INPUT | CPIA_MODULE_VP_CTRL | 18)
169 #define CPIA_COMMAND_SetSensorMatrix	(OUTPUT | CPIA_MODULE_VP_CTRL | 19)
170 #define CPIA_COMMAND_ColourBars		(OUTPUT | CPIA_MODULE_VP_CTRL | 25)
171 #define CPIA_COMMAND_ReadVPRegs		(INPUT | CPIA_MODULE_VP_CTRL | 30)
172 #define CPIA_COMMAND_WriteVPReg		(OUTPUT | CPIA_MODULE_VP_CTRL | 31)
173 
174 #define CPIA_COMMAND_GrabFrame		(OUTPUT | CPIA_MODULE_CAPTURE | 1)
175 #define CPIA_COMMAND_UploadFrame	(OUTPUT | CPIA_MODULE_CAPTURE | 2)
176 #define CPIA_COMMAND_SetGrabMode	(OUTPUT | CPIA_MODULE_CAPTURE | 3)
177 #define CPIA_COMMAND_InitStreamCap	(OUTPUT | CPIA_MODULE_CAPTURE | 4)
178 #define CPIA_COMMAND_FiniStreamCap	(OUTPUT | CPIA_MODULE_CAPTURE | 5)
179 #define CPIA_COMMAND_StartStreamCap	(OUTPUT | CPIA_MODULE_CAPTURE | 6)
180 #define CPIA_COMMAND_EndStreamCap	(OUTPUT | CPIA_MODULE_CAPTURE | 7)
181 #define CPIA_COMMAND_SetFormat		(OUTPUT | CPIA_MODULE_CAPTURE | 8)
182 #define CPIA_COMMAND_SetROI		(OUTPUT | CPIA_MODULE_CAPTURE | 9)
183 #define CPIA_COMMAND_SetCompression	(OUTPUT | CPIA_MODULE_CAPTURE | 10)
184 #define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
185 #define CPIA_COMMAND_SetYUVThresh	(OUTPUT | CPIA_MODULE_CAPTURE | 12)
186 #define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
187 #define CPIA_COMMAND_DiscardFrame	(OUTPUT | CPIA_MODULE_CAPTURE | 14)
188 #define CPIA_COMMAND_GrabReset		(OUTPUT | CPIA_MODULE_CAPTURE | 15)
189 
190 #define CPIA_COMMAND_OutputRS232	(OUTPUT | CPIA_MODULE_DEBUG | 1)
191 #define CPIA_COMMAND_AbortProcess	(OUTPUT | CPIA_MODULE_DEBUG | 4)
192 #define CPIA_COMMAND_SetDramPage	(OUTPUT | CPIA_MODULE_DEBUG | 5)
193 #define CPIA_COMMAND_StartDramUpload	(OUTPUT | CPIA_MODULE_DEBUG | 6)
194 #define CPIA_COMMAND_StartDummyDtream	(OUTPUT | CPIA_MODULE_DEBUG | 8)
195 #define CPIA_COMMAND_AbortStream	(OUTPUT | CPIA_MODULE_DEBUG | 9)
196 #define CPIA_COMMAND_DownloadDRAM	(OUTPUT | CPIA_MODULE_DEBUG | 10)
197 #define CPIA_COMMAND_Null		(OUTPUT | CPIA_MODULE_DEBUG | 11)
198 
199 #define ROUND_UP_EXP_FOR_FLICKER 15
200 
201 /* Constants for automatic frame rate adjustment */
202 #define MAX_EXP       302
203 #define MAX_EXP_102   255
204 #define LOW_EXP       140
205 #define VERY_LOW_EXP   70
206 #define TC             94
207 #define	EXP_ACC_DARK   50
208 #define	EXP_ACC_LIGHT  90
209 #define HIGH_COMP_102 160
210 #define MAX_COMP      239
211 #define DARK_TIME       3
212 #define LIGHT_TIME      3
213 
214 #define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \
215 				sd->params.version.firmwareRevision == (y))
216 
217 #define CPIA1_CID_COMP_TARGET (V4L2_CTRL_CLASS_USER + 0x1000)
218 #define BRIGHTNESS_DEF 50
219 #define CONTRAST_DEF 48
220 #define SATURATION_DEF 50
221 #define FREQ_DEF V4L2_CID_POWER_LINE_FREQUENCY_50HZ
222 #define ILLUMINATORS_1_DEF 0
223 #define ILLUMINATORS_2_DEF 0
224 #define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY
225 
226 /* Developer's Guide Table 5 p 3-34
227  * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
228 static u8 flicker_jumps[2][2][4] =
229 { { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
230   { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
231 };
232 
233 struct cam_params {
234 	struct {
235 		u8 firmwareVersion;
236 		u8 firmwareRevision;
237 		u8 vcVersion;
238 		u8 vcRevision;
239 	} version;
240 	struct {
241 		u16 vendor;
242 		u16 product;
243 		u16 deviceRevision;
244 	} pnpID;
245 	struct {
246 		u8 vpVersion;
247 		u8 vpRevision;
248 		u16 cameraHeadID;
249 	} vpVersion;
250 	struct {
251 		u8 systemState;
252 		u8 grabState;
253 		u8 streamState;
254 		u8 fatalError;
255 		u8 cmdError;
256 		u8 debugFlags;
257 		u8 vpStatus;
258 		u8 errorCode;
259 	} status;
260 	struct {
261 		u8 brightness;
262 		u8 contrast;
263 		u8 saturation;
264 	} colourParams;
265 	struct {
266 		u8 gainMode;
267 		u8 expMode;
268 		u8 compMode;
269 		u8 centreWeight;
270 		u8 gain;
271 		u8 fineExp;
272 		u8 coarseExpLo;
273 		u8 coarseExpHi;
274 		u8 redComp;
275 		u8 green1Comp;
276 		u8 green2Comp;
277 		u8 blueComp;
278 	} exposure;
279 	struct {
280 		u8 balanceMode;
281 		u8 redGain;
282 		u8 greenGain;
283 		u8 blueGain;
284 	} colourBalance;
285 	struct {
286 		u8 divisor;
287 		u8 baserate;
288 	} sensorFps;
289 	struct {
290 		u8 gain1;
291 		u8 gain2;
292 		u8 gain4;
293 		u8 gain8;
294 	} apcor;
295 	struct {
296 		u8 disabled;
297 		u8 flickerMode;
298 		u8 coarseJump;
299 		u8 allowableOverExposure;
300 	} flickerControl;
301 	struct {
302 		u8 gain1;
303 		u8 gain2;
304 		u8 gain4;
305 		u8 gain8;
306 	} vlOffset;
307 	struct {
308 		u8 mode;
309 		u8 decimation;
310 	} compression;
311 	struct {
312 		u8 frTargeting;
313 		u8 targetFR;
314 		u8 targetQ;
315 	} compressionTarget;
316 	struct {
317 		u8 yThreshold;
318 		u8 uvThreshold;
319 	} yuvThreshold;
320 	struct {
321 		u8 hysteresis;
322 		u8 threshMax;
323 		u8 smallStep;
324 		u8 largeStep;
325 		u8 decimationHysteresis;
326 		u8 frDiffStepThresh;
327 		u8 qDiffStepThresh;
328 		u8 decimationThreshMod;
329 	} compressionParams;
330 	struct {
331 		u8 videoSize;		/* CIF/QCIF */
332 		u8 subSample;
333 		u8 yuvOrder;
334 	} format;
335 	struct {                        /* Intel QX3 specific data */
336 		u8 qx3_detected;        /* a QX3 is present */
337 		u8 toplight;            /* top light lit , R/W */
338 		u8 bottomlight;         /* bottom light lit, R/W */
339 		u8 button;              /* snapshot button pressed (R/O) */
340 		u8 cradled;             /* microscope is in cradle (R/O) */
341 	} qx3;
342 	struct {
343 		u8 colStart;		/* skip first 8*colStart pixels */
344 		u8 colEnd;		/* finish at 8*colEnd pixels */
345 		u8 rowStart;		/* skip first 4*rowStart lines */
346 		u8 rowEnd;		/* finish at 4*rowEnd lines */
347 	} roi;
348 	u8 ecpTiming;
349 	u8 streamStartLine;
350 };
351 
352 /* specific webcam descriptor */
353 struct sd {
354 	struct gspca_dev gspca_dev;		/* !! must be the first item */
355 	struct cam_params params;		/* camera settings */
356 
357 	atomic_t cam_exposure;
358 	atomic_t fps;
359 	int exposure_count;
360 	u8 exposure_status;
361 	struct v4l2_ctrl *freq;
362 	u8 mainsFreq;				/* 0 = 50hz, 1 = 60hz */
363 	u8 first_frame;
364 };
365 
366 static const struct v4l2_pix_format mode[] = {
367 	{160, 120, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
368 		/* The sizeimage is trial and error, as with low framerates
369 		 *  the camera will pad out usb frames, making the image
370 		 *  data larger than strictly necessary
371 		 */
372 		.bytesperline = 160,
373 		.sizeimage = 65536,
374 		.colorspace = V4L2_COLORSPACE_SRGB,
375 		.priv = 3},
376 	{176, 144, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
377 		.bytesperline = 172,
378 		.sizeimage = 65536,
379 		.colorspace = V4L2_COLORSPACE_SRGB,
380 		.priv = 2},
381 	{320, 240, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
382 		.bytesperline = 320,
383 		.sizeimage = 262144,
384 		.colorspace = V4L2_COLORSPACE_SRGB,
385 		.priv = 1},
386 	{352, 288, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
387 		.bytesperline = 352,
388 		.sizeimage = 262144,
389 		.colorspace = V4L2_COLORSPACE_SRGB,
390 		.priv = 0},
391 };
392 
393 /**********************************************************************
394  *
395  * General functions
396  *
397  **********************************************************************/
398 
399 static int cpia_usb_transferCmd(struct gspca_dev *gspca_dev, u8 *command)
400 {
401 	u8 requesttype;
402 	unsigned int pipe;
403 	int ret, databytes = command[6] | (command[7] << 8);
404 	/* Sometimes we see spurious EPIPE errors */
405 	int retries = 3;
406 
407 	if (command[0] == DATA_IN) {
408 		pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
409 		requesttype = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
410 	} else if (command[0] == DATA_OUT) {
411 		pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
412 		requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE;
413 	} else {
414 		gspca_err(gspca_dev, "Unexpected first byte of command: %x\n",
415 			  command[0]);
416 		return -EINVAL;
417 	}
418 
419 retry:
420 	ret = usb_control_msg(gspca_dev->dev, pipe,
421 			      command[1],
422 			      requesttype,
423 			      command[2] | (command[3] << 8),
424 			      command[4] | (command[5] << 8),
425 			      gspca_dev->usb_buf, databytes, 1000);
426 
427 	if (ret < 0)
428 		pr_err("usb_control_msg %02x, error %d\n", command[1], ret);
429 
430 	if (ret == -EPIPE && retries > 0) {
431 		retries--;
432 		goto retry;
433 	}
434 
435 	return (ret < 0) ? ret : 0;
436 }
437 
438 /* send an arbitrary command to the camera */
439 static int do_command(struct gspca_dev *gspca_dev, u16 command,
440 		      u8 a, u8 b, u8 c, u8 d)
441 {
442 	struct sd *sd = (struct sd *) gspca_dev;
443 	int ret, datasize;
444 	u8 cmd[8];
445 
446 	switch (command) {
447 	case CPIA_COMMAND_GetCPIAVersion:
448 	case CPIA_COMMAND_GetPnPID:
449 	case CPIA_COMMAND_GetCameraStatus:
450 	case CPIA_COMMAND_GetVPVersion:
451 	case CPIA_COMMAND_GetColourParams:
452 	case CPIA_COMMAND_GetColourBalance:
453 	case CPIA_COMMAND_GetExposure:
454 		datasize = 8;
455 		break;
456 	case CPIA_COMMAND_ReadMCPorts:
457 	case CPIA_COMMAND_ReadVCRegs:
458 		datasize = 4;
459 		break;
460 	default:
461 		datasize = 0;
462 		break;
463 	}
464 
465 	cmd[0] = command >> 8;
466 	cmd[1] = command & 0xff;
467 	cmd[2] = a;
468 	cmd[3] = b;
469 	cmd[4] = c;
470 	cmd[5] = d;
471 	cmd[6] = datasize;
472 	cmd[7] = 0;
473 
474 	ret = cpia_usb_transferCmd(gspca_dev, cmd);
475 	if (ret)
476 		return ret;
477 
478 	switch (command) {
479 	case CPIA_COMMAND_GetCPIAVersion:
480 		sd->params.version.firmwareVersion = gspca_dev->usb_buf[0];
481 		sd->params.version.firmwareRevision = gspca_dev->usb_buf[1];
482 		sd->params.version.vcVersion = gspca_dev->usb_buf[2];
483 		sd->params.version.vcRevision = gspca_dev->usb_buf[3];
484 		break;
485 	case CPIA_COMMAND_GetPnPID:
486 		sd->params.pnpID.vendor =
487 			gspca_dev->usb_buf[0] | (gspca_dev->usb_buf[1] << 8);
488 		sd->params.pnpID.product =
489 			gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
490 		sd->params.pnpID.deviceRevision =
491 			gspca_dev->usb_buf[4] | (gspca_dev->usb_buf[5] << 8);
492 		break;
493 	case CPIA_COMMAND_GetCameraStatus:
494 		sd->params.status.systemState = gspca_dev->usb_buf[0];
495 		sd->params.status.grabState = gspca_dev->usb_buf[1];
496 		sd->params.status.streamState = gspca_dev->usb_buf[2];
497 		sd->params.status.fatalError = gspca_dev->usb_buf[3];
498 		sd->params.status.cmdError = gspca_dev->usb_buf[4];
499 		sd->params.status.debugFlags = gspca_dev->usb_buf[5];
500 		sd->params.status.vpStatus = gspca_dev->usb_buf[6];
501 		sd->params.status.errorCode = gspca_dev->usb_buf[7];
502 		break;
503 	case CPIA_COMMAND_GetVPVersion:
504 		sd->params.vpVersion.vpVersion = gspca_dev->usb_buf[0];
505 		sd->params.vpVersion.vpRevision = gspca_dev->usb_buf[1];
506 		sd->params.vpVersion.cameraHeadID =
507 			gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
508 		break;
509 	case CPIA_COMMAND_GetColourParams:
510 		sd->params.colourParams.brightness = gspca_dev->usb_buf[0];
511 		sd->params.colourParams.contrast = gspca_dev->usb_buf[1];
512 		sd->params.colourParams.saturation = gspca_dev->usb_buf[2];
513 		break;
514 	case CPIA_COMMAND_GetColourBalance:
515 		sd->params.colourBalance.redGain = gspca_dev->usb_buf[0];
516 		sd->params.colourBalance.greenGain = gspca_dev->usb_buf[1];
517 		sd->params.colourBalance.blueGain = gspca_dev->usb_buf[2];
518 		break;
519 	case CPIA_COMMAND_GetExposure:
520 		sd->params.exposure.gain = gspca_dev->usb_buf[0];
521 		sd->params.exposure.fineExp = gspca_dev->usb_buf[1];
522 		sd->params.exposure.coarseExpLo = gspca_dev->usb_buf[2];
523 		sd->params.exposure.coarseExpHi = gspca_dev->usb_buf[3];
524 		sd->params.exposure.redComp = gspca_dev->usb_buf[4];
525 		sd->params.exposure.green1Comp = gspca_dev->usb_buf[5];
526 		sd->params.exposure.green2Comp = gspca_dev->usb_buf[6];
527 		sd->params.exposure.blueComp = gspca_dev->usb_buf[7];
528 		break;
529 
530 	case CPIA_COMMAND_ReadMCPorts:
531 		/* test button press */
532 		a = ((gspca_dev->usb_buf[1] & 0x02) == 0);
533 		if (a != sd->params.qx3.button) {
534 #if IS_ENABLED(CONFIG_INPUT)
535 			input_report_key(gspca_dev->input_dev, KEY_CAMERA, a);
536 			input_sync(gspca_dev->input_dev);
537 #endif
538 			sd->params.qx3.button = a;
539 		}
540 		if (sd->params.qx3.button) {
541 			/* button pressed - unlock the latch */
542 			ret = do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
543 				   3, 0xdf, 0xdf, 0);
544 			if (ret)
545 				return ret;
546 			ret = do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
547 				   3, 0xff, 0xff, 0);
548 			if (ret)
549 				return ret;
550 		}
551 
552 		/* test whether microscope is cradled */
553 		sd->params.qx3.cradled = ((gspca_dev->usb_buf[2] & 0x40) == 0);
554 		break;
555 	}
556 
557 	return 0;
558 }
559 
560 /* send a command to the camera with an additional data transaction */
561 static int do_command_extended(struct gspca_dev *gspca_dev, u16 command,
562 			       u8 a, u8 b, u8 c, u8 d,
563 			       u8 e, u8 f, u8 g, u8 h,
564 			       u8 i, u8 j, u8 k, u8 l)
565 {
566 	u8 cmd[8];
567 
568 	cmd[0] = command >> 8;
569 	cmd[1] = command & 0xff;
570 	cmd[2] = a;
571 	cmd[3] = b;
572 	cmd[4] = c;
573 	cmd[5] = d;
574 	cmd[6] = 8;
575 	cmd[7] = 0;
576 	gspca_dev->usb_buf[0] = e;
577 	gspca_dev->usb_buf[1] = f;
578 	gspca_dev->usb_buf[2] = g;
579 	gspca_dev->usb_buf[3] = h;
580 	gspca_dev->usb_buf[4] = i;
581 	gspca_dev->usb_buf[5] = j;
582 	gspca_dev->usb_buf[6] = k;
583 	gspca_dev->usb_buf[7] = l;
584 
585 	return cpia_usb_transferCmd(gspca_dev, cmd);
586 }
587 
588 /*  find_over_exposure
589  *  Finds a suitable value of OverExposure for use with SetFlickerCtrl
590  *  Some calculation is required because this value changes with the brightness
591  *  set with SetColourParameters
592  *
593  *  Parameters: Brightness - last brightness value set with SetColourParameters
594  *
595  *  Returns: OverExposure value to use with SetFlickerCtrl
596  */
597 #define FLICKER_MAX_EXPOSURE                    250
598 #define FLICKER_ALLOWABLE_OVER_EXPOSURE         146
599 #define FLICKER_BRIGHTNESS_CONSTANT             59
600 static int find_over_exposure(int brightness)
601 {
602 	int MaxAllowableOverExposure, OverExposure;
603 
604 	MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness -
605 				   FLICKER_BRIGHTNESS_CONSTANT;
606 
607 	if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE)
608 		OverExposure = MaxAllowableOverExposure;
609 	else
610 		OverExposure = FLICKER_ALLOWABLE_OVER_EXPOSURE;
611 
612 	return OverExposure;
613 }
614 #undef FLICKER_MAX_EXPOSURE
615 #undef FLICKER_ALLOWABLE_OVER_EXPOSURE
616 #undef FLICKER_BRIGHTNESS_CONSTANT
617 
618 /* initialise cam_data structure  */
619 static void reset_camera_params(struct gspca_dev *gspca_dev)
620 {
621 	struct sd *sd = (struct sd *) gspca_dev;
622 	struct cam_params *params = &sd->params;
623 
624 	/* The following parameter values are the defaults from
625 	 * "Software Developer's Guide for CPiA Cameras".  Any changes
626 	 * to the defaults are noted in comments. */
627 	params->colourParams.brightness = BRIGHTNESS_DEF;
628 	params->colourParams.contrast = CONTRAST_DEF;
629 	params->colourParams.saturation = SATURATION_DEF;
630 	params->exposure.gainMode = 4;
631 	params->exposure.expMode = 2;		/* AEC */
632 	params->exposure.compMode = 1;
633 	params->exposure.centreWeight = 1;
634 	params->exposure.gain = 0;
635 	params->exposure.fineExp = 0;
636 	params->exposure.coarseExpLo = 185;
637 	params->exposure.coarseExpHi = 0;
638 	params->exposure.redComp = COMP_RED;
639 	params->exposure.green1Comp = COMP_GREEN1;
640 	params->exposure.green2Comp = COMP_GREEN2;
641 	params->exposure.blueComp = COMP_BLUE;
642 	params->colourBalance.balanceMode = 2;	/* ACB */
643 	params->colourBalance.redGain = 32;
644 	params->colourBalance.greenGain = 6;
645 	params->colourBalance.blueGain = 92;
646 	params->apcor.gain1 = 0x18;
647 	params->apcor.gain2 = 0x16;
648 	params->apcor.gain4 = 0x24;
649 	params->apcor.gain8 = 0x34;
650 	params->vlOffset.gain1 = 20;
651 	params->vlOffset.gain2 = 24;
652 	params->vlOffset.gain4 = 26;
653 	params->vlOffset.gain8 = 26;
654 	params->compressionParams.hysteresis = 3;
655 	params->compressionParams.threshMax = 11;
656 	params->compressionParams.smallStep = 1;
657 	params->compressionParams.largeStep = 3;
658 	params->compressionParams.decimationHysteresis = 2;
659 	params->compressionParams.frDiffStepThresh = 5;
660 	params->compressionParams.qDiffStepThresh = 3;
661 	params->compressionParams.decimationThreshMod = 2;
662 	/* End of default values from Software Developer's Guide */
663 
664 	/* Set Sensor FPS to 15fps. This seems better than 30fps
665 	 * for indoor lighting. */
666 	params->sensorFps.divisor = 1;
667 	params->sensorFps.baserate = 1;
668 
669 	params->flickerControl.flickerMode = 0;
670 	params->flickerControl.disabled = 1;
671 	params->flickerControl.coarseJump =
672 		flicker_jumps[sd->mainsFreq]
673 			     [params->sensorFps.baserate]
674 			     [params->sensorFps.divisor];
675 	params->flickerControl.allowableOverExposure =
676 		find_over_exposure(params->colourParams.brightness);
677 
678 	params->yuvThreshold.yThreshold = 6; /* From windows driver */
679 	params->yuvThreshold.uvThreshold = 6; /* From windows driver */
680 
681 	params->format.subSample = SUBSAMPLE_420;
682 	params->format.yuvOrder = YUVORDER_YUYV;
683 
684 	params->compression.mode = CPIA_COMPRESSION_AUTO;
685 	params->compression.decimation = NO_DECIMATION;
686 
687 	params->compressionTarget.frTargeting = COMP_TARGET_DEF;
688 	params->compressionTarget.targetFR = 15; /* From windows driver */
689 	params->compressionTarget.targetQ = 5; /* From windows driver */
690 
691 	params->qx3.qx3_detected = 0;
692 	params->qx3.toplight = 0;
693 	params->qx3.bottomlight = 0;
694 	params->qx3.button = 0;
695 	params->qx3.cradled = 0;
696 }
697 
698 static void printstatus(struct gspca_dev *gspca_dev, struct cam_params *params)
699 {
700 	gspca_dbg(gspca_dev, D_PROBE, "status: %02x %02x %02x %02x %02x %02x %02x %02x\n",
701 		  params->status.systemState, params->status.grabState,
702 		  params->status.streamState, params->status.fatalError,
703 		  params->status.cmdError, params->status.debugFlags,
704 		  params->status.vpStatus, params->status.errorCode);
705 }
706 
707 static int goto_low_power(struct gspca_dev *gspca_dev)
708 {
709 	struct sd *sd = (struct sd *) gspca_dev;
710 	int ret;
711 
712 	ret = do_command(gspca_dev, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0);
713 	if (ret)
714 		return ret;
715 
716 	ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
717 	if (ret)
718 		return ret;
719 
720 	if (sd->params.status.systemState != LO_POWER_STATE) {
721 		if (sd->params.status.systemState != WARM_BOOT_STATE) {
722 			gspca_err(gspca_dev, "unexpected state after lo power cmd: %02x\n",
723 				  sd->params.status.systemState);
724 			printstatus(gspca_dev, &sd->params);
725 		}
726 		return -EIO;
727 	}
728 
729 	gspca_dbg(gspca_dev, D_CONF, "camera now in LOW power state\n");
730 	return 0;
731 }
732 
733 static int goto_high_power(struct gspca_dev *gspca_dev)
734 {
735 	struct sd *sd = (struct sd *) gspca_dev;
736 	int ret;
737 
738 	ret = do_command(gspca_dev, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0);
739 	if (ret)
740 		return ret;
741 
742 	msleep_interruptible(40);	/* windows driver does it too */
743 
744 	if (signal_pending(current))
745 		return -EINTR;
746 
747 	ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
748 	if (ret)
749 		return ret;
750 
751 	if (sd->params.status.systemState != HI_POWER_STATE) {
752 		gspca_err(gspca_dev, "unexpected state after hi power cmd: %02x\n",
753 			  sd->params.status.systemState);
754 		printstatus(gspca_dev, &sd->params);
755 		return -EIO;
756 	}
757 
758 	gspca_dbg(gspca_dev, D_CONF, "camera now in HIGH power state\n");
759 	return 0;
760 }
761 
762 static int get_version_information(struct gspca_dev *gspca_dev)
763 {
764 	int ret;
765 
766 	/* GetCPIAVersion */
767 	ret = do_command(gspca_dev, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0);
768 	if (ret)
769 		return ret;
770 
771 	/* GetPnPID */
772 	return do_command(gspca_dev, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0);
773 }
774 
775 static int save_camera_state(struct gspca_dev *gspca_dev)
776 {
777 	int ret;
778 
779 	ret = do_command(gspca_dev, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
780 	if (ret)
781 		return ret;
782 
783 	return do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
784 }
785 
786 static int command_setformat(struct gspca_dev *gspca_dev)
787 {
788 	struct sd *sd = (struct sd *) gspca_dev;
789 	int ret;
790 
791 	ret = do_command(gspca_dev, CPIA_COMMAND_SetFormat,
792 			 sd->params.format.videoSize,
793 			 sd->params.format.subSample,
794 			 sd->params.format.yuvOrder, 0);
795 	if (ret)
796 		return ret;
797 
798 	return do_command(gspca_dev, CPIA_COMMAND_SetROI,
799 			  sd->params.roi.colStart, sd->params.roi.colEnd,
800 			  sd->params.roi.rowStart, sd->params.roi.rowEnd);
801 }
802 
803 static int command_setcolourparams(struct gspca_dev *gspca_dev)
804 {
805 	struct sd *sd = (struct sd *) gspca_dev;
806 	return do_command(gspca_dev, CPIA_COMMAND_SetColourParams,
807 			  sd->params.colourParams.brightness,
808 			  sd->params.colourParams.contrast,
809 			  sd->params.colourParams.saturation, 0);
810 }
811 
812 static int command_setapcor(struct gspca_dev *gspca_dev)
813 {
814 	struct sd *sd = (struct sd *) gspca_dev;
815 	return do_command(gspca_dev, CPIA_COMMAND_SetApcor,
816 			  sd->params.apcor.gain1,
817 			  sd->params.apcor.gain2,
818 			  sd->params.apcor.gain4,
819 			  sd->params.apcor.gain8);
820 }
821 
822 static int command_setvloffset(struct gspca_dev *gspca_dev)
823 {
824 	struct sd *sd = (struct sd *) gspca_dev;
825 	return do_command(gspca_dev, CPIA_COMMAND_SetVLOffset,
826 			  sd->params.vlOffset.gain1,
827 			  sd->params.vlOffset.gain2,
828 			  sd->params.vlOffset.gain4,
829 			  sd->params.vlOffset.gain8);
830 }
831 
832 static int command_setexposure(struct gspca_dev *gspca_dev)
833 {
834 	struct sd *sd = (struct sd *) gspca_dev;
835 	int ret;
836 
837 	ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
838 				  sd->params.exposure.gainMode,
839 				  1,
840 				  sd->params.exposure.compMode,
841 				  sd->params.exposure.centreWeight,
842 				  sd->params.exposure.gain,
843 				  sd->params.exposure.fineExp,
844 				  sd->params.exposure.coarseExpLo,
845 				  sd->params.exposure.coarseExpHi,
846 				  sd->params.exposure.redComp,
847 				  sd->params.exposure.green1Comp,
848 				  sd->params.exposure.green2Comp,
849 				  sd->params.exposure.blueComp);
850 	if (ret)
851 		return ret;
852 
853 	if (sd->params.exposure.expMode != 1) {
854 		ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
855 					  0,
856 					  sd->params.exposure.expMode,
857 					  0, 0,
858 					  sd->params.exposure.gain,
859 					  sd->params.exposure.fineExp,
860 					  sd->params.exposure.coarseExpLo,
861 					  sd->params.exposure.coarseExpHi,
862 					  0, 0, 0, 0);
863 	}
864 
865 	return ret;
866 }
867 
868 static int command_setcolourbalance(struct gspca_dev *gspca_dev)
869 {
870 	struct sd *sd = (struct sd *) gspca_dev;
871 
872 	if (sd->params.colourBalance.balanceMode == 1) {
873 		int ret;
874 
875 		ret = do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
876 				 1,
877 				 sd->params.colourBalance.redGain,
878 				 sd->params.colourBalance.greenGain,
879 				 sd->params.colourBalance.blueGain);
880 		if (ret)
881 			return ret;
882 
883 		return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
884 				  3, 0, 0, 0);
885 	}
886 	if (sd->params.colourBalance.balanceMode == 2) {
887 		return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
888 				  2, 0, 0, 0);
889 	}
890 	if (sd->params.colourBalance.balanceMode == 3) {
891 		return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
892 				  3, 0, 0, 0);
893 	}
894 
895 	return -EINVAL;
896 }
897 
898 static int command_setcompressiontarget(struct gspca_dev *gspca_dev)
899 {
900 	struct sd *sd = (struct sd *) gspca_dev;
901 
902 	return do_command(gspca_dev, CPIA_COMMAND_SetCompressionTarget,
903 			  sd->params.compressionTarget.frTargeting,
904 			  sd->params.compressionTarget.targetFR,
905 			  sd->params.compressionTarget.targetQ, 0);
906 }
907 
908 static int command_setyuvtresh(struct gspca_dev *gspca_dev)
909 {
910 	struct sd *sd = (struct sd *) gspca_dev;
911 
912 	return do_command(gspca_dev, CPIA_COMMAND_SetYUVThresh,
913 			  sd->params.yuvThreshold.yThreshold,
914 			  sd->params.yuvThreshold.uvThreshold, 0, 0);
915 }
916 
917 static int command_setcompressionparams(struct gspca_dev *gspca_dev)
918 {
919 	struct sd *sd = (struct sd *) gspca_dev;
920 
921 	return do_command_extended(gspca_dev,
922 			    CPIA_COMMAND_SetCompressionParams,
923 			    0, 0, 0, 0,
924 			    sd->params.compressionParams.hysteresis,
925 			    sd->params.compressionParams.threshMax,
926 			    sd->params.compressionParams.smallStep,
927 			    sd->params.compressionParams.largeStep,
928 			    sd->params.compressionParams.decimationHysteresis,
929 			    sd->params.compressionParams.frDiffStepThresh,
930 			    sd->params.compressionParams.qDiffStepThresh,
931 			    sd->params.compressionParams.decimationThreshMod);
932 }
933 
934 static int command_setcompression(struct gspca_dev *gspca_dev)
935 {
936 	struct sd *sd = (struct sd *) gspca_dev;
937 
938 	return do_command(gspca_dev, CPIA_COMMAND_SetCompression,
939 			  sd->params.compression.mode,
940 			  sd->params.compression.decimation, 0, 0);
941 }
942 
943 static int command_setsensorfps(struct gspca_dev *gspca_dev)
944 {
945 	struct sd *sd = (struct sd *) gspca_dev;
946 
947 	return do_command(gspca_dev, CPIA_COMMAND_SetSensorFPS,
948 			  sd->params.sensorFps.divisor,
949 			  sd->params.sensorFps.baserate, 0, 0);
950 }
951 
952 static int command_setflickerctrl(struct gspca_dev *gspca_dev)
953 {
954 	struct sd *sd = (struct sd *) gspca_dev;
955 
956 	return do_command(gspca_dev, CPIA_COMMAND_SetFlickerCtrl,
957 			  sd->params.flickerControl.flickerMode,
958 			  sd->params.flickerControl.coarseJump,
959 			  sd->params.flickerControl.allowableOverExposure,
960 			  0);
961 }
962 
963 static int command_setecptiming(struct gspca_dev *gspca_dev)
964 {
965 	struct sd *sd = (struct sd *) gspca_dev;
966 
967 	return do_command(gspca_dev, CPIA_COMMAND_SetECPTiming,
968 			  sd->params.ecpTiming, 0, 0, 0);
969 }
970 
971 static int command_pause(struct gspca_dev *gspca_dev)
972 {
973 	return do_command(gspca_dev, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
974 }
975 
976 static int command_resume(struct gspca_dev *gspca_dev)
977 {
978 	struct sd *sd = (struct sd *) gspca_dev;
979 
980 	return do_command(gspca_dev, CPIA_COMMAND_InitStreamCap,
981 			  0, sd->params.streamStartLine, 0, 0);
982 }
983 
984 static int command_setlights(struct gspca_dev *gspca_dev)
985 {
986 	struct sd *sd = (struct sd *) gspca_dev;
987 	int ret, p1, p2;
988 
989 	p1 = (sd->params.qx3.bottomlight == 0) << 1;
990 	p2 = (sd->params.qx3.toplight == 0) << 3;
991 
992 	ret = do_command(gspca_dev, CPIA_COMMAND_WriteVCReg,
993 			 0x90, 0x8f, 0x50, 0);
994 	if (ret)
995 		return ret;
996 
997 	return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0,
998 			  p1 | p2 | 0xe0, 0);
999 }
1000 
1001 static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply)
1002 {
1003 	/* Everything in here is from the Windows driver */
1004 /* define for compgain calculation */
1005 #if 0
1006 #define COMPGAIN(base, curexp, newexp) \
1007     (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
1008 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1009     (u16)((float)curexp * (float)(u8)(curcomp + 128) / \
1010     (float)(u8)(basecomp - 128))
1011 #else
1012   /* equivalent functions without floating point math */
1013 #define COMPGAIN(base, curexp, newexp) \
1014     (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2 * newexp)))
1015 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1016     (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
1017 #endif
1018 
1019 	struct sd *sd = (struct sd *) gspca_dev;
1020 	int currentexp = sd->params.exposure.coarseExpLo +
1021 			 sd->params.exposure.coarseExpHi * 256;
1022 	int ret, startexp;
1023 
1024 	if (on) {
1025 		int cj = sd->params.flickerControl.coarseJump;
1026 		sd->params.flickerControl.flickerMode = 1;
1027 		sd->params.flickerControl.disabled = 0;
1028 		if (sd->params.exposure.expMode != 2) {
1029 			sd->params.exposure.expMode = 2;
1030 			sd->exposure_status = EXPOSURE_NORMAL;
1031 		}
1032 		if (sd->params.exposure.gain >= BITS_PER_TYPE(currentexp))
1033 			return -EINVAL;
1034 		currentexp = currentexp << sd->params.exposure.gain;
1035 		sd->params.exposure.gain = 0;
1036 		/* round down current exposure to nearest value */
1037 		startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj;
1038 		if (startexp < 1)
1039 			startexp = 1;
1040 		startexp = (startexp * cj) - 1;
1041 		if (FIRMWARE_VERSION(1, 2))
1042 			while (startexp > MAX_EXP_102)
1043 				startexp -= cj;
1044 		else
1045 			while (startexp > MAX_EXP)
1046 				startexp -= cj;
1047 		sd->params.exposure.coarseExpLo = startexp & 0xff;
1048 		sd->params.exposure.coarseExpHi = startexp >> 8;
1049 		if (currentexp > startexp) {
1050 			if (currentexp > (2 * startexp))
1051 				currentexp = 2 * startexp;
1052 			sd->params.exposure.redComp =
1053 				COMPGAIN(COMP_RED, currentexp, startexp);
1054 			sd->params.exposure.green1Comp =
1055 				COMPGAIN(COMP_GREEN1, currentexp, startexp);
1056 			sd->params.exposure.green2Comp =
1057 				COMPGAIN(COMP_GREEN2, currentexp, startexp);
1058 			sd->params.exposure.blueComp =
1059 				COMPGAIN(COMP_BLUE, currentexp, startexp);
1060 		} else {
1061 			sd->params.exposure.redComp = COMP_RED;
1062 			sd->params.exposure.green1Comp = COMP_GREEN1;
1063 			sd->params.exposure.green2Comp = COMP_GREEN2;
1064 			sd->params.exposure.blueComp = COMP_BLUE;
1065 		}
1066 		if (FIRMWARE_VERSION(1, 2))
1067 			sd->params.exposure.compMode = 0;
1068 		else
1069 			sd->params.exposure.compMode = 1;
1070 
1071 		sd->params.apcor.gain1 = 0x18;
1072 		sd->params.apcor.gain2 = 0x18;
1073 		sd->params.apcor.gain4 = 0x16;
1074 		sd->params.apcor.gain8 = 0x14;
1075 	} else {
1076 		sd->params.flickerControl.flickerMode = 0;
1077 		sd->params.flickerControl.disabled = 1;
1078 		/* Average equivalent coarse for each comp channel */
1079 		startexp = EXP_FROM_COMP(COMP_RED,
1080 				sd->params.exposure.redComp, currentexp);
1081 		startexp += EXP_FROM_COMP(COMP_GREEN1,
1082 				sd->params.exposure.green1Comp, currentexp);
1083 		startexp += EXP_FROM_COMP(COMP_GREEN2,
1084 				sd->params.exposure.green2Comp, currentexp);
1085 		startexp += EXP_FROM_COMP(COMP_BLUE,
1086 				sd->params.exposure.blueComp, currentexp);
1087 		startexp = startexp >> 2;
1088 		while (startexp > MAX_EXP && sd->params.exposure.gain <
1089 		       sd->params.exposure.gainMode - 1) {
1090 			startexp = startexp >> 1;
1091 			++sd->params.exposure.gain;
1092 		}
1093 		if (FIRMWARE_VERSION(1, 2) && startexp > MAX_EXP_102)
1094 			startexp = MAX_EXP_102;
1095 		if (startexp > MAX_EXP)
1096 			startexp = MAX_EXP;
1097 		sd->params.exposure.coarseExpLo = startexp & 0xff;
1098 		sd->params.exposure.coarseExpHi = startexp >> 8;
1099 		sd->params.exposure.redComp = COMP_RED;
1100 		sd->params.exposure.green1Comp = COMP_GREEN1;
1101 		sd->params.exposure.green2Comp = COMP_GREEN2;
1102 		sd->params.exposure.blueComp = COMP_BLUE;
1103 		sd->params.exposure.compMode = 1;
1104 		sd->params.apcor.gain1 = 0x18;
1105 		sd->params.apcor.gain2 = 0x16;
1106 		sd->params.apcor.gain4 = 0x24;
1107 		sd->params.apcor.gain8 = 0x34;
1108 	}
1109 	sd->params.vlOffset.gain1 = 20;
1110 	sd->params.vlOffset.gain2 = 24;
1111 	sd->params.vlOffset.gain4 = 26;
1112 	sd->params.vlOffset.gain8 = 26;
1113 
1114 	if (apply) {
1115 		ret = command_setexposure(gspca_dev);
1116 		if (ret)
1117 			return ret;
1118 
1119 		ret = command_setapcor(gspca_dev);
1120 		if (ret)
1121 			return ret;
1122 
1123 		ret = command_setvloffset(gspca_dev);
1124 		if (ret)
1125 			return ret;
1126 
1127 		ret = command_setflickerctrl(gspca_dev);
1128 		if (ret)
1129 			return ret;
1130 	}
1131 
1132 	return 0;
1133 #undef EXP_FROM_COMP
1134 #undef COMPGAIN
1135 }
1136 
1137 /* monitor the exposure and adjust the sensor frame rate if needed */
1138 static void monitor_exposure(struct gspca_dev *gspca_dev)
1139 {
1140 	struct sd *sd = (struct sd *) gspca_dev;
1141 	u8 exp_acc, bcomp, cmd[8];
1142 	int ret, light_exp, dark_exp, very_dark_exp;
1143 	int old_exposure, new_exposure, framerate;
1144 	int setfps = 0, setexp = 0, setflicker = 0;
1145 
1146 	/* get necessary stats and register settings from camera */
1147 	/* do_command can't handle this, so do it ourselves */
1148 	cmd[0] = CPIA_COMMAND_ReadVPRegs >> 8;
1149 	cmd[1] = CPIA_COMMAND_ReadVPRegs & 0xff;
1150 	cmd[2] = 30;
1151 	cmd[3] = 4;
1152 	cmd[4] = 9;
1153 	cmd[5] = 8;
1154 	cmd[6] = 8;
1155 	cmd[7] = 0;
1156 	ret = cpia_usb_transferCmd(gspca_dev, cmd);
1157 	if (ret) {
1158 		pr_err("ReadVPRegs(30,4,9,8) - failed: %d\n", ret);
1159 		return;
1160 	}
1161 	exp_acc = gspca_dev->usb_buf[0];
1162 	bcomp = gspca_dev->usb_buf[1];
1163 
1164 	light_exp = sd->params.colourParams.brightness +
1165 		    TC - 50 + EXP_ACC_LIGHT;
1166 	if (light_exp > 255)
1167 		light_exp = 255;
1168 	dark_exp = sd->params.colourParams.brightness +
1169 		   TC - 50 - EXP_ACC_DARK;
1170 	if (dark_exp < 0)
1171 		dark_exp = 0;
1172 	very_dark_exp = dark_exp / 2;
1173 
1174 	old_exposure = sd->params.exposure.coarseExpHi * 256 +
1175 		       sd->params.exposure.coarseExpLo;
1176 
1177 	if (!sd->params.flickerControl.disabled) {
1178 		/* Flicker control on */
1179 		int max_comp = FIRMWARE_VERSION(1, 2) ? MAX_COMP :
1180 							HIGH_COMP_102;
1181 		bcomp += 128;	/* decode */
1182 		if (bcomp >= max_comp && exp_acc < dark_exp) {
1183 			/* dark */
1184 			if (exp_acc < very_dark_exp) {
1185 				/* very dark */
1186 				if (sd->exposure_status == EXPOSURE_VERY_DARK)
1187 					++sd->exposure_count;
1188 				else {
1189 					sd->exposure_status =
1190 						EXPOSURE_VERY_DARK;
1191 					sd->exposure_count = 1;
1192 				}
1193 			} else {
1194 				/* just dark */
1195 				if (sd->exposure_status == EXPOSURE_DARK)
1196 					++sd->exposure_count;
1197 				else {
1198 					sd->exposure_status = EXPOSURE_DARK;
1199 					sd->exposure_count = 1;
1200 				}
1201 			}
1202 		} else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1203 			/* light */
1204 			if (old_exposure <= VERY_LOW_EXP) {
1205 				/* very light */
1206 				if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1207 					++sd->exposure_count;
1208 				else {
1209 					sd->exposure_status =
1210 						EXPOSURE_VERY_LIGHT;
1211 					sd->exposure_count = 1;
1212 				}
1213 			} else {
1214 				/* just light */
1215 				if (sd->exposure_status == EXPOSURE_LIGHT)
1216 					++sd->exposure_count;
1217 				else {
1218 					sd->exposure_status = EXPOSURE_LIGHT;
1219 					sd->exposure_count = 1;
1220 				}
1221 			}
1222 		} else {
1223 			/* not dark or light */
1224 			sd->exposure_status = EXPOSURE_NORMAL;
1225 		}
1226 	} else {
1227 		/* Flicker control off */
1228 		if (old_exposure >= MAX_EXP && exp_acc < dark_exp) {
1229 			/* dark */
1230 			if (exp_acc < very_dark_exp) {
1231 				/* very dark */
1232 				if (sd->exposure_status == EXPOSURE_VERY_DARK)
1233 					++sd->exposure_count;
1234 				else {
1235 					sd->exposure_status =
1236 						EXPOSURE_VERY_DARK;
1237 					sd->exposure_count = 1;
1238 				}
1239 			} else {
1240 				/* just dark */
1241 				if (sd->exposure_status == EXPOSURE_DARK)
1242 					++sd->exposure_count;
1243 				else {
1244 					sd->exposure_status = EXPOSURE_DARK;
1245 					sd->exposure_count = 1;
1246 				}
1247 			}
1248 		} else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1249 			/* light */
1250 			if (old_exposure <= VERY_LOW_EXP) {
1251 				/* very light */
1252 				if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1253 					++sd->exposure_count;
1254 				else {
1255 					sd->exposure_status =
1256 						EXPOSURE_VERY_LIGHT;
1257 					sd->exposure_count = 1;
1258 				}
1259 			} else {
1260 				/* just light */
1261 				if (sd->exposure_status == EXPOSURE_LIGHT)
1262 					++sd->exposure_count;
1263 				else {
1264 					sd->exposure_status = EXPOSURE_LIGHT;
1265 					sd->exposure_count = 1;
1266 				}
1267 			}
1268 		} else {
1269 			/* not dark or light */
1270 			sd->exposure_status = EXPOSURE_NORMAL;
1271 		}
1272 	}
1273 
1274 	framerate = atomic_read(&sd->fps);
1275 	if (framerate > 30 || framerate < 1)
1276 		framerate = 1;
1277 
1278 	if (!sd->params.flickerControl.disabled) {
1279 		/* Flicker control on */
1280 		if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1281 		     sd->exposure_status == EXPOSURE_DARK) &&
1282 		    sd->exposure_count >= DARK_TIME * framerate &&
1283 		    sd->params.sensorFps.divisor < 2) {
1284 
1285 			/* dark for too long */
1286 			++sd->params.sensorFps.divisor;
1287 			setfps = 1;
1288 
1289 			sd->params.flickerControl.coarseJump =
1290 				flicker_jumps[sd->mainsFreq]
1291 					     [sd->params.sensorFps.baserate]
1292 					     [sd->params.sensorFps.divisor];
1293 			setflicker = 1;
1294 
1295 			new_exposure = sd->params.flickerControl.coarseJump-1;
1296 			while (new_exposure < old_exposure / 2)
1297 				new_exposure +=
1298 					sd->params.flickerControl.coarseJump;
1299 			sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1300 			sd->params.exposure.coarseExpHi = new_exposure >> 8;
1301 			setexp = 1;
1302 			sd->exposure_status = EXPOSURE_NORMAL;
1303 			gspca_dbg(gspca_dev, D_CONF, "Automatically decreasing sensor_fps\n");
1304 
1305 		} else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1306 			    sd->exposure_status == EXPOSURE_LIGHT) &&
1307 			   sd->exposure_count >= LIGHT_TIME * framerate &&
1308 			   sd->params.sensorFps.divisor > 0) {
1309 
1310 			/* light for too long */
1311 			int max_exp = FIRMWARE_VERSION(1, 2) ? MAX_EXP_102 :
1312 							       MAX_EXP;
1313 			--sd->params.sensorFps.divisor;
1314 			setfps = 1;
1315 
1316 			sd->params.flickerControl.coarseJump =
1317 				flicker_jumps[sd->mainsFreq]
1318 					     [sd->params.sensorFps.baserate]
1319 					     [sd->params.sensorFps.divisor];
1320 			setflicker = 1;
1321 
1322 			new_exposure = sd->params.flickerControl.coarseJump-1;
1323 			while (new_exposure < 2 * old_exposure &&
1324 			       new_exposure +
1325 			       sd->params.flickerControl.coarseJump < max_exp)
1326 				new_exposure +=
1327 					sd->params.flickerControl.coarseJump;
1328 			sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1329 			sd->params.exposure.coarseExpHi = new_exposure >> 8;
1330 			setexp = 1;
1331 			sd->exposure_status = EXPOSURE_NORMAL;
1332 			gspca_dbg(gspca_dev, D_CONF, "Automatically increasing sensor_fps\n");
1333 		}
1334 	} else {
1335 		/* Flicker control off */
1336 		if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1337 		     sd->exposure_status == EXPOSURE_DARK) &&
1338 		    sd->exposure_count >= DARK_TIME * framerate &&
1339 		    sd->params.sensorFps.divisor < 2) {
1340 
1341 			/* dark for too long */
1342 			++sd->params.sensorFps.divisor;
1343 			setfps = 1;
1344 
1345 			if (sd->params.exposure.gain > 0) {
1346 				--sd->params.exposure.gain;
1347 				setexp = 1;
1348 			}
1349 			sd->exposure_status = EXPOSURE_NORMAL;
1350 			gspca_dbg(gspca_dev, D_CONF, "Automatically decreasing sensor_fps\n");
1351 
1352 		} else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1353 			    sd->exposure_status == EXPOSURE_LIGHT) &&
1354 			   sd->exposure_count >= LIGHT_TIME * framerate &&
1355 			   sd->params.sensorFps.divisor > 0) {
1356 
1357 			/* light for too long */
1358 			--sd->params.sensorFps.divisor;
1359 			setfps = 1;
1360 
1361 			if (sd->params.exposure.gain <
1362 			    sd->params.exposure.gainMode - 1) {
1363 				++sd->params.exposure.gain;
1364 				setexp = 1;
1365 			}
1366 			sd->exposure_status = EXPOSURE_NORMAL;
1367 			gspca_dbg(gspca_dev, D_CONF, "Automatically increasing sensor_fps\n");
1368 		}
1369 	}
1370 
1371 	if (setexp)
1372 		command_setexposure(gspca_dev);
1373 
1374 	if (setfps)
1375 		command_setsensorfps(gspca_dev);
1376 
1377 	if (setflicker)
1378 		command_setflickerctrl(gspca_dev);
1379 }
1380 
1381 /*-----------------------------------------------------------------*/
1382 /* if flicker is switched off, this function switches it back on.It checks,
1383    however, that conditions are suitable before restarting it.
1384    This should only be called for firmware version 1.2.
1385 
1386    It also adjust the colour balance when an exposure step is detected - as
1387    long as flicker is running
1388 */
1389 static void restart_flicker(struct gspca_dev *gspca_dev)
1390 {
1391 	struct sd *sd = (struct sd *) gspca_dev;
1392 	int cam_exposure, old_exp;
1393 
1394 	if (!FIRMWARE_VERSION(1, 2))
1395 		return;
1396 
1397 	cam_exposure = atomic_read(&sd->cam_exposure);
1398 
1399 	if (sd->params.flickerControl.flickerMode == 0 ||
1400 	    cam_exposure == 0)
1401 		return;
1402 
1403 	old_exp = sd->params.exposure.coarseExpLo +
1404 		  sd->params.exposure.coarseExpHi*256;
1405 	/*
1406 	  see how far away camera exposure is from a valid
1407 	  flicker exposure value
1408 	*/
1409 	cam_exposure %= sd->params.flickerControl.coarseJump;
1410 	if (!sd->params.flickerControl.disabled &&
1411 	    cam_exposure <= sd->params.flickerControl.coarseJump - 3) {
1412 		/* Flicker control auto-disabled */
1413 		sd->params.flickerControl.disabled = 1;
1414 	}
1415 
1416 	if (sd->params.flickerControl.disabled &&
1417 	    old_exp > sd->params.flickerControl.coarseJump +
1418 		      ROUND_UP_EXP_FOR_FLICKER) {
1419 		/* exposure is now high enough to switch
1420 		   flicker control back on */
1421 		set_flicker(gspca_dev, 1, 1);
1422 	}
1423 }
1424 
1425 /* this function is called at probe time */
1426 static int sd_config(struct gspca_dev *gspca_dev,
1427 			const struct usb_device_id *id)
1428 {
1429 	struct sd *sd = (struct sd *) gspca_dev;
1430 	struct cam *cam;
1431 
1432 	sd->mainsFreq = FREQ_DEF == V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
1433 	reset_camera_params(gspca_dev);
1434 
1435 	gspca_dbg(gspca_dev, D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)\n",
1436 		  id->idVendor, id->idProduct);
1437 
1438 	cam = &gspca_dev->cam;
1439 	cam->cam_mode = mode;
1440 	cam->nmodes = ARRAY_SIZE(mode);
1441 
1442 	goto_low_power(gspca_dev);
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