Merge branch 'v6v7' into devel
[linux/fpc-iii.git] / drivers / media / video / gspca / cpia1.c
blob4bf2cab98d64cd2a4c38a8f77de2ffb57f1decf5
1 /*
2 * cpia CPiA (1) gspca driver
4 * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com>
6 * This module is adapted from the in kernel v4l1 cpia driver which is :
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
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.
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.
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
29 #define MODULE_NAME "cpia1"
31 #include "gspca.h"
33 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
34 MODULE_DESCRIPTION("Vision CPiA");
35 MODULE_LICENSE("GPL");
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
56 /* Image grab modes */
57 #define CPIA_GRAB_SINGLE 0
58 #define CPIA_GRAB_CONTINEOUS 1
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
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
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
84 /* GrabState */
85 #define GRAB_IDLE 0
86 #define GRAB_ACTIVE 1
87 #define GRAB_DONE 2
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
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
106 /* VPStatus */
107 #define VP_STATE_OK 0x00
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
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
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
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
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)
138 #define INPUT (DATA_IN << 8)
139 #define OUTPUT (DATA_OUT << 8)
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)
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)
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)
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)
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)
207 #define ROUND_UP_EXP_FOR_FLICKER 15
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
222 #define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \
223 sd->params.version.firmwareRevision == (y))
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} }
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;
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 */
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;
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 static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val);
377 static int sd_getilluminator1(struct gspca_dev *gspca_dev, __s32 *val);
378 static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val);
379 static int sd_getilluminator2(struct gspca_dev *gspca_dev, __s32 *val);
381 static const struct ctrl sd_ctrls[] = {
383 #define BRIGHTNESS_IDX 0
385 .id = V4L2_CID_BRIGHTNESS,
386 .type = V4L2_CTRL_TYPE_INTEGER,
387 .name = "Brightness",
388 .minimum = 0,
389 .maximum = 100,
390 .step = 1,
391 #define BRIGHTNESS_DEF 50
392 .default_value = BRIGHTNESS_DEF,
393 .flags = 0,
395 .set = sd_setbrightness,
396 .get = sd_getbrightness,
398 #define CONTRAST_IDX 1
401 .id = V4L2_CID_CONTRAST,
402 .type = V4L2_CTRL_TYPE_INTEGER,
403 .name = "Contrast",
404 .minimum = 0,
405 .maximum = 96,
406 .step = 8,
407 #define CONTRAST_DEF 48
408 .default_value = CONTRAST_DEF,
410 .set = sd_setcontrast,
411 .get = sd_getcontrast,
413 #define SATURATION_IDX 2
416 .id = V4L2_CID_SATURATION,
417 .type = V4L2_CTRL_TYPE_INTEGER,
418 .name = "Saturation",
419 .minimum = 0,
420 .maximum = 100,
421 .step = 1,
422 #define SATURATION_DEF 50
423 .default_value = SATURATION_DEF,
425 .set = sd_setsaturation,
426 .get = sd_getsaturation,
428 #define POWER_LINE_FREQUENCY_IDX 3
431 .id = V4L2_CID_POWER_LINE_FREQUENCY,
432 .type = V4L2_CTRL_TYPE_MENU,
433 .name = "Light frequency filter",
434 .minimum = 0,
435 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
436 .step = 1,
437 #define FREQ_DEF 1
438 .default_value = FREQ_DEF,
440 .set = sd_setfreq,
441 .get = sd_getfreq,
443 #define ILLUMINATORS_1_IDX 4
446 .id = V4L2_CID_ILLUMINATORS_1,
447 .type = V4L2_CTRL_TYPE_BOOLEAN,
448 .name = "Illuminator 1",
449 .minimum = 0,
450 .maximum = 1,
451 .step = 1,
452 #define ILLUMINATORS_1_DEF 0
453 .default_value = ILLUMINATORS_1_DEF,
455 .set = sd_setilluminator1,
456 .get = sd_getilluminator1,
458 #define ILLUMINATORS_2_IDX 5
461 .id = V4L2_CID_ILLUMINATORS_2,
462 .type = V4L2_CTRL_TYPE_BOOLEAN,
463 .name = "Illuminator 2",
464 .minimum = 0,
465 .maximum = 1,
466 .step = 1,
467 #define ILLUMINATORS_2_DEF 0
468 .default_value = ILLUMINATORS_2_DEF,
470 .set = sd_setilluminator2,
471 .get = sd_getilluminator2,
473 #define COMP_TARGET_IDX 6
476 #define V4L2_CID_COMP_TARGET V4L2_CID_PRIVATE_BASE
477 .id = V4L2_CID_COMP_TARGET,
478 .type = V4L2_CTRL_TYPE_MENU,
479 .name = "Compression Target",
480 .minimum = 0,
481 .maximum = 1,
482 .step = 1,
483 #define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY
484 .default_value = COMP_TARGET_DEF,
486 .set = sd_setcomptarget,
487 .get = sd_getcomptarget,
491 static const struct v4l2_pix_format mode[] = {
492 {160, 120, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
493 /* The sizeimage is trial and error, as with low framerates
494 the camera will pad out usb frames, making the image
495 data larger then strictly necessary */
496 .bytesperline = 160,
497 .sizeimage = 65536,
498 .colorspace = V4L2_COLORSPACE_SRGB,
499 .priv = 3},
500 {176, 144, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
501 .bytesperline = 172,
502 .sizeimage = 65536,
503 .colorspace = V4L2_COLORSPACE_SRGB,
504 .priv = 2},
505 {320, 240, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
506 .bytesperline = 320,
507 .sizeimage = 262144,
508 .colorspace = V4L2_COLORSPACE_SRGB,
509 .priv = 1},
510 {352, 288, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
511 .bytesperline = 352,
512 .sizeimage = 262144,
513 .colorspace = V4L2_COLORSPACE_SRGB,
514 .priv = 0},
517 /**********************************************************************
519 * General functions
521 **********************************************************************/
523 static int cpia_usb_transferCmd(struct gspca_dev *gspca_dev, u8 *command)
525 u8 requesttype;
526 unsigned int pipe;
527 int ret, databytes = command[6] | (command[7] << 8);
528 /* Sometimes we see spurious EPIPE errors */
529 int retries = 3;
531 if (command[0] == DATA_IN) {
532 pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
533 requesttype = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
534 } else if (command[0] == DATA_OUT) {
535 pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
536 requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE;
537 } else {
538 PDEBUG(D_ERR, "Unexpected first byte of command: %x",
539 command[0]);
540 return -EINVAL;
543 retry:
544 ret = usb_control_msg(gspca_dev->dev, pipe,
545 command[1],
546 requesttype,
547 command[2] | (command[3] << 8),
548 command[4] | (command[5] << 8),
549 gspca_dev->usb_buf, databytes, 1000);
551 if (ret < 0)
552 err("usb_control_msg %02x, error %d", command[1],
553 ret);
555 if (ret == -EPIPE && retries > 0) {
556 retries--;
557 goto retry;
560 return (ret < 0) ? ret : 0;
563 /* send an arbitrary command to the camera */
564 static int do_command(struct gspca_dev *gspca_dev, u16 command,
565 u8 a, u8 b, u8 c, u8 d)
567 struct sd *sd = (struct sd *) gspca_dev;
568 int ret, datasize;
569 u8 cmd[8];
571 switch (command) {
572 case CPIA_COMMAND_GetCPIAVersion:
573 case CPIA_COMMAND_GetPnPID:
574 case CPIA_COMMAND_GetCameraStatus:
575 case CPIA_COMMAND_GetVPVersion:
576 case CPIA_COMMAND_GetColourParams:
577 case CPIA_COMMAND_GetColourBalance:
578 case CPIA_COMMAND_GetExposure:
579 datasize = 8;
580 break;
581 case CPIA_COMMAND_ReadMCPorts:
582 case CPIA_COMMAND_ReadVCRegs:
583 datasize = 4;
584 break;
585 default:
586 datasize = 0;
587 break;
590 cmd[0] = command >> 8;
591 cmd[1] = command & 0xff;
592 cmd[2] = a;
593 cmd[3] = b;
594 cmd[4] = c;
595 cmd[5] = d;
596 cmd[6] = datasize;
597 cmd[7] = 0;
599 ret = cpia_usb_transferCmd(gspca_dev, cmd);
600 if (ret)
601 return ret;
603 switch (command) {
604 case CPIA_COMMAND_GetCPIAVersion:
605 sd->params.version.firmwareVersion = gspca_dev->usb_buf[0];
606 sd->params.version.firmwareRevision = gspca_dev->usb_buf[1];
607 sd->params.version.vcVersion = gspca_dev->usb_buf[2];
608 sd->params.version.vcRevision = gspca_dev->usb_buf[3];
609 break;
610 case CPIA_COMMAND_GetPnPID:
611 sd->params.pnpID.vendor =
612 gspca_dev->usb_buf[0] | (gspca_dev->usb_buf[1] << 8);
613 sd->params.pnpID.product =
614 gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
615 sd->params.pnpID.deviceRevision =
616 gspca_dev->usb_buf[4] | (gspca_dev->usb_buf[5] << 8);
617 break;
618 case CPIA_COMMAND_GetCameraStatus:
619 sd->params.status.systemState = gspca_dev->usb_buf[0];
620 sd->params.status.grabState = gspca_dev->usb_buf[1];
621 sd->params.status.streamState = gspca_dev->usb_buf[2];
622 sd->params.status.fatalError = gspca_dev->usb_buf[3];
623 sd->params.status.cmdError = gspca_dev->usb_buf[4];
624 sd->params.status.debugFlags = gspca_dev->usb_buf[5];
625 sd->params.status.vpStatus = gspca_dev->usb_buf[6];
626 sd->params.status.errorCode = gspca_dev->usb_buf[7];
627 break;
628 case CPIA_COMMAND_GetVPVersion:
629 sd->params.vpVersion.vpVersion = gspca_dev->usb_buf[0];
630 sd->params.vpVersion.vpRevision = gspca_dev->usb_buf[1];
631 sd->params.vpVersion.cameraHeadID =
632 gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
633 break;
634 case CPIA_COMMAND_GetColourParams:
635 sd->params.colourParams.brightness = gspca_dev->usb_buf[0];
636 sd->params.colourParams.contrast = gspca_dev->usb_buf[1];
637 sd->params.colourParams.saturation = gspca_dev->usb_buf[2];
638 break;
639 case CPIA_COMMAND_GetColourBalance:
640 sd->params.colourBalance.redGain = gspca_dev->usb_buf[0];
641 sd->params.colourBalance.greenGain = gspca_dev->usb_buf[1];
642 sd->params.colourBalance.blueGain = gspca_dev->usb_buf[2];
643 break;
644 case CPIA_COMMAND_GetExposure:
645 sd->params.exposure.gain = gspca_dev->usb_buf[0];
646 sd->params.exposure.fineExp = gspca_dev->usb_buf[1];
647 sd->params.exposure.coarseExpLo = gspca_dev->usb_buf[2];
648 sd->params.exposure.coarseExpHi = gspca_dev->usb_buf[3];
649 sd->params.exposure.redComp = gspca_dev->usb_buf[4];
650 sd->params.exposure.green1Comp = gspca_dev->usb_buf[5];
651 sd->params.exposure.green2Comp = gspca_dev->usb_buf[6];
652 sd->params.exposure.blueComp = gspca_dev->usb_buf[7];
653 break;
655 case CPIA_COMMAND_ReadMCPorts:
656 if (!sd->params.qx3.qx3_detected)
657 break;
658 /* test button press */
659 sd->params.qx3.button = ((gspca_dev->usb_buf[1] & 0x02) == 0);
660 if (sd->params.qx3.button) {
661 /* button pressed - unlock the latch */
662 do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
663 3, 0xdf, 0xdf, 0);
664 do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
665 3, 0xff, 0xff, 0);
668 /* test whether microscope is cradled */
669 sd->params.qx3.cradled = ((gspca_dev->usb_buf[2] & 0x40) == 0);
670 break;
673 return 0;
676 /* send a command to the camera with an additional data transaction */
677 static int do_command_extended(struct gspca_dev *gspca_dev, u16 command,
678 u8 a, u8 b, u8 c, u8 d,
679 u8 e, u8 f, u8 g, u8 h,
680 u8 i, u8 j, u8 k, u8 l)
682 u8 cmd[8];
684 cmd[0] = command >> 8;
685 cmd[1] = command & 0xff;
686 cmd[2] = a;
687 cmd[3] = b;
688 cmd[4] = c;
689 cmd[5] = d;
690 cmd[6] = 8;
691 cmd[7] = 0;
692 gspca_dev->usb_buf[0] = e;
693 gspca_dev->usb_buf[1] = f;
694 gspca_dev->usb_buf[2] = g;
695 gspca_dev->usb_buf[3] = h;
696 gspca_dev->usb_buf[4] = i;
697 gspca_dev->usb_buf[5] = j;
698 gspca_dev->usb_buf[6] = k;
699 gspca_dev->usb_buf[7] = l;
701 return cpia_usb_transferCmd(gspca_dev, cmd);
704 /* find_over_exposure
705 * Finds a suitable value of OverExposure for use with SetFlickerCtrl
706 * Some calculation is required because this value changes with the brightness
707 * set with SetColourParameters
709 * Parameters: Brightness - last brightness value set with SetColourParameters
711 * Returns: OverExposure value to use with SetFlickerCtrl
713 #define FLICKER_MAX_EXPOSURE 250
714 #define FLICKER_ALLOWABLE_OVER_EXPOSURE 146
715 #define FLICKER_BRIGHTNESS_CONSTANT 59
716 static int find_over_exposure(int brightness)
718 int MaxAllowableOverExposure, OverExposure;
720 MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness -
721 FLICKER_BRIGHTNESS_CONSTANT;
723 if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE)
724 OverExposure = MaxAllowableOverExposure;
725 else
726 OverExposure = FLICKER_ALLOWABLE_OVER_EXPOSURE;
728 return OverExposure;
730 #undef FLICKER_MAX_EXPOSURE
731 #undef FLICKER_ALLOWABLE_OVER_EXPOSURE
732 #undef FLICKER_BRIGHTNESS_CONSTANT
734 /* initialise cam_data structure */
735 static void reset_camera_params(struct gspca_dev *gspca_dev)
737 struct sd *sd = (struct sd *) gspca_dev;
738 struct cam_params *params = &sd->params;
740 /* The following parameter values are the defaults from
741 * "Software Developer's Guide for CPiA Cameras". Any changes
742 * to the defaults are noted in comments. */
743 params->colourParams.brightness = BRIGHTNESS_DEF;
744 params->colourParams.contrast = CONTRAST_DEF;
745 params->colourParams.saturation = SATURATION_DEF;
746 params->exposure.gainMode = 4;
747 params->exposure.expMode = 2; /* AEC */
748 params->exposure.compMode = 1;
749 params->exposure.centreWeight = 1;
750 params->exposure.gain = 0;
751 params->exposure.fineExp = 0;
752 params->exposure.coarseExpLo = 185;
753 params->exposure.coarseExpHi = 0;
754 params->exposure.redComp = COMP_RED;
755 params->exposure.green1Comp = COMP_GREEN1;
756 params->exposure.green2Comp = COMP_GREEN2;
757 params->exposure.blueComp = COMP_BLUE;
758 params->colourBalance.balanceMode = 2; /* ACB */
759 params->colourBalance.redGain = 32;
760 params->colourBalance.greenGain = 6;
761 params->colourBalance.blueGain = 92;
762 params->apcor.gain1 = 0x18;
763 params->apcor.gain2 = 0x16;
764 params->apcor.gain4 = 0x24;
765 params->apcor.gain8 = 0x34;
766 params->flickerControl.flickerMode = 0;
767 params->flickerControl.disabled = 1;
769 params->flickerControl.coarseJump =
770 flicker_jumps[sd->mainsFreq]
771 [params->sensorFps.baserate]
772 [params->sensorFps.divisor];
773 params->flickerControl.allowableOverExposure =
774 find_over_exposure(params->colourParams.brightness);
775 params->vlOffset.gain1 = 20;
776 params->vlOffset.gain2 = 24;
777 params->vlOffset.gain4 = 26;
778 params->vlOffset.gain8 = 26;
779 params->compressionParams.hysteresis = 3;
780 params->compressionParams.threshMax = 11;
781 params->compressionParams.smallStep = 1;
782 params->compressionParams.largeStep = 3;
783 params->compressionParams.decimationHysteresis = 2;
784 params->compressionParams.frDiffStepThresh = 5;
785 params->compressionParams.qDiffStepThresh = 3;
786 params->compressionParams.decimationThreshMod = 2;
787 /* End of default values from Software Developer's Guide */
789 /* Set Sensor FPS to 15fps. This seems better than 30fps
790 * for indoor lighting. */
791 params->sensorFps.divisor = 1;
792 params->sensorFps.baserate = 1;
794 params->yuvThreshold.yThreshold = 6; /* From windows driver */
795 params->yuvThreshold.uvThreshold = 6; /* From windows driver */
797 params->format.subSample = SUBSAMPLE_420;
798 params->format.yuvOrder = YUVORDER_YUYV;
800 params->compression.mode = CPIA_COMPRESSION_AUTO;
801 params->compression.decimation = NO_DECIMATION;
803 params->compressionTarget.frTargeting = COMP_TARGET_DEF;
804 params->compressionTarget.targetFR = 15; /* From windows driver */
805 params->compressionTarget.targetQ = 5; /* From windows driver */
807 params->qx3.qx3_detected = 0;
808 params->qx3.toplight = 0;
809 params->qx3.bottomlight = 0;
810 params->qx3.button = 0;
811 params->qx3.cradled = 0;
814 static void printstatus(struct cam_params *params)
816 PDEBUG(D_PROBE, "status: %02x %02x %02x %02x %02x %02x %02x %02x",
817 params->status.systemState, params->status.grabState,
818 params->status.streamState, params->status.fatalError,
819 params->status.cmdError, params->status.debugFlags,
820 params->status.vpStatus, params->status.errorCode);
823 static int goto_low_power(struct gspca_dev *gspca_dev)
825 struct sd *sd = (struct sd *) gspca_dev;
826 int ret;
828 ret = do_command(gspca_dev, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0);
829 if (ret)
830 return ret;
832 ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
833 if (ret)
834 return ret;
836 if (sd->params.status.systemState != LO_POWER_STATE) {
837 if (sd->params.status.systemState != WARM_BOOT_STATE) {
838 PDEBUG(D_ERR,
839 "unexpected state after lo power cmd: %02x",
840 sd->params.status.systemState);
841 printstatus(&sd->params);
843 return -EIO;
846 PDEBUG(D_CONF, "camera now in LOW power state");
847 return 0;
850 static int goto_high_power(struct gspca_dev *gspca_dev)
852 struct sd *sd = (struct sd *) gspca_dev;
853 int ret;
855 ret = do_command(gspca_dev, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0);
856 if (ret)
857 return ret;
859 msleep_interruptible(40); /* windows driver does it too */
861 if (signal_pending(current))
862 return -EINTR;
864 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
865 if (ret)
866 return ret;
868 if (sd->params.status.systemState != HI_POWER_STATE) {
869 PDEBUG(D_ERR, "unexpected state after hi power cmd: %02x",
870 sd->params.status.systemState);
871 printstatus(&sd->params);
872 return -EIO;
875 PDEBUG(D_CONF, "camera now in HIGH power state");
876 return 0;
879 static int get_version_information(struct gspca_dev *gspca_dev)
881 int ret;
883 /* GetCPIAVersion */
884 ret = do_command(gspca_dev, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0);
885 if (ret)
886 return ret;
888 /* GetPnPID */
889 return do_command(gspca_dev, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0);
892 static int save_camera_state(struct gspca_dev *gspca_dev)
894 int ret;
896 ret = do_command(gspca_dev, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
897 if (ret)
898 return ret;
900 return do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
903 static int command_setformat(struct gspca_dev *gspca_dev)
905 struct sd *sd = (struct sd *) gspca_dev;
906 int ret;
908 ret = do_command(gspca_dev, CPIA_COMMAND_SetFormat,
909 sd->params.format.videoSize,
910 sd->params.format.subSample,
911 sd->params.format.yuvOrder, 0);
912 if (ret)
913 return ret;
915 return do_command(gspca_dev, CPIA_COMMAND_SetROI,
916 sd->params.roi.colStart, sd->params.roi.colEnd,
917 sd->params.roi.rowStart, sd->params.roi.rowEnd);
920 static int command_setcolourparams(struct gspca_dev *gspca_dev)
922 struct sd *sd = (struct sd *) gspca_dev;
923 return do_command(gspca_dev, CPIA_COMMAND_SetColourParams,
924 sd->params.colourParams.brightness,
925 sd->params.colourParams.contrast,
926 sd->params.colourParams.saturation, 0);
929 static int command_setapcor(struct gspca_dev *gspca_dev)
931 struct sd *sd = (struct sd *) gspca_dev;
932 return do_command(gspca_dev, CPIA_COMMAND_SetApcor,
933 sd->params.apcor.gain1,
934 sd->params.apcor.gain2,
935 sd->params.apcor.gain4,
936 sd->params.apcor.gain8);
939 static int command_setvloffset(struct gspca_dev *gspca_dev)
941 struct sd *sd = (struct sd *) gspca_dev;
942 return do_command(gspca_dev, CPIA_COMMAND_SetVLOffset,
943 sd->params.vlOffset.gain1,
944 sd->params.vlOffset.gain2,
945 sd->params.vlOffset.gain4,
946 sd->params.vlOffset.gain8);
949 static int command_setexposure(struct gspca_dev *gspca_dev)
951 struct sd *sd = (struct sd *) gspca_dev;
952 int ret;
954 ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
955 sd->params.exposure.gainMode,
957 sd->params.exposure.compMode,
958 sd->params.exposure.centreWeight,
959 sd->params.exposure.gain,
960 sd->params.exposure.fineExp,
961 sd->params.exposure.coarseExpLo,
962 sd->params.exposure.coarseExpHi,
963 sd->params.exposure.redComp,
964 sd->params.exposure.green1Comp,
965 sd->params.exposure.green2Comp,
966 sd->params.exposure.blueComp);
967 if (ret)
968 return ret;
970 if (sd->params.exposure.expMode != 1) {
971 ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
973 sd->params.exposure.expMode,
974 0, 0,
975 sd->params.exposure.gain,
976 sd->params.exposure.fineExp,
977 sd->params.exposure.coarseExpLo,
978 sd->params.exposure.coarseExpHi,
979 0, 0, 0, 0);
982 return ret;
985 static int command_setcolourbalance(struct gspca_dev *gspca_dev)
987 struct sd *sd = (struct sd *) gspca_dev;
989 if (sd->params.colourBalance.balanceMode == 1) {
990 int ret;
992 ret = do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
994 sd->params.colourBalance.redGain,
995 sd->params.colourBalance.greenGain,
996 sd->params.colourBalance.blueGain);
997 if (ret)
998 return ret;
1000 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
1001 3, 0, 0, 0);
1003 if (sd->params.colourBalance.balanceMode == 2) {
1004 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
1005 2, 0, 0, 0);
1007 if (sd->params.colourBalance.balanceMode == 3) {
1008 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
1009 3, 0, 0, 0);
1012 return -EINVAL;
1015 static int command_setcompressiontarget(struct gspca_dev *gspca_dev)
1017 struct sd *sd = (struct sd *) gspca_dev;
1019 return do_command(gspca_dev, CPIA_COMMAND_SetCompressionTarget,
1020 sd->params.compressionTarget.frTargeting,
1021 sd->params.compressionTarget.targetFR,
1022 sd->params.compressionTarget.targetQ, 0);
1025 static int command_setyuvtresh(struct gspca_dev *gspca_dev)
1027 struct sd *sd = (struct sd *) gspca_dev;
1029 return do_command(gspca_dev, CPIA_COMMAND_SetYUVThresh,
1030 sd->params.yuvThreshold.yThreshold,
1031 sd->params.yuvThreshold.uvThreshold, 0, 0);
1034 static int command_setcompressionparams(struct gspca_dev *gspca_dev)
1036 struct sd *sd = (struct sd *) gspca_dev;
1038 return do_command_extended(gspca_dev,
1039 CPIA_COMMAND_SetCompressionParams,
1040 0, 0, 0, 0,
1041 sd->params.compressionParams.hysteresis,
1042 sd->params.compressionParams.threshMax,
1043 sd->params.compressionParams.smallStep,
1044 sd->params.compressionParams.largeStep,
1045 sd->params.compressionParams.decimationHysteresis,
1046 sd->params.compressionParams.frDiffStepThresh,
1047 sd->params.compressionParams.qDiffStepThresh,
1048 sd->params.compressionParams.decimationThreshMod);
1051 static int command_setcompression(struct gspca_dev *gspca_dev)
1053 struct sd *sd = (struct sd *) gspca_dev;
1055 return do_command(gspca_dev, CPIA_COMMAND_SetCompression,
1056 sd->params.compression.mode,
1057 sd->params.compression.decimation, 0, 0);
1060 static int command_setsensorfps(struct gspca_dev *gspca_dev)
1062 struct sd *sd = (struct sd *) gspca_dev;
1064 return do_command(gspca_dev, CPIA_COMMAND_SetSensorFPS,
1065 sd->params.sensorFps.divisor,
1066 sd->params.sensorFps.baserate, 0, 0);
1069 static int command_setflickerctrl(struct gspca_dev *gspca_dev)
1071 struct sd *sd = (struct sd *) gspca_dev;
1073 return do_command(gspca_dev, CPIA_COMMAND_SetFlickerCtrl,
1074 sd->params.flickerControl.flickerMode,
1075 sd->params.flickerControl.coarseJump,
1076 sd->params.flickerControl.allowableOverExposure,
1080 static int command_setecptiming(struct gspca_dev *gspca_dev)
1082 struct sd *sd = (struct sd *) gspca_dev;
1084 return do_command(gspca_dev, CPIA_COMMAND_SetECPTiming,
1085 sd->params.ecpTiming, 0, 0, 0);
1088 static int command_pause(struct gspca_dev *gspca_dev)
1090 return do_command(gspca_dev, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
1093 static int command_resume(struct gspca_dev *gspca_dev)
1095 struct sd *sd = (struct sd *) gspca_dev;
1097 return do_command(gspca_dev, CPIA_COMMAND_InitStreamCap,
1098 0, sd->params.streamStartLine, 0, 0);
1101 static int command_setlights(struct gspca_dev *gspca_dev)
1103 struct sd *sd = (struct sd *) gspca_dev;
1104 int ret, p1, p2;
1106 if (!sd->params.qx3.qx3_detected)
1107 return 0;
1109 p1 = (sd->params.qx3.bottomlight == 0) << 1;
1110 p2 = (sd->params.qx3.toplight == 0) << 3;
1112 ret = do_command(gspca_dev, CPIA_COMMAND_WriteVCReg,
1113 0x90, 0x8f, 0x50, 0);
1114 if (ret)
1115 return ret;
1117 return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0,
1118 p1 | p2 | 0xe0, 0);
1121 static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply)
1123 /* Everything in here is from the Windows driver */
1124 /* define for compgain calculation */
1125 #if 0
1126 #define COMPGAIN(base, curexp, newexp) \
1127 (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
1128 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1129 (u16)((float)curexp * (float)(u8)(curcomp + 128) / \
1130 (float)(u8)(basecomp - 128))
1131 #else
1132 /* equivalent functions without floating point math */
1133 #define COMPGAIN(base, curexp, newexp) \
1134 (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2 * newexp)))
1135 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1136 (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
1137 #endif
1139 struct sd *sd = (struct sd *) gspca_dev;
1140 int currentexp = sd->params.exposure.coarseExpLo +
1141 sd->params.exposure.coarseExpHi * 256;
1142 int ret, startexp;
1144 if (on) {
1145 int cj = sd->params.flickerControl.coarseJump;
1146 sd->params.flickerControl.flickerMode = 1;
1147 sd->params.flickerControl.disabled = 0;
1148 if (sd->params.exposure.expMode != 2) {
1149 sd->params.exposure.expMode = 2;
1150 sd->exposure_status = EXPOSURE_NORMAL;
1152 currentexp = currentexp << sd->params.exposure.gain;
1153 sd->params.exposure.gain = 0;
1154 /* round down current exposure to nearest value */
1155 startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj;
1156 if (startexp < 1)
1157 startexp = 1;
1158 startexp = (startexp * cj) - 1;
1159 if (FIRMWARE_VERSION(1, 2))
1160 while (startexp > MAX_EXP_102)
1161 startexp -= cj;
1162 else
1163 while (startexp > MAX_EXP)
1164 startexp -= cj;
1165 sd->params.exposure.coarseExpLo = startexp & 0xff;
1166 sd->params.exposure.coarseExpHi = startexp >> 8;
1167 if (currentexp > startexp) {
1168 if (currentexp > (2 * startexp))
1169 currentexp = 2 * startexp;
1170 sd->params.exposure.redComp =
1171 COMPGAIN(COMP_RED, currentexp, startexp);
1172 sd->params.exposure.green1Comp =
1173 COMPGAIN(COMP_GREEN1, currentexp, startexp);
1174 sd->params.exposure.green2Comp =
1175 COMPGAIN(COMP_GREEN2, currentexp, startexp);
1176 sd->params.exposure.blueComp =
1177 COMPGAIN(COMP_BLUE, currentexp, startexp);
1178 } else {
1179 sd->params.exposure.redComp = COMP_RED;
1180 sd->params.exposure.green1Comp = COMP_GREEN1;
1181 sd->params.exposure.green2Comp = COMP_GREEN2;
1182 sd->params.exposure.blueComp = COMP_BLUE;
1184 if (FIRMWARE_VERSION(1, 2))
1185 sd->params.exposure.compMode = 0;
1186 else
1187 sd->params.exposure.compMode = 1;
1189 sd->params.apcor.gain1 = 0x18;
1190 sd->params.apcor.gain2 = 0x18;
1191 sd->params.apcor.gain4 = 0x16;
1192 sd->params.apcor.gain8 = 0x14;
1193 } else {
1194 sd->params.flickerControl.flickerMode = 0;
1195 sd->params.flickerControl.disabled = 1;
1196 /* Average equivalent coarse for each comp channel */
1197 startexp = EXP_FROM_COMP(COMP_RED,
1198 sd->params.exposure.redComp, currentexp);
1199 startexp += EXP_FROM_COMP(COMP_GREEN1,
1200 sd->params.exposure.green1Comp, currentexp);
1201 startexp += EXP_FROM_COMP(COMP_GREEN2,
1202 sd->params.exposure.green2Comp, currentexp);
1203 startexp += EXP_FROM_COMP(COMP_BLUE,
1204 sd->params.exposure.blueComp, currentexp);
1205 startexp = startexp >> 2;
1206 while (startexp > MAX_EXP && sd->params.exposure.gain <
1207 sd->params.exposure.gainMode - 1) {
1208 startexp = startexp >> 1;
1209 ++sd->params.exposure.gain;
1211 if (FIRMWARE_VERSION(1, 2) && startexp > MAX_EXP_102)
1212 startexp = MAX_EXP_102;
1213 if (startexp > MAX_EXP)
1214 startexp = MAX_EXP;
1215 sd->params.exposure.coarseExpLo = startexp & 0xff;
1216 sd->params.exposure.coarseExpHi = startexp >> 8;
1217 sd->params.exposure.redComp = COMP_RED;
1218 sd->params.exposure.green1Comp = COMP_GREEN1;
1219 sd->params.exposure.green2Comp = COMP_GREEN2;
1220 sd->params.exposure.blueComp = COMP_BLUE;
1221 sd->params.exposure.compMode = 1;
1222 sd->params.apcor.gain1 = 0x18;
1223 sd->params.apcor.gain2 = 0x16;
1224 sd->params.apcor.gain4 = 0x24;
1225 sd->params.apcor.gain8 = 0x34;
1227 sd->params.vlOffset.gain1 = 20;
1228 sd->params.vlOffset.gain2 = 24;
1229 sd->params.vlOffset.gain4 = 26;
1230 sd->params.vlOffset.gain8 = 26;
1232 if (apply) {
1233 ret = command_setexposure(gspca_dev);
1234 if (ret)
1235 return ret;
1237 ret = command_setapcor(gspca_dev);
1238 if (ret)
1239 return ret;
1241 ret = command_setvloffset(gspca_dev);
1242 if (ret)
1243 return ret;
1245 ret = command_setflickerctrl(gspca_dev);
1246 if (ret)
1247 return ret;
1250 return 0;
1251 #undef EXP_FROM_COMP
1252 #undef COMPGAIN
1255 /* monitor the exposure and adjust the sensor frame rate if needed */
1256 static void monitor_exposure(struct gspca_dev *gspca_dev)
1258 struct sd *sd = (struct sd *) gspca_dev;
1259 u8 exp_acc, bcomp, gain, coarseL, cmd[8];
1260 int ret, light_exp, dark_exp, very_dark_exp;
1261 int old_exposure, new_exposure, framerate;
1262 int setfps = 0, setexp = 0, setflicker = 0;
1264 /* get necessary stats and register settings from camera */
1265 /* do_command can't handle this, so do it ourselves */
1266 cmd[0] = CPIA_COMMAND_ReadVPRegs >> 8;
1267 cmd[1] = CPIA_COMMAND_ReadVPRegs & 0xff;
1268 cmd[2] = 30;
1269 cmd[3] = 4;
1270 cmd[4] = 9;
1271 cmd[5] = 8;
1272 cmd[6] = 8;
1273 cmd[7] = 0;
1274 ret = cpia_usb_transferCmd(gspca_dev, cmd);
1275 if (ret) {
1276 err("ReadVPRegs(30,4,9,8) - failed: %d", ret);
1277 return;
1279 exp_acc = gspca_dev->usb_buf[0];
1280 bcomp = gspca_dev->usb_buf[1];
1281 gain = gspca_dev->usb_buf[2];
1282 coarseL = gspca_dev->usb_buf[3];
1284 light_exp = sd->params.colourParams.brightness +
1285 TC - 50 + EXP_ACC_LIGHT;
1286 if (light_exp > 255)
1287 light_exp = 255;
1288 dark_exp = sd->params.colourParams.brightness +
1289 TC - 50 - EXP_ACC_DARK;
1290 if (dark_exp < 0)
1291 dark_exp = 0;
1292 very_dark_exp = dark_exp / 2;
1294 old_exposure = sd->params.exposure.coarseExpHi * 256 +
1295 sd->params.exposure.coarseExpLo;
1297 if (!sd->params.flickerControl.disabled) {
1298 /* Flicker control on */
1299 int max_comp = FIRMWARE_VERSION(1, 2) ? MAX_COMP :
1300 HIGH_COMP_102;
1301 bcomp += 128; /* decode */
1302 if (bcomp >= max_comp && exp_acc < dark_exp) {
1303 /* dark */
1304 if (exp_acc < very_dark_exp) {
1305 /* very dark */
1306 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1307 ++sd->exposure_count;
1308 else {
1309 sd->exposure_status =
1310 EXPOSURE_VERY_DARK;
1311 sd->exposure_count = 1;
1313 } else {
1314 /* just dark */
1315 if (sd->exposure_status == EXPOSURE_DARK)
1316 ++sd->exposure_count;
1317 else {
1318 sd->exposure_status = EXPOSURE_DARK;
1319 sd->exposure_count = 1;
1322 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1323 /* light */
1324 if (old_exposure <= VERY_LOW_EXP) {
1325 /* very light */
1326 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1327 ++sd->exposure_count;
1328 else {
1329 sd->exposure_status =
1330 EXPOSURE_VERY_LIGHT;
1331 sd->exposure_count = 1;
1333 } else {
1334 /* just light */
1335 if (sd->exposure_status == EXPOSURE_LIGHT)
1336 ++sd->exposure_count;
1337 else {
1338 sd->exposure_status = EXPOSURE_LIGHT;
1339 sd->exposure_count = 1;
1342 } else {
1343 /* not dark or light */
1344 sd->exposure_status = EXPOSURE_NORMAL;
1346 } else {
1347 /* Flicker control off */
1348 if (old_exposure >= MAX_EXP && exp_acc < dark_exp) {
1349 /* dark */
1350 if (exp_acc < very_dark_exp) {
1351 /* very dark */
1352 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1353 ++sd->exposure_count;
1354 else {
1355 sd->exposure_status =
1356 EXPOSURE_VERY_DARK;
1357 sd->exposure_count = 1;
1359 } else {
1360 /* just dark */
1361 if (sd->exposure_status == EXPOSURE_DARK)
1362 ++sd->exposure_count;
1363 else {
1364 sd->exposure_status = EXPOSURE_DARK;
1365 sd->exposure_count = 1;
1368 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1369 /* light */
1370 if (old_exposure <= VERY_LOW_EXP) {
1371 /* very light */
1372 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1373 ++sd->exposure_count;
1374 else {
1375 sd->exposure_status =
1376 EXPOSURE_VERY_LIGHT;
1377 sd->exposure_count = 1;
1379 } else {
1380 /* just light */
1381 if (sd->exposure_status == EXPOSURE_LIGHT)
1382 ++sd->exposure_count;
1383 else {
1384 sd->exposure_status = EXPOSURE_LIGHT;
1385 sd->exposure_count = 1;
1388 } else {
1389 /* not dark or light */
1390 sd->exposure_status = EXPOSURE_NORMAL;
1394 framerate = atomic_read(&sd->fps);
1395 if (framerate > 30 || framerate < 1)
1396 framerate = 1;
1398 if (!sd->params.flickerControl.disabled) {
1399 /* Flicker control on */
1400 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1401 sd->exposure_status == EXPOSURE_DARK) &&
1402 sd->exposure_count >= DARK_TIME * framerate &&
1403 sd->params.sensorFps.divisor < 3) {
1405 /* dark for too long */
1406 ++sd->params.sensorFps.divisor;
1407 setfps = 1;
1409 sd->params.flickerControl.coarseJump =
1410 flicker_jumps[sd->mainsFreq]
1411 [sd->params.sensorFps.baserate]
1412 [sd->params.sensorFps.divisor];
1413 setflicker = 1;
1415 new_exposure = sd->params.flickerControl.coarseJump-1;
1416 while (new_exposure < old_exposure / 2)
1417 new_exposure +=
1418 sd->params.flickerControl.coarseJump;
1419 sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1420 sd->params.exposure.coarseExpHi = new_exposure >> 8;
1421 setexp = 1;
1422 sd->exposure_status = EXPOSURE_NORMAL;
1423 PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
1425 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1426 sd->exposure_status == EXPOSURE_LIGHT) &&
1427 sd->exposure_count >= LIGHT_TIME * framerate &&
1428 sd->params.sensorFps.divisor > 0) {
1430 /* light for too long */
1431 int max_exp = FIRMWARE_VERSION(1, 2) ? MAX_EXP_102 :
1432 MAX_EXP;
1433 --sd->params.sensorFps.divisor;
1434 setfps = 1;
1436 sd->params.flickerControl.coarseJump =
1437 flicker_jumps[sd->mainsFreq]
1438 [sd->params.sensorFps.baserate]
1439 [sd->params.sensorFps.divisor];
1440 setflicker = 1;
1442 new_exposure = sd->params.flickerControl.coarseJump-1;
1443 while (new_exposure < 2 * old_exposure &&
1444 new_exposure +
1445 sd->params.flickerControl.coarseJump < max_exp)
1446 new_exposure +=
1447 sd->params.flickerControl.coarseJump;
1448 sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1449 sd->params.exposure.coarseExpHi = new_exposure >> 8;
1450 setexp = 1;
1451 sd->exposure_status = EXPOSURE_NORMAL;
1452 PDEBUG(D_CONF, "Automatically increasing sensor_fps");
1454 } else {
1455 /* Flicker control off */
1456 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1457 sd->exposure_status == EXPOSURE_DARK) &&
1458 sd->exposure_count >= DARK_TIME * framerate &&
1459 sd->params.sensorFps.divisor < 3) {
1461 /* dark for too long */
1462 ++sd->params.sensorFps.divisor;
1463 setfps = 1;
1465 if (sd->params.exposure.gain > 0) {
1466 --sd->params.exposure.gain;
1467 setexp = 1;
1469 sd->exposure_status = EXPOSURE_NORMAL;
1470 PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
1472 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1473 sd->exposure_status == EXPOSURE_LIGHT) &&
1474 sd->exposure_count >= LIGHT_TIME * framerate &&
1475 sd->params.sensorFps.divisor > 0) {
1477 /* light for too long */
1478 --sd->params.sensorFps.divisor;
1479 setfps = 1;
1481 if (sd->params.exposure.gain <
1482 sd->params.exposure.gainMode - 1) {
1483 ++sd->params.exposure.gain;
1484 setexp = 1;
1486 sd->exposure_status = EXPOSURE_NORMAL;
1487 PDEBUG(D_CONF, "Automatically increasing sensor_fps");
1491 if (setexp)
1492 command_setexposure(gspca_dev);
1494 if (setfps)
1495 command_setsensorfps(gspca_dev);
1497 if (setflicker)
1498 command_setflickerctrl(gspca_dev);
1501 /*-----------------------------------------------------------------*/
1502 /* if flicker is switched off, this function switches it back on.It checks,
1503 however, that conditions are suitable before restarting it.
1504 This should only be called for firmware version 1.2.
1506 It also adjust the colour balance when an exposure step is detected - as
1507 long as flicker is running
1509 static void restart_flicker(struct gspca_dev *gspca_dev)
1511 struct sd *sd = (struct sd *) gspca_dev;
1512 int cam_exposure, old_exp;
1514 if (!FIRMWARE_VERSION(1, 2))
1515 return;
1517 cam_exposure = atomic_read(&sd->cam_exposure);
1519 if (sd->params.flickerControl.flickerMode == 0 ||
1520 cam_exposure == 0)
1521 return;
1523 old_exp = sd->params.exposure.coarseExpLo +
1524 sd->params.exposure.coarseExpHi*256;
1526 see how far away camera exposure is from a valid
1527 flicker exposure value
1529 cam_exposure %= sd->params.flickerControl.coarseJump;
1530 if (!sd->params.flickerControl.disabled &&
1531 cam_exposure <= sd->params.flickerControl.coarseJump - 3) {
1532 /* Flicker control auto-disabled */
1533 sd->params.flickerControl.disabled = 1;
1536 if (sd->params.flickerControl.disabled &&
1537 old_exp > sd->params.flickerControl.coarseJump +
1538 ROUND_UP_EXP_FOR_FLICKER) {
1539 /* exposure is now high enough to switch
1540 flicker control back on */
1541 set_flicker(gspca_dev, 1, 1);
1545 /* this function is called at probe time */
1546 static int sd_config(struct gspca_dev *gspca_dev,
1547 const struct usb_device_id *id)
1549 struct cam *cam;
1551 reset_camera_params(gspca_dev);
1553 PDEBUG(D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)",
1554 id->idVendor, id->idProduct);
1556 cam = &gspca_dev->cam;
1557 cam->cam_mode = mode;
1558 cam->nmodes = ARRAY_SIZE(mode);
1560 sd_setfreq(gspca_dev, FREQ_DEF);
1562 return 0;
1565 /* -- start the camera -- */
1566 static int sd_start(struct gspca_dev *gspca_dev)
1568 struct sd *sd = (struct sd *) gspca_dev;
1569 int priv, ret;
1571 /* Start the camera in low power mode */
1572 if (goto_low_power(gspca_dev)) {
1573 if (sd->params.status.systemState != WARM_BOOT_STATE) {
1574 PDEBUG(D_ERR, "unexpected systemstate: %02x",
1575 sd->params.status.systemState);
1576 printstatus(&sd->params);
1577 return -ENODEV;
1580 /* FIXME: this is just dirty trial and error */
1581 ret = goto_high_power(gspca_dev);
1582 if (ret)
1583 return ret;
1585 ret = do_command(gspca_dev, CPIA_COMMAND_DiscardFrame,
1586 0, 0, 0, 0);
1587 if (ret)
1588 return ret;
1590 ret = goto_low_power(gspca_dev);
1591 if (ret)
1592 return ret;
1595 /* procedure described in developer's guide p3-28 */
1597 /* Check the firmware version. */
1598 sd->params.version.firmwareVersion = 0;
1599 get_version_information(gspca_dev);
1600 if (sd->params.version.firmwareVersion != 1) {
1601 PDEBUG(D_ERR, "only firmware version 1 is supported (got: %d)",
1602 sd->params.version.firmwareVersion);
1603 return -ENODEV;
1606 /* A bug in firmware 1-02 limits gainMode to 2 */
1607 if (sd->params.version.firmwareRevision <= 2 &&
1608 sd->params.exposure.gainMode > 2) {
1609 sd->params.exposure.gainMode = 2;
1612 /* set QX3 detected flag */
1613 sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 &&
1614 sd->params.pnpID.product == 0x0001);
1616 /* The fatal error checking should be done after
1617 * the camera powers up (developer's guide p 3-38) */
1619 /* Set streamState before transition to high power to avoid bug
1620 * in firmware 1-02 */
1621 ret = do_command(gspca_dev, CPIA_COMMAND_ModifyCameraStatus,
1622 STREAMSTATE, 0, STREAM_NOT_READY, 0);
1623 if (ret)
1624 return ret;
1626 /* GotoHiPower */
1627 ret = goto_high_power(gspca_dev);
1628 if (ret)
1629 return ret;
1631 /* Check the camera status */
1632 ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1633 if (ret)
1634 return ret;
1636 if (sd->params.status.fatalError) {
1637 PDEBUG(D_ERR, "fatal_error: %04x, vp_status: %04x",
1638 sd->params.status.fatalError,
1639 sd->params.status.vpStatus);
1640 return -EIO;
1643 /* VPVersion can't be retrieved before the camera is in HiPower,
1644 * so get it here instead of in get_version_information. */
1645 ret = do_command(gspca_dev, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0);
1646 if (ret)
1647 return ret;
1649 /* Determine video mode settings */
1650 sd->params.streamStartLine = 120;
1652 priv = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1653 if (priv & 0x01) { /* crop */
1654 sd->params.roi.colStart = 2;
1655 sd->params.roi.rowStart = 6;
1656 } else {
1657 sd->params.roi.colStart = 0;
1658 sd->params.roi.rowStart = 0;
1661 if (priv & 0x02) { /* quarter */
1662 sd->params.format.videoSize = VIDEOSIZE_QCIF;
1663 sd->params.roi.colStart /= 2;
1664 sd->params.roi.rowStart /= 2;
1665 sd->params.streamStartLine /= 2;
1666 } else
1667 sd->params.format.videoSize = VIDEOSIZE_CIF;
1669 sd->params.roi.colEnd = sd->params.roi.colStart +
1670 (gspca_dev->width >> 3);
1671 sd->params.roi.rowEnd = sd->params.roi.rowStart +
1672 (gspca_dev->height >> 2);
1674 /* And now set the camera to a known state */
1675 ret = do_command(gspca_dev, CPIA_COMMAND_SetGrabMode,
1676 CPIA_GRAB_CONTINEOUS, 0, 0, 0);
1677 if (ret)
1678 return ret;
1679 /* We start with compression disabled, as we need one uncompressed
1680 frame to handle later compressed frames */
1681 ret = do_command(gspca_dev, CPIA_COMMAND_SetCompression,
1682 CPIA_COMPRESSION_NONE,
1683 NO_DECIMATION, 0, 0);
1684 if (ret)
1685 return ret;
1686 ret = command_setcompressiontarget(gspca_dev);
1687 if (ret)
1688 return ret;
1689 ret = command_setcolourparams(gspca_dev);
1690 if (ret)
1691 return ret;
1692 ret = command_setformat(gspca_dev);
1693 if (ret)
1694 return ret;
1695 ret = command_setyuvtresh(gspca_dev);
1696 if (ret)
1697 return ret;
1698 ret = command_setecptiming(gspca_dev);
1699 if (ret)
1700 return ret;
1701 ret = command_setcompressionparams(gspca_dev);
1702 if (ret)
1703 return ret;
1704 ret = command_setexposure(gspca_dev);
1705 if (ret)
1706 return ret;
1707 ret = command_setcolourbalance(gspca_dev);
1708 if (ret)
1709 return ret;
1710 ret = command_setsensorfps(gspca_dev);
1711 if (ret)
1712 return ret;
1713 ret = command_setapcor(gspca_dev);
1714 if (ret)
1715 return ret;
1716 ret = command_setflickerctrl(gspca_dev);
1717 if (ret)
1718 return ret;
1719 ret = command_setvloffset(gspca_dev);
1720 if (ret)
1721 return ret;
1723 /* Start stream */
1724 ret = command_resume(gspca_dev);
1725 if (ret)
1726 return ret;
1728 /* Wait 6 frames before turning compression on for the sensor to get
1729 all settings and AEC/ACB to settle */
1730 sd->first_frame = 6;
1731 sd->exposure_status = EXPOSURE_NORMAL;
1732 sd->exposure_count = 0;
1733 atomic_set(&sd->cam_exposure, 0);
1734 atomic_set(&sd->fps, 0);
1736 return 0;
1739 static void sd_stopN(struct gspca_dev *gspca_dev)
1741 command_pause(gspca_dev);
1743 /* save camera state for later open (developers guide ch 3.5.3) */
1744 save_camera_state(gspca_dev);
1746 /* GotoLoPower */
1747 goto_low_power(gspca_dev);
1749 /* Update the camera status */
1750 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1753 /* this function is called at probe and resume time */
1754 static int sd_init(struct gspca_dev *gspca_dev)
1756 #ifdef GSPCA_DEBUG
1757 struct sd *sd = (struct sd *) gspca_dev;
1758 #endif
1759 int ret;
1761 /* Start / Stop the camera to make sure we are talking to
1762 a supported camera, and to get some information from it
1763 to print. */
1764 ret = sd_start(gspca_dev);
1765 if (ret)
1766 return ret;
1768 /* Ensure the QX3 illuminators' states are restored upon resume,
1769 or disable the illuminator controls, if this isn't a QX3 */
1770 if (sd->params.qx3.qx3_detected)
1771 command_setlights(gspca_dev);
1772 else
1773 gspca_dev->ctrl_dis |=
1774 ((1 << ILLUMINATORS_1_IDX) | (1 << ILLUMINATORS_2_IDX));
1776 sd_stopN(gspca_dev);
1778 PDEBUG(D_PROBE, "CPIA Version: %d.%02d (%d.%d)",
1779 sd->params.version.firmwareVersion,
1780 sd->params.version.firmwareRevision,
1781 sd->params.version.vcVersion,
1782 sd->params.version.vcRevision);
1783 PDEBUG(D_PROBE, "CPIA PnP-ID: %04x:%04x:%04x",
1784 sd->params.pnpID.vendor, sd->params.pnpID.product,
1785 sd->params.pnpID.deviceRevision);
1786 PDEBUG(D_PROBE, "VP-Version: %d.%d %04x",
1787 sd->params.vpVersion.vpVersion,
1788 sd->params.vpVersion.vpRevision,
1789 sd->params.vpVersion.cameraHeadID);
1791 return 0;
1794 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1795 u8 *data,
1796 int len)
1798 struct sd *sd = (struct sd *) gspca_dev;
1800 /* Check for SOF */
1801 if (len >= 64 &&
1802 data[0] == MAGIC_0 && data[1] == MAGIC_1 &&
1803 data[16] == sd->params.format.videoSize &&
1804 data[17] == sd->params.format.subSample &&
1805 data[18] == sd->params.format.yuvOrder &&
1806 data[24] == sd->params.roi.colStart &&
1807 data[25] == sd->params.roi.colEnd &&
1808 data[26] == sd->params.roi.rowStart &&
1809 data[27] == sd->params.roi.rowEnd) {
1810 u8 *image;
1812 atomic_set(&sd->cam_exposure, data[39] * 2);
1813 atomic_set(&sd->fps, data[41]);
1815 /* Check for proper EOF for last frame */
1816 image = gspca_dev->image;
1817 if (image != NULL &&
1818 gspca_dev->image_len > 4 &&
1819 image[gspca_dev->image_len - 4] == 0xff &&
1820 image[gspca_dev->image_len - 3] == 0xff &&
1821 image[gspca_dev->image_len - 2] == 0xff &&
1822 image[gspca_dev->image_len - 1] == 0xff)
1823 gspca_frame_add(gspca_dev, LAST_PACKET,
1824 NULL, 0);
1826 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
1827 return;
1830 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1833 static void sd_dq_callback(struct gspca_dev *gspca_dev)
1835 struct sd *sd = (struct sd *) gspca_dev;
1837 /* Set the normal compression settings once we have captured a
1838 few uncompressed frames (and AEC has hopefully settled) */
1839 if (sd->first_frame) {
1840 sd->first_frame--;
1841 if (sd->first_frame == 0)
1842 command_setcompression(gspca_dev);
1845 /* Switch flicker control back on if it got turned off */
1846 restart_flicker(gspca_dev);
1848 /* If AEC is enabled, monitor the exposure and
1849 adjust the sensor frame rate if needed */
1850 if (sd->params.exposure.expMode == 2)
1851 monitor_exposure(gspca_dev);
1853 /* Update our knowledge of the camera state */
1854 do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
1855 if (sd->params.qx3.qx3_detected)
1856 do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
1859 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1861 struct sd *sd = (struct sd *) gspca_dev;
1862 int ret;
1864 sd->params.colourParams.brightness = val;
1865 sd->params.flickerControl.allowableOverExposure =
1866 find_over_exposure(sd->params.colourParams.brightness);
1867 if (gspca_dev->streaming) {
1868 ret = command_setcolourparams(gspca_dev);
1869 if (ret)
1870 return ret;
1871 return command_setflickerctrl(gspca_dev);
1873 return 0;
1876 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1878 struct sd *sd = (struct sd *) gspca_dev;
1880 *val = sd->params.colourParams.brightness;
1881 return 0;
1884 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1886 struct sd *sd = (struct sd *) gspca_dev;
1888 sd->params.colourParams.contrast = val;
1889 if (gspca_dev->streaming)
1890 return command_setcolourparams(gspca_dev);
1892 return 0;
1895 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1897 struct sd *sd = (struct sd *) gspca_dev;
1899 *val = sd->params.colourParams.contrast;
1900 return 0;
1903 static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val)
1905 struct sd *sd = (struct sd *) gspca_dev;
1907 sd->params.colourParams.saturation = val;
1908 if (gspca_dev->streaming)
1909 return command_setcolourparams(gspca_dev);
1911 return 0;
1914 static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val)
1916 struct sd *sd = (struct sd *) gspca_dev;
1918 *val = sd->params.colourParams.saturation;
1919 return 0;
1922 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1924 struct sd *sd = (struct sd *) gspca_dev;
1925 int on;
1927 switch (val) {
1928 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1929 on = 0;
1930 break;
1931 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1932 on = 1;
1933 sd->mainsFreq = 0;
1934 break;
1935 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1936 on = 1;
1937 sd->mainsFreq = 1;
1938 break;
1939 default:
1940 return -EINVAL;
1943 sd->freq = val;
1944 sd->params.flickerControl.coarseJump =
1945 flicker_jumps[sd->mainsFreq]
1946 [sd->params.sensorFps.baserate]
1947 [sd->params.sensorFps.divisor];
1949 return set_flicker(gspca_dev, on, gspca_dev->streaming);
1952 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1954 struct sd *sd = (struct sd *) gspca_dev;
1956 *val = sd->freq;
1957 return 0;
1960 static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val)
1962 struct sd *sd = (struct sd *) gspca_dev;
1964 sd->params.compressionTarget.frTargeting = val;
1965 if (gspca_dev->streaming)
1966 return command_setcompressiontarget(gspca_dev);
1968 return 0;
1971 static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val)
1973 struct sd *sd = (struct sd *) gspca_dev;
1975 *val = sd->params.compressionTarget.frTargeting;
1976 return 0;
1979 static int sd_setilluminator(struct gspca_dev *gspca_dev, __s32 val, int n)
1981 struct sd *sd = (struct sd *) gspca_dev;
1982 int ret;
1984 if (!sd->params.qx3.qx3_detected)
1985 return -EINVAL;
1987 switch (n) {
1988 case 1:
1989 sd->params.qx3.bottomlight = val ? 1 : 0;
1990 break;
1991 case 2:
1992 sd->params.qx3.toplight = val ? 1 : 0;
1993 break;
1994 default:
1995 return -EINVAL;
1998 ret = command_setlights(gspca_dev);
1999 if (ret && ret != -EINVAL)
2000 ret = -EBUSY;
2002 return ret;
2005 static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val)
2007 return sd_setilluminator(gspca_dev, val, 1);
2010 static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val)
2012 return sd_setilluminator(gspca_dev, val, 2);
2015 static int sd_getilluminator(struct gspca_dev *gspca_dev, __s32 *val, int n)
2017 struct sd *sd = (struct sd *) gspca_dev;
2019 if (!sd->params.qx3.qx3_detected)
2020 return -EINVAL;
2022 switch (n) {
2023 case 1:
2024 *val = sd->params.qx3.bottomlight;
2025 break;
2026 case 2:
2027 *val = sd->params.qx3.toplight;
2028 break;
2029 default:
2030 return -EINVAL;
2032 return 0;
2035 static int sd_getilluminator1(struct gspca_dev *gspca_dev, __s32 *val)
2037 return sd_getilluminator(gspca_dev, val, 1);
2040 static int sd_getilluminator2(struct gspca_dev *gspca_dev, __s32 *val)
2042 return sd_getilluminator(gspca_dev, val, 2);
2045 static int sd_querymenu(struct gspca_dev *gspca_dev,
2046 struct v4l2_querymenu *menu)
2048 switch (menu->id) {
2049 case V4L2_CID_POWER_LINE_FREQUENCY:
2050 switch (menu->index) {
2051 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2052 strcpy((char *) menu->name, "NoFliker");
2053 return 0;
2054 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2055 strcpy((char *) menu->name, "50 Hz");
2056 return 0;
2057 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2058 strcpy((char *) menu->name, "60 Hz");
2059 return 0;
2061 break;
2062 case V4L2_CID_COMP_TARGET:
2063 switch (menu->index) {
2064 case CPIA_COMPRESSION_TARGET_QUALITY:
2065 strcpy((char *) menu->name, "Quality");
2066 return 0;
2067 case CPIA_COMPRESSION_TARGET_FRAMERATE:
2068 strcpy((char *) menu->name, "Framerate");
2069 return 0;
2071 break;
2073 return -EINVAL;
2076 /* sub-driver description */
2077 static const struct sd_desc sd_desc = {
2078 .name = MODULE_NAME,
2079 .ctrls = sd_ctrls,
2080 .nctrls = ARRAY_SIZE(sd_ctrls),
2081 .config = sd_config,
2082 .init = sd_init,
2083 .start = sd_start,
2084 .stopN = sd_stopN,
2085 .dq_callback = sd_dq_callback,
2086 .pkt_scan = sd_pkt_scan,
2087 .querymenu = sd_querymenu,
2090 /* -- module initialisation -- */
2091 static const struct usb_device_id device_table[] = {
2092 {USB_DEVICE(0x0553, 0x0002)},
2093 {USB_DEVICE(0x0813, 0x0001)},
2096 MODULE_DEVICE_TABLE(usb, device_table);
2098 /* -- device connect -- */
2099 static int sd_probe(struct usb_interface *intf,
2100 const struct usb_device_id *id)
2102 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2103 THIS_MODULE);
2106 static struct usb_driver sd_driver = {
2107 .name = MODULE_NAME,
2108 .id_table = device_table,
2109 .probe = sd_probe,
2110 .disconnect = gspca_disconnect,
2111 #ifdef CONFIG_PM
2112 .suspend = gspca_suspend,
2113 .resume = gspca_resume,
2114 #endif
2117 /* -- module insert / remove -- */
2118 static int __init sd_mod_init(void)
2120 return usb_register(&sd_driver);
2122 static void __exit sd_mod_exit(void)
2124 usb_deregister(&sd_driver);
2127 module_init(sd_mod_init);
2128 module_exit(sd_mod_exit);