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