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