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