linux/drivers/media/usb/gspca/cpia1.c
<<
>>
Prefs
   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
  36MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
  37MODULE_DESCRIPTION("Vision CPiA");
  38MODULE_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]*/
 239static 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
 244struct 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 */
 364struct 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
 377static 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
 409static 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
 428retry:
 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 */
 448static 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 */
 566static 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
 605static 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  */
 624static 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
 703static 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
 712static 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
 738static 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
 767static 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
 780static 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
 791static 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
 808static 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
 817static 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
 827static 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
 837static 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
 873static 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
 903static 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
 913static 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
 922static 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
 939static 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
 948static 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
 957static 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
 968static 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
 976static int command_pause(struct gspca_dev *gspca_dev)
 977{
 978        return do_command(gspca_dev, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
 979}
 980
 981static 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
 989static 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
1006static 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 */
1141static 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*/
1392static 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 */
1429static 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 -- */
1468static 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
1625static 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 */
1653static 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
1688static 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
1727static 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
1752static 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
1807static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1808        .s_ctrl = sd_s_ctrl,
1809};
1810
1811static 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 */
1860static 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 -- */
1875static const struct usb_device_id device_table[] = {
1876        {USB_DEVICE(0x0553, 0x0002)},
1877        {USB_DEVICE(0x0813, 0x0001)},
1878        {}
1879};
1880MODULE_DEVICE_TABLE(usb, device_table);
1881
1882/* -- device connect -- */
1883static 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
1890static 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
1902module_usb_driver(sd_driver);
1903