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