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
22 #include "gspca.h"
23
24 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
25 MODULE_DESCRIPTION("Vision CPiA");
26 MODULE_LICENSE("GPL");
27
28 /* constant value's */
29 #define MAGIC_0 0x19
30 #define MAGIC_1 0x68
31 #define DATA_IN 0xc0
32 #define DATA_OUT 0x40
33 #define VIDEOSIZE_QCIF 0 /* 176x144 */
34 #define VIDEOSIZE_CIF 1 /* 352x288 */
35 #define SUBSAMPLE_420 0
36 #define SUBSAMPLE_422 1
37 #define YUVORDER_YUYV 0
38 #define YUVORDER_UYVY 1
39 #define NOT_COMPRESSED 0
40 #define COMPRESSED 1
41 #define NO_DECIMATION 0
42 #define DECIMATION_ENAB 1
43 #define EOI 0xff /* End Of Image */
44 #define EOL 0xfd /* End Of Line */
45 #define FRAME_HEADER_SIZE 64
46
47 /* Image grab modes */
48 #define CPIA_GRAB_SINGLE 0
49 #define CPIA_GRAB_CONTINEOUS 1
50
51 /* Compression parameters */
52 #define CPIA_COMPRESSION_NONE 0
53 #define CPIA_COMPRESSION_AUTO 1
54 #define CPIA_COMPRESSION_MANUAL 2
55 #define CPIA_COMPRESSION_TARGET_QUALITY 0
56 #define CPIA_COMPRESSION_TARGET_FRAMERATE 1
57
58 /* Return offsets for GetCameraState */
59 #define SYSTEMSTATE 0
60 #define GRABSTATE 1
61 #define STREAMSTATE 2
62 #define FATALERROR 3
63 #define CMDERROR 4
64 #define DEBUGFLAGS 5
65 #define VPSTATUS 6
66 #define ERRORCODE 7
67
68 /* SystemState */
69 #define UNINITIALISED_STATE 0
70 #define PASS_THROUGH_STATE 1
71 #define LO_POWER_STATE 2
72 #define HI_POWER_STATE 3
73 #define WARM_BOOT_STATE 4
74
75 /* GrabState */
76 #define GRAB_IDLE 0
77 #define GRAB_ACTIVE 1
78 #define GRAB_DONE 2
79
80 /* StreamState */
81 #define STREAM_NOT_READY 0
82 #define STREAM_READY 1
83 #define STREAM_OPEN 2
84 #define STREAM_PAUSED 3
85 #define STREAM_FINISHED 4
86
87 /* Fatal Error, CmdError, and DebugFlags */
88 #define CPIA_FLAG 1
89 #define SYSTEM_FLAG 2
90 #define INT_CTRL_FLAG 4
91 #define PROCESS_FLAG 8
92 #define COM_FLAG 16
93 #define VP_CTRL_FLAG 32
94 #define CAPTURE_FLAG 64
95 #define DEBUG_FLAG 128
96
97 /* VPStatus */
98 #define VP_STATE_OK 0x00
99
100 #define VP_STATE_FAILED_VIDEOINIT 0x01
101 #define VP_STATE_FAILED_AECACBINIT 0x02
102 #define VP_STATE_AEC_MAX 0x04
103 #define VP_STATE_ACB_BMAX 0x08
104
105 #define VP_STATE_ACB_RMIN 0x10
106 #define VP_STATE_ACB_GMIN 0x20
107 #define VP_STATE_ACB_RMAX 0x40
108 #define VP_STATE_ACB_GMAX 0x80
109
110 /* default (minimum) compensation values */
111 #define COMP_RED 220
112 #define COMP_GREEN1 214
113 #define COMP_GREEN2 COMP_GREEN1
114 #define COMP_BLUE 230
115
116 /* exposure status */
117 #define EXPOSURE_VERY_LIGHT 0
118 #define EXPOSURE_LIGHT 1
119 #define EXPOSURE_NORMAL 2
120 #define EXPOSURE_DARK 3
121 #define EXPOSURE_VERY_DARK 4
122
123 #define CPIA_MODULE_CPIA (0 << 5)
124 #define CPIA_MODULE_SYSTEM (1 << 5)
125 #define CPIA_MODULE_VP_CTRL (5 << 5)
126 #define CPIA_MODULE_CAPTURE (6 << 5)
127 #define CPIA_MODULE_DEBUG (7 << 5)
128
129 #define INPUT (DATA_IN << 8)
130 #define OUTPUT (DATA_OUT << 8)
131
132 #define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)
133 #define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)
134 #define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)
135 #define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)
136 #define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)
137 #define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)
138 #define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)
139 #define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)
140
141 #define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)
142 #define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)
143 #define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)
144 #define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)
145 #define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)
146 #define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)
147 #define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)
148 #define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)
149 #define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)
150 #define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)
151 #define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)
152 #define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)
153 #define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
154
155 #define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
156 #define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)
157 #define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
158 #define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
159 #define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
160 #define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)
161 #define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)
162 #define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)
163 #define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)
164 #define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)
165 #define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)
166 #define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)
167 #define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)
168 #define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)
169 #define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)
170 #define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)
171 #define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)
172
173 #define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)
174 #define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)
175 #define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)
176 #define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)
177 #define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)
178 #define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)
179 #define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)
180 #define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)
181 #define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)
182 #define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)
183 #define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
184 #define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
185 #define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
186 #define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
187 #define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)
188
189 #define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
190 #define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
191 #define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)
192 #define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)
193 #define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
194 #define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
195 #define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
196 #define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)
197
198 #define ROUND_UP_EXP_FOR_FLICKER 15
199
200 /* Constants for automatic frame rate adjustment */
201 #define MAX_EXP 302
202 #define MAX_EXP_102 255
203 #define LOW_EXP 140
204 #define VERY_LOW_EXP 70
205 #define TC 94
206 #define EXP_ACC_DARK 50
207 #define EXP_ACC_LIGHT 90
208 #define HIGH_COMP_102 160
209 #define MAX_COMP 239
210 #define DARK_TIME 3
211 #define LIGHT_TIME 3
212
213 #define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \
214 sd->params.version.firmwareRevision == (y))
215
216 #define CPIA1_CID_COMP_TARGET (V4L2_CTRL_CLASS_USER + 0x1000)
217 #define BRIGHTNESS_DEF 50
218 #define CONTRAST_DEF 48
219 #define SATURATION_DEF 50
220 #define FREQ_DEF V4L2_CID_POWER_LINE_FREQUENCY_50HZ
221 #define ILLUMINATORS_1_DEF 0
222 #define ILLUMINATORS_2_DEF 0
223 #define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY
224
225 /* Developer's Guide Table 5 p 3-34
226 * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
227 static u8 flicker_jumps[2][2][4] =
228 { { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
229 { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
230 };
231
232 struct cam_params {
233 struct {
234 u8 firmwareVersion;
235 u8 firmwareRevision;
236 u8 vcVersion;
237 u8 vcRevision;
238 } version;
239 struct {
240 u16 vendor;
241 u16 product;
242 u16 deviceRevision;
243 } pnpID;
244 struct {
245 u8 vpVersion;
246 u8 vpRevision;
247 u16 cameraHeadID;
248 } vpVersion;
249 struct {
250 u8 systemState;
251 u8 grabState;
252 u8 streamState;
253 u8 fatalError;
254 u8 cmdError;
255 u8 debugFlags;
256 u8 vpStatus;
257 u8 errorCode;
258 } status;
259 struct {
260 u8 brightness;
261 u8 contrast;
262 u8 saturation;
263 } colourParams;
264 struct {
265 u8 gainMode;
266 u8 expMode;
267 u8 compMode;
268 u8 centreWeight;
269 u8 gain;
270 u8 fineExp;
271 u8 coarseExpLo;
272 u8 coarseExpHi;
273 u8 redComp;
274 u8 green1Comp;
275 u8 green2Comp;
276 u8 blueComp;
277 } exposure;
278 struct {
279 u8 balanceMode;
280 u8 redGain;
281 u8 greenGain;
282 u8 blueGain;
283 } colourBalance;
284 struct {
285 u8 divisor;
286 u8 baserate;
287 } sensorFps;
288 struct {
289 u8 gain1;
290 u8 gain2;
291 u8 gain4;
292 u8 gain8;
293 } apcor;
294 struct {
295 u8 disabled;
296 u8 flickerMode;
297 u8 coarseJump;
298 u8 allowableOverExposure;
299 } flickerControl;
300 struct {
301 u8 gain1;
302 u8 gain2;
303 u8 gain4;
304 u8 gain8;
305 } vlOffset;
306 struct {
307 u8 mode;
308 u8 decimation;
309 } compression;
310 struct {
311 u8 frTargeting;
312 u8 targetFR;
313 u8 targetQ;
314 } compressionTarget;
315 struct {
316 u8 yThreshold;
317 u8 uvThreshold;
318 } yuvThreshold;
319 struct {
320 u8 hysteresis;
321 u8 threshMax;
322 u8 smallStep;
323 u8 largeStep;
324 u8 decimationHysteresis;
325 u8 frDiffStepThresh;
326 u8 qDiffStepThresh;
327 u8 decimationThreshMod;
328 } compressionParams;
329 struct {
330 u8 videoSize; /* CIF/QCIF */
331 u8 subSample;
332 u8 yuvOrder;
333 } format;
334 struct { /* Intel QX3 specific data */
335 u8 qx3_detected; /* a QX3 is present */
336 u8 toplight; /* top light lit , R/W */
337 u8 bottomlight; /* bottom light lit, R/W */
338 u8 button; /* snapshot button pressed (R/O) */
339 u8 cradled; /* microscope is in cradle (R/O) */
340 } qx3;
341 struct {
342 u8 colStart; /* skip first 8*colStart pixels */
343 u8 colEnd; /* finish at 8*colEnd pixels */
344 u8 rowStart; /* skip first 4*rowStart lines */
345 u8 rowEnd; /* finish at 4*rowEnd lines */
346 } roi;
347 u8 ecpTiming;
348 u8 streamStartLine;
349 };
350
351 /* specific webcam descriptor */
352 struct sd {
353 struct gspca_dev gspca_dev; /* !! must be the first item */
354 struct cam_params params; /* camera settings */
355
356 atomic_t cam_exposure;
357 atomic_t fps;
358 int exposure_count;
359 u8 exposure_status;
360 struct v4l2_ctrl *freq;
361 u8 mainsFreq; /* 0 = 50hz, 1 = 60hz */
362 u8 first_frame;
363 };
364
365 static const struct v4l2_pix_format mode[] = {
366 {160, 120, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
367 /* The sizeimage is trial and error, as with low framerates
368 * the camera will pad out usb frames, making the image
369 * data larger than strictly necessary
370 */
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 currentexp = currentexp << sd->params.exposure.gain;
1032 sd->params.exposure.gain = 0;
1033 /* round down current exposure to nearest value */
1034 startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj;
1035 if (startexp < 1)
1036 startexp = 1;
1037 startexp = (startexp * cj) - 1;
1038 if (FIRMWARE_VERSION(1, 2))
1039 while (startexp > MAX_EXP_102)
1040 startexp -= cj;
1041 else
1042 while (startexp > MAX_EXP)
1043 startexp -= cj;
1044 sd->params.exposure.coarseExpLo = startexp & 0xff;
1045 sd->params.exposure.coarseExpHi = startexp >> 8;
1046 if (currentexp > startexp) {
1047 if (currentexp > (2 * startexp))
1048 currentexp = 2 * startexp;
1049 sd->params.exposure.redComp =
1050 COMPGAIN(COMP_RED, currentexp, startexp);
1051 sd->params.exposure.green1Comp =
1052 COMPGAIN(COMP_GREEN1, currentexp, startexp);
1053 sd->params.exposure.green2Comp =
1054 COMPGAIN(COMP_GREEN2, currentexp, startexp);
1055 sd->params.exposure.blueComp =
1056 COMPGAIN(COMP_BLUE, currentexp, startexp);
1057 } else {
1058 sd->params.exposure.redComp = COMP_RED;
1059 sd->params.exposure.green1Comp = COMP_GREEN1;
1060 sd->params.exposure.green2Comp = COMP_GREEN2;
1061 sd->params.exposure.blueComp = COMP_BLUE;
1062 }
1063 if (FIRMWARE_VERSION(1, 2))
1064 sd->params.exposure.compMode = 0;
1065 else
1066 sd->params.exposure.compMode = 1;
1067
1068 sd->params.apcor.gain1 = 0x18;
1069 sd->params.apcor.gain2 = 0x18;
1070 sd->params.apcor.gain4 = 0x16;
1071 sd->params.apcor.gain8 = 0x14;
1072 } else {
1073 sd->params.flickerControl.flickerMode = 0;
1074 sd->params.flickerControl.disabled = 1;
1075 /* Average equivalent coarse for each comp channel */
1076 startexp = EXP_FROM_COMP(COMP_RED,
1077 sd->params.exposure.redComp, currentexp);
1078 startexp += EXP_FROM_COMP(COMP_GREEN1,
1079 sd->params.exposure.green1Comp, currentexp);
1080 startexp += EXP_FROM_COMP(COMP_GREEN2,
1081 sd->params.exposure.green2Comp, currentexp);
1082 startexp += EXP_FROM_COMP(COMP_BLUE,
1083 sd->params.exposure.blueComp, currentexp);
1084 startexp = startexp >> 2;
1085 while (startexp > MAX_EXP && sd->params.exposure.gain <
1086 sd->params.exposure.gainMode - 1) {
1087 startexp = startexp >> 1;
1088 ++sd->params.exposure.gain;
1089 }
1090 if (FIRMWARE_VERSION(1, 2) && startexp > MAX_EXP_102)
1091 startexp = MAX_EXP_102;
1092 if (startexp > MAX_EXP)
1093 startexp = MAX_EXP;
1094 sd->params.exposure.coarseExpLo = startexp & 0xff;
1095 sd->params.exposure.coarseExpHi = startexp >> 8;
1096 sd->params.exposure.redComp = COMP_RED;
1097 sd->params.exposure.green1Comp = COMP_GREEN1;
1098 sd->params.exposure.green2Comp = COMP_GREEN2;
1099 sd->params.exposure.blueComp = COMP_BLUE;
1100 sd->params.exposure.compMode = 1;
1101 sd->params.apcor.gain1 = 0x18;
1102 sd->params.apcor.gain2 = 0x16;
1103 sd->params.apcor.gain4 = 0x24;
1104 sd->params.apcor.gain8 = 0x34;
1105 }
1106 sd->params.vlOffset.gain1 = 20;
1107 sd->params.vlOffset.gain2 = 24;
1108 sd->params.vlOffset.gain4 = 26;
1109 sd->params.vlOffset.gain8 = 26;
1110
1111 if (apply) {
1112 ret = command_setexposure(gspca_dev);
1113 if (ret)
1114 return ret;
1115
1116 ret = command_setapcor(gspca_dev);
1117 if (ret)
1118 return ret;
1119
1120 ret = command_setvloffset(gspca_dev);
1121 if (ret)
1122 return ret;
1123
1124 ret = command_setflickerctrl(gspca_dev);
1125 if (ret)
1126 return ret;
1127 }
1128
1129 return 0;
1130 #undef EXP_FROM_COMP
1131 #undef COMPGAIN
1132 }
1133
1134 /* monitor the exposure and adjust the sensor frame rate if needed */
monitor_exposure(struct gspca_dev * gspca_dev)1135 static void monitor_exposure(struct gspca_dev *gspca_dev)
1136 {
1137 struct sd *sd = (struct sd *) gspca_dev;
1138 u8 exp_acc, bcomp, cmd[8];
1139 int ret, light_exp, dark_exp, very_dark_exp;
1140 int old_exposure, new_exposure, framerate;
1141 int setfps = 0, setexp = 0, setflicker = 0;
1142
1143 /* get necessary stats and register settings from camera */
1144 /* do_command can't handle this, so do it ourselves */
1145 cmd[0] = CPIA_COMMAND_ReadVPRegs >> 8;
1146 cmd[1] = CPIA_COMMAND_ReadVPRegs & 0xff;
1147 cmd[2] = 30;
1148 cmd[3] = 4;
1149 cmd[4] = 9;
1150 cmd[5] = 8;
1151 cmd[6] = 8;
1152 cmd[7] = 0;
1153 ret = cpia_usb_transferCmd(gspca_dev, cmd);
1154 if (ret) {
1155 pr_err("ReadVPRegs(30,4,9,8) - failed: %d\n", ret);
1156 return;
1157 }
1158 exp_acc = gspca_dev->usb_buf[0];
1159 bcomp = gspca_dev->usb_buf[1];
1160
1161 light_exp = sd->params.colourParams.brightness +
1162 TC - 50 + EXP_ACC_LIGHT;
1163 if (light_exp > 255)
1164 light_exp = 255;
1165 dark_exp = sd->params.colourParams.brightness +
1166 TC - 50 - EXP_ACC_DARK;
1167 if (dark_exp < 0)
1168 dark_exp = 0;
1169 very_dark_exp = dark_exp / 2;
1170
1171 old_exposure = sd->params.exposure.coarseExpHi * 256 +
1172 sd->params.exposure.coarseExpLo;
1173
1174 if (!sd->params.flickerControl.disabled) {
1175 /* Flicker control on */
1176 int max_comp = FIRMWARE_VERSION(1, 2) ? MAX_COMP :
1177 HIGH_COMP_102;
1178 bcomp += 128; /* decode */
1179 if (bcomp >= max_comp && exp_acc < dark_exp) {
1180 /* dark */
1181 if (exp_acc < very_dark_exp) {
1182 /* very dark */
1183 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1184 ++sd->exposure_count;
1185 else {
1186 sd->exposure_status =
1187 EXPOSURE_VERY_DARK;
1188 sd->exposure_count = 1;
1189 }
1190 } else {
1191 /* just dark */
1192 if (sd->exposure_status == EXPOSURE_DARK)
1193 ++sd->exposure_count;
1194 else {
1195 sd->exposure_status = EXPOSURE_DARK;
1196 sd->exposure_count = 1;
1197 }
1198 }
1199 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1200 /* light */
1201 if (old_exposure <= VERY_LOW_EXP) {
1202 /* very light */
1203 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1204 ++sd->exposure_count;
1205 else {
1206 sd->exposure_status =
1207 EXPOSURE_VERY_LIGHT;
1208 sd->exposure_count = 1;
1209 }
1210 } else {
1211 /* just light */
1212 if (sd->exposure_status == EXPOSURE_LIGHT)
1213 ++sd->exposure_count;
1214 else {
1215 sd->exposure_status = EXPOSURE_LIGHT;
1216 sd->exposure_count = 1;
1217 }
1218 }
1219 } else {
1220 /* not dark or light */
1221 sd->exposure_status = EXPOSURE_NORMAL;
1222 }
1223 } else {
1224 /* Flicker control off */
1225 if (old_exposure >= MAX_EXP && exp_acc < dark_exp) {
1226 /* dark */
1227 if (exp_acc < very_dark_exp) {
1228 /* very dark */
1229 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1230 ++sd->exposure_count;
1231 else {
1232 sd->exposure_status =
1233 EXPOSURE_VERY_DARK;
1234 sd->exposure_count = 1;
1235 }
1236 } else {
1237 /* just dark */
1238 if (sd->exposure_status == EXPOSURE_DARK)
1239 ++sd->exposure_count;
1240 else {
1241 sd->exposure_status = EXPOSURE_DARK;
1242 sd->exposure_count = 1;
1243 }
1244 }
1245 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1246 /* light */
1247 if (old_exposure <= VERY_LOW_EXP) {
1248 /* very light */
1249 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1250 ++sd->exposure_count;
1251 else {
1252 sd->exposure_status =
1253 EXPOSURE_VERY_LIGHT;
1254 sd->exposure_count = 1;
1255 }
1256 } else {
1257 /* just light */
1258 if (sd->exposure_status == EXPOSURE_LIGHT)
1259 ++sd->exposure_count;
1260 else {
1261 sd->exposure_status = EXPOSURE_LIGHT;
1262 sd->exposure_count = 1;
1263 }
1264 }
1265 } else {
1266 /* not dark or light */
1267 sd->exposure_status = EXPOSURE_NORMAL;
1268 }
1269 }
1270
1271 framerate = atomic_read(&sd->fps);
1272 if (framerate > 30 || framerate < 1)
1273 framerate = 1;
1274
1275 if (!sd->params.flickerControl.disabled) {
1276 /* Flicker control on */
1277 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1278 sd->exposure_status == EXPOSURE_DARK) &&
1279 sd->exposure_count >= DARK_TIME * framerate &&
1280 sd->params.sensorFps.divisor < 2) {
1281
1282 /* dark for too long */
1283 ++sd->params.sensorFps.divisor;
1284 setfps = 1;
1285
1286 sd->params.flickerControl.coarseJump =
1287 flicker_jumps[sd->mainsFreq]
1288 [sd->params.sensorFps.baserate]
1289 [sd->params.sensorFps.divisor];
1290 setflicker = 1;
1291
1292 new_exposure = sd->params.flickerControl.coarseJump-1;
1293 while (new_exposure < old_exposure / 2)
1294 new_exposure +=
1295 sd->params.flickerControl.coarseJump;
1296 sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1297 sd->params.exposure.coarseExpHi = new_exposure >> 8;
1298 setexp = 1;
1299 sd->exposure_status = EXPOSURE_NORMAL;
1300 gspca_dbg(gspca_dev, D_CONF, "Automatically decreasing sensor_fps\n");
1301
1302 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1303 sd->exposure_status == EXPOSURE_LIGHT) &&
1304 sd->exposure_count >= LIGHT_TIME * framerate &&
1305 sd->params.sensorFps.divisor > 0) {
1306
1307 /* light for too long */
1308 int max_exp = FIRMWARE_VERSION(1, 2) ? MAX_EXP_102 :
1309 MAX_EXP;
1310 --sd->params.sensorFps.divisor;
1311 setfps = 1;
1312
1313 sd->params.flickerControl.coarseJump =
1314 flicker_jumps[sd->mainsFreq]
1315 [sd->params.sensorFps.baserate]
1316 [sd->params.sensorFps.divisor];
1317 setflicker = 1;
1318
1319 new_exposure = sd->params.flickerControl.coarseJump-1;
1320 while (new_exposure < 2 * old_exposure &&
1321 new_exposure +
1322 sd->params.flickerControl.coarseJump < max_exp)
1323 new_exposure +=
1324 sd->params.flickerControl.coarseJump;
1325 sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1326 sd->params.exposure.coarseExpHi = new_exposure >> 8;
1327 setexp = 1;
1328 sd->exposure_status = EXPOSURE_NORMAL;
1329 gspca_dbg(gspca_dev, D_CONF, "Automatically increasing sensor_fps\n");
1330 }
1331 } else {
1332 /* Flicker control off */
1333 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1334 sd->exposure_status == EXPOSURE_DARK) &&
1335 sd->exposure_count >= DARK_TIME * framerate &&
1336 sd->params.sensorFps.divisor < 2) {
1337
1338 /* dark for too long */
1339 ++sd->params.sensorFps.divisor;
1340 setfps = 1;
1341
1342 if (sd->params.exposure.gain > 0) {
1343 --sd->params.exposure.gain;
1344 setexp = 1;
1345 }
1346 sd->exposure_status = EXPOSURE_NORMAL;
1347 gspca_dbg(gspca_dev, D_CONF, "Automatically decreasing sensor_fps\n");
1348
1349 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1350 sd->exposure_status == EXPOSURE_LIGHT) &&
1351 sd->exposure_count >= LIGHT_TIME * framerate &&
1352 sd->params.sensorFps.divisor > 0) {
1353
1354 /* light for too long */
1355 --sd->params.sensorFps.divisor;
1356 setfps = 1;
1357
1358 if (sd->params.exposure.gain <
1359 sd->params.exposure.gainMode - 1) {
1360 ++sd->params.exposure.gain;
1361 setexp = 1;
1362 }
1363 sd->exposure_status = EXPOSURE_NORMAL;
1364 gspca_dbg(gspca_dev, D_CONF, "Automatically increasing sensor_fps\n");
1365 }
1366 }
1367
1368 if (setexp)
1369 command_setexposure(gspca_dev);
1370
1371 if (setfps)
1372 command_setsensorfps(gspca_dev);
1373
1374 if (setflicker)
1375 command_setflickerctrl(gspca_dev);
1376 }
1377
1378 /*-----------------------------------------------------------------*/
1379 /* if flicker is switched off, this function switches it back on.It checks,
1380 however, that conditions are suitable before restarting it.
1381 This should only be called for firmware version 1.2.
1382
1383 It also adjust the colour balance when an exposure step is detected - as
1384 long as flicker is running
1385 */
restart_flicker(struct gspca_dev * gspca_dev)1386 static void restart_flicker(struct gspca_dev *gspca_dev)
1387 {
1388 struct sd *sd = (struct sd *) gspca_dev;
1389 int cam_exposure, old_exp;
1390
1391 if (!FIRMWARE_VERSION(1, 2))
1392 return;
1393
1394 cam_exposure = atomic_read(&sd->cam_exposure);
1395
1396 if (sd->params.flickerControl.flickerMode == 0 ||
1397 cam_exposure == 0)
1398 return;
1399
1400 old_exp = sd->params.exposure.coarseExpLo +
1401 sd->params.exposure.coarseExpHi*256;
1402 /*
1403 see how far away camera exposure is from a valid
1404 flicker exposure value
1405 */
1406 cam_exposure %= sd->params.flickerControl.coarseJump;
1407 if (!sd->params.flickerControl.disabled &&
1408 cam_exposure <= sd->params.flickerControl.coarseJump - 3) {
1409 /* Flicker control auto-disabled */
1410 sd->params.flickerControl.disabled = 1;
1411 }
1412
1413 if (sd->params.flickerControl.disabled &&
1414 old_exp > sd->params.flickerControl.coarseJump +
1415 ROUND_UP_EXP_FOR_FLICKER) {
1416 /* exposure is now high enough to switch
1417 flicker control back on */
1418 set_flicker(gspca_dev, 1, 1);
1419 }
1420 }
1421
1422 /* this function is called at probe time */
sd_config(struct gspca_dev * gspca_dev,const struct usb_device_id * id)1423 static int sd_config(struct gspca_dev *gspca_dev,
1424 const struct usb_device_id *id)
1425 {
1426 struct sd *sd = (struct sd *) gspca_dev;
1427 struct cam *cam;
1428
1429 sd->mainsFreq = FREQ_DEF == V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
1430 reset_camera_params(gspca_dev);
1431
1432 gspca_dbg(gspca_dev, D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)\n",
1433 id->idVendor, id->idProduct);
1434
1435 cam = &gspca_dev->cam;
1436 cam->cam_mode = mode;
1437 cam->nmodes = ARRAY_SIZE(mode);
1438
1439 goto_low_power(gspca_dev);
1440 /* Check the firmware version. */
1441 sd->params.version.firmwareVersion = 0;
1442 get_version_information(gspca_dev);
1443 if (sd->params.version.firmwareVersion != 1) {
1444 gspca_err(gspca_dev, "only firmware version 1 is supported (got: %d)\n",
1445 sd->params.version.firmwareVersion);
1446 return -ENODEV;
1447 }
1448
1449 /* A bug in firmware 1-02 limits gainMode to 2 */
1450 if (sd->params.version.firmwareRevision <= 2 &&
1451 sd->params.exposure.gainMode > 2) {
1452 sd->params.exposure.gainMode = 2;
1453 }
1454
1455 /* set QX3 detected flag */
1456 sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 &&
1457 sd->params.pnpID.product == 0x0001);
1458 return 0;
1459 }
1460
1461 /* -- start the camera -- */
sd_start(struct gspca_dev * gspca_dev)1462 static int sd_start(struct gspca_dev *gspca_dev)
1463 {
1464 struct sd *sd = (struct sd *) gspca_dev;
1465 int priv, ret;
1466
1467 /* Start the camera in low power mode */
1468 if (goto_low_power(gspca_dev)) {
1469 if (sd->params.status.systemState != WARM_BOOT_STATE) {
1470 gspca_err(gspca_dev, "unexpected systemstate: %02x\n",
1471 sd->params.status.systemState);
1472 printstatus(gspca_dev, &sd->params);
1473 return -ENODEV;
1474 }
1475
1476 /* FIXME: this is just dirty trial and error */
1477 ret = goto_high_power(gspca_dev);
1478 if (ret)
1479 return ret;
1480
1481 ret = do_command(gspca_dev, CPIA_COMMAND_DiscardFrame,
1482 0, 0, 0, 0);
1483 if (ret)
1484 return ret;
1485
1486 ret = goto_low_power(gspca_dev);
1487 if (ret)
1488 return ret;
1489 }
1490
1491 /* procedure described in developer's guide p3-28 */
1492
1493 /* Check the firmware version. */
1494 sd->params.version.firmwareVersion = 0;
1495 get_version_information(gspca_dev);
1496
1497 /* The fatal error checking should be done after
1498 * the camera powers up (developer's guide p 3-38) */
1499
1500 /* Set streamState before transition to high power to avoid bug
1501 * in firmware 1-02 */
1502 ret = do_command(gspca_dev, CPIA_COMMAND_ModifyCameraStatus,
1503 STREAMSTATE, 0, STREAM_NOT_READY, 0);
1504 if (ret)
1505 return ret;
1506
1507 /* GotoHiPower */
1508 ret = goto_high_power(gspca_dev);
1509 if (ret)
1510 return ret;
1511
1512 /* Check the camera status */
1513 ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1514 if (ret)
1515 return ret;
1516
1517 if (sd->params.status.fatalError) {
1518 gspca_err(gspca_dev, "fatal_error: %04x, vp_status: %04x\n",
1519 sd->params.status.fatalError,
1520 sd->params.status.vpStatus);
1521 return -EIO;
1522 }
1523
1524 /* VPVersion can't be retrieved before the camera is in HiPower,
1525 * so get it here instead of in get_version_information. */
1526 ret = do_command(gspca_dev, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0);
1527 if (ret)
1528 return ret;
1529
1530 /* Determine video mode settings */
1531 sd->params.streamStartLine = 120;
1532
1533 priv = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1534 if (priv & 0x01) { /* crop */
1535 sd->params.roi.colStart = 2;
1536 sd->params.roi.rowStart = 6;
1537 } else {
1538 sd->params.roi.colStart = 0;
1539 sd->params.roi.rowStart = 0;
1540 }
1541
1542 if (priv & 0x02) { /* quarter */
1543 sd->params.format.videoSize = VIDEOSIZE_QCIF;
1544 sd->params.roi.colStart /= 2;
1545 sd->params.roi.rowStart /= 2;
1546 sd->params.streamStartLine /= 2;
1547 } else
1548 sd->params.format.videoSize = VIDEOSIZE_CIF;
1549
1550 sd->params.roi.colEnd = sd->params.roi.colStart +
1551 (gspca_dev->pixfmt.width >> 3);
1552 sd->params.roi.rowEnd = sd->params.roi.rowStart +
1553 (gspca_dev->pixfmt.height >> 2);
1554
1555 /* And now set the camera to a known state */
1556 ret = do_command(gspca_dev, CPIA_COMMAND_SetGrabMode,
1557 CPIA_GRAB_CONTINEOUS, 0, 0, 0);
1558 if (ret)
1559 return ret;
1560 /* We start with compression disabled, as we need one uncompressed
1561 frame to handle later compressed frames */
1562 ret = do_command(gspca_dev, CPIA_COMMAND_SetCompression,
1563 CPIA_COMPRESSION_NONE,
1564 NO_DECIMATION, 0, 0);
1565 if (ret)
1566 return ret;
1567 ret = command_setcompressiontarget(gspca_dev);
1568 if (ret)
1569 return ret;
1570 ret = command_setcolourparams(gspca_dev);
1571 if (ret)
1572 return ret;
1573 ret = command_setformat(gspca_dev);
1574 if (ret)
1575 return ret;
1576 ret = command_setyuvtresh(gspca_dev);
1577 if (ret)
1578 return ret;
1579 ret = command_setecptiming(gspca_dev);
1580 if (ret)
1581 return ret;
1582 ret = command_setcompressionparams(gspca_dev);
1583 if (ret)
1584 return ret;
1585 ret = command_setexposure(gspca_dev);
1586 if (ret)
1587 return ret;
1588 ret = command_setcolourbalance(gspca_dev);
1589 if (ret)
1590 return ret;
1591 ret = command_setsensorfps(gspca_dev);
1592 if (ret)
1593 return ret;
1594 ret = command_setapcor(gspca_dev);
1595 if (ret)
1596 return ret;
1597 ret = command_setflickerctrl(gspca_dev);
1598 if (ret)
1599 return ret;
1600 ret = command_setvloffset(gspca_dev);
1601 if (ret)
1602 return ret;
1603
1604 /* Start stream */
1605 ret = command_resume(gspca_dev);
1606 if (ret)
1607 return ret;
1608
1609 /* Wait 6 frames before turning compression on for the sensor to get
1610 all settings and AEC/ACB to settle */
1611 sd->first_frame = 6;
1612 sd->exposure_status = EXPOSURE_NORMAL;
1613 sd->exposure_count = 0;
1614 atomic_set(&sd->cam_exposure, 0);
1615 atomic_set(&sd->fps, 0);
1616
1617 return 0;
1618 }
1619
sd_stopN(struct gspca_dev * gspca_dev)1620 static void sd_stopN(struct gspca_dev *gspca_dev)
1621 {
1622 struct sd *sd __maybe_unused = (struct sd *) gspca_dev;
1623
1624 command_pause(gspca_dev);
1625
1626 /* save camera state for later open (developers guide ch 3.5.3) */
1627 save_camera_state(gspca_dev);
1628
1629 /* GotoLoPower */
1630 goto_low_power(gspca_dev);
1631
1632 /* Update the camera status */
1633 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1634
1635 #if IS_ENABLED(CONFIG_INPUT)
1636 /* If the last button state is pressed, release it now! */
1637 if (sd->params.qx3.button) {
1638 /* The camera latch will hold the pressed state until we reset
1639 the latch, so we do not reset sd->params.qx3.button now, to
1640 avoid a false keypress being reported the next sd_start */
1641 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1642 input_sync(gspca_dev->input_dev);
1643 }
1644 #endif
1645 }
1646
1647 /* this function is called at probe and resume time */
sd_init(struct gspca_dev * gspca_dev)1648 static int sd_init(struct gspca_dev *gspca_dev)
1649 {
1650 struct sd *sd = (struct sd *) gspca_dev;
1651 int ret;
1652
1653 /* Start / Stop the camera to make sure we are talking to
1654 a supported camera, and to get some information from it
1655 to print. */
1656 ret = sd_start(gspca_dev);
1657 if (ret)
1658 return ret;
1659
1660 /* Ensure the QX3 illuminators' states are restored upon resume,
1661 or disable the illuminator controls, if this isn't a QX3 */
1662 if (sd->params.qx3.qx3_detected)
1663 command_setlights(gspca_dev);
1664
1665 sd_stopN(gspca_dev);
1666
1667 gspca_dbg(gspca_dev, D_PROBE, "CPIA Version: %d.%02d (%d.%d)\n",
1668 sd->params.version.firmwareVersion,
1669 sd->params.version.firmwareRevision,
1670 sd->params.version.vcVersion,
1671 sd->params.version.vcRevision);
1672 gspca_dbg(gspca_dev, D_PROBE, "CPIA PnP-ID: %04x:%04x:%04x",
1673 sd->params.pnpID.vendor, sd->params.pnpID.product,
1674 sd->params.pnpID.deviceRevision);
1675 gspca_dbg(gspca_dev, D_PROBE, "VP-Version: %d.%d %04x",
1676 sd->params.vpVersion.vpVersion,
1677 sd->params.vpVersion.vpRevision,
1678 sd->params.vpVersion.cameraHeadID);
1679
1680 return 0;
1681 }
1682
sd_pkt_scan(struct gspca_dev * gspca_dev,u8 * data,int len)1683 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1684 u8 *data,
1685 int len)
1686 {
1687 struct sd *sd = (struct sd *) gspca_dev;
1688
1689 /* Check for SOF */
1690 if (len >= 64 &&
1691 data[0] == MAGIC_0 && data[1] == MAGIC_1 &&
1692 data[16] == sd->params.format.videoSize &&
1693 data[17] == sd->params.format.subSample &&
1694 data[18] == sd->params.format.yuvOrder &&
1695 data[24] == sd->params.roi.colStart &&
1696 data[25] == sd->params.roi.colEnd &&
1697 data[26] == sd->params.roi.rowStart &&
1698 data[27] == sd->params.roi.rowEnd) {
1699 u8 *image;
1700
1701 atomic_set(&sd->cam_exposure, data[39] * 2);
1702 atomic_set(&sd->fps, data[41]);
1703
1704 /* Check for proper EOF for last frame */
1705 image = gspca_dev->image;
1706 if (image != NULL &&
1707 gspca_dev->image_len > 4 &&
1708 image[gspca_dev->image_len - 4] == 0xff &&
1709 image[gspca_dev->image_len - 3] == 0xff &&
1710 image[gspca_dev->image_len - 2] == 0xff &&
1711 image[gspca_dev->image_len - 1] == 0xff)
1712 gspca_frame_add(gspca_dev, LAST_PACKET,
1713 NULL, 0);
1714
1715 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
1716 return;
1717 }
1718
1719 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1720 }
1721
sd_dq_callback(struct gspca_dev * gspca_dev)1722 static void sd_dq_callback(struct gspca_dev *gspca_dev)
1723 {
1724 struct sd *sd = (struct sd *) gspca_dev;
1725
1726 /* Set the normal compression settings once we have captured a
1727 few uncompressed frames (and AEC has hopefully settled) */
1728 if (sd->first_frame) {
1729 sd->first_frame--;
1730 if (sd->first_frame == 0)
1731 command_setcompression(gspca_dev);
1732 }
1733
1734 /* Switch flicker control back on if it got turned off */
1735 restart_flicker(gspca_dev);
1736
1737 /* If AEC is enabled, monitor the exposure and
1738 adjust the sensor frame rate if needed */
1739 if (sd->params.exposure.expMode == 2)
1740 monitor_exposure(gspca_dev);
1741
1742 /* Update our knowledge of the camera state */
1743 do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
1744 do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
1745 }
1746
sd_s_ctrl(struct v4l2_ctrl * ctrl)1747 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1748 {
1749 struct gspca_dev *gspca_dev =
1750 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1751 struct sd *sd = (struct sd *)gspca_dev;
1752
1753 gspca_dev->usb_err = 0;
1754
1755 if (!gspca_dev->streaming && ctrl->id != V4L2_CID_POWER_LINE_FREQUENCY)
1756 return 0;
1757
1758 switch (ctrl->id) {
1759 case V4L2_CID_BRIGHTNESS:
1760 sd->params.colourParams.brightness = ctrl->val;
1761 sd->params.flickerControl.allowableOverExposure =
1762 find_over_exposure(sd->params.colourParams.brightness);
1763 gspca_dev->usb_err = command_setcolourparams(gspca_dev);
1764 if (!gspca_dev->usb_err)
1765 gspca_dev->usb_err = command_setflickerctrl(gspca_dev);
1766 break;
1767 case V4L2_CID_CONTRAST:
1768 sd->params.colourParams.contrast = ctrl->val;
1769 gspca_dev->usb_err = command_setcolourparams(gspca_dev);
1770 break;
1771 case V4L2_CID_SATURATION:
1772 sd->params.colourParams.saturation = ctrl->val;
1773 gspca_dev->usb_err = command_setcolourparams(gspca_dev);
1774 break;
1775 case V4L2_CID_POWER_LINE_FREQUENCY:
1776 sd->mainsFreq = ctrl->val == V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
1777 sd->params.flickerControl.coarseJump =
1778 flicker_jumps[sd->mainsFreq]
1779 [sd->params.sensorFps.baserate]
1780 [sd->params.sensorFps.divisor];
1781
1782 gspca_dev->usb_err = set_flicker(gspca_dev,
1783 ctrl->val != V4L2_CID_POWER_LINE_FREQUENCY_DISABLED,
1784 gspca_dev->streaming);
1785 break;
1786 case V4L2_CID_ILLUMINATORS_1:
1787 sd->params.qx3.bottomlight = ctrl->val;
1788 gspca_dev->usb_err = command_setlights(gspca_dev);
1789 break;
1790 case V4L2_CID_ILLUMINATORS_2:
1791 sd->params.qx3.toplight = ctrl->val;
1792 gspca_dev->usb_err = command_setlights(gspca_dev);
1793 break;
1794 case CPIA1_CID_COMP_TARGET:
1795 sd->params.compressionTarget.frTargeting = ctrl->val;
1796 gspca_dev->usb_err = command_setcompressiontarget(gspca_dev);
1797 break;
1798 }
1799 return gspca_dev->usb_err;
1800 }
1801
1802 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1803 .s_ctrl = sd_s_ctrl,
1804 };
1805
sd_init_controls(struct gspca_dev * gspca_dev)1806 static int sd_init_controls(struct gspca_dev *gspca_dev)
1807 {
1808 struct sd *sd = (struct sd *)gspca_dev;
1809 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1810 static const char * const comp_target_menu[] = {
1811 "Quality",
1812 "Framerate",
1813 NULL
1814 };
1815 static const struct v4l2_ctrl_config comp_target = {
1816 .ops = &sd_ctrl_ops,
1817 .id = CPIA1_CID_COMP_TARGET,
1818 .type = V4L2_CTRL_TYPE_MENU,
1819 .name = "Compression Target",
1820 .qmenu = comp_target_menu,
1821 .max = 1,
1822 .def = COMP_TARGET_DEF,
1823 };
1824
1825 gspca_dev->vdev.ctrl_handler = hdl;
1826 v4l2_ctrl_handler_init(hdl, 7);
1827 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1828 V4L2_CID_BRIGHTNESS, 0, 100, 1, BRIGHTNESS_DEF);
1829 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1830 V4L2_CID_CONTRAST, 0, 96, 8, CONTRAST_DEF);
1831 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1832 V4L2_CID_SATURATION, 0, 100, 1, SATURATION_DEF);
1833 sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
1834 V4L2_CID_POWER_LINE_FREQUENCY,
1835 V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
1836 FREQ_DEF);
1837 if (sd->params.qx3.qx3_detected) {
1838 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1839 V4L2_CID_ILLUMINATORS_1, 0, 1, 1,
1840 ILLUMINATORS_1_DEF);
1841 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1842 V4L2_CID_ILLUMINATORS_2, 0, 1, 1,
1843 ILLUMINATORS_2_DEF);
1844 }
1845 v4l2_ctrl_new_custom(hdl, &comp_target, NULL);
1846
1847 if (hdl->error) {
1848 pr_err("Could not initialize controls\n");
1849 return hdl->error;
1850 }
1851 return 0;
1852 }
1853
1854 /* sub-driver description */
1855 static const struct sd_desc sd_desc = {
1856 .name = MODULE_NAME,
1857 .config = sd_config,
1858 .init = sd_init,
1859 .init_controls = sd_init_controls,
1860 .start = sd_start,
1861 .stopN = sd_stopN,
1862 .dq_callback = sd_dq_callback,
1863 .pkt_scan = sd_pkt_scan,
1864 #if IS_ENABLED(CONFIG_INPUT)
1865 .other_input = 1,
1866 #endif
1867 };
1868
1869 /* -- module initialisation -- */
1870 static const struct usb_device_id device_table[] = {
1871 {USB_DEVICE(0x0553, 0x0002)},
1872 {USB_DEVICE(0x0813, 0x0001)},
1873 {}
1874 };
1875 MODULE_DEVICE_TABLE(usb, device_table);
1876
1877 /* -- device connect -- */
sd_probe(struct usb_interface * intf,const struct usb_device_id * id)1878 static int sd_probe(struct usb_interface *intf,
1879 const struct usb_device_id *id)
1880 {
1881 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1882 THIS_MODULE);
1883 }
1884
1885 static struct usb_driver sd_driver = {
1886 .name = MODULE_NAME,
1887 .id_table = device_table,
1888 .probe = sd_probe,
1889 .disconnect = gspca_disconnect,
1890 #ifdef CONFIG_PM
1891 .suspend = gspca_suspend,
1892 .resume = gspca_resume,
1893 .reset_resume = gspca_resume,
1894 #endif
1895 };
1896
1897 module_usb_driver(sd_driver);
1898