]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/media/video/gspca/cpia1.c
V4L/DVB: gspca_cpia1: Disable illuminator controls if not an Intel Play QX3
[mirror_ubuntu-artful-kernel.git] / drivers / media / video / gspca / cpia1.c
1 /*
2 * cpia CPiA (1) gspca driver
3 *
4 * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com>
5 *
6 * This module is adapted from the in kernel v4l1 cpia driver which is :
7 *
8 * (C) Copyright 1999-2000 Peter Pregler
9 * (C) Copyright 1999-2000 Scott J. Bertin
10 * (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.com>
11 * (C) Copyright 2000 STMicroelectronics
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 */
28
29 #define MODULE_NAME "cpia1"
30
31 #include "gspca.h"
32
33 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
34 MODULE_DESCRIPTION("Vision CPiA");
35 MODULE_LICENSE("GPL");
36
37 /* constant value's */
38 #define MAGIC_0 0x19
39 #define MAGIC_1 0x68
40 #define DATA_IN 0xC0
41 #define DATA_OUT 0x40
42 #define VIDEOSIZE_QCIF 0 /* 176x144 */
43 #define VIDEOSIZE_CIF 1 /* 352x288 */
44 #define SUBSAMPLE_420 0
45 #define SUBSAMPLE_422 1
46 #define YUVORDER_YUYV 0
47 #define YUVORDER_UYVY 1
48 #define NOT_COMPRESSED 0
49 #define COMPRESSED 1
50 #define NO_DECIMATION 0
51 #define DECIMATION_ENAB 1
52 #define EOI 0xff /* End Of Image */
53 #define EOL 0xfd /* End Of Line */
54 #define FRAME_HEADER_SIZE 64
55
56 /* Image grab modes */
57 #define CPIA_GRAB_SINGLE 0
58 #define CPIA_GRAB_CONTINEOUS 1
59
60 /* Compression parameters */
61 #define CPIA_COMPRESSION_NONE 0
62 #define CPIA_COMPRESSION_AUTO 1
63 #define CPIA_COMPRESSION_MANUAL 2
64 #define CPIA_COMPRESSION_TARGET_QUALITY 0
65 #define CPIA_COMPRESSION_TARGET_FRAMERATE 1
66
67 /* Return offsets for GetCameraState */
68 #define SYSTEMSTATE 0
69 #define GRABSTATE 1
70 #define STREAMSTATE 2
71 #define FATALERROR 3
72 #define CMDERROR 4
73 #define DEBUGFLAGS 5
74 #define VPSTATUS 6
75 #define ERRORCODE 7
76
77 /* SystemState */
78 #define UNINITIALISED_STATE 0
79 #define PASS_THROUGH_STATE 1
80 #define LO_POWER_STATE 2
81 #define HI_POWER_STATE 3
82 #define WARM_BOOT_STATE 4
83
84 /* GrabState */
85 #define GRAB_IDLE 0
86 #define GRAB_ACTIVE 1
87 #define GRAB_DONE 2
88
89 /* StreamState */
90 #define STREAM_NOT_READY 0
91 #define STREAM_READY 1
92 #define STREAM_OPEN 2
93 #define STREAM_PAUSED 3
94 #define STREAM_FINISHED 4
95
96 /* Fatal Error, CmdError, and DebugFlags */
97 #define CPIA_FLAG 1
98 #define SYSTEM_FLAG 2
99 #define INT_CTRL_FLAG 4
100 #define PROCESS_FLAG 8
101 #define COM_FLAG 16
102 #define VP_CTRL_FLAG 32
103 #define CAPTURE_FLAG 64
104 #define DEBUG_FLAG 128
105
106 /* VPStatus */
107 #define VP_STATE_OK 0x00
108
109 #define VP_STATE_FAILED_VIDEOINIT 0x01
110 #define VP_STATE_FAILED_AECACBINIT 0x02
111 #define VP_STATE_AEC_MAX 0x04
112 #define VP_STATE_ACB_BMAX 0x08
113
114 #define VP_STATE_ACB_RMIN 0x10
115 #define VP_STATE_ACB_GMIN 0x20
116 #define VP_STATE_ACB_RMAX 0x40
117 #define VP_STATE_ACB_GMAX 0x80
118
119 /* default (minimum) compensation values */
120 #define COMP_RED 220
121 #define COMP_GREEN1 214
122 #define COMP_GREEN2 COMP_GREEN1
123 #define COMP_BLUE 230
124
125 /* exposure status */
126 #define EXPOSURE_VERY_LIGHT 0
127 #define EXPOSURE_LIGHT 1
128 #define EXPOSURE_NORMAL 2
129 #define EXPOSURE_DARK 3
130 #define EXPOSURE_VERY_DARK 4
131
132 #define CPIA_MODULE_CPIA (0 << 5)
133 #define CPIA_MODULE_SYSTEM (1 << 5)
134 #define CPIA_MODULE_VP_CTRL (5 << 5)
135 #define CPIA_MODULE_CAPTURE (6 << 5)
136 #define CPIA_MODULE_DEBUG (7 << 5)
137
138 #define INPUT (DATA_IN << 8)
139 #define OUTPUT (DATA_OUT << 8)
140
141 #define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)
142 #define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)
143 #define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)
144 #define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)
145 #define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)
146 #define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)
147 #define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)
148 #define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)
149
150 #define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)
151 #define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)
152 #define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)
153 #define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)
154 #define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)
155 #define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)
156 #define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)
157 #define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)
158 #define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)
159 #define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)
160 #define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)
161 #define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)
162 #define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
163
164 #define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
165 #define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)
166 #define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
167 #define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
168 #define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
169 #define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)
170 #define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)
171 #define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)
172 #define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)
173 #define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)
174 #define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)
175 #define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)
176 #define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)
177 #define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)
178 #define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)
179 #define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)
180 #define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)
181
182 #define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)
183 #define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)
184 #define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)
185 #define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)
186 #define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)
187 #define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)
188 #define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)
189 #define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)
190 #define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)
191 #define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)
192 #define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
193 #define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
194 #define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
195 #define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
196 #define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)
197
198 #define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
199 #define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
200 #define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)
201 #define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)
202 #define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
203 #define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
204 #define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
205 #define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)
206
207 #define ROUND_UP_EXP_FOR_FLICKER 15
208
209 /* Constants for automatic frame rate adjustment */
210 #define MAX_EXP 302
211 #define MAX_EXP_102 255
212 #define LOW_EXP 140
213 #define VERY_LOW_EXP 70
214 #define TC 94
215 #define EXP_ACC_DARK 50
216 #define EXP_ACC_LIGHT 90
217 #define HIGH_COMP_102 160
218 #define MAX_COMP 239
219 #define DARK_TIME 3
220 #define LIGHT_TIME 3
221
222 #define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \
223 sd->params.version.firmwareRevision == (y))
224
225 /* Developer's Guide Table 5 p 3-34
226 * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
227 static u8 flicker_jumps[2][2][4] =
228 { { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
229 { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
230 };
231
232 struct cam_params {
233 struct {
234 u8 firmwareVersion;
235 u8 firmwareRevision;
236 u8 vcVersion;
237 u8 vcRevision;
238 } version;
239 struct {
240 u16 vendor;
241 u16 product;
242 u16 deviceRevision;
243 } pnpID;
244 struct {
245 u8 vpVersion;
246 u8 vpRevision;
247 u16 cameraHeadID;
248 } vpVersion;
249 struct {
250 u8 systemState;
251 u8 grabState;
252 u8 streamState;
253 u8 fatalError;
254 u8 cmdError;
255 u8 debugFlags;
256 u8 vpStatus;
257 u8 errorCode;
258 } status;
259 struct {
260 u8 brightness;
261 u8 contrast;
262 u8 saturation;
263 } colourParams;
264 struct {
265 u8 gainMode;
266 u8 expMode;
267 u8 compMode;
268 u8 centreWeight;
269 u8 gain;
270 u8 fineExp;
271 u8 coarseExpLo;
272 u8 coarseExpHi;
273 u8 redComp;
274 u8 green1Comp;
275 u8 green2Comp;
276 u8 blueComp;
277 } exposure;
278 struct {
279 u8 balanceMode;
280 u8 redGain;
281 u8 greenGain;
282 u8 blueGain;
283 } colourBalance;
284 struct {
285 u8 divisor;
286 u8 baserate;
287 } sensorFps;
288 struct {
289 u8 gain1;
290 u8 gain2;
291 u8 gain4;
292 u8 gain8;
293 } apcor;
294 struct {
295 u8 disabled;
296 u8 flickerMode;
297 u8 coarseJump;
298 u8 allowableOverExposure;
299 } flickerControl;
300 struct {
301 u8 gain1;
302 u8 gain2;
303 u8 gain4;
304 u8 gain8;
305 } vlOffset;
306 struct {
307 u8 mode;
308 u8 decimation;
309 } compression;
310 struct {
311 u8 frTargeting;
312 u8 targetFR;
313 u8 targetQ;
314 } compressionTarget;
315 struct {
316 u8 yThreshold;
317 u8 uvThreshold;
318 } yuvThreshold;
319 struct {
320 u8 hysteresis;
321 u8 threshMax;
322 u8 smallStep;
323 u8 largeStep;
324 u8 decimationHysteresis;
325 u8 frDiffStepThresh;
326 u8 qDiffStepThresh;
327 u8 decimationThreshMod;
328 } compressionParams;
329 struct {
330 u8 videoSize; /* CIF/QCIF */
331 u8 subSample;
332 u8 yuvOrder;
333 } format;
334 struct { /* Intel QX3 specific data */
335 u8 qx3_detected; /* a QX3 is present */
336 u8 toplight; /* top light lit , R/W */
337 u8 bottomlight; /* bottom light lit, R/W */
338 u8 button; /* snapshot button pressed (R/O) */
339 u8 cradled; /* microscope is in cradle (R/O) */
340 } qx3;
341 struct {
342 u8 colStart; /* skip first 8*colStart pixels */
343 u8 colEnd; /* finish at 8*colEnd pixels */
344 u8 rowStart; /* skip first 4*rowStart lines */
345 u8 rowEnd; /* finish at 4*rowEnd lines */
346 } roi;
347 u8 ecpTiming;
348 u8 streamStartLine;
349 };
350
351 /* specific webcam descriptor */
352 struct sd {
353 struct gspca_dev gspca_dev; /* !! must be the first item */
354 struct cam_params params; /* camera settings */
355
356 atomic_t cam_exposure;
357 atomic_t fps;
358 int exposure_count;
359 u8 exposure_status;
360 u8 mainsFreq; /* 0 = 50hz, 1 = 60hz */
361 u8 first_frame;
362 u8 freq;
363 };
364
365 /* V4L2 controls supported by the driver */
366 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
367 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
368 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
369 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
370 static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val);
371 static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val);
372 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
373 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
374 static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val);
375 static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val);
376 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);
380
381 static const struct ctrl sd_ctrls[] = {
382 {
383 #define BRIGHTNESS_IDX 0
384 {
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,
394 },
395 .set = sd_setbrightness,
396 .get = sd_getbrightness,
397 },
398 #define CONTRAST_IDX 1
399 {
400 {
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,
409 },
410 .set = sd_setcontrast,
411 .get = sd_getcontrast,
412 },
413 #define SATURATION_IDX 2
414 {
415 {
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,
424 },
425 .set = sd_setsaturation,
426 .get = sd_getsaturation,
427 },
428 #define POWER_LINE_FREQUENCY_IDX 3
429 {
430 {
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,
439 },
440 .set = sd_setfreq,
441 .get = sd_getfreq,
442 },
443 #define ILLUMINATORS_1_IDX 4
444 {
445 {
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,
454 },
455 .set = sd_setilluminator1,
456 .get = sd_getilluminator1,
457 },
458 #define ILLUMINATORS_2_IDX 5
459 {
460 {
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,
469 },
470 .set = sd_setilluminator2,
471 .get = sd_getilluminator2,
472 },
473 #define COMP_TARGET_IDX 6
474 {
475 {
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,
485 },
486 .set = sd_setcomptarget,
487 .get = sd_getcomptarget,
488 },
489 };
490
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},
515 };
516
517 /**********************************************************************
518 *
519 * General functions
520 *
521 **********************************************************************/
522
523 static int cpia_usb_transferCmd(struct gspca_dev *gspca_dev, u8 *command)
524 {
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;
530
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;
541 }
542
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);
550
551 if (ret < 0)
552 err("usb_control_msg %02x, error %d", command[1],
553 ret);
554
555 if (ret == -EPIPE && retries > 0) {
556 retries--;
557 goto retry;
558 }
559
560 return (ret < 0) ? ret : 0;
561 }
562
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)
566 {
567 struct sd *sd = (struct sd *) gspca_dev;
568 int ret, datasize;
569 u8 cmd[8];
570
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;
588 }
589
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;
598
599 ret = cpia_usb_transferCmd(gspca_dev, cmd);
600 if (ret)
601 return ret;
602
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;
654
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);
666 }
667
668 /* test whether microscope is cradled */
669 sd->params.qx3.cradled = ((gspca_dev->usb_buf[2] & 0x40) == 0);
670 break;
671 }
672
673 return 0;
674 }
675
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)
681 {
682 u8 cmd[8];
683
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;
700
701 return cpia_usb_transferCmd(gspca_dev, cmd);
702 }
703
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
708 *
709 * Parameters: Brightness - last brightness value set with SetColourParameters
710 *
711 * Returns: OverExposure value to use with SetFlickerCtrl
712 */
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)
717 {
718 int MaxAllowableOverExposure, OverExposure;
719
720 MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness -
721 FLICKER_BRIGHTNESS_CONSTANT;
722
723 if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE)
724 OverExposure = MaxAllowableOverExposure;
725 else
726 OverExposure = FLICKER_ALLOWABLE_OVER_EXPOSURE;
727
728 return OverExposure;
729 }
730 #undef FLICKER_MAX_EXPOSURE
731 #undef FLICKER_ALLOWABLE_OVER_EXPOSURE
732 #undef FLICKER_BRIGHTNESS_CONSTANT
733
734 /* initialise cam_data structure */
735 static void reset_camera_params(struct gspca_dev *gspca_dev)
736 {
737 struct sd *sd = (struct sd *) gspca_dev;
738 struct cam_params *params = &sd->params;
739
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;
768
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 */
788
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;
793
794 params->yuvThreshold.yThreshold = 6; /* From windows driver */
795 params->yuvThreshold.uvThreshold = 6; /* From windows driver */
796
797 params->format.subSample = SUBSAMPLE_420;
798 params->format.yuvOrder = YUVORDER_YUYV;
799
800 params->compression.mode = CPIA_COMPRESSION_AUTO;
801 params->compression.decimation = NO_DECIMATION;
802
803 params->compressionTarget.frTargeting = COMP_TARGET_DEF;
804 params->compressionTarget.targetFR = 15; /* From windows driver */
805 params->compressionTarget.targetQ = 5; /* From windows driver */
806
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;
812 }
813
814 static void printstatus(struct cam_params *params)
815 {
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);
821 }
822
823 static int goto_low_power(struct gspca_dev *gspca_dev)
824 {
825 struct sd *sd = (struct sd *) gspca_dev;
826 int ret;
827
828 ret = do_command(gspca_dev, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0);
829 if (ret)
830 return ret;
831
832 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
833 if (ret)
834 return ret;
835
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);
842 }
843 return -EIO;
844 }
845
846 PDEBUG(D_CONF, "camera now in LOW power state");
847 return 0;
848 }
849
850 static int goto_high_power(struct gspca_dev *gspca_dev)
851 {
852 struct sd *sd = (struct sd *) gspca_dev;
853 int ret;
854
855 ret = do_command(gspca_dev, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0);
856 if (ret)
857 return ret;
858
859 msleep_interruptible(40); /* windows driver does it too */
860
861 if (signal_pending(current))
862 return -EINTR;
863
864 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
865 if (ret)
866 return ret;
867
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;
873 }
874
875 PDEBUG(D_CONF, "camera now in HIGH power state");
876 return 0;
877 }
878
879 static int get_version_information(struct gspca_dev *gspca_dev)
880 {
881 int ret;
882
883 /* GetCPIAVersion */
884 ret = do_command(gspca_dev, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0);
885 if (ret)
886 return ret;
887
888 /* GetPnPID */
889 return do_command(gspca_dev, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0);
890 }
891
892 static int save_camera_state(struct gspca_dev *gspca_dev)
893 {
894 int ret;
895
896 ret = do_command(gspca_dev, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
897 if (ret)
898 return ret;
899
900 return do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
901 }
902
903 static int command_setformat(struct gspca_dev *gspca_dev)
904 {
905 struct sd *sd = (struct sd *) gspca_dev;
906 int ret;
907
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;
914
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);
918 }
919
920 static int command_setcolourparams(struct gspca_dev *gspca_dev)
921 {
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);
927 }
928
929 static int command_setapcor(struct gspca_dev *gspca_dev)
930 {
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);
937 }
938
939 static int command_setvloffset(struct gspca_dev *gspca_dev)
940 {
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);
947 }
948
949 static int command_setexposure(struct gspca_dev *gspca_dev)
950 {
951 struct sd *sd = (struct sd *) gspca_dev;
952 int ret;
953
954 ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
955 sd->params.exposure.gainMode,
956 1,
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;
969
970 if (sd->params.exposure.expMode != 1) {
971 ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
972 0,
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);
980 }
981
982 return ret;
983 }
984
985 static int command_setcolourbalance(struct gspca_dev *gspca_dev)
986 {
987 struct sd *sd = (struct sd *) gspca_dev;
988
989 if (sd->params.colourBalance.balanceMode == 1) {
990 int ret;
991
992 ret = do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
993 1,
994 sd->params.colourBalance.redGain,
995 sd->params.colourBalance.greenGain,
996 sd->params.colourBalance.blueGain);
997 if (ret)
998 return ret;
999
1000 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
1001 3, 0, 0, 0);
1002 }
1003 if (sd->params.colourBalance.balanceMode == 2) {
1004 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
1005 2, 0, 0, 0);
1006 }
1007 if (sd->params.colourBalance.balanceMode == 3) {
1008 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
1009 3, 0, 0, 0);
1010 }
1011
1012 return -EINVAL;
1013 }
1014
1015 static int command_setcompressiontarget(struct gspca_dev *gspca_dev)
1016 {
1017 struct sd *sd = (struct sd *) gspca_dev;
1018
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);
1023 }
1024
1025 static int command_setyuvtresh(struct gspca_dev *gspca_dev)
1026 {
1027 struct sd *sd = (struct sd *) gspca_dev;
1028
1029 return do_command(gspca_dev, CPIA_COMMAND_SetYUVThresh,
1030 sd->params.yuvThreshold.yThreshold,
1031 sd->params.yuvThreshold.uvThreshold, 0, 0);
1032 }
1033
1034 static int command_setcompressionparams(struct gspca_dev *gspca_dev)
1035 {
1036 struct sd *sd = (struct sd *) gspca_dev;
1037
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);
1049 }
1050
1051 static int command_setcompression(struct gspca_dev *gspca_dev)
1052 {
1053 struct sd *sd = (struct sd *) gspca_dev;
1054
1055 return do_command(gspca_dev, CPIA_COMMAND_SetCompression,
1056 sd->params.compression.mode,
1057 sd->params.compression.decimation, 0, 0);
1058 }
1059
1060 static int command_setsensorfps(struct gspca_dev *gspca_dev)
1061 {
1062 struct sd *sd = (struct sd *) gspca_dev;
1063
1064 return do_command(gspca_dev, CPIA_COMMAND_SetSensorFPS,
1065 sd->params.sensorFps.divisor,
1066 sd->params.sensorFps.baserate, 0, 0);
1067 }
1068
1069 static int command_setflickerctrl(struct gspca_dev *gspca_dev)
1070 {
1071 struct sd *sd = (struct sd *) gspca_dev;
1072
1073 return do_command(gspca_dev, CPIA_COMMAND_SetFlickerCtrl,
1074 sd->params.flickerControl.flickerMode,
1075 sd->params.flickerControl.coarseJump,
1076 sd->params.flickerControl.allowableOverExposure,
1077 0);
1078 }
1079
1080 static int command_setecptiming(struct gspca_dev *gspca_dev)
1081 {
1082 struct sd *sd = (struct sd *) gspca_dev;
1083
1084 return do_command(gspca_dev, CPIA_COMMAND_SetECPTiming,
1085 sd->params.ecpTiming, 0, 0, 0);
1086 }
1087
1088 static int command_pause(struct gspca_dev *gspca_dev)
1089 {
1090 return do_command(gspca_dev, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
1091 }
1092
1093 static int command_resume(struct gspca_dev *gspca_dev)
1094 {
1095 struct sd *sd = (struct sd *) gspca_dev;
1096
1097 return do_command(gspca_dev, CPIA_COMMAND_InitStreamCap,
1098 0, sd->params.streamStartLine, 0, 0);
1099 }
1100
1101 static int command_setlights(struct gspca_dev *gspca_dev)
1102 {
1103 struct sd *sd = (struct sd *) gspca_dev;
1104 int ret, p1, p2;
1105
1106 if (!sd->params.qx3.qx3_detected)
1107 return 0;
1108
1109 p1 = (sd->params.qx3.bottomlight == 0) << 1;
1110 p2 = (sd->params.qx3.toplight == 0) << 3;
1111
1112 ret = do_command(gspca_dev, CPIA_COMMAND_WriteVCReg,
1113 0x90, 0x8F, 0x50, 0);
1114 if (ret)
1115 return ret;
1116
1117 return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0,
1118 p1 | p2 | 0xE0, 0);
1119 }
1120
1121 static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply)
1122 {
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
1138
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;
1143
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;
1151 }
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;
1183 }
1184 if (FIRMWARE_VERSION(1, 2))
1185 sd->params.exposure.compMode = 0;
1186 else
1187 sd->params.exposure.compMode = 1;
1188
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;
1210 }
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;
1226 }
1227 sd->params.vlOffset.gain1 = 20;
1228 sd->params.vlOffset.gain2 = 24;
1229 sd->params.vlOffset.gain4 = 26;
1230 sd->params.vlOffset.gain8 = 26;
1231
1232 if (apply) {
1233 ret = command_setexposure(gspca_dev);
1234 if (ret)
1235 return ret;
1236
1237 ret = command_setapcor(gspca_dev);
1238 if (ret)
1239 return ret;
1240
1241 ret = command_setvloffset(gspca_dev);
1242 if (ret)
1243 return ret;
1244
1245 ret = command_setflickerctrl(gspca_dev);
1246 if (ret)
1247 return ret;
1248 }
1249
1250 return 0;
1251 #undef EXP_FROM_COMP
1252 #undef COMPGAIN
1253 }
1254
1255 /* monitor the exposure and adjust the sensor frame rate if needed */
1256 static void monitor_exposure(struct gspca_dev *gspca_dev)
1257 {
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;
1263
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;
1278 }
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];
1283
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;
1293
1294 old_exposure = sd->params.exposure.coarseExpHi * 256 +
1295 sd->params.exposure.coarseExpLo;
1296
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;
1312 }
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;
1320 }
1321 }
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;
1332 }
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;
1340 }
1341 }
1342 } else {
1343 /* not dark or light */
1344 sd->exposure_status = EXPOSURE_NORMAL;
1345 }
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;
1358 }
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;
1366 }
1367 }
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;
1378 }
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;
1386 }
1387 }
1388 } else {
1389 /* not dark or light */
1390 sd->exposure_status = EXPOSURE_NORMAL;
1391 }
1392 }
1393
1394 framerate = atomic_read(&sd->fps);
1395 if (framerate > 30 || framerate < 1)
1396 framerate = 1;
1397
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) {
1404
1405 /* dark for too long */
1406 ++sd->params.sensorFps.divisor;
1407 setfps = 1;
1408
1409 sd->params.flickerControl.coarseJump =
1410 flicker_jumps[sd->mainsFreq]
1411 [sd->params.sensorFps.baserate]
1412 [sd->params.sensorFps.divisor];
1413 setflicker = 1;
1414
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");
1424
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) {
1429
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;
1435
1436 sd->params.flickerControl.coarseJump =
1437 flicker_jumps[sd->mainsFreq]
1438 [sd->params.sensorFps.baserate]
1439 [sd->params.sensorFps.divisor];
1440 setflicker = 1;
1441
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");
1453 }
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) {
1460
1461 /* dark for too long */
1462 ++sd->params.sensorFps.divisor;
1463 setfps = 1;
1464
1465 if (sd->params.exposure.gain > 0) {
1466 --sd->params.exposure.gain;
1467 setexp = 1;
1468 }
1469 sd->exposure_status = EXPOSURE_NORMAL;
1470 PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
1471
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) {
1476
1477 /* light for too long */
1478 --sd->params.sensorFps.divisor;
1479 setfps = 1;
1480
1481 if (sd->params.exposure.gain <
1482 sd->params.exposure.gainMode - 1) {
1483 ++sd->params.exposure.gain;
1484 setexp = 1;
1485 }
1486 sd->exposure_status = EXPOSURE_NORMAL;
1487 PDEBUG(D_CONF, "Automatically increasing sensor_fps");
1488 }
1489 }
1490
1491 if (setexp)
1492 command_setexposure(gspca_dev);
1493
1494 if (setfps)
1495 command_setsensorfps(gspca_dev);
1496
1497 if (setflicker)
1498 command_setflickerctrl(gspca_dev);
1499 }
1500
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.
1505
1506 It also adjust the colour balance when an exposure step is detected - as
1507 long as flicker is running
1508 */
1509 static void restart_flicker(struct gspca_dev *gspca_dev)
1510 {
1511 struct sd *sd = (struct sd *) gspca_dev;
1512 int cam_exposure, old_exp;
1513
1514 if (!FIRMWARE_VERSION(1, 2))
1515 return;
1516
1517 cam_exposure = atomic_read(&sd->cam_exposure);
1518
1519 if (sd->params.flickerControl.flickerMode == 0 ||
1520 cam_exposure == 0)
1521 return;
1522
1523 old_exp = sd->params.exposure.coarseExpLo +
1524 sd->params.exposure.coarseExpHi*256;
1525 /*
1526 see how far away camera exposure is from a valid
1527 flicker exposure value
1528 */
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;
1534 }
1535
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);
1542 }
1543 }
1544
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)
1548 {
1549 struct cam *cam;
1550
1551 reset_camera_params(gspca_dev);
1552
1553 PDEBUG(D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)",
1554 id->idVendor, id->idProduct);
1555
1556 cam = &gspca_dev->cam;
1557 cam->cam_mode = mode;
1558 cam->nmodes = ARRAY_SIZE(mode);
1559
1560 sd_setfreq(gspca_dev, FREQ_DEF);
1561
1562 return 0;
1563 }
1564
1565 /* -- start the camera -- */
1566 static int sd_start(struct gspca_dev *gspca_dev)
1567 {
1568 struct sd *sd = (struct sd *) gspca_dev;
1569 int priv, ret;
1570
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;
1578 }
1579
1580 /* FIXME: this is just dirty trial and error */
1581 ret = goto_high_power(gspca_dev);
1582 if (ret)
1583 return ret;
1584
1585 ret = do_command(gspca_dev, CPIA_COMMAND_DiscardFrame,
1586 0, 0, 0, 0);
1587 if (ret)
1588 return ret;
1589
1590 ret = goto_low_power(gspca_dev);
1591 if (ret)
1592 return ret;
1593 }
1594
1595 /* procedure described in developer's guide p3-28 */
1596
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;
1604 }
1605
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;
1610 }
1611
1612 /* set QX3 detected flag */
1613 sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 &&
1614 sd->params.pnpID.product == 0x0001);
1615
1616 /* The fatal error checking should be done after
1617 * the camera powers up (developer's guide p 3-38) */
1618
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;
1625
1626 /* GotoHiPower */
1627 ret = goto_high_power(gspca_dev);
1628 if (ret)
1629 return ret;
1630
1631 /* Check the camera status */
1632 ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1633 if (ret)
1634 return ret;
1635
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;
1641 }
1642
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;
1648
1649 /* Determine video mode settings */
1650 sd->params.streamStartLine = 120;
1651
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;
1659 }
1660
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;
1668
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);
1673
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;
1722
1723 /* Start stream */
1724 ret = command_resume(gspca_dev);
1725 if (ret)
1726 return ret;
1727
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);
1735
1736 return 0;
1737 }
1738
1739 static void sd_stopN(struct gspca_dev *gspca_dev)
1740 {
1741 command_pause(gspca_dev);
1742
1743 /* save camera state for later open (developers guide ch 3.5.3) */
1744 save_camera_state(gspca_dev);
1745
1746 /* GotoLoPower */
1747 goto_low_power(gspca_dev);
1748
1749 /* Update the camera status */
1750 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1751 }
1752
1753 /* this function is called at probe and resume time */
1754 static int sd_init(struct gspca_dev *gspca_dev)
1755 {
1756 struct sd *sd = (struct sd *) gspca_dev;
1757 int ret;
1758
1759 /* Start / Stop the camera to make sure we are talking to
1760 a supported camera, and to get some information from it
1761 to print. */
1762 ret = sd_start(gspca_dev);
1763 if (ret)
1764 return ret;
1765
1766 /* Ensure the QX3 illuminators' states are restored upon resume,
1767 or disable the illuminator controls, if this isn't a QX3 */
1768 if (sd->params.qx3.qx3_detected)
1769 command_setlights(gspca_dev);
1770 else
1771 gspca_dev->ctrl_dis |=
1772 ((1 << ILLUMINATORS_1_IDX) | (1 << ILLUMINATORS_2_IDX));
1773
1774 sd_stopN(gspca_dev);
1775
1776 PDEBUG(D_PROBE, "CPIA Version: %d.%02d (%d.%d)",
1777 sd->params.version.firmwareVersion,
1778 sd->params.version.firmwareRevision,
1779 sd->params.version.vcVersion,
1780 sd->params.version.vcRevision);
1781 PDEBUG(D_PROBE, "CPIA PnP-ID: %04x:%04x:%04x",
1782 sd->params.pnpID.vendor, sd->params.pnpID.product,
1783 sd->params.pnpID.deviceRevision);
1784 PDEBUG(D_PROBE, "VP-Version: %d.%d %04x",
1785 sd->params.vpVersion.vpVersion,
1786 sd->params.vpVersion.vpRevision,
1787 sd->params.vpVersion.cameraHeadID);
1788
1789 return 0;
1790 }
1791
1792 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1793 u8 *data,
1794 int len)
1795 {
1796 struct sd *sd = (struct sd *) gspca_dev;
1797
1798 /* Check for SOF */
1799 if (len >= 64 &&
1800 data[0] == MAGIC_0 && data[1] == MAGIC_1 &&
1801 data[16] == sd->params.format.videoSize &&
1802 data[17] == sd->params.format.subSample &&
1803 data[18] == sd->params.format.yuvOrder &&
1804 data[24] == sd->params.roi.colStart &&
1805 data[25] == sd->params.roi.colEnd &&
1806 data[26] == sd->params.roi.rowStart &&
1807 data[27] == sd->params.roi.rowEnd) {
1808 u8 *image;
1809
1810 atomic_set(&sd->cam_exposure, data[39] * 2);
1811 atomic_set(&sd->fps, data[41]);
1812
1813 /* Check for proper EOF for last frame */
1814 image = gspca_dev->image;
1815 if (image != NULL &&
1816 gspca_dev->image_len > 4 &&
1817 image[gspca_dev->image_len - 4] == 0xff &&
1818 image[gspca_dev->image_len - 3] == 0xff &&
1819 image[gspca_dev->image_len - 2] == 0xff &&
1820 image[gspca_dev->image_len - 1] == 0xff)
1821 gspca_frame_add(gspca_dev, LAST_PACKET,
1822 NULL, 0);
1823
1824 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
1825 return;
1826 }
1827
1828 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1829 }
1830
1831 static void sd_dq_callback(struct gspca_dev *gspca_dev)
1832 {
1833 struct sd *sd = (struct sd *) gspca_dev;
1834
1835 /* Set the normal compression settings once we have captured a
1836 few uncompressed frames (and AEC has hopefully settled) */
1837 if (sd->first_frame) {
1838 sd->first_frame--;
1839 if (sd->first_frame == 0)
1840 command_setcompression(gspca_dev);
1841 }
1842
1843 /* Switch flicker control back on if it got turned off */
1844 restart_flicker(gspca_dev);
1845
1846 /* If AEC is enabled, monitor the exposure and
1847 adjust the sensor frame rate if needed */
1848 if (sd->params.exposure.expMode == 2)
1849 monitor_exposure(gspca_dev);
1850
1851 /* Update our knowledge of the camera state */
1852 do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
1853 if (sd->params.qx3.qx3_detected)
1854 do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
1855 }
1856
1857 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1858 {
1859 struct sd *sd = (struct sd *) gspca_dev;
1860 int ret;
1861
1862 sd->params.colourParams.brightness = val;
1863 sd->params.flickerControl.allowableOverExposure =
1864 find_over_exposure(sd->params.colourParams.brightness);
1865 if (gspca_dev->streaming) {
1866 ret = command_setcolourparams(gspca_dev);
1867 if (ret)
1868 return ret;
1869 return command_setflickerctrl(gspca_dev);
1870 }
1871 return 0;
1872 }
1873
1874 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1875 {
1876 struct sd *sd = (struct sd *) gspca_dev;
1877
1878 *val = sd->params.colourParams.brightness;
1879 return 0;
1880 }
1881
1882 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1883 {
1884 struct sd *sd = (struct sd *) gspca_dev;
1885
1886 sd->params.colourParams.contrast = val;
1887 if (gspca_dev->streaming)
1888 return command_setcolourparams(gspca_dev);
1889
1890 return 0;
1891 }
1892
1893 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1894 {
1895 struct sd *sd = (struct sd *) gspca_dev;
1896
1897 *val = sd->params.colourParams.contrast;
1898 return 0;
1899 }
1900
1901 static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val)
1902 {
1903 struct sd *sd = (struct sd *) gspca_dev;
1904
1905 sd->params.colourParams.saturation = val;
1906 if (gspca_dev->streaming)
1907 return command_setcolourparams(gspca_dev);
1908
1909 return 0;
1910 }
1911
1912 static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val)
1913 {
1914 struct sd *sd = (struct sd *) gspca_dev;
1915
1916 *val = sd->params.colourParams.saturation;
1917 return 0;
1918 }
1919
1920 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1921 {
1922 struct sd *sd = (struct sd *) gspca_dev;
1923 int on;
1924
1925 switch (val) {
1926 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1927 on = 0;
1928 break;
1929 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1930 on = 1;
1931 sd->mainsFreq = 0;
1932 break;
1933 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1934 on = 1;
1935 sd->mainsFreq = 1;
1936 break;
1937 default:
1938 return -EINVAL;
1939 }
1940
1941 sd->freq = val;
1942 sd->params.flickerControl.coarseJump =
1943 flicker_jumps[sd->mainsFreq]
1944 [sd->params.sensorFps.baserate]
1945 [sd->params.sensorFps.divisor];
1946
1947 return set_flicker(gspca_dev, on, gspca_dev->streaming);
1948 }
1949
1950 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1951 {
1952 struct sd *sd = (struct sd *) gspca_dev;
1953
1954 *val = sd->freq;
1955 return 0;
1956 }
1957
1958 static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val)
1959 {
1960 struct sd *sd = (struct sd *) gspca_dev;
1961
1962 sd->params.compressionTarget.frTargeting = val;
1963 if (gspca_dev->streaming)
1964 return command_setcompressiontarget(gspca_dev);
1965
1966 return 0;
1967 }
1968
1969 static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val)
1970 {
1971 struct sd *sd = (struct sd *) gspca_dev;
1972
1973 *val = sd->params.compressionTarget.frTargeting;
1974 return 0;
1975 }
1976
1977 static int sd_setilluminator(struct gspca_dev *gspca_dev, __s32 val, int n)
1978 {
1979 struct sd *sd = (struct sd *) gspca_dev;
1980 int ret;
1981
1982 if (!sd->params.qx3.qx3_detected)
1983 return -EINVAL;
1984
1985 switch (n) {
1986 case 1:
1987 sd->params.qx3.bottomlight = val ? 1 : 0;
1988 break;
1989 case 2:
1990 sd->params.qx3.toplight = val ? 1 : 0;
1991 break;
1992 default:
1993 return -EINVAL;
1994 }
1995
1996 ret = command_setlights(gspca_dev);
1997 if (ret && ret != -EINVAL)
1998 ret = -EBUSY;
1999
2000 return ret;
2001 }
2002
2003 static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val)
2004 {
2005 return sd_setilluminator(gspca_dev, val, 1);
2006 }
2007
2008 static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val)
2009 {
2010 return sd_setilluminator(gspca_dev, val, 2);
2011 }
2012
2013 static int sd_getilluminator(struct gspca_dev *gspca_dev, __s32 *val, int n)
2014 {
2015 struct sd *sd = (struct sd *) gspca_dev;
2016
2017 if (!sd->params.qx3.qx3_detected)
2018 return -EINVAL;
2019
2020 switch (n) {
2021 case 1:
2022 *val = sd->params.qx3.bottomlight;
2023 break;
2024 case 2:
2025 *val = sd->params.qx3.toplight;
2026 break;
2027 default:
2028 return -EINVAL;
2029 }
2030 return 0;
2031 }
2032
2033 static int sd_getilluminator1(struct gspca_dev *gspca_dev, __s32 *val)
2034 {
2035 return sd_getilluminator(gspca_dev, val, 1);
2036 }
2037
2038 static int sd_getilluminator2(struct gspca_dev *gspca_dev, __s32 *val)
2039 {
2040 return sd_getilluminator(gspca_dev, val, 2);
2041 }
2042
2043 static int sd_querymenu(struct gspca_dev *gspca_dev,
2044 struct v4l2_querymenu *menu)
2045 {
2046 switch (menu->id) {
2047 case V4L2_CID_POWER_LINE_FREQUENCY:
2048 switch (menu->index) {
2049 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2050 strcpy((char *) menu->name, "NoFliker");
2051 return 0;
2052 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2053 strcpy((char *) menu->name, "50 Hz");
2054 return 0;
2055 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2056 strcpy((char *) menu->name, "60 Hz");
2057 return 0;
2058 }
2059 break;
2060 case V4L2_CID_COMP_TARGET:
2061 switch (menu->index) {
2062 case CPIA_COMPRESSION_TARGET_QUALITY:
2063 strcpy((char *) menu->name, "Quality");
2064 return 0;
2065 case CPIA_COMPRESSION_TARGET_FRAMERATE:
2066 strcpy((char *) menu->name, "Framerate");
2067 return 0;
2068 }
2069 break;
2070 }
2071 return -EINVAL;
2072 }
2073
2074 /* sub-driver description */
2075 static const struct sd_desc sd_desc = {
2076 .name = MODULE_NAME,
2077 .ctrls = sd_ctrls,
2078 .nctrls = ARRAY_SIZE(sd_ctrls),
2079 .config = sd_config,
2080 .init = sd_init,
2081 .start = sd_start,
2082 .stopN = sd_stopN,
2083 .dq_callback = sd_dq_callback,
2084 .pkt_scan = sd_pkt_scan,
2085 .querymenu = sd_querymenu,
2086 };
2087
2088 /* -- module initialisation -- */
2089 static const __devinitdata struct usb_device_id device_table[] = {
2090 {USB_DEVICE(0x0553, 0x0002)},
2091 {USB_DEVICE(0x0813, 0x0001)},
2092 {}
2093 };
2094 MODULE_DEVICE_TABLE(usb, device_table);
2095
2096 /* -- device connect -- */
2097 static int sd_probe(struct usb_interface *intf,
2098 const struct usb_device_id *id)
2099 {
2100 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2101 THIS_MODULE);
2102 }
2103
2104 static struct usb_driver sd_driver = {
2105 .name = MODULE_NAME,
2106 .id_table = device_table,
2107 .probe = sd_probe,
2108 .disconnect = gspca_disconnect,
2109 #ifdef CONFIG_PM
2110 .suspend = gspca_suspend,
2111 .resume = gspca_resume,
2112 #endif
2113 };
2114
2115 /* -- module insert / remove -- */
2116 static int __init sd_mod_init(void)
2117 {
2118 return usb_register(&sd_driver);
2119 }
2120 static void __exit sd_mod_exit(void)
2121 {
2122 usb_deregister(&sd_driver);
2123 }
2124
2125 module_init(sd_mod_init);
2126 module_exit(sd_mod_exit);