Avoid beyond bounds copy while caching ACL
[zen-stable.git] / drivers / media / video / gspca / cpia1.c
blob8f33bbd091ad2d2976a46a7fe6e660ad3af4f1f9
1 /*
2 * cpia CPiA (1) gspca driver
4 * Copyright (C) 2010-2011 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 pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31 #define MODULE_NAME "cpia1"
33 #include <linux/input.h>
34 #include "gspca.h"
36 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
37 MODULE_DESCRIPTION("Vision CPiA");
38 MODULE_LICENSE("GPL");
40 /* constant value's */
41 #define MAGIC_0 0x19
42 #define MAGIC_1 0x68
43 #define DATA_IN 0xc0
44 #define DATA_OUT 0x40
45 #define VIDEOSIZE_QCIF 0 /* 176x144 */
46 #define VIDEOSIZE_CIF 1 /* 352x288 */
47 #define SUBSAMPLE_420 0
48 #define SUBSAMPLE_422 1
49 #define YUVORDER_YUYV 0
50 #define YUVORDER_UYVY 1
51 #define NOT_COMPRESSED 0
52 #define COMPRESSED 1
53 #define NO_DECIMATION 0
54 #define DECIMATION_ENAB 1
55 #define EOI 0xff /* End Of Image */
56 #define EOL 0xfd /* End Of Line */
57 #define FRAME_HEADER_SIZE 64
59 /* Image grab modes */
60 #define CPIA_GRAB_SINGLE 0
61 #define CPIA_GRAB_CONTINEOUS 1
63 /* Compression parameters */
64 #define CPIA_COMPRESSION_NONE 0
65 #define CPIA_COMPRESSION_AUTO 1
66 #define CPIA_COMPRESSION_MANUAL 2
67 #define CPIA_COMPRESSION_TARGET_QUALITY 0
68 #define CPIA_COMPRESSION_TARGET_FRAMERATE 1
70 /* Return offsets for GetCameraState */
71 #define SYSTEMSTATE 0
72 #define GRABSTATE 1
73 #define STREAMSTATE 2
74 #define FATALERROR 3
75 #define CMDERROR 4
76 #define DEBUGFLAGS 5
77 #define VPSTATUS 6
78 #define ERRORCODE 7
80 /* SystemState */
81 #define UNINITIALISED_STATE 0
82 #define PASS_THROUGH_STATE 1
83 #define LO_POWER_STATE 2
84 #define HI_POWER_STATE 3
85 #define WARM_BOOT_STATE 4
87 /* GrabState */
88 #define GRAB_IDLE 0
89 #define GRAB_ACTIVE 1
90 #define GRAB_DONE 2
92 /* StreamState */
93 #define STREAM_NOT_READY 0
94 #define STREAM_READY 1
95 #define STREAM_OPEN 2
96 #define STREAM_PAUSED 3
97 #define STREAM_FINISHED 4
99 /* Fatal Error, CmdError, and DebugFlags */
100 #define CPIA_FLAG 1
101 #define SYSTEM_FLAG 2
102 #define INT_CTRL_FLAG 4
103 #define PROCESS_FLAG 8
104 #define COM_FLAG 16
105 #define VP_CTRL_FLAG 32
106 #define CAPTURE_FLAG 64
107 #define DEBUG_FLAG 128
109 /* VPStatus */
110 #define VP_STATE_OK 0x00
112 #define VP_STATE_FAILED_VIDEOINIT 0x01
113 #define VP_STATE_FAILED_AECACBINIT 0x02
114 #define VP_STATE_AEC_MAX 0x04
115 #define VP_STATE_ACB_BMAX 0x08
117 #define VP_STATE_ACB_RMIN 0x10
118 #define VP_STATE_ACB_GMIN 0x20
119 #define VP_STATE_ACB_RMAX 0x40
120 #define VP_STATE_ACB_GMAX 0x80
122 /* default (minimum) compensation values */
123 #define COMP_RED 220
124 #define COMP_GREEN1 214
125 #define COMP_GREEN2 COMP_GREEN1
126 #define COMP_BLUE 230
128 /* exposure status */
129 #define EXPOSURE_VERY_LIGHT 0
130 #define EXPOSURE_LIGHT 1
131 #define EXPOSURE_NORMAL 2
132 #define EXPOSURE_DARK 3
133 #define EXPOSURE_VERY_DARK 4
135 #define CPIA_MODULE_CPIA (0 << 5)
136 #define CPIA_MODULE_SYSTEM (1 << 5)
137 #define CPIA_MODULE_VP_CTRL (5 << 5)
138 #define CPIA_MODULE_CAPTURE (6 << 5)
139 #define CPIA_MODULE_DEBUG (7 << 5)
141 #define INPUT (DATA_IN << 8)
142 #define OUTPUT (DATA_OUT << 8)
144 #define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)
145 #define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)
146 #define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)
147 #define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)
148 #define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)
149 #define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)
150 #define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)
151 #define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)
153 #define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)
154 #define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)
155 #define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)
156 #define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)
157 #define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)
158 #define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)
159 #define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)
160 #define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)
161 #define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)
162 #define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)
163 #define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)
164 #define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)
165 #define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
167 #define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
168 #define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)
169 #define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
170 #define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
171 #define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
172 #define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)
173 #define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)
174 #define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)
175 #define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)
176 #define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)
177 #define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)
178 #define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)
179 #define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)
180 #define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)
181 #define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)
182 #define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)
183 #define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)
185 #define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)
186 #define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)
187 #define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)
188 #define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)
189 #define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)
190 #define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)
191 #define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)
192 #define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)
193 #define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)
194 #define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)
195 #define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
196 #define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
197 #define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
198 #define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
199 #define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)
201 #define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
202 #define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
203 #define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)
204 #define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)
205 #define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
206 #define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
207 #define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
208 #define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)
210 #define ROUND_UP_EXP_FOR_FLICKER 15
212 /* Constants for automatic frame rate adjustment */
213 #define MAX_EXP 302
214 #define MAX_EXP_102 255
215 #define LOW_EXP 140
216 #define VERY_LOW_EXP 70
217 #define TC 94
218 #define EXP_ACC_DARK 50
219 #define EXP_ACC_LIGHT 90
220 #define HIGH_COMP_102 160
221 #define MAX_COMP 239
222 #define DARK_TIME 3
223 #define LIGHT_TIME 3
225 #define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \
226 sd->params.version.firmwareRevision == (y))
228 /* Developer's Guide Table 5 p 3-34
229 * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
230 static u8 flicker_jumps[2][2][4] =
231 { { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
232 { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
235 struct cam_params {
236 struct {
237 u8 firmwareVersion;
238 u8 firmwareRevision;
239 u8 vcVersion;
240 u8 vcRevision;
241 } version;
242 struct {
243 u16 vendor;
244 u16 product;
245 u16 deviceRevision;
246 } pnpID;
247 struct {
248 u8 vpVersion;
249 u8 vpRevision;
250 u16 cameraHeadID;
251 } vpVersion;
252 struct {
253 u8 systemState;
254 u8 grabState;
255 u8 streamState;
256 u8 fatalError;
257 u8 cmdError;
258 u8 debugFlags;
259 u8 vpStatus;
260 u8 errorCode;
261 } status;
262 struct {
263 u8 brightness;
264 u8 contrast;
265 u8 saturation;
266 } colourParams;
267 struct {
268 u8 gainMode;
269 u8 expMode;
270 u8 compMode;
271 u8 centreWeight;
272 u8 gain;
273 u8 fineExp;
274 u8 coarseExpLo;
275 u8 coarseExpHi;
276 u8 redComp;
277 u8 green1Comp;
278 u8 green2Comp;
279 u8 blueComp;
280 } exposure;
281 struct {
282 u8 balanceMode;
283 u8 redGain;
284 u8 greenGain;
285 u8 blueGain;
286 } colourBalance;
287 struct {
288 u8 divisor;
289 u8 baserate;
290 } sensorFps;
291 struct {
292 u8 gain1;
293 u8 gain2;
294 u8 gain4;
295 u8 gain8;
296 } apcor;
297 struct {
298 u8 disabled;
299 u8 flickerMode;
300 u8 coarseJump;
301 u8 allowableOverExposure;
302 } flickerControl;
303 struct {
304 u8 gain1;
305 u8 gain2;
306 u8 gain4;
307 u8 gain8;
308 } vlOffset;
309 struct {
310 u8 mode;
311 u8 decimation;
312 } compression;
313 struct {
314 u8 frTargeting;
315 u8 targetFR;
316 u8 targetQ;
317 } compressionTarget;
318 struct {
319 u8 yThreshold;
320 u8 uvThreshold;
321 } yuvThreshold;
322 struct {
323 u8 hysteresis;
324 u8 threshMax;
325 u8 smallStep;
326 u8 largeStep;
327 u8 decimationHysteresis;
328 u8 frDiffStepThresh;
329 u8 qDiffStepThresh;
330 u8 decimationThreshMod;
331 } compressionParams;
332 struct {
333 u8 videoSize; /* CIF/QCIF */
334 u8 subSample;
335 u8 yuvOrder;
336 } format;
337 struct { /* Intel QX3 specific data */
338 u8 qx3_detected; /* a QX3 is present */
339 u8 toplight; /* top light lit , R/W */
340 u8 bottomlight; /* bottom light lit, R/W */
341 u8 button; /* snapshot button pressed (R/O) */
342 u8 cradled; /* microscope is in cradle (R/O) */
343 } qx3;
344 struct {
345 u8 colStart; /* skip first 8*colStart pixels */
346 u8 colEnd; /* finish at 8*colEnd pixels */
347 u8 rowStart; /* skip first 4*rowStart lines */
348 u8 rowEnd; /* finish at 4*rowEnd lines */
349 } roi;
350 u8 ecpTiming;
351 u8 streamStartLine;
354 /* specific webcam descriptor */
355 struct sd {
356 struct gspca_dev gspca_dev; /* !! must be the first item */
357 struct cam_params params; /* camera settings */
359 atomic_t cam_exposure;
360 atomic_t fps;
361 int exposure_count;
362 u8 exposure_status;
363 u8 mainsFreq; /* 0 = 50hz, 1 = 60hz */
364 u8 first_frame;
365 u8 freq;
368 /* V4L2 controls supported by the driver */
369 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
370 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
371 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
372 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
373 static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val);
374 static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val);
375 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
376 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
377 static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val);
378 static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val);
379 static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val);
380 static int sd_getilluminator1(struct gspca_dev *gspca_dev, __s32 *val);
381 static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val);
382 static int sd_getilluminator2(struct gspca_dev *gspca_dev, __s32 *val);
384 static const struct ctrl sd_ctrls[] = {
386 #define BRIGHTNESS_IDX 0
388 .id = V4L2_CID_BRIGHTNESS,
389 .type = V4L2_CTRL_TYPE_INTEGER,
390 .name = "Brightness",
391 .minimum = 0,
392 .maximum = 100,
393 .step = 1,
394 #define BRIGHTNESS_DEF 50
395 .default_value = BRIGHTNESS_DEF,
396 .flags = 0,
398 .set = sd_setbrightness,
399 .get = sd_getbrightness,
401 #define CONTRAST_IDX 1
404 .id = V4L2_CID_CONTRAST,
405 .type = V4L2_CTRL_TYPE_INTEGER,
406 .name = "Contrast",
407 .minimum = 0,
408 .maximum = 96,
409 .step = 8,
410 #define CONTRAST_DEF 48
411 .default_value = CONTRAST_DEF,
413 .set = sd_setcontrast,
414 .get = sd_getcontrast,
416 #define SATURATION_IDX 2
419 .id = V4L2_CID_SATURATION,
420 .type = V4L2_CTRL_TYPE_INTEGER,
421 .name = "Saturation",
422 .minimum = 0,
423 .maximum = 100,
424 .step = 1,
425 #define SATURATION_DEF 50
426 .default_value = SATURATION_DEF,
428 .set = sd_setsaturation,
429 .get = sd_getsaturation,
431 #define POWER_LINE_FREQUENCY_IDX 3
434 .id = V4L2_CID_POWER_LINE_FREQUENCY,
435 .type = V4L2_CTRL_TYPE_MENU,
436 .name = "Light frequency filter",
437 .minimum = 0,
438 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
439 .step = 1,
440 #define FREQ_DEF 1
441 .default_value = FREQ_DEF,
443 .set = sd_setfreq,
444 .get = sd_getfreq,
446 #define ILLUMINATORS_1_IDX 4
449 .id = V4L2_CID_ILLUMINATORS_1,
450 .type = V4L2_CTRL_TYPE_BOOLEAN,
451 .name = "Illuminator 1",
452 .minimum = 0,
453 .maximum = 1,
454 .step = 1,
455 #define ILLUMINATORS_1_DEF 0
456 .default_value = ILLUMINATORS_1_DEF,
458 .set = sd_setilluminator1,
459 .get = sd_getilluminator1,
461 #define ILLUMINATORS_2_IDX 5
464 .id = V4L2_CID_ILLUMINATORS_2,
465 .type = V4L2_CTRL_TYPE_BOOLEAN,
466 .name = "Illuminator 2",
467 .minimum = 0,
468 .maximum = 1,
469 .step = 1,
470 #define ILLUMINATORS_2_DEF 0
471 .default_value = ILLUMINATORS_2_DEF,
473 .set = sd_setilluminator2,
474 .get = sd_getilluminator2,
476 #define COMP_TARGET_IDX 6
479 #define V4L2_CID_COMP_TARGET V4L2_CID_PRIVATE_BASE
480 .id = V4L2_CID_COMP_TARGET,
481 .type = V4L2_CTRL_TYPE_MENU,
482 .name = "Compression Target",
483 .minimum = 0,
484 .maximum = 1,
485 .step = 1,
486 #define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY
487 .default_value = COMP_TARGET_DEF,
489 .set = sd_setcomptarget,
490 .get = sd_getcomptarget,
494 static const struct v4l2_pix_format mode[] = {
495 {160, 120, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
496 /* The sizeimage is trial and error, as with low framerates
497 the camera will pad out usb frames, making the image
498 data larger then strictly necessary */
499 .bytesperline = 160,
500 .sizeimage = 65536,
501 .colorspace = V4L2_COLORSPACE_SRGB,
502 .priv = 3},
503 {176, 144, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
504 .bytesperline = 172,
505 .sizeimage = 65536,
506 .colorspace = V4L2_COLORSPACE_SRGB,
507 .priv = 2},
508 {320, 240, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
509 .bytesperline = 320,
510 .sizeimage = 262144,
511 .colorspace = V4L2_COLORSPACE_SRGB,
512 .priv = 1},
513 {352, 288, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
514 .bytesperline = 352,
515 .sizeimage = 262144,
516 .colorspace = V4L2_COLORSPACE_SRGB,
517 .priv = 0},
520 /**********************************************************************
522 * General functions
524 **********************************************************************/
526 static int cpia_usb_transferCmd(struct gspca_dev *gspca_dev, u8 *command)
528 u8 requesttype;
529 unsigned int pipe;
530 int ret, databytes = command[6] | (command[7] << 8);
531 /* Sometimes we see spurious EPIPE errors */
532 int retries = 3;
534 if (command[0] == DATA_IN) {
535 pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
536 requesttype = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
537 } else if (command[0] == DATA_OUT) {
538 pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
539 requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE;
540 } else {
541 PDEBUG(D_ERR, "Unexpected first byte of command: %x",
542 command[0]);
543 return -EINVAL;
546 retry:
547 ret = usb_control_msg(gspca_dev->dev, pipe,
548 command[1],
549 requesttype,
550 command[2] | (command[3] << 8),
551 command[4] | (command[5] << 8),
552 gspca_dev->usb_buf, databytes, 1000);
554 if (ret < 0)
555 pr_err("usb_control_msg %02x, error %d\n", command[1], ret);
557 if (ret == -EPIPE && retries > 0) {
558 retries--;
559 goto retry;
562 return (ret < 0) ? ret : 0;
565 /* send an arbitrary command to the camera */
566 static int do_command(struct gspca_dev *gspca_dev, u16 command,
567 u8 a, u8 b, u8 c, u8 d)
569 struct sd *sd = (struct sd *) gspca_dev;
570 int ret, datasize;
571 u8 cmd[8];
573 switch (command) {
574 case CPIA_COMMAND_GetCPIAVersion:
575 case CPIA_COMMAND_GetPnPID:
576 case CPIA_COMMAND_GetCameraStatus:
577 case CPIA_COMMAND_GetVPVersion:
578 case CPIA_COMMAND_GetColourParams:
579 case CPIA_COMMAND_GetColourBalance:
580 case CPIA_COMMAND_GetExposure:
581 datasize = 8;
582 break;
583 case CPIA_COMMAND_ReadMCPorts:
584 case CPIA_COMMAND_ReadVCRegs:
585 datasize = 4;
586 break;
587 default:
588 datasize = 0;
589 break;
592 cmd[0] = command >> 8;
593 cmd[1] = command & 0xff;
594 cmd[2] = a;
595 cmd[3] = b;
596 cmd[4] = c;
597 cmd[5] = d;
598 cmd[6] = datasize;
599 cmd[7] = 0;
601 ret = cpia_usb_transferCmd(gspca_dev, cmd);
602 if (ret)
603 return ret;
605 switch (command) {
606 case CPIA_COMMAND_GetCPIAVersion:
607 sd->params.version.firmwareVersion = gspca_dev->usb_buf[0];
608 sd->params.version.firmwareRevision = gspca_dev->usb_buf[1];
609 sd->params.version.vcVersion = gspca_dev->usb_buf[2];
610 sd->params.version.vcRevision = gspca_dev->usb_buf[3];
611 break;
612 case CPIA_COMMAND_GetPnPID:
613 sd->params.pnpID.vendor =
614 gspca_dev->usb_buf[0] | (gspca_dev->usb_buf[1] << 8);
615 sd->params.pnpID.product =
616 gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
617 sd->params.pnpID.deviceRevision =
618 gspca_dev->usb_buf[4] | (gspca_dev->usb_buf[5] << 8);
619 break;
620 case CPIA_COMMAND_GetCameraStatus:
621 sd->params.status.systemState = gspca_dev->usb_buf[0];
622 sd->params.status.grabState = gspca_dev->usb_buf[1];
623 sd->params.status.streamState = gspca_dev->usb_buf[2];
624 sd->params.status.fatalError = gspca_dev->usb_buf[3];
625 sd->params.status.cmdError = gspca_dev->usb_buf[4];
626 sd->params.status.debugFlags = gspca_dev->usb_buf[5];
627 sd->params.status.vpStatus = gspca_dev->usb_buf[6];
628 sd->params.status.errorCode = gspca_dev->usb_buf[7];
629 break;
630 case CPIA_COMMAND_GetVPVersion:
631 sd->params.vpVersion.vpVersion = gspca_dev->usb_buf[0];
632 sd->params.vpVersion.vpRevision = gspca_dev->usb_buf[1];
633 sd->params.vpVersion.cameraHeadID =
634 gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
635 break;
636 case CPIA_COMMAND_GetColourParams:
637 sd->params.colourParams.brightness = gspca_dev->usb_buf[0];
638 sd->params.colourParams.contrast = gspca_dev->usb_buf[1];
639 sd->params.colourParams.saturation = gspca_dev->usb_buf[2];
640 break;
641 case CPIA_COMMAND_GetColourBalance:
642 sd->params.colourBalance.redGain = gspca_dev->usb_buf[0];
643 sd->params.colourBalance.greenGain = gspca_dev->usb_buf[1];
644 sd->params.colourBalance.blueGain = gspca_dev->usb_buf[2];
645 break;
646 case CPIA_COMMAND_GetExposure:
647 sd->params.exposure.gain = gspca_dev->usb_buf[0];
648 sd->params.exposure.fineExp = gspca_dev->usb_buf[1];
649 sd->params.exposure.coarseExpLo = gspca_dev->usb_buf[2];
650 sd->params.exposure.coarseExpHi = gspca_dev->usb_buf[3];
651 sd->params.exposure.redComp = gspca_dev->usb_buf[4];
652 sd->params.exposure.green1Comp = gspca_dev->usb_buf[5];
653 sd->params.exposure.green2Comp = gspca_dev->usb_buf[6];
654 sd->params.exposure.blueComp = gspca_dev->usb_buf[7];
655 break;
657 case CPIA_COMMAND_ReadMCPorts:
658 /* test button press */
659 a = ((gspca_dev->usb_buf[1] & 0x02) == 0);
660 if (a != sd->params.qx3.button) {
661 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
662 input_report_key(gspca_dev->input_dev, KEY_CAMERA, a);
663 input_sync(gspca_dev->input_dev);
664 #endif
665 sd->params.qx3.button = a;
667 if (sd->params.qx3.button) {
668 /* button pressed - unlock the latch */
669 do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
670 3, 0xdf, 0xdf, 0);
671 do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
672 3, 0xff, 0xff, 0);
675 /* test whether microscope is cradled */
676 sd->params.qx3.cradled = ((gspca_dev->usb_buf[2] & 0x40) == 0);
677 break;
680 return 0;
683 /* send a command to the camera with an additional data transaction */
684 static int do_command_extended(struct gspca_dev *gspca_dev, u16 command,
685 u8 a, u8 b, u8 c, u8 d,
686 u8 e, u8 f, u8 g, u8 h,
687 u8 i, u8 j, u8 k, u8 l)
689 u8 cmd[8];
691 cmd[0] = command >> 8;
692 cmd[1] = command & 0xff;
693 cmd[2] = a;
694 cmd[3] = b;
695 cmd[4] = c;
696 cmd[5] = d;
697 cmd[6] = 8;
698 cmd[7] = 0;
699 gspca_dev->usb_buf[0] = e;
700 gspca_dev->usb_buf[1] = f;
701 gspca_dev->usb_buf[2] = g;
702 gspca_dev->usb_buf[3] = h;
703 gspca_dev->usb_buf[4] = i;
704 gspca_dev->usb_buf[5] = j;
705 gspca_dev->usb_buf[6] = k;
706 gspca_dev->usb_buf[7] = l;
708 return cpia_usb_transferCmd(gspca_dev, cmd);
711 /* find_over_exposure
712 * Finds a suitable value of OverExposure for use with SetFlickerCtrl
713 * Some calculation is required because this value changes with the brightness
714 * set with SetColourParameters
716 * Parameters: Brightness - last brightness value set with SetColourParameters
718 * Returns: OverExposure value to use with SetFlickerCtrl
720 #define FLICKER_MAX_EXPOSURE 250
721 #define FLICKER_ALLOWABLE_OVER_EXPOSURE 146
722 #define FLICKER_BRIGHTNESS_CONSTANT 59
723 static int find_over_exposure(int brightness)
725 int MaxAllowableOverExposure, OverExposure;
727 MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness -
728 FLICKER_BRIGHTNESS_CONSTANT;
730 if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE)
731 OverExposure = MaxAllowableOverExposure;
732 else
733 OverExposure = FLICKER_ALLOWABLE_OVER_EXPOSURE;
735 return OverExposure;
737 #undef FLICKER_MAX_EXPOSURE
738 #undef FLICKER_ALLOWABLE_OVER_EXPOSURE
739 #undef FLICKER_BRIGHTNESS_CONSTANT
741 /* initialise cam_data structure */
742 static void reset_camera_params(struct gspca_dev *gspca_dev)
744 struct sd *sd = (struct sd *) gspca_dev;
745 struct cam_params *params = &sd->params;
747 /* The following parameter values are the defaults from
748 * "Software Developer's Guide for CPiA Cameras". Any changes
749 * to the defaults are noted in comments. */
750 params->colourParams.brightness = BRIGHTNESS_DEF;
751 params->colourParams.contrast = CONTRAST_DEF;
752 params->colourParams.saturation = SATURATION_DEF;
753 params->exposure.gainMode = 4;
754 params->exposure.expMode = 2; /* AEC */
755 params->exposure.compMode = 1;
756 params->exposure.centreWeight = 1;
757 params->exposure.gain = 0;
758 params->exposure.fineExp = 0;
759 params->exposure.coarseExpLo = 185;
760 params->exposure.coarseExpHi = 0;
761 params->exposure.redComp = COMP_RED;
762 params->exposure.green1Comp = COMP_GREEN1;
763 params->exposure.green2Comp = COMP_GREEN2;
764 params->exposure.blueComp = COMP_BLUE;
765 params->colourBalance.balanceMode = 2; /* ACB */
766 params->colourBalance.redGain = 32;
767 params->colourBalance.greenGain = 6;
768 params->colourBalance.blueGain = 92;
769 params->apcor.gain1 = 0x18;
770 params->apcor.gain2 = 0x16;
771 params->apcor.gain4 = 0x24;
772 params->apcor.gain8 = 0x34;
773 params->flickerControl.flickerMode = 0;
774 params->flickerControl.disabled = 1;
776 params->flickerControl.coarseJump =
777 flicker_jumps[sd->mainsFreq]
778 [params->sensorFps.baserate]
779 [params->sensorFps.divisor];
780 params->flickerControl.allowableOverExposure =
781 find_over_exposure(params->colourParams.brightness);
782 params->vlOffset.gain1 = 20;
783 params->vlOffset.gain2 = 24;
784 params->vlOffset.gain4 = 26;
785 params->vlOffset.gain8 = 26;
786 params->compressionParams.hysteresis = 3;
787 params->compressionParams.threshMax = 11;
788 params->compressionParams.smallStep = 1;
789 params->compressionParams.largeStep = 3;
790 params->compressionParams.decimationHysteresis = 2;
791 params->compressionParams.frDiffStepThresh = 5;
792 params->compressionParams.qDiffStepThresh = 3;
793 params->compressionParams.decimationThreshMod = 2;
794 /* End of default values from Software Developer's Guide */
796 /* Set Sensor FPS to 15fps. This seems better than 30fps
797 * for indoor lighting. */
798 params->sensorFps.divisor = 1;
799 params->sensorFps.baserate = 1;
801 params->yuvThreshold.yThreshold = 6; /* From windows driver */
802 params->yuvThreshold.uvThreshold = 6; /* From windows driver */
804 params->format.subSample = SUBSAMPLE_420;
805 params->format.yuvOrder = YUVORDER_YUYV;
807 params->compression.mode = CPIA_COMPRESSION_AUTO;
808 params->compression.decimation = NO_DECIMATION;
810 params->compressionTarget.frTargeting = COMP_TARGET_DEF;
811 params->compressionTarget.targetFR = 15; /* From windows driver */
812 params->compressionTarget.targetQ = 5; /* From windows driver */
814 params->qx3.qx3_detected = 0;
815 params->qx3.toplight = 0;
816 params->qx3.bottomlight = 0;
817 params->qx3.button = 0;
818 params->qx3.cradled = 0;
821 static void printstatus(struct cam_params *params)
823 PDEBUG(D_PROBE, "status: %02x %02x %02x %02x %02x %02x %02x %02x",
824 params->status.systemState, params->status.grabState,
825 params->status.streamState, params->status.fatalError,
826 params->status.cmdError, params->status.debugFlags,
827 params->status.vpStatus, params->status.errorCode);
830 static int goto_low_power(struct gspca_dev *gspca_dev)
832 struct sd *sd = (struct sd *) gspca_dev;
833 int ret;
835 ret = do_command(gspca_dev, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0);
836 if (ret)
837 return ret;
839 ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
840 if (ret)
841 return ret;
843 if (sd->params.status.systemState != LO_POWER_STATE) {
844 if (sd->params.status.systemState != WARM_BOOT_STATE) {
845 PDEBUG(D_ERR,
846 "unexpected state after lo power cmd: %02x",
847 sd->params.status.systemState);
848 printstatus(&sd->params);
850 return -EIO;
853 PDEBUG(D_CONF, "camera now in LOW power state");
854 return 0;
857 static int goto_high_power(struct gspca_dev *gspca_dev)
859 struct sd *sd = (struct sd *) gspca_dev;
860 int ret;
862 ret = do_command(gspca_dev, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0);
863 if (ret)
864 return ret;
866 msleep_interruptible(40); /* windows driver does it too */
868 if (signal_pending(current))
869 return -EINTR;
871 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
872 if (ret)
873 return ret;
875 if (sd->params.status.systemState != HI_POWER_STATE) {
876 PDEBUG(D_ERR, "unexpected state after hi power cmd: %02x",
877 sd->params.status.systemState);
878 printstatus(&sd->params);
879 return -EIO;
882 PDEBUG(D_CONF, "camera now in HIGH power state");
883 return 0;
886 static int get_version_information(struct gspca_dev *gspca_dev)
888 int ret;
890 /* GetCPIAVersion */
891 ret = do_command(gspca_dev, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0);
892 if (ret)
893 return ret;
895 /* GetPnPID */
896 return do_command(gspca_dev, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0);
899 static int save_camera_state(struct gspca_dev *gspca_dev)
901 int ret;
903 ret = do_command(gspca_dev, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
904 if (ret)
905 return ret;
907 return do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
910 static int command_setformat(struct gspca_dev *gspca_dev)
912 struct sd *sd = (struct sd *) gspca_dev;
913 int ret;
915 ret = do_command(gspca_dev, CPIA_COMMAND_SetFormat,
916 sd->params.format.videoSize,
917 sd->params.format.subSample,
918 sd->params.format.yuvOrder, 0);
919 if (ret)
920 return ret;
922 return do_command(gspca_dev, CPIA_COMMAND_SetROI,
923 sd->params.roi.colStart, sd->params.roi.colEnd,
924 sd->params.roi.rowStart, sd->params.roi.rowEnd);
927 static int command_setcolourparams(struct gspca_dev *gspca_dev)
929 struct sd *sd = (struct sd *) gspca_dev;
930 return do_command(gspca_dev, CPIA_COMMAND_SetColourParams,
931 sd->params.colourParams.brightness,
932 sd->params.colourParams.contrast,
933 sd->params.colourParams.saturation, 0);
936 static int command_setapcor(struct gspca_dev *gspca_dev)
938 struct sd *sd = (struct sd *) gspca_dev;
939 return do_command(gspca_dev, CPIA_COMMAND_SetApcor,
940 sd->params.apcor.gain1,
941 sd->params.apcor.gain2,
942 sd->params.apcor.gain4,
943 sd->params.apcor.gain8);
946 static int command_setvloffset(struct gspca_dev *gspca_dev)
948 struct sd *sd = (struct sd *) gspca_dev;
949 return do_command(gspca_dev, CPIA_COMMAND_SetVLOffset,
950 sd->params.vlOffset.gain1,
951 sd->params.vlOffset.gain2,
952 sd->params.vlOffset.gain4,
953 sd->params.vlOffset.gain8);
956 static int command_setexposure(struct gspca_dev *gspca_dev)
958 struct sd *sd = (struct sd *) gspca_dev;
959 int ret;
961 ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
962 sd->params.exposure.gainMode,
964 sd->params.exposure.compMode,
965 sd->params.exposure.centreWeight,
966 sd->params.exposure.gain,
967 sd->params.exposure.fineExp,
968 sd->params.exposure.coarseExpLo,
969 sd->params.exposure.coarseExpHi,
970 sd->params.exposure.redComp,
971 sd->params.exposure.green1Comp,
972 sd->params.exposure.green2Comp,
973 sd->params.exposure.blueComp);
974 if (ret)
975 return ret;
977 if (sd->params.exposure.expMode != 1) {
978 ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
980 sd->params.exposure.expMode,
981 0, 0,
982 sd->params.exposure.gain,
983 sd->params.exposure.fineExp,
984 sd->params.exposure.coarseExpLo,
985 sd->params.exposure.coarseExpHi,
986 0, 0, 0, 0);
989 return ret;
992 static int command_setcolourbalance(struct gspca_dev *gspca_dev)
994 struct sd *sd = (struct sd *) gspca_dev;
996 if (sd->params.colourBalance.balanceMode == 1) {
997 int ret;
999 ret = do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
1001 sd->params.colourBalance.redGain,
1002 sd->params.colourBalance.greenGain,
1003 sd->params.colourBalance.blueGain);
1004 if (ret)
1005 return ret;
1007 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
1008 3, 0, 0, 0);
1010 if (sd->params.colourBalance.balanceMode == 2) {
1011 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
1012 2, 0, 0, 0);
1014 if (sd->params.colourBalance.balanceMode == 3) {
1015 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
1016 3, 0, 0, 0);
1019 return -EINVAL;
1022 static int command_setcompressiontarget(struct gspca_dev *gspca_dev)
1024 struct sd *sd = (struct sd *) gspca_dev;
1026 return do_command(gspca_dev, CPIA_COMMAND_SetCompressionTarget,
1027 sd->params.compressionTarget.frTargeting,
1028 sd->params.compressionTarget.targetFR,
1029 sd->params.compressionTarget.targetQ, 0);
1032 static int command_setyuvtresh(struct gspca_dev *gspca_dev)
1034 struct sd *sd = (struct sd *) gspca_dev;
1036 return do_command(gspca_dev, CPIA_COMMAND_SetYUVThresh,
1037 sd->params.yuvThreshold.yThreshold,
1038 sd->params.yuvThreshold.uvThreshold, 0, 0);
1041 static int command_setcompressionparams(struct gspca_dev *gspca_dev)
1043 struct sd *sd = (struct sd *) gspca_dev;
1045 return do_command_extended(gspca_dev,
1046 CPIA_COMMAND_SetCompressionParams,
1047 0, 0, 0, 0,
1048 sd->params.compressionParams.hysteresis,
1049 sd->params.compressionParams.threshMax,
1050 sd->params.compressionParams.smallStep,
1051 sd->params.compressionParams.largeStep,
1052 sd->params.compressionParams.decimationHysteresis,
1053 sd->params.compressionParams.frDiffStepThresh,
1054 sd->params.compressionParams.qDiffStepThresh,
1055 sd->params.compressionParams.decimationThreshMod);
1058 static int command_setcompression(struct gspca_dev *gspca_dev)
1060 struct sd *sd = (struct sd *) gspca_dev;
1062 return do_command(gspca_dev, CPIA_COMMAND_SetCompression,
1063 sd->params.compression.mode,
1064 sd->params.compression.decimation, 0, 0);
1067 static int command_setsensorfps(struct gspca_dev *gspca_dev)
1069 struct sd *sd = (struct sd *) gspca_dev;
1071 return do_command(gspca_dev, CPIA_COMMAND_SetSensorFPS,
1072 sd->params.sensorFps.divisor,
1073 sd->params.sensorFps.baserate, 0, 0);
1076 static int command_setflickerctrl(struct gspca_dev *gspca_dev)
1078 struct sd *sd = (struct sd *) gspca_dev;
1080 return do_command(gspca_dev, CPIA_COMMAND_SetFlickerCtrl,
1081 sd->params.flickerControl.flickerMode,
1082 sd->params.flickerControl.coarseJump,
1083 sd->params.flickerControl.allowableOverExposure,
1087 static int command_setecptiming(struct gspca_dev *gspca_dev)
1089 struct sd *sd = (struct sd *) gspca_dev;
1091 return do_command(gspca_dev, CPIA_COMMAND_SetECPTiming,
1092 sd->params.ecpTiming, 0, 0, 0);
1095 static int command_pause(struct gspca_dev *gspca_dev)
1097 return do_command(gspca_dev, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
1100 static int command_resume(struct gspca_dev *gspca_dev)
1102 struct sd *sd = (struct sd *) gspca_dev;
1104 return do_command(gspca_dev, CPIA_COMMAND_InitStreamCap,
1105 0, sd->params.streamStartLine, 0, 0);
1108 static int command_setlights(struct gspca_dev *gspca_dev)
1110 struct sd *sd = (struct sd *) gspca_dev;
1111 int ret, p1, p2;
1113 if (!sd->params.qx3.qx3_detected)
1114 return 0;
1116 p1 = (sd->params.qx3.bottomlight == 0) << 1;
1117 p2 = (sd->params.qx3.toplight == 0) << 3;
1119 ret = do_command(gspca_dev, CPIA_COMMAND_WriteVCReg,
1120 0x90, 0x8f, 0x50, 0);
1121 if (ret)
1122 return ret;
1124 return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0,
1125 p1 | p2 | 0xe0, 0);
1128 static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply)
1130 /* Everything in here is from the Windows driver */
1131 /* define for compgain calculation */
1132 #if 0
1133 #define COMPGAIN(base, curexp, newexp) \
1134 (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
1135 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1136 (u16)((float)curexp * (float)(u8)(curcomp + 128) / \
1137 (float)(u8)(basecomp - 128))
1138 #else
1139 /* equivalent functions without floating point math */
1140 #define COMPGAIN(base, curexp, newexp) \
1141 (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2 * newexp)))
1142 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1143 (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
1144 #endif
1146 struct sd *sd = (struct sd *) gspca_dev;
1147 int currentexp = sd->params.exposure.coarseExpLo +
1148 sd->params.exposure.coarseExpHi * 256;
1149 int ret, startexp;
1151 if (on) {
1152 int cj = sd->params.flickerControl.coarseJump;
1153 sd->params.flickerControl.flickerMode = 1;
1154 sd->params.flickerControl.disabled = 0;
1155 if (sd->params.exposure.expMode != 2) {
1156 sd->params.exposure.expMode = 2;
1157 sd->exposure_status = EXPOSURE_NORMAL;
1159 currentexp = currentexp << sd->params.exposure.gain;
1160 sd->params.exposure.gain = 0;
1161 /* round down current exposure to nearest value */
1162 startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj;
1163 if (startexp < 1)
1164 startexp = 1;
1165 startexp = (startexp * cj) - 1;
1166 if (FIRMWARE_VERSION(1, 2))
1167 while (startexp > MAX_EXP_102)
1168 startexp -= cj;
1169 else
1170 while (startexp > MAX_EXP)
1171 startexp -= cj;
1172 sd->params.exposure.coarseExpLo = startexp & 0xff;
1173 sd->params.exposure.coarseExpHi = startexp >> 8;
1174 if (currentexp > startexp) {
1175 if (currentexp > (2 * startexp))
1176 currentexp = 2 * startexp;
1177 sd->params.exposure.redComp =
1178 COMPGAIN(COMP_RED, currentexp, startexp);
1179 sd->params.exposure.green1Comp =
1180 COMPGAIN(COMP_GREEN1, currentexp, startexp);
1181 sd->params.exposure.green2Comp =
1182 COMPGAIN(COMP_GREEN2, currentexp, startexp);
1183 sd->params.exposure.blueComp =
1184 COMPGAIN(COMP_BLUE, currentexp, startexp);
1185 } else {
1186 sd->params.exposure.redComp = COMP_RED;
1187 sd->params.exposure.green1Comp = COMP_GREEN1;
1188 sd->params.exposure.green2Comp = COMP_GREEN2;
1189 sd->params.exposure.blueComp = COMP_BLUE;
1191 if (FIRMWARE_VERSION(1, 2))
1192 sd->params.exposure.compMode = 0;
1193 else
1194 sd->params.exposure.compMode = 1;
1196 sd->params.apcor.gain1 = 0x18;
1197 sd->params.apcor.gain2 = 0x18;
1198 sd->params.apcor.gain4 = 0x16;
1199 sd->params.apcor.gain8 = 0x14;
1200 } else {
1201 sd->params.flickerControl.flickerMode = 0;
1202 sd->params.flickerControl.disabled = 1;
1203 /* Average equivalent coarse for each comp channel */
1204 startexp = EXP_FROM_COMP(COMP_RED,
1205 sd->params.exposure.redComp, currentexp);
1206 startexp += EXP_FROM_COMP(COMP_GREEN1,
1207 sd->params.exposure.green1Comp, currentexp);
1208 startexp += EXP_FROM_COMP(COMP_GREEN2,
1209 sd->params.exposure.green2Comp, currentexp);
1210 startexp += EXP_FROM_COMP(COMP_BLUE,
1211 sd->params.exposure.blueComp, currentexp);
1212 startexp = startexp >> 2;
1213 while (startexp > MAX_EXP && sd->params.exposure.gain <
1214 sd->params.exposure.gainMode - 1) {
1215 startexp = startexp >> 1;
1216 ++sd->params.exposure.gain;
1218 if (FIRMWARE_VERSION(1, 2) && startexp > MAX_EXP_102)
1219 startexp = MAX_EXP_102;
1220 if (startexp > MAX_EXP)
1221 startexp = MAX_EXP;
1222 sd->params.exposure.coarseExpLo = startexp & 0xff;
1223 sd->params.exposure.coarseExpHi = startexp >> 8;
1224 sd->params.exposure.redComp = COMP_RED;
1225 sd->params.exposure.green1Comp = COMP_GREEN1;
1226 sd->params.exposure.green2Comp = COMP_GREEN2;
1227 sd->params.exposure.blueComp = COMP_BLUE;
1228 sd->params.exposure.compMode = 1;
1229 sd->params.apcor.gain1 = 0x18;
1230 sd->params.apcor.gain2 = 0x16;
1231 sd->params.apcor.gain4 = 0x24;
1232 sd->params.apcor.gain8 = 0x34;
1234 sd->params.vlOffset.gain1 = 20;
1235 sd->params.vlOffset.gain2 = 24;
1236 sd->params.vlOffset.gain4 = 26;
1237 sd->params.vlOffset.gain8 = 26;
1239 if (apply) {
1240 ret = command_setexposure(gspca_dev);
1241 if (ret)
1242 return ret;
1244 ret = command_setapcor(gspca_dev);
1245 if (ret)
1246 return ret;
1248 ret = command_setvloffset(gspca_dev);
1249 if (ret)
1250 return ret;
1252 ret = command_setflickerctrl(gspca_dev);
1253 if (ret)
1254 return ret;
1257 return 0;
1258 #undef EXP_FROM_COMP
1259 #undef COMPGAIN
1262 /* monitor the exposure and adjust the sensor frame rate if needed */
1263 static void monitor_exposure(struct gspca_dev *gspca_dev)
1265 struct sd *sd = (struct sd *) gspca_dev;
1266 u8 exp_acc, bcomp, cmd[8];
1267 int ret, light_exp, dark_exp, very_dark_exp;
1268 int old_exposure, new_exposure, framerate;
1269 int setfps = 0, setexp = 0, setflicker = 0;
1271 /* get necessary stats and register settings from camera */
1272 /* do_command can't handle this, so do it ourselves */
1273 cmd[0] = CPIA_COMMAND_ReadVPRegs >> 8;
1274 cmd[1] = CPIA_COMMAND_ReadVPRegs & 0xff;
1275 cmd[2] = 30;
1276 cmd[3] = 4;
1277 cmd[4] = 9;
1278 cmd[5] = 8;
1279 cmd[6] = 8;
1280 cmd[7] = 0;
1281 ret = cpia_usb_transferCmd(gspca_dev, cmd);
1282 if (ret) {
1283 pr_err("ReadVPRegs(30,4,9,8) - failed: %d\n", ret);
1284 return;
1286 exp_acc = gspca_dev->usb_buf[0];
1287 bcomp = gspca_dev->usb_buf[1];
1289 light_exp = sd->params.colourParams.brightness +
1290 TC - 50 + EXP_ACC_LIGHT;
1291 if (light_exp > 255)
1292 light_exp = 255;
1293 dark_exp = sd->params.colourParams.brightness +
1294 TC - 50 - EXP_ACC_DARK;
1295 if (dark_exp < 0)
1296 dark_exp = 0;
1297 very_dark_exp = dark_exp / 2;
1299 old_exposure = sd->params.exposure.coarseExpHi * 256 +
1300 sd->params.exposure.coarseExpLo;
1302 if (!sd->params.flickerControl.disabled) {
1303 /* Flicker control on */
1304 int max_comp = FIRMWARE_VERSION(1, 2) ? MAX_COMP :
1305 HIGH_COMP_102;
1306 bcomp += 128; /* decode */
1307 if (bcomp >= max_comp && exp_acc < dark_exp) {
1308 /* dark */
1309 if (exp_acc < very_dark_exp) {
1310 /* very dark */
1311 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1312 ++sd->exposure_count;
1313 else {
1314 sd->exposure_status =
1315 EXPOSURE_VERY_DARK;
1316 sd->exposure_count = 1;
1318 } else {
1319 /* just dark */
1320 if (sd->exposure_status == EXPOSURE_DARK)
1321 ++sd->exposure_count;
1322 else {
1323 sd->exposure_status = EXPOSURE_DARK;
1324 sd->exposure_count = 1;
1327 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1328 /* light */
1329 if (old_exposure <= VERY_LOW_EXP) {
1330 /* very light */
1331 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1332 ++sd->exposure_count;
1333 else {
1334 sd->exposure_status =
1335 EXPOSURE_VERY_LIGHT;
1336 sd->exposure_count = 1;
1338 } else {
1339 /* just light */
1340 if (sd->exposure_status == EXPOSURE_LIGHT)
1341 ++sd->exposure_count;
1342 else {
1343 sd->exposure_status = EXPOSURE_LIGHT;
1344 sd->exposure_count = 1;
1347 } else {
1348 /* not dark or light */
1349 sd->exposure_status = EXPOSURE_NORMAL;
1351 } else {
1352 /* Flicker control off */
1353 if (old_exposure >= MAX_EXP && exp_acc < dark_exp) {
1354 /* dark */
1355 if (exp_acc < very_dark_exp) {
1356 /* very dark */
1357 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1358 ++sd->exposure_count;
1359 else {
1360 sd->exposure_status =
1361 EXPOSURE_VERY_DARK;
1362 sd->exposure_count = 1;
1364 } else {
1365 /* just dark */
1366 if (sd->exposure_status == EXPOSURE_DARK)
1367 ++sd->exposure_count;
1368 else {
1369 sd->exposure_status = EXPOSURE_DARK;
1370 sd->exposure_count = 1;
1373 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1374 /* light */
1375 if (old_exposure <= VERY_LOW_EXP) {
1376 /* very light */
1377 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1378 ++sd->exposure_count;
1379 else {
1380 sd->exposure_status =
1381 EXPOSURE_VERY_LIGHT;
1382 sd->exposure_count = 1;
1384 } else {
1385 /* just light */
1386 if (sd->exposure_status == EXPOSURE_LIGHT)
1387 ++sd->exposure_count;
1388 else {
1389 sd->exposure_status = EXPOSURE_LIGHT;
1390 sd->exposure_count = 1;
1393 } else {
1394 /* not dark or light */
1395 sd->exposure_status = EXPOSURE_NORMAL;
1399 framerate = atomic_read(&sd->fps);
1400 if (framerate > 30 || framerate < 1)
1401 framerate = 1;
1403 if (!sd->params.flickerControl.disabled) {
1404 /* Flicker control on */
1405 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1406 sd->exposure_status == EXPOSURE_DARK) &&
1407 sd->exposure_count >= DARK_TIME * framerate &&
1408 sd->params.sensorFps.divisor < 2) {
1410 /* dark for too long */
1411 ++sd->params.sensorFps.divisor;
1412 setfps = 1;
1414 sd->params.flickerControl.coarseJump =
1415 flicker_jumps[sd->mainsFreq]
1416 [sd->params.sensorFps.baserate]
1417 [sd->params.sensorFps.divisor];
1418 setflicker = 1;
1420 new_exposure = sd->params.flickerControl.coarseJump-1;
1421 while (new_exposure < old_exposure / 2)
1422 new_exposure +=
1423 sd->params.flickerControl.coarseJump;
1424 sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1425 sd->params.exposure.coarseExpHi = new_exposure >> 8;
1426 setexp = 1;
1427 sd->exposure_status = EXPOSURE_NORMAL;
1428 PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
1430 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1431 sd->exposure_status == EXPOSURE_LIGHT) &&
1432 sd->exposure_count >= LIGHT_TIME * framerate &&
1433 sd->params.sensorFps.divisor > 0) {
1435 /* light for too long */
1436 int max_exp = FIRMWARE_VERSION(1, 2) ? MAX_EXP_102 :
1437 MAX_EXP;
1438 --sd->params.sensorFps.divisor;
1439 setfps = 1;
1441 sd->params.flickerControl.coarseJump =
1442 flicker_jumps[sd->mainsFreq]
1443 [sd->params.sensorFps.baserate]
1444 [sd->params.sensorFps.divisor];
1445 setflicker = 1;
1447 new_exposure = sd->params.flickerControl.coarseJump-1;
1448 while (new_exposure < 2 * old_exposure &&
1449 new_exposure +
1450 sd->params.flickerControl.coarseJump < max_exp)
1451 new_exposure +=
1452 sd->params.flickerControl.coarseJump;
1453 sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1454 sd->params.exposure.coarseExpHi = new_exposure >> 8;
1455 setexp = 1;
1456 sd->exposure_status = EXPOSURE_NORMAL;
1457 PDEBUG(D_CONF, "Automatically increasing sensor_fps");
1459 } else {
1460 /* Flicker control off */
1461 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1462 sd->exposure_status == EXPOSURE_DARK) &&
1463 sd->exposure_count >= DARK_TIME * framerate &&
1464 sd->params.sensorFps.divisor < 2) {
1466 /* dark for too long */
1467 ++sd->params.sensorFps.divisor;
1468 setfps = 1;
1470 if (sd->params.exposure.gain > 0) {
1471 --sd->params.exposure.gain;
1472 setexp = 1;
1474 sd->exposure_status = EXPOSURE_NORMAL;
1475 PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
1477 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1478 sd->exposure_status == EXPOSURE_LIGHT) &&
1479 sd->exposure_count >= LIGHT_TIME * framerate &&
1480 sd->params.sensorFps.divisor > 0) {
1482 /* light for too long */
1483 --sd->params.sensorFps.divisor;
1484 setfps = 1;
1486 if (sd->params.exposure.gain <
1487 sd->params.exposure.gainMode - 1) {
1488 ++sd->params.exposure.gain;
1489 setexp = 1;
1491 sd->exposure_status = EXPOSURE_NORMAL;
1492 PDEBUG(D_CONF, "Automatically increasing sensor_fps");
1496 if (setexp)
1497 command_setexposure(gspca_dev);
1499 if (setfps)
1500 command_setsensorfps(gspca_dev);
1502 if (setflicker)
1503 command_setflickerctrl(gspca_dev);
1506 /*-----------------------------------------------------------------*/
1507 /* if flicker is switched off, this function switches it back on.It checks,
1508 however, that conditions are suitable before restarting it.
1509 This should only be called for firmware version 1.2.
1511 It also adjust the colour balance when an exposure step is detected - as
1512 long as flicker is running
1514 static void restart_flicker(struct gspca_dev *gspca_dev)
1516 struct sd *sd = (struct sd *) gspca_dev;
1517 int cam_exposure, old_exp;
1519 if (!FIRMWARE_VERSION(1, 2))
1520 return;
1522 cam_exposure = atomic_read(&sd->cam_exposure);
1524 if (sd->params.flickerControl.flickerMode == 0 ||
1525 cam_exposure == 0)
1526 return;
1528 old_exp = sd->params.exposure.coarseExpLo +
1529 sd->params.exposure.coarseExpHi*256;
1531 see how far away camera exposure is from a valid
1532 flicker exposure value
1534 cam_exposure %= sd->params.flickerControl.coarseJump;
1535 if (!sd->params.flickerControl.disabled &&
1536 cam_exposure <= sd->params.flickerControl.coarseJump - 3) {
1537 /* Flicker control auto-disabled */
1538 sd->params.flickerControl.disabled = 1;
1541 if (sd->params.flickerControl.disabled &&
1542 old_exp > sd->params.flickerControl.coarseJump +
1543 ROUND_UP_EXP_FOR_FLICKER) {
1544 /* exposure is now high enough to switch
1545 flicker control back on */
1546 set_flicker(gspca_dev, 1, 1);
1550 /* this function is called at probe time */
1551 static int sd_config(struct gspca_dev *gspca_dev,
1552 const struct usb_device_id *id)
1554 struct cam *cam;
1556 reset_camera_params(gspca_dev);
1558 PDEBUG(D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)",
1559 id->idVendor, id->idProduct);
1561 cam = &gspca_dev->cam;
1562 cam->cam_mode = mode;
1563 cam->nmodes = ARRAY_SIZE(mode);
1565 sd_setfreq(gspca_dev, FREQ_DEF);
1567 return 0;
1570 /* -- start the camera -- */
1571 static int sd_start(struct gspca_dev *gspca_dev)
1573 struct sd *sd = (struct sd *) gspca_dev;
1574 int priv, ret;
1576 /* Start the camera in low power mode */
1577 if (goto_low_power(gspca_dev)) {
1578 if (sd->params.status.systemState != WARM_BOOT_STATE) {
1579 PDEBUG(D_ERR, "unexpected systemstate: %02x",
1580 sd->params.status.systemState);
1581 printstatus(&sd->params);
1582 return -ENODEV;
1585 /* FIXME: this is just dirty trial and error */
1586 ret = goto_high_power(gspca_dev);
1587 if (ret)
1588 return ret;
1590 ret = do_command(gspca_dev, CPIA_COMMAND_DiscardFrame,
1591 0, 0, 0, 0);
1592 if (ret)
1593 return ret;
1595 ret = goto_low_power(gspca_dev);
1596 if (ret)
1597 return ret;
1600 /* procedure described in developer's guide p3-28 */
1602 /* Check the firmware version. */
1603 sd->params.version.firmwareVersion = 0;
1604 get_version_information(gspca_dev);
1605 if (sd->params.version.firmwareVersion != 1) {
1606 PDEBUG(D_ERR, "only firmware version 1 is supported (got: %d)",
1607 sd->params.version.firmwareVersion);
1608 return -ENODEV;
1611 /* A bug in firmware 1-02 limits gainMode to 2 */
1612 if (sd->params.version.firmwareRevision <= 2 &&
1613 sd->params.exposure.gainMode > 2) {
1614 sd->params.exposure.gainMode = 2;
1617 /* set QX3 detected flag */
1618 sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 &&
1619 sd->params.pnpID.product == 0x0001);
1621 /* The fatal error checking should be done after
1622 * the camera powers up (developer's guide p 3-38) */
1624 /* Set streamState before transition to high power to avoid bug
1625 * in firmware 1-02 */
1626 ret = do_command(gspca_dev, CPIA_COMMAND_ModifyCameraStatus,
1627 STREAMSTATE, 0, STREAM_NOT_READY, 0);
1628 if (ret)
1629 return ret;
1631 /* GotoHiPower */
1632 ret = goto_high_power(gspca_dev);
1633 if (ret)
1634 return ret;
1636 /* Check the camera status */
1637 ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1638 if (ret)
1639 return ret;
1641 if (sd->params.status.fatalError) {
1642 PDEBUG(D_ERR, "fatal_error: %04x, vp_status: %04x",
1643 sd->params.status.fatalError,
1644 sd->params.status.vpStatus);
1645 return -EIO;
1648 /* VPVersion can't be retrieved before the camera is in HiPower,
1649 * so get it here instead of in get_version_information. */
1650 ret = do_command(gspca_dev, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0);
1651 if (ret)
1652 return ret;
1654 /* Determine video mode settings */
1655 sd->params.streamStartLine = 120;
1657 priv = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1658 if (priv & 0x01) { /* crop */
1659 sd->params.roi.colStart = 2;
1660 sd->params.roi.rowStart = 6;
1661 } else {
1662 sd->params.roi.colStart = 0;
1663 sd->params.roi.rowStart = 0;
1666 if (priv & 0x02) { /* quarter */
1667 sd->params.format.videoSize = VIDEOSIZE_QCIF;
1668 sd->params.roi.colStart /= 2;
1669 sd->params.roi.rowStart /= 2;
1670 sd->params.streamStartLine /= 2;
1671 } else
1672 sd->params.format.videoSize = VIDEOSIZE_CIF;
1674 sd->params.roi.colEnd = sd->params.roi.colStart +
1675 (gspca_dev->width >> 3);
1676 sd->params.roi.rowEnd = sd->params.roi.rowStart +
1677 (gspca_dev->height >> 2);
1679 /* And now set the camera to a known state */
1680 ret = do_command(gspca_dev, CPIA_COMMAND_SetGrabMode,
1681 CPIA_GRAB_CONTINEOUS, 0, 0, 0);
1682 if (ret)
1683 return ret;
1684 /* We start with compression disabled, as we need one uncompressed
1685 frame to handle later compressed frames */
1686 ret = do_command(gspca_dev, CPIA_COMMAND_SetCompression,
1687 CPIA_COMPRESSION_NONE,
1688 NO_DECIMATION, 0, 0);
1689 if (ret)
1690 return ret;
1691 ret = command_setcompressiontarget(gspca_dev);
1692 if (ret)
1693 return ret;
1694 ret = command_setcolourparams(gspca_dev);
1695 if (ret)
1696 return ret;
1697 ret = command_setformat(gspca_dev);
1698 if (ret)
1699 return ret;
1700 ret = command_setyuvtresh(gspca_dev);
1701 if (ret)
1702 return ret;
1703 ret = command_setecptiming(gspca_dev);
1704 if (ret)
1705 return ret;
1706 ret = command_setcompressionparams(gspca_dev);
1707 if (ret)
1708 return ret;
1709 ret = command_setexposure(gspca_dev);
1710 if (ret)
1711 return ret;
1712 ret = command_setcolourbalance(gspca_dev);
1713 if (ret)
1714 return ret;
1715 ret = command_setsensorfps(gspca_dev);
1716 if (ret)
1717 return ret;
1718 ret = command_setapcor(gspca_dev);
1719 if (ret)
1720 return ret;
1721 ret = command_setflickerctrl(gspca_dev);
1722 if (ret)
1723 return ret;
1724 ret = command_setvloffset(gspca_dev);
1725 if (ret)
1726 return ret;
1728 /* Start stream */
1729 ret = command_resume(gspca_dev);
1730 if (ret)
1731 return ret;
1733 /* Wait 6 frames before turning compression on for the sensor to get
1734 all settings and AEC/ACB to settle */
1735 sd->first_frame = 6;
1736 sd->exposure_status = EXPOSURE_NORMAL;
1737 sd->exposure_count = 0;
1738 atomic_set(&sd->cam_exposure, 0);
1739 atomic_set(&sd->fps, 0);
1741 return 0;
1744 static void sd_stopN(struct gspca_dev *gspca_dev)
1746 struct sd *sd = (struct sd *) gspca_dev;
1748 command_pause(gspca_dev);
1750 /* save camera state for later open (developers guide ch 3.5.3) */
1751 save_camera_state(gspca_dev);
1753 /* GotoLoPower */
1754 goto_low_power(gspca_dev);
1756 /* Update the camera status */
1757 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1759 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1760 /* If the last button state is pressed, release it now! */
1761 if (sd->params.qx3.button) {
1762 /* The camera latch will hold the pressed state until we reset
1763 the latch, so we do not reset sd->params.qx3.button now, to
1764 avoid a false keypress being reported the next sd_start */
1765 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1766 input_sync(gspca_dev->input_dev);
1768 #endif
1771 /* this function is called at probe and resume time */
1772 static int sd_init(struct gspca_dev *gspca_dev)
1774 struct sd *sd = (struct sd *) gspca_dev;
1775 int ret;
1777 /* Start / Stop the camera to make sure we are talking to
1778 a supported camera, and to get some information from it
1779 to print. */
1780 ret = sd_start(gspca_dev);
1781 if (ret)
1782 return ret;
1784 /* Ensure the QX3 illuminators' states are restored upon resume,
1785 or disable the illuminator controls, if this isn't a QX3 */
1786 if (sd->params.qx3.qx3_detected)
1787 command_setlights(gspca_dev);
1788 else
1789 gspca_dev->ctrl_dis |=
1790 ((1 << ILLUMINATORS_1_IDX) | (1 << ILLUMINATORS_2_IDX));
1792 sd_stopN(gspca_dev);
1794 PDEBUG(D_PROBE, "CPIA Version: %d.%02d (%d.%d)",
1795 sd->params.version.firmwareVersion,
1796 sd->params.version.firmwareRevision,
1797 sd->params.version.vcVersion,
1798 sd->params.version.vcRevision);
1799 PDEBUG(D_PROBE, "CPIA PnP-ID: %04x:%04x:%04x",
1800 sd->params.pnpID.vendor, sd->params.pnpID.product,
1801 sd->params.pnpID.deviceRevision);
1802 PDEBUG(D_PROBE, "VP-Version: %d.%d %04x",
1803 sd->params.vpVersion.vpVersion,
1804 sd->params.vpVersion.vpRevision,
1805 sd->params.vpVersion.cameraHeadID);
1807 return 0;
1810 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1811 u8 *data,
1812 int len)
1814 struct sd *sd = (struct sd *) gspca_dev;
1816 /* Check for SOF */
1817 if (len >= 64 &&
1818 data[0] == MAGIC_0 && data[1] == MAGIC_1 &&
1819 data[16] == sd->params.format.videoSize &&
1820 data[17] == sd->params.format.subSample &&
1821 data[18] == sd->params.format.yuvOrder &&
1822 data[24] == sd->params.roi.colStart &&
1823 data[25] == sd->params.roi.colEnd &&
1824 data[26] == sd->params.roi.rowStart &&
1825 data[27] == sd->params.roi.rowEnd) {
1826 u8 *image;
1828 atomic_set(&sd->cam_exposure, data[39] * 2);
1829 atomic_set(&sd->fps, data[41]);
1831 /* Check for proper EOF for last frame */
1832 image = gspca_dev->image;
1833 if (image != NULL &&
1834 gspca_dev->image_len > 4 &&
1835 image[gspca_dev->image_len - 4] == 0xff &&
1836 image[gspca_dev->image_len - 3] == 0xff &&
1837 image[gspca_dev->image_len - 2] == 0xff &&
1838 image[gspca_dev->image_len - 1] == 0xff)
1839 gspca_frame_add(gspca_dev, LAST_PACKET,
1840 NULL, 0);
1842 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
1843 return;
1846 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1849 static void sd_dq_callback(struct gspca_dev *gspca_dev)
1851 struct sd *sd = (struct sd *) gspca_dev;
1853 /* Set the normal compression settings once we have captured a
1854 few uncompressed frames (and AEC has hopefully settled) */
1855 if (sd->first_frame) {
1856 sd->first_frame--;
1857 if (sd->first_frame == 0)
1858 command_setcompression(gspca_dev);
1861 /* Switch flicker control back on if it got turned off */
1862 restart_flicker(gspca_dev);
1864 /* If AEC is enabled, monitor the exposure and
1865 adjust the sensor frame rate if needed */
1866 if (sd->params.exposure.expMode == 2)
1867 monitor_exposure(gspca_dev);
1869 /* Update our knowledge of the camera state */
1870 do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
1871 do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
1874 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1876 struct sd *sd = (struct sd *) gspca_dev;
1877 int ret;
1879 sd->params.colourParams.brightness = val;
1880 sd->params.flickerControl.allowableOverExposure =
1881 find_over_exposure(sd->params.colourParams.brightness);
1882 if (gspca_dev->streaming) {
1883 ret = command_setcolourparams(gspca_dev);
1884 if (ret)
1885 return ret;
1886 return command_setflickerctrl(gspca_dev);
1888 return 0;
1891 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1893 struct sd *sd = (struct sd *) gspca_dev;
1895 *val = sd->params.colourParams.brightness;
1896 return 0;
1899 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1901 struct sd *sd = (struct sd *) gspca_dev;
1903 sd->params.colourParams.contrast = val;
1904 if (gspca_dev->streaming)
1905 return command_setcolourparams(gspca_dev);
1907 return 0;
1910 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1912 struct sd *sd = (struct sd *) gspca_dev;
1914 *val = sd->params.colourParams.contrast;
1915 return 0;
1918 static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val)
1920 struct sd *sd = (struct sd *) gspca_dev;
1922 sd->params.colourParams.saturation = val;
1923 if (gspca_dev->streaming)
1924 return command_setcolourparams(gspca_dev);
1926 return 0;
1929 static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val)
1931 struct sd *sd = (struct sd *) gspca_dev;
1933 *val = sd->params.colourParams.saturation;
1934 return 0;
1937 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1939 struct sd *sd = (struct sd *) gspca_dev;
1940 int on;
1942 switch (val) {
1943 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1944 on = 0;
1945 break;
1946 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1947 on = 1;
1948 sd->mainsFreq = 0;
1949 break;
1950 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1951 on = 1;
1952 sd->mainsFreq = 1;
1953 break;
1954 default:
1955 return -EINVAL;
1958 sd->freq = val;
1959 sd->params.flickerControl.coarseJump =
1960 flicker_jumps[sd->mainsFreq]
1961 [sd->params.sensorFps.baserate]
1962 [sd->params.sensorFps.divisor];
1964 return set_flicker(gspca_dev, on, gspca_dev->streaming);
1967 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1969 struct sd *sd = (struct sd *) gspca_dev;
1971 *val = sd->freq;
1972 return 0;
1975 static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val)
1977 struct sd *sd = (struct sd *) gspca_dev;
1979 sd->params.compressionTarget.frTargeting = val;
1980 if (gspca_dev->streaming)
1981 return command_setcompressiontarget(gspca_dev);
1983 return 0;
1986 static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val)
1988 struct sd *sd = (struct sd *) gspca_dev;
1990 *val = sd->params.compressionTarget.frTargeting;
1991 return 0;
1994 static int sd_setilluminator(struct gspca_dev *gspca_dev, __s32 val, int n)
1996 struct sd *sd = (struct sd *) gspca_dev;
1997 int ret;
1999 if (!sd->params.qx3.qx3_detected)
2000 return -EINVAL;
2002 switch (n) {
2003 case 1:
2004 sd->params.qx3.bottomlight = val ? 1 : 0;
2005 break;
2006 case 2:
2007 sd->params.qx3.toplight = val ? 1 : 0;
2008 break;
2009 default:
2010 return -EINVAL;
2013 ret = command_setlights(gspca_dev);
2014 if (ret && ret != -EINVAL)
2015 ret = -EBUSY;
2017 return ret;
2020 static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val)
2022 return sd_setilluminator(gspca_dev, val, 1);
2025 static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val)
2027 return sd_setilluminator(gspca_dev, val, 2);
2030 static int sd_getilluminator(struct gspca_dev *gspca_dev, __s32 *val, int n)
2032 struct sd *sd = (struct sd *) gspca_dev;
2034 if (!sd->params.qx3.qx3_detected)
2035 return -EINVAL;
2037 switch (n) {
2038 case 1:
2039 *val = sd->params.qx3.bottomlight;
2040 break;
2041 case 2:
2042 *val = sd->params.qx3.toplight;
2043 break;
2044 default:
2045 return -EINVAL;
2047 return 0;
2050 static int sd_getilluminator1(struct gspca_dev *gspca_dev, __s32 *val)
2052 return sd_getilluminator(gspca_dev, val, 1);
2055 static int sd_getilluminator2(struct gspca_dev *gspca_dev, __s32 *val)
2057 return sd_getilluminator(gspca_dev, val, 2);
2060 static int sd_querymenu(struct gspca_dev *gspca_dev,
2061 struct v4l2_querymenu *menu)
2063 switch (menu->id) {
2064 case V4L2_CID_POWER_LINE_FREQUENCY:
2065 switch (menu->index) {
2066 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2067 strcpy((char *) menu->name, "NoFliker");
2068 return 0;
2069 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2070 strcpy((char *) menu->name, "50 Hz");
2071 return 0;
2072 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2073 strcpy((char *) menu->name, "60 Hz");
2074 return 0;
2076 break;
2077 case V4L2_CID_COMP_TARGET:
2078 switch (menu->index) {
2079 case CPIA_COMPRESSION_TARGET_QUALITY:
2080 strcpy((char *) menu->name, "Quality");
2081 return 0;
2082 case CPIA_COMPRESSION_TARGET_FRAMERATE:
2083 strcpy((char *) menu->name, "Framerate");
2084 return 0;
2086 break;
2088 return -EINVAL;
2091 /* sub-driver description */
2092 static const struct sd_desc sd_desc = {
2093 .name = MODULE_NAME,
2094 .ctrls = sd_ctrls,
2095 .nctrls = ARRAY_SIZE(sd_ctrls),
2096 .config = sd_config,
2097 .init = sd_init,
2098 .start = sd_start,
2099 .stopN = sd_stopN,
2100 .dq_callback = sd_dq_callback,
2101 .pkt_scan = sd_pkt_scan,
2102 .querymenu = sd_querymenu,
2103 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2104 .other_input = 1,
2105 #endif
2108 /* -- module initialisation -- */
2109 static const struct usb_device_id device_table[] = {
2110 {USB_DEVICE(0x0553, 0x0002)},
2111 {USB_DEVICE(0x0813, 0x0001)},
2114 MODULE_DEVICE_TABLE(usb, device_table);
2116 /* -- device connect -- */
2117 static int sd_probe(struct usb_interface *intf,
2118 const struct usb_device_id *id)
2120 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2121 THIS_MODULE);
2124 static struct usb_driver sd_driver = {
2125 .name = MODULE_NAME,
2126 .id_table = device_table,
2127 .probe = sd_probe,
2128 .disconnect = gspca_disconnect,
2129 #ifdef CONFIG_PM
2130 .suspend = gspca_suspend,
2131 .resume = gspca_resume,
2132 #endif
2135 module_usb_driver(sd_driver);