]> Git Repo - linux.git/blob - drivers/media/usb/gspca/cpia1.c
Linux 6.14-rc3
[linux.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 <[email protected]>
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 <[email protected]>
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 <[email protected]>");
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         OverExposure = min(MaxAllowableOverExposure,
608                            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                 if (sd->params.exposure.gain >= BITS_PER_TYPE(currentexp))
1031                         return -EINVAL;
1032                 currentexp = currentexp << sd->params.exposure.gain;
1033                 sd->params.exposure.gain = 0;
1034                 /* round down current exposure to nearest value */
1035                 startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj;
1036                 if (startexp < 1)
1037                         startexp = 1;
1038                 startexp = (startexp * cj) - 1;
1039                 if (FIRMWARE_VERSION(1, 2))
1040                         while (startexp > MAX_EXP_102)
1041                                 startexp -= cj;
1042                 else
1043                         while (startexp > MAX_EXP)
1044                                 startexp -= cj;
1045                 sd->params.exposure.coarseExpLo = startexp & 0xff;
1046                 sd->params.exposure.coarseExpHi = startexp >> 8;
1047                 if (currentexp > startexp) {
1048                         if (currentexp > (2 * startexp))
1049                                 currentexp = 2 * startexp;
1050                         sd->params.exposure.redComp =
1051                                 COMPGAIN(COMP_RED, currentexp, startexp);
1052                         sd->params.exposure.green1Comp =
1053                                 COMPGAIN(COMP_GREEN1, currentexp, startexp);
1054                         sd->params.exposure.green2Comp =
1055                                 COMPGAIN(COMP_GREEN2, currentexp, startexp);
1056                         sd->params.exposure.blueComp =
1057                                 COMPGAIN(COMP_BLUE, currentexp, startexp);
1058                 } else {
1059                         sd->params.exposure.redComp = COMP_RED;
1060                         sd->params.exposure.green1Comp = COMP_GREEN1;
1061                         sd->params.exposure.green2Comp = COMP_GREEN2;
1062                         sd->params.exposure.blueComp = COMP_BLUE;
1063                 }
1064                 if (FIRMWARE_VERSION(1, 2))
1065                         sd->params.exposure.compMode = 0;
1066                 else
1067                         sd->params.exposure.compMode = 1;
1068
1069                 sd->params.apcor.gain1 = 0x18;
1070                 sd->params.apcor.gain2 = 0x18;
1071                 sd->params.apcor.gain4 = 0x16;
1072                 sd->params.apcor.gain8 = 0x14;
1073         } else {
1074                 sd->params.flickerControl.flickerMode = 0;
1075                 sd->params.flickerControl.disabled = 1;
1076                 /* Average equivalent coarse for each comp channel */
1077                 startexp = EXP_FROM_COMP(COMP_RED,
1078                                 sd->params.exposure.redComp, currentexp);
1079                 startexp += EXP_FROM_COMP(COMP_GREEN1,
1080                                 sd->params.exposure.green1Comp, currentexp);
1081                 startexp += EXP_FROM_COMP(COMP_GREEN2,
1082                                 sd->params.exposure.green2Comp, currentexp);
1083                 startexp += EXP_FROM_COMP(COMP_BLUE,
1084                                 sd->params.exposure.blueComp, currentexp);
1085                 startexp = startexp >> 2;
1086                 while (startexp > MAX_EXP && sd->params.exposure.gain <
1087                        sd->params.exposure.gainMode - 1) {
1088                         startexp = startexp >> 1;
1089                         ++sd->params.exposure.gain;
1090                 }
1091                 if (FIRMWARE_VERSION(1, 2) && startexp > MAX_EXP_102)
1092                         startexp = MAX_EXP_102;
1093                 if (startexp > MAX_EXP)
1094                         startexp = MAX_EXP;
1095                 sd->params.exposure.coarseExpLo = startexp & 0xff;
1096                 sd->params.exposure.coarseExpHi = startexp >> 8;
1097                 sd->params.exposure.redComp = COMP_RED;
1098                 sd->params.exposure.green1Comp = COMP_GREEN1;
1099                 sd->params.exposure.green2Comp = COMP_GREEN2;
1100                 sd->params.exposure.blueComp = COMP_BLUE;
1101                 sd->params.exposure.compMode = 1;
1102                 sd->params.apcor.gain1 = 0x18;
1103                 sd->params.apcor.gain2 = 0x16;
1104                 sd->params.apcor.gain4 = 0x24;
1105                 sd->params.apcor.gain8 = 0x34;
1106         }
1107         sd->params.vlOffset.gain1 = 20;
1108         sd->params.vlOffset.gain2 = 24;
1109         sd->params.vlOffset.gain4 = 26;
1110         sd->params.vlOffset.gain8 = 26;
1111
1112         if (apply) {
1113                 ret = command_setexposure(gspca_dev);
1114                 if (ret)
1115                         return ret;
1116
1117                 ret = command_setapcor(gspca_dev);
1118                 if (ret)
1119                         return ret;
1120
1121                 ret = command_setvloffset(gspca_dev);
1122                 if (ret)
1123                         return ret;
1124
1125                 ret = command_setflickerctrl(gspca_dev);
1126                 if (ret)
1127                         return ret;
1128         }
1129
1130         return 0;
1131 #undef EXP_FROM_COMP
1132 #undef COMPGAIN
1133 }
1134
1135 /* monitor the exposure and adjust the sensor frame rate if needed */
1136 static void monitor_exposure(struct gspca_dev *gspca_dev)
1137 {
1138         struct sd *sd = (struct sd *) gspca_dev;
1139         u8 exp_acc, bcomp, cmd[8];
1140         int ret, light_exp, dark_exp, very_dark_exp;
1141         int old_exposure, new_exposure, framerate;
1142         int setfps = 0, setexp = 0, setflicker = 0;
1143
1144         /* get necessary stats and register settings from camera */
1145         /* do_command can't handle this, so do it ourselves */
1146         cmd[0] = CPIA_COMMAND_ReadVPRegs >> 8;
1147         cmd[1] = CPIA_COMMAND_ReadVPRegs & 0xff;
1148         cmd[2] = 30;
1149         cmd[3] = 4;
1150         cmd[4] = 9;
1151         cmd[5] = 8;
1152         cmd[6] = 8;
1153         cmd[7] = 0;
1154         ret = cpia_usb_transferCmd(gspca_dev, cmd);
1155         if (ret) {
1156                 pr_err("ReadVPRegs(30,4,9,8) - failed: %d\n", ret);
1157                 return;
1158         }
1159         exp_acc = gspca_dev->usb_buf[0];
1160         bcomp = gspca_dev->usb_buf[1];
1161
1162         light_exp = sd->params.colourParams.brightness +
1163                     TC - 50 + EXP_ACC_LIGHT;
1164         if (light_exp > 255)
1165                 light_exp = 255;
1166         dark_exp = sd->params.colourParams.brightness +
1167                    TC - 50 - EXP_ACC_DARK;
1168         if (dark_exp < 0)
1169                 dark_exp = 0;
1170         very_dark_exp = dark_exp / 2;
1171
1172         old_exposure = sd->params.exposure.coarseExpHi * 256 +
1173                        sd->params.exposure.coarseExpLo;
1174
1175         if (!sd->params.flickerControl.disabled) {
1176                 /* Flicker control on */
1177                 int max_comp = FIRMWARE_VERSION(1, 2) ? MAX_COMP :
1178                                                         HIGH_COMP_102;
1179                 bcomp += 128;   /* decode */
1180                 if (bcomp >= max_comp && exp_acc < dark_exp) {
1181                         /* dark */
1182                         if (exp_acc < very_dark_exp) {
1183                                 /* very dark */
1184                                 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1185                                         ++sd->exposure_count;
1186                                 else {
1187                                         sd->exposure_status =
1188                                                 EXPOSURE_VERY_DARK;
1189                                         sd->exposure_count = 1;
1190                                 }
1191                         } else {
1192                                 /* just dark */
1193                                 if (sd->exposure_status == EXPOSURE_DARK)
1194                                         ++sd->exposure_count;
1195                                 else {
1196                                         sd->exposure_status = EXPOSURE_DARK;
1197                                         sd->exposure_count = 1;
1198                                 }
1199                         }
1200                 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1201                         /* light */
1202                         if (old_exposure <= VERY_LOW_EXP) {
1203                                 /* very light */
1204                                 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1205                                         ++sd->exposure_count;
1206                                 else {
1207                                         sd->exposure_status =
1208                                                 EXPOSURE_VERY_LIGHT;
1209                                         sd->exposure_count = 1;
1210                                 }
1211                         } else {
1212                                 /* just light */
1213                                 if (sd->exposure_status == EXPOSURE_LIGHT)
1214                                         ++sd->exposure_count;
1215                                 else {
1216                                         sd->exposure_status = EXPOSURE_LIGHT;
1217                                         sd->exposure_count = 1;
1218                                 }
1219                         }
1220                 } else {
1221                         /* not dark or light */
1222                         sd->exposure_status = EXPOSURE_NORMAL;
1223                 }
1224         } else {
1225                 /* Flicker control off */
1226                 if (old_exposure >= MAX_EXP && exp_acc < dark_exp) {
1227                         /* dark */
1228                         if (exp_acc < very_dark_exp) {
1229                                 /* very dark */
1230                                 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1231                                         ++sd->exposure_count;
1232                                 else {
1233                                         sd->exposure_status =
1234                                                 EXPOSURE_VERY_DARK;
1235                                         sd->exposure_count = 1;
1236                                 }
1237                         } else {
1238                                 /* just dark */
1239                                 if (sd->exposure_status == EXPOSURE_DARK)
1240                                         ++sd->exposure_count;
1241                                 else {
1242                                         sd->exposure_status = EXPOSURE_DARK;
1243                                         sd->exposure_count = 1;
1244                                 }
1245                         }
1246                 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1247                         /* light */
1248                         if (old_exposure <= VERY_LOW_EXP) {
1249                                 /* very light */
1250                                 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1251                                         ++sd->exposure_count;
1252                                 else {
1253                                         sd->exposure_status =
1254                                                 EXPOSURE_VERY_LIGHT;
1255                                         sd->exposure_count = 1;
1256                                 }
1257                         } else {
1258                                 /* just light */
1259                                 if (sd->exposure_status == EXPOSURE_LIGHT)
1260                                         ++sd->exposure_count;
1261                                 else {
1262                                         sd->exposure_status = EXPOSURE_LIGHT;
1263                                         sd->exposure_count = 1;
1264                                 }
1265                         }
1266                 } else {
1267                         /* not dark or light */
1268                         sd->exposure_status = EXPOSURE_NORMAL;
1269                 }
1270         }
1271
1272         framerate = atomic_read(&sd->fps);
1273         if (framerate > 30 || framerate < 1)
1274                 framerate = 1;
1275
1276         if (!sd->params.flickerControl.disabled) {
1277                 /* Flicker control on */
1278                 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1279                      sd->exposure_status == EXPOSURE_DARK) &&
1280                     sd->exposure_count >= DARK_TIME * framerate &&
1281                     sd->params.sensorFps.divisor < 2) {
1282
1283                         /* dark for too long */
1284                         ++sd->params.sensorFps.divisor;
1285                         setfps = 1;
1286
1287                         sd->params.flickerControl.coarseJump =
1288                                 flicker_jumps[sd->mainsFreq]
1289                                              [sd->params.sensorFps.baserate]
1290                                              [sd->params.sensorFps.divisor];
1291                         setflicker = 1;
1292
1293                         new_exposure = sd->params.flickerControl.coarseJump-1;
1294                         while (new_exposure < old_exposure / 2)
1295                                 new_exposure +=
1296                                         sd->params.flickerControl.coarseJump;
1297                         sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1298                         sd->params.exposure.coarseExpHi = new_exposure >> 8;
1299                         setexp = 1;
1300                         sd->exposure_status = EXPOSURE_NORMAL;
1301                         gspca_dbg(gspca_dev, D_CONF, "Automatically decreasing sensor_fps\n");
1302
1303                 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1304                             sd->exposure_status == EXPOSURE_LIGHT) &&
1305                            sd->exposure_count >= LIGHT_TIME * framerate &&
1306                            sd->params.sensorFps.divisor > 0) {
1307
1308                         /* light for too long */
1309                         int max_exp = FIRMWARE_VERSION(1, 2) ? MAX_EXP_102 :
1310                                                                MAX_EXP;
1311                         --sd->params.sensorFps.divisor;
1312                         setfps = 1;
1313
1314                         sd->params.flickerControl.coarseJump =
1315                                 flicker_jumps[sd->mainsFreq]
1316                                              [sd->params.sensorFps.baserate]
1317                                              [sd->params.sensorFps.divisor];
1318                         setflicker = 1;
1319
1320                         new_exposure = sd->params.flickerControl.coarseJump-1;
1321                         while (new_exposure < 2 * old_exposure &&
1322                                new_exposure +
1323                                sd->params.flickerControl.coarseJump < max_exp)
1324                                 new_exposure +=
1325                                         sd->params.flickerControl.coarseJump;
1326                         sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1327                         sd->params.exposure.coarseExpHi = new_exposure >> 8;
1328                         setexp = 1;
1329                         sd->exposure_status = EXPOSURE_NORMAL;
1330                         gspca_dbg(gspca_dev, D_CONF, "Automatically increasing sensor_fps\n");
1331                 }
1332         } else {
1333                 /* Flicker control off */
1334                 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1335                      sd->exposure_status == EXPOSURE_DARK) &&
1336                     sd->exposure_count >= DARK_TIME * framerate &&
1337                     sd->params.sensorFps.divisor < 2) {
1338
1339                         /* dark for too long */
1340                         ++sd->params.sensorFps.divisor;
1341                         setfps = 1;
1342
1343                         if (sd->params.exposure.gain > 0) {
1344                                 --sd->params.exposure.gain;
1345                                 setexp = 1;
1346                         }
1347                         sd->exposure_status = EXPOSURE_NORMAL;
1348                         gspca_dbg(gspca_dev, D_CONF, "Automatically decreasing sensor_fps\n");
1349
1350                 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1351                             sd->exposure_status == EXPOSURE_LIGHT) &&
1352                            sd->exposure_count >= LIGHT_TIME * framerate &&
1353                            sd->params.sensorFps.divisor > 0) {
1354
1355                         /* light for too long */
1356                         --sd->params.sensorFps.divisor;
1357                         setfps = 1;
1358
1359                         if (sd->params.exposure.gain <
1360                             sd->params.exposure.gainMode - 1) {
1361                                 ++sd->params.exposure.gain;
1362                                 setexp = 1;
1363                         }
1364                         sd->exposure_status = EXPOSURE_NORMAL;
1365                         gspca_dbg(gspca_dev, D_CONF, "Automatically increasing sensor_fps\n");
1366                 }
1367         }
1368
1369         if (setexp)
1370                 command_setexposure(gspca_dev);
1371
1372         if (setfps)
1373                 command_setsensorfps(gspca_dev);
1374
1375         if (setflicker)
1376                 command_setflickerctrl(gspca_dev);
1377 }
1378
1379 /*-----------------------------------------------------------------*/
1380 /* if flicker is switched off, this function switches it back on.It checks,
1381    however, that conditions are suitable before restarting it.
1382    This should only be called for firmware version 1.2.
1383
1384    It also adjust the colour balance when an exposure step is detected - as
1385    long as flicker is running
1386 */
1387 static void restart_flicker(struct gspca_dev *gspca_dev)
1388 {
1389         struct sd *sd = (struct sd *) gspca_dev;
1390         int cam_exposure, old_exp;
1391
1392         if (!FIRMWARE_VERSION(1, 2))
1393                 return;
1394
1395         cam_exposure = atomic_read(&sd->cam_exposure);
1396
1397         if (sd->params.flickerControl.flickerMode == 0 ||
1398             cam_exposure == 0)
1399                 return;
1400
1401         old_exp = sd->params.exposure.coarseExpLo +
1402                   sd->params.exposure.coarseExpHi*256;
1403         /*
1404           see how far away camera exposure is from a valid
1405           flicker exposure value
1406         */
1407         cam_exposure %= sd->params.flickerControl.coarseJump;
1408         if (!sd->params.flickerControl.disabled &&
1409             cam_exposure <= sd->params.flickerControl.coarseJump - 3) {
1410                 /* Flicker control auto-disabled */
1411                 sd->params.flickerControl.disabled = 1;
1412         }
1413
1414         if (sd->params.flickerControl.disabled &&
1415             old_exp > sd->params.flickerControl.coarseJump +
1416                       ROUND_UP_EXP_FOR_FLICKER) {
1417                 /* exposure is now high enough to switch
1418                    flicker control back on */
1419                 set_flicker(gspca_dev, 1, 1);
1420         }
1421 }
1422
1423 /* this function is called at probe time */
1424 static int sd_config(struct gspca_dev *gspca_dev,
1425                         const struct usb_device_id *id)
1426 {
1427         struct sd *sd = (struct sd *) gspca_dev;
1428         struct cam *cam;
1429
1430         sd->mainsFreq = FREQ_DEF == V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
1431         reset_camera_params(gspca_dev);
1432
1433         gspca_dbg(gspca_dev, D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)\n",
1434                   id->idVendor, id->idProduct);
1435
1436         cam = &gspca_dev->cam;
1437         cam->cam_mode = mode;
1438         cam->nmodes = ARRAY_SIZE(mode);
1439
1440         goto_low_power(gspca_dev);
1441         /* Check the firmware version. */
1442         sd->params.version.firmwareVersion = 0;
1443         get_version_information(gspca_dev);
1444         if (sd->params.version.firmwareVersion != 1) {
1445                 gspca_err(gspca_dev, "only firmware version 1 is supported (got: %d)\n",
1446                           sd->params.version.firmwareVersion);
1447                 return -ENODEV;
1448         }
1449
1450         /* A bug in firmware 1-02 limits gainMode to 2 */
1451         if (sd->params.version.firmwareRevision <= 2 &&
1452             sd->params.exposure.gainMode > 2) {
1453                 sd->params.exposure.gainMode = 2;
1454         }
1455
1456         /* set QX3 detected flag */
1457         sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 &&
1458                                        sd->params.pnpID.product == 0x0001);
1459         return 0;
1460 }
1461
1462 /* -- start the camera -- */
1463 static int sd_start(struct gspca_dev *gspca_dev)
1464 {
1465         struct sd *sd = (struct sd *) gspca_dev;
1466         int priv, ret;
1467
1468         /* Start the camera in low power mode */
1469         if (goto_low_power(gspca_dev)) {
1470                 if (sd->params.status.systemState != WARM_BOOT_STATE) {
1471                         gspca_err(gspca_dev, "unexpected systemstate: %02x\n",
1472                                   sd->params.status.systemState);
1473                         printstatus(gspca_dev, &sd->params);
1474                         return -ENODEV;
1475                 }
1476
1477                 /* FIXME: this is just dirty trial and error */
1478                 ret = goto_high_power(gspca_dev);
1479                 if (ret)
1480                         return ret;
1481
1482                 ret = do_command(gspca_dev, CPIA_COMMAND_DiscardFrame,
1483                                  0, 0, 0, 0);
1484                 if (ret)
1485                         return ret;
1486
1487                 ret = goto_low_power(gspca_dev);
1488                 if (ret)
1489                         return ret;
1490         }
1491
1492         /* procedure described in developer's guide p3-28 */
1493
1494         /* Check the firmware version. */
1495         sd->params.version.firmwareVersion = 0;
1496         get_version_information(gspca_dev);
1497
1498         /* The fatal error checking should be done after
1499          * the camera powers up (developer's guide p 3-38) */
1500
1501         /* Set streamState before transition to high power to avoid bug
1502          * in firmware 1-02 */
1503         ret = do_command(gspca_dev, CPIA_COMMAND_ModifyCameraStatus,
1504                          STREAMSTATE, 0, STREAM_NOT_READY, 0);
1505         if (ret)
1506                 return ret;
1507
1508         /* GotoHiPower */
1509         ret = goto_high_power(gspca_dev);
1510         if (ret)
1511                 return ret;
1512
1513         /* Check the camera status */
1514         ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1515         if (ret)
1516                 return ret;
1517
1518         if (sd->params.status.fatalError) {
1519                 gspca_err(gspca_dev, "fatal_error: %04x, vp_status: %04x\n",
1520                           sd->params.status.fatalError,
1521                           sd->params.status.vpStatus);
1522                 return -EIO;
1523         }
1524
1525         /* VPVersion can't be retrieved before the camera is in HiPower,
1526          * so get it here instead of in get_version_information. */
1527         ret = do_command(gspca_dev, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0);
1528         if (ret)
1529                 return ret;
1530
1531         /* Determine video mode settings */
1532         sd->params.streamStartLine = 120;
1533
1534         priv = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1535         if (priv & 0x01) { /* crop */
1536                 sd->params.roi.colStart = 2;
1537                 sd->params.roi.rowStart = 6;
1538         } else {
1539                 sd->params.roi.colStart = 0;
1540                 sd->params.roi.rowStart = 0;
1541         }
1542
1543         if (priv & 0x02) { /* quarter */
1544                 sd->params.format.videoSize = VIDEOSIZE_QCIF;
1545                 sd->params.roi.colStart /= 2;
1546                 sd->params.roi.rowStart /= 2;
1547                 sd->params.streamStartLine /= 2;
1548         } else
1549                 sd->params.format.videoSize = VIDEOSIZE_CIF;
1550
1551         sd->params.roi.colEnd = sd->params.roi.colStart +
1552                                 (gspca_dev->pixfmt.width >> 3);
1553         sd->params.roi.rowEnd = sd->params.roi.rowStart +
1554                                 (gspca_dev->pixfmt.height >> 2);
1555
1556         /* And now set the camera to a known state */
1557         ret = do_command(gspca_dev, CPIA_COMMAND_SetGrabMode,
1558                          CPIA_GRAB_CONTINEOUS, 0, 0, 0);
1559         if (ret)
1560                 return ret;
1561         /* We start with compression disabled, as we need one uncompressed
1562            frame to handle later compressed frames */
1563         ret = do_command(gspca_dev, CPIA_COMMAND_SetCompression,
1564                          CPIA_COMPRESSION_NONE,
1565                          NO_DECIMATION, 0, 0);
1566         if (ret)
1567                 return ret;
1568         ret = command_setcompressiontarget(gspca_dev);
1569         if (ret)
1570                 return ret;
1571         ret = command_setcolourparams(gspca_dev);
1572         if (ret)
1573                 return ret;
1574         ret = command_setformat(gspca_dev);
1575         if (ret)
1576                 return ret;
1577         ret = command_setyuvtresh(gspca_dev);
1578         if (ret)
1579                 return ret;
1580         ret = command_setecptiming(gspca_dev);
1581         if (ret)
1582                 return ret;
1583         ret = command_setcompressionparams(gspca_dev);
1584         if (ret)
1585                 return ret;
1586         ret = command_setexposure(gspca_dev);
1587         if (ret)
1588                 return ret;
1589         ret = command_setcolourbalance(gspca_dev);
1590         if (ret)
1591                 return ret;
1592         ret = command_setsensorfps(gspca_dev);
1593         if (ret)
1594                 return ret;
1595         ret = command_setapcor(gspca_dev);
1596         if (ret)
1597                 return ret;
1598         ret = command_setflickerctrl(gspca_dev);
1599         if (ret)
1600                 return ret;
1601         ret = command_setvloffset(gspca_dev);
1602         if (ret)
1603                 return ret;
1604
1605         /* Start stream */
1606         ret = command_resume(gspca_dev);
1607         if (ret)
1608                 return ret;
1609
1610         /* Wait 6 frames before turning compression on for the sensor to get
1611            all settings and AEC/ACB to settle */
1612         sd->first_frame = 6;
1613         sd->exposure_status = EXPOSURE_NORMAL;
1614         sd->exposure_count = 0;
1615         atomic_set(&sd->cam_exposure, 0);
1616         atomic_set(&sd->fps, 0);
1617
1618         return 0;
1619 }
1620
1621 static void sd_stopN(struct gspca_dev *gspca_dev)
1622 {
1623         struct sd *sd __maybe_unused = (struct sd *) gspca_dev;
1624
1625         command_pause(gspca_dev);
1626
1627         /* save camera state for later open (developers guide ch 3.5.3) */
1628         save_camera_state(gspca_dev);
1629
1630         /* GotoLoPower */
1631         goto_low_power(gspca_dev);
1632
1633         /* Update the camera status */
1634         do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1635
1636 #if IS_ENABLED(CONFIG_INPUT)
1637         /* If the last button state is pressed, release it now! */
1638         if (sd->params.qx3.button) {
1639                 /* The camera latch will hold the pressed state until we reset
1640                    the latch, so we do not reset sd->params.qx3.button now, to
1641                    avoid a false keypress being reported the next sd_start */
1642                 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1643                 input_sync(gspca_dev->input_dev);
1644         }
1645 #endif
1646 }
1647
1648 /* this function is called at probe and resume time */
1649 static int sd_init(struct gspca_dev *gspca_dev)
1650 {
1651         struct sd *sd = (struct sd *) gspca_dev;
1652         int ret;
1653
1654         /* Start / Stop the camera to make sure we are talking to
1655            a supported camera, and to get some information from it
1656            to print. */
1657         ret = sd_start(gspca_dev);
1658         if (ret)
1659                 return ret;
1660
1661         /* Ensure the QX3 illuminators' states are restored upon resume,
1662            or disable the illuminator controls, if this isn't a QX3 */
1663         if (sd->params.qx3.qx3_detected)
1664                 command_setlights(gspca_dev);
1665
1666         sd_stopN(gspca_dev);
1667
1668         gspca_dbg(gspca_dev, D_PROBE, "CPIA Version:             %d.%02d (%d.%d)\n",
1669                   sd->params.version.firmwareVersion,
1670                   sd->params.version.firmwareRevision,
1671                   sd->params.version.vcVersion,
1672                   sd->params.version.vcRevision);
1673         gspca_dbg(gspca_dev, D_PROBE, "CPIA PnP-ID:              %04x:%04x:%04x",
1674                   sd->params.pnpID.vendor, sd->params.pnpID.product,
1675                   sd->params.pnpID.deviceRevision);
1676         gspca_dbg(gspca_dev, D_PROBE, "VP-Version:               %d.%d %04x",
1677                   sd->params.vpVersion.vpVersion,
1678                   sd->params.vpVersion.vpRevision,
1679                   sd->params.vpVersion.cameraHeadID);
1680
1681         return 0;
1682 }
1683
1684 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1685                         u8 *data,
1686                         int len)
1687 {
1688         struct sd *sd = (struct sd *) gspca_dev;
1689
1690         /* Check for SOF */
1691         if (len >= 64 &&
1692             data[0] == MAGIC_0 && data[1] == MAGIC_1 &&
1693             data[16] == sd->params.format.videoSize &&
1694             data[17] == sd->params.format.subSample &&
1695             data[18] == sd->params.format.yuvOrder &&
1696             data[24] == sd->params.roi.colStart &&
1697             data[25] == sd->params.roi.colEnd &&
1698             data[26] == sd->params.roi.rowStart &&
1699             data[27] == sd->params.roi.rowEnd) {
1700                 u8 *image;
1701
1702                 atomic_set(&sd->cam_exposure, data[39] * 2);
1703                 atomic_set(&sd->fps, data[41]);
1704
1705                 /* Check for proper EOF for last frame */
1706                 image = gspca_dev->image;
1707                 if (image != NULL &&
1708                     gspca_dev->image_len > 4 &&
1709                     image[gspca_dev->image_len - 4] == 0xff &&
1710                     image[gspca_dev->image_len - 3] == 0xff &&
1711                     image[gspca_dev->image_len - 2] == 0xff &&
1712                     image[gspca_dev->image_len - 1] == 0xff)
1713                         gspca_frame_add(gspca_dev, LAST_PACKET,
1714                                                 NULL, 0);
1715
1716                 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
1717                 return;
1718         }
1719
1720         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1721 }
1722
1723 static void sd_dq_callback(struct gspca_dev *gspca_dev)
1724 {
1725         struct sd *sd = (struct sd *) gspca_dev;
1726
1727         /* Set the normal compression settings once we have captured a
1728            few uncompressed frames (and AEC has hopefully settled) */
1729         if (sd->first_frame) {
1730                 sd->first_frame--;
1731                 if (sd->first_frame == 0)
1732                         command_setcompression(gspca_dev);
1733         }
1734
1735         /* Switch flicker control back on if it got turned off */
1736         restart_flicker(gspca_dev);
1737
1738         /* If AEC is enabled, monitor the exposure and
1739            adjust the sensor frame rate if needed */
1740         if (sd->params.exposure.expMode == 2)
1741                 monitor_exposure(gspca_dev);
1742
1743         /* Update our knowledge of the camera state */
1744         do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
1745         do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
1746 }
1747
1748 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1749 {
1750         struct gspca_dev *gspca_dev =
1751                 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1752         struct sd *sd = (struct sd *)gspca_dev;
1753
1754         gspca_dev->usb_err = 0;
1755
1756         if (!gspca_dev->streaming && ctrl->id != V4L2_CID_POWER_LINE_FREQUENCY)
1757                 return 0;
1758
1759         switch (ctrl->id) {
1760         case V4L2_CID_BRIGHTNESS:
1761                 sd->params.colourParams.brightness = ctrl->val;
1762                 sd->params.flickerControl.allowableOverExposure =
1763                         find_over_exposure(sd->params.colourParams.brightness);
1764                 gspca_dev->usb_err = command_setcolourparams(gspca_dev);
1765                 if (!gspca_dev->usb_err)
1766                         gspca_dev->usb_err = command_setflickerctrl(gspca_dev);
1767                 break;
1768         case V4L2_CID_CONTRAST:
1769                 sd->params.colourParams.contrast = ctrl->val;
1770                 gspca_dev->usb_err = command_setcolourparams(gspca_dev);
1771                 break;
1772         case V4L2_CID_SATURATION:
1773                 sd->params.colourParams.saturation = ctrl->val;
1774                 gspca_dev->usb_err = command_setcolourparams(gspca_dev);
1775                 break;
1776         case V4L2_CID_POWER_LINE_FREQUENCY:
1777                 sd->mainsFreq = ctrl->val == V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
1778                 sd->params.flickerControl.coarseJump =
1779                         flicker_jumps[sd->mainsFreq]
1780                         [sd->params.sensorFps.baserate]
1781                         [sd->params.sensorFps.divisor];
1782
1783                 gspca_dev->usb_err = set_flicker(gspca_dev,
1784                         ctrl->val != V4L2_CID_POWER_LINE_FREQUENCY_DISABLED,
1785                         gspca_dev->streaming);
1786                 break;
1787         case V4L2_CID_ILLUMINATORS_1:
1788                 sd->params.qx3.bottomlight = ctrl->val;
1789                 gspca_dev->usb_err = command_setlights(gspca_dev);
1790                 break;
1791         case V4L2_CID_ILLUMINATORS_2:
1792                 sd->params.qx3.toplight = ctrl->val;
1793                 gspca_dev->usb_err = command_setlights(gspca_dev);
1794                 break;
1795         case CPIA1_CID_COMP_TARGET:
1796                 sd->params.compressionTarget.frTargeting = ctrl->val;
1797                 gspca_dev->usb_err = command_setcompressiontarget(gspca_dev);
1798                 break;
1799         }
1800         return gspca_dev->usb_err;
1801 }
1802
1803 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1804         .s_ctrl = sd_s_ctrl,
1805 };
1806
1807 static int sd_init_controls(struct gspca_dev *gspca_dev)
1808 {
1809         struct sd *sd = (struct sd *)gspca_dev;
1810         struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1811         static const char * const comp_target_menu[] = {
1812                 "Quality",
1813                 "Framerate",
1814                 NULL
1815         };
1816         static const struct v4l2_ctrl_config comp_target = {
1817                 .ops = &sd_ctrl_ops,
1818                 .id = CPIA1_CID_COMP_TARGET,
1819                 .type = V4L2_CTRL_TYPE_MENU,
1820                 .name = "Compression Target",
1821                 .qmenu = comp_target_menu,
1822                 .max = 1,
1823                 .def = COMP_TARGET_DEF,
1824         };
1825
1826         gspca_dev->vdev.ctrl_handler = hdl;
1827         v4l2_ctrl_handler_init(hdl, 7);
1828         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1829                         V4L2_CID_BRIGHTNESS, 0, 100, 1, BRIGHTNESS_DEF);
1830         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1831                         V4L2_CID_CONTRAST, 0, 96, 8, CONTRAST_DEF);
1832         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1833                         V4L2_CID_SATURATION, 0, 100, 1, SATURATION_DEF);
1834         sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
1835                         V4L2_CID_POWER_LINE_FREQUENCY,
1836                         V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
1837                         FREQ_DEF);
1838         if (sd->params.qx3.qx3_detected) {
1839                 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1840                                 V4L2_CID_ILLUMINATORS_1, 0, 1, 1,
1841                                 ILLUMINATORS_1_DEF);
1842                 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1843                                 V4L2_CID_ILLUMINATORS_2, 0, 1, 1,
1844                                 ILLUMINATORS_2_DEF);
1845         }
1846         v4l2_ctrl_new_custom(hdl, &comp_target, NULL);
1847
1848         if (hdl->error) {
1849                 pr_err("Could not initialize controls\n");
1850                 return hdl->error;
1851         }
1852         return 0;
1853 }
1854
1855 /* sub-driver description */
1856 static const struct sd_desc sd_desc = {
1857         .name = MODULE_NAME,
1858         .config = sd_config,
1859         .init = sd_init,
1860         .init_controls = sd_init_controls,
1861         .start = sd_start,
1862         .stopN = sd_stopN,
1863         .dq_callback = sd_dq_callback,
1864         .pkt_scan = sd_pkt_scan,
1865 #if IS_ENABLED(CONFIG_INPUT)
1866         .other_input = 1,
1867 #endif
1868 };
1869
1870 /* -- module initialisation -- */
1871 static const struct usb_device_id device_table[] = {
1872         {USB_DEVICE(0x0553, 0x0002)},
1873         {USB_DEVICE(0x0813, 0x0001)},
1874         {}
1875 };
1876 MODULE_DEVICE_TABLE(usb, device_table);
1877
1878 /* -- device connect -- */
1879 static int sd_probe(struct usb_interface *intf,
1880                         const struct usb_device_id *id)
1881 {
1882         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1883                                 THIS_MODULE);
1884 }
1885
1886 static struct usb_driver sd_driver = {
1887         .name = MODULE_NAME,
1888         .id_table = device_table,
1889         .probe = sd_probe,
1890         .disconnect = gspca_disconnect,
1891 #ifdef CONFIG_PM
1892         .suspend = gspca_suspend,
1893         .resume = gspca_resume,
1894         .reset_resume = gspca_resume,
1895 #endif
1896 };
1897
1898 module_usb_driver(sd_driver);
This page took 0.144163 seconds and 4 git commands to generate.