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