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