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

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cpia_usb_transferCmd
  2. do_command
  3. do_command_extended
  4. find_over_exposure
  5. reset_camera_params
  6. printstatus
  7. goto_low_power
  8. goto_high_power
  9. get_version_information
  10. save_camera_state
  11. command_setformat
  12. command_setcolourparams
  13. command_setapcor
  14. command_setvloffset
  15. command_setexposure
  16. command_setcolourbalance
  17. command_setcompressiontarget
  18. command_setyuvtresh
  19. command_setcompressionparams
  20. command_setcompression
  21. command_setsensorfps
  22. command_setflickerctrl
  23. command_setecptiming
  24. command_pause
  25. command_resume
  26. command_setlights
  27. set_flicker
  28. monitor_exposure
  29. restart_flicker
  30. sd_config
  31. sd_start
  32. sd_stopN
  33. sd_init
  34. sd_pkt_scan
  35. sd_dq_callback
  36. sd_s_ctrl
  37. sd_init_controls
  38. sd_probe

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

/* [<][>][^][v][top][bottom][index][help] */