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