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