Version:  2.0.40 2.2.26 2.4.37 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16

Linux/drivers/media/usb/gspca/cpia1.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us