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