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