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