2 * cpia CPiA (1) gspca driver
4 * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com>
6 * This module is adapted from the in kernel v4l1 cpia driver which is :
8 * (C) Copyright 1999-2000 Peter Pregler
9 * (C) Copyright 1999-2000 Scott J. Bertin
10 * (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.com>
11 * (C) Copyright 2000 STMicroelectronics
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #define MODULE_NAME "cpia1"
33 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
34 MODULE_DESCRIPTION("Vision CPiA");
35 MODULE_LICENSE("GPL");
37 /* constant value's */
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
50 #define NO_DECIMATION 0
51 #define DECIMATION_ENAB 1
52 #define EOI 0xff /* End Of Image */
53 #define EOL 0xfd /* End Of Line */
54 #define FRAME_HEADER_SIZE 64
56 /* Image grab modes */
57 #define CPIA_GRAB_SINGLE 0
58 #define CPIA_GRAB_CONTINEOUS 1
60 /* Compression parameters */
61 #define CPIA_COMPRESSION_NONE 0
62 #define CPIA_COMPRESSION_AUTO 1
63 #define CPIA_COMPRESSION_MANUAL 2
64 #define CPIA_COMPRESSION_TARGET_QUALITY 0
65 #define CPIA_COMPRESSION_TARGET_FRAMERATE 1
67 /* Return offsets for GetCameraState */
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
90 #define STREAM_NOT_READY 0
91 #define STREAM_READY 1
93 #define STREAM_PAUSED 3
94 #define STREAM_FINISHED 4
96 /* Fatal Error, CmdError, and DebugFlags */
99 #define INT_CTRL_FLAG 4
100 #define PROCESS_FLAG 8
102 #define VP_CTRL_FLAG 32
103 #define CAPTURE_FLAG 64
104 #define DEBUG_FLAG 128
107 #define VP_STATE_OK 0x00
109 #define VP_STATE_FAILED_VIDEOINIT 0x01
110 #define VP_STATE_FAILED_AECACBINIT 0x02
111 #define VP_STATE_AEC_MAX 0x04
112 #define VP_STATE_ACB_BMAX 0x08
114 #define VP_STATE_ACB_RMIN 0x10
115 #define VP_STATE_ACB_GMIN 0x20
116 #define VP_STATE_ACB_RMAX 0x40
117 #define VP_STATE_ACB_GMAX 0x80
119 /* default (minimum) compensation values */
121 #define COMP_GREEN1 214
122 #define COMP_GREEN2 COMP_GREEN1
123 #define COMP_BLUE 230
125 /* exposure status */
126 #define EXPOSURE_VERY_LIGHT 0
127 #define EXPOSURE_LIGHT 1
128 #define EXPOSURE_NORMAL 2
129 #define EXPOSURE_DARK 3
130 #define EXPOSURE_VERY_DARK 4
132 #define CPIA_MODULE_CPIA (0 << 5)
133 #define CPIA_MODULE_SYSTEM (1 << 5)
134 #define CPIA_MODULE_VP_CTRL (5 << 5)
135 #define CPIA_MODULE_CAPTURE (6 << 5)
136 #define CPIA_MODULE_DEBUG (7 << 5)
138 #define INPUT (DATA_IN << 8)
139 #define OUTPUT (DATA_OUT << 8)
141 #define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)
142 #define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)
143 #define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)
144 #define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)
145 #define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)
146 #define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)
147 #define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)
148 #define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)
150 #define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)
151 #define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)
152 #define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)
153 #define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)
154 #define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)
155 #define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)
156 #define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)
157 #define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)
158 #define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)
159 #define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)
160 #define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)
161 #define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)
162 #define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
164 #define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
165 #define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)
166 #define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
167 #define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
168 #define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
169 #define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)
170 #define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)
171 #define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)
172 #define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)
173 #define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)
174 #define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)
175 #define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)
176 #define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)
177 #define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)
178 #define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)
179 #define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)
180 #define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)
182 #define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)
183 #define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)
184 #define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)
185 #define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)
186 #define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)
187 #define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)
188 #define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)
189 #define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)
190 #define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)
191 #define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)
192 #define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
193 #define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
194 #define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
195 #define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
196 #define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)
198 #define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
199 #define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
200 #define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)
201 #define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)
202 #define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
203 #define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
204 #define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
205 #define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)
207 #define ROUND_UP_EXP_FOR_FLICKER 15
209 /* Constants for automatic frame rate adjustment */
211 #define MAX_EXP_102 255
213 #define VERY_LOW_EXP 70
215 #define EXP_ACC_DARK 50
216 #define EXP_ACC_LIGHT 90
217 #define HIGH_COMP_102 160
222 #define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \
223 sd->params.version.firmwareRevision == (y))
225 /* Developer's Guide Table 5 p 3-34
226 * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
227 static u8 flicker_jumps[2][2][4] =
228 { { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
229 { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
298 u8 allowableOverExposure;
324 u8 decimationHysteresis;
327 u8 decimationThreshMod;
330 u8 videoSize; /* CIF/QCIF */
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) */
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 */
351 /* specific webcam descriptor */
353 struct gspca_dev gspca_dev; /* !! must be the first item */
354 struct cam_params params; /* camera settings */
356 atomic_t cam_exposure;
360 u8 mainsFreq; /* 0 = 50hz, 1 = 60hz */
365 /* V4L2 controls supported by the driver */
366 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
367 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
368 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
369 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
370 static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val);
371 static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val);
372 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
373 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
374 static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val);
375 static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val);
376 static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val);
377 static int sd_getilluminator1(struct gspca_dev *gspca_dev, __s32 *val);
378 static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val);
379 static int sd_getilluminator2(struct gspca_dev *gspca_dev, __s32 *val);
381 static const struct ctrl sd_ctrls[] = {
384 .id = V4L2_CID_BRIGHTNESS,
385 .type = V4L2_CTRL_TYPE_INTEGER,
386 .name = "Brightness",
390 #define BRIGHTNESS_DEF 50
391 .default_value = BRIGHTNESS_DEF,
394 .set = sd_setbrightness,
395 .get = sd_getbrightness,
399 .id = V4L2_CID_CONTRAST,
400 .type = V4L2_CTRL_TYPE_INTEGER,
405 #define CONTRAST_DEF 48
406 .default_value = CONTRAST_DEF,
408 .set = sd_setcontrast,
409 .get = sd_getcontrast,
413 .id = V4L2_CID_SATURATION,
414 .type = V4L2_CTRL_TYPE_INTEGER,
415 .name = "Saturation",
419 #define SATURATION_DEF 50
420 .default_value = SATURATION_DEF,
422 .set = sd_setsaturation,
423 .get = sd_getsaturation,
427 .id = V4L2_CID_POWER_LINE_FREQUENCY,
428 .type = V4L2_CTRL_TYPE_MENU,
429 .name = "Light frequency filter",
431 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
434 .default_value = FREQ_DEF,
441 .id = V4L2_CID_ILLUMINATORS_1,
442 .type = V4L2_CTRL_TYPE_BOOLEAN,
443 .name = "Illuminator 1",
447 #define ILLUMINATORS_1_DEF 0
448 .default_value = ILLUMINATORS_1_DEF,
450 .set = sd_setilluminator1,
451 .get = sd_getilluminator1,
455 .id = V4L2_CID_ILLUMINATORS_2,
456 .type = V4L2_CTRL_TYPE_BOOLEAN,
457 .name = "Illuminator 2",
461 #define ILLUMINATORS_2_DEF 0
462 .default_value = ILLUMINATORS_2_DEF,
464 .set = sd_setilluminator2,
465 .get = sd_getilluminator2,
469 #define V4L2_CID_COMP_TARGET V4L2_CID_PRIVATE_BASE
470 .id = V4L2_CID_COMP_TARGET,
471 .type = V4L2_CTRL_TYPE_MENU,
472 .name = "Compression Target",
476 #define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY
477 .default_value = COMP_TARGET_DEF,
479 .set = sd_setcomptarget,
480 .get = sd_getcomptarget,
484 static const struct v4l2_pix_format mode[] = {
485 {160, 120, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
486 /* The sizeimage is trial and error, as with low framerates
487 the camera will pad out usb frames, making the image
488 data larger then strictly necessary */
491 .colorspace = V4L2_COLORSPACE_SRGB,
493 {176, 144, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
496 .colorspace = V4L2_COLORSPACE_SRGB,
498 {320, 240, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
501 .colorspace = V4L2_COLORSPACE_SRGB,
503 {352, 288, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
506 .colorspace = V4L2_COLORSPACE_SRGB,
510 /**********************************************************************
514 **********************************************************************/
516 static int cpia_usb_transferCmd(struct gspca_dev *gspca_dev, u8 *command)
520 int ret, databytes = command[6] | (command[7] << 8);
521 /* Sometimes we see spurious EPIPE errors */
524 if (command[0] == DATA_IN) {
525 pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
526 requesttype = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
527 } else if (command[0] == DATA_OUT) {
528 pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
529 requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE;
531 PDEBUG(D_ERR, "Unexpected first byte of command: %x",
537 ret = usb_control_msg(gspca_dev->dev, pipe,
540 command[2] | (command[3] << 8),
541 command[4] | (command[5] << 8),
542 gspca_dev->usb_buf, databytes, 1000);
545 err("usb_control_msg %02x, error %d", command[1],
548 if (ret == -EPIPE && retries > 0) {
553 return (ret < 0) ? ret : 0;
556 /* send an arbitrary command to the camera */
557 static int do_command(struct gspca_dev *gspca_dev, u16 command,
558 u8 a, u8 b, u8 c, u8 d)
560 struct sd *sd = (struct sd *) gspca_dev;
565 case CPIA_COMMAND_GetCPIAVersion:
566 case CPIA_COMMAND_GetPnPID:
567 case CPIA_COMMAND_GetCameraStatus:
568 case CPIA_COMMAND_GetVPVersion:
569 case CPIA_COMMAND_GetColourParams:
570 case CPIA_COMMAND_GetColourBalance:
571 case CPIA_COMMAND_GetExposure:
574 case CPIA_COMMAND_ReadMCPorts:
575 case CPIA_COMMAND_ReadVCRegs:
583 cmd[0] = command >> 8;
584 cmd[1] = command & 0xff;
592 ret = cpia_usb_transferCmd(gspca_dev, cmd);
597 case CPIA_COMMAND_GetCPIAVersion:
598 sd->params.version.firmwareVersion = gspca_dev->usb_buf[0];
599 sd->params.version.firmwareRevision = gspca_dev->usb_buf[1];
600 sd->params.version.vcVersion = gspca_dev->usb_buf[2];
601 sd->params.version.vcRevision = gspca_dev->usb_buf[3];
603 case CPIA_COMMAND_GetPnPID:
604 sd->params.pnpID.vendor =
605 gspca_dev->usb_buf[0] | (gspca_dev->usb_buf[1] << 8);
606 sd->params.pnpID.product =
607 gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
608 sd->params.pnpID.deviceRevision =
609 gspca_dev->usb_buf[4] | (gspca_dev->usb_buf[5] << 8);
611 case CPIA_COMMAND_GetCameraStatus:
612 sd->params.status.systemState = gspca_dev->usb_buf[0];
613 sd->params.status.grabState = gspca_dev->usb_buf[1];
614 sd->params.status.streamState = gspca_dev->usb_buf[2];
615 sd->params.status.fatalError = gspca_dev->usb_buf[3];
616 sd->params.status.cmdError = gspca_dev->usb_buf[4];
617 sd->params.status.debugFlags = gspca_dev->usb_buf[5];
618 sd->params.status.vpStatus = gspca_dev->usb_buf[6];
619 sd->params.status.errorCode = gspca_dev->usb_buf[7];
621 case CPIA_COMMAND_GetVPVersion:
622 sd->params.vpVersion.vpVersion = gspca_dev->usb_buf[0];
623 sd->params.vpVersion.vpRevision = gspca_dev->usb_buf[1];
624 sd->params.vpVersion.cameraHeadID =
625 gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
627 case CPIA_COMMAND_GetColourParams:
628 sd->params.colourParams.brightness = gspca_dev->usb_buf[0];
629 sd->params.colourParams.contrast = gspca_dev->usb_buf[1];
630 sd->params.colourParams.saturation = gspca_dev->usb_buf[2];
632 case CPIA_COMMAND_GetColourBalance:
633 sd->params.colourBalance.redGain = gspca_dev->usb_buf[0];
634 sd->params.colourBalance.greenGain = gspca_dev->usb_buf[1];
635 sd->params.colourBalance.blueGain = gspca_dev->usb_buf[2];
637 case CPIA_COMMAND_GetExposure:
638 sd->params.exposure.gain = gspca_dev->usb_buf[0];
639 sd->params.exposure.fineExp = gspca_dev->usb_buf[1];
640 sd->params.exposure.coarseExpLo = gspca_dev->usb_buf[2];
641 sd->params.exposure.coarseExpHi = gspca_dev->usb_buf[3];
642 sd->params.exposure.redComp = gspca_dev->usb_buf[4];
643 sd->params.exposure.green1Comp = gspca_dev->usb_buf[5];
644 sd->params.exposure.green2Comp = gspca_dev->usb_buf[6];
645 sd->params.exposure.blueComp = gspca_dev->usb_buf[7];
648 case CPIA_COMMAND_ReadMCPorts:
649 if (!sd->params.qx3.qx3_detected)
651 /* test button press */
652 sd->params.qx3.button = ((gspca_dev->usb_buf[1] & 0x02) == 0);
653 if (sd->params.qx3.button) {
654 /* button pressed - unlock the latch */
655 do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
657 do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
661 /* test whether microscope is cradled */
662 sd->params.qx3.cradled = ((gspca_dev->usb_buf[2] & 0x40) == 0);
669 /* send a command to the camera with an additional data transaction */
670 static int do_command_extended(struct gspca_dev *gspca_dev, u16 command,
671 u8 a, u8 b, u8 c, u8 d,
672 u8 e, u8 f, u8 g, u8 h,
673 u8 i, u8 j, u8 k, u8 l)
677 cmd[0] = command >> 8;
678 cmd[1] = command & 0xff;
685 gspca_dev->usb_buf[0] = e;
686 gspca_dev->usb_buf[1] = f;
687 gspca_dev->usb_buf[2] = g;
688 gspca_dev->usb_buf[3] = h;
689 gspca_dev->usb_buf[4] = i;
690 gspca_dev->usb_buf[5] = j;
691 gspca_dev->usb_buf[6] = k;
692 gspca_dev->usb_buf[7] = l;
694 return cpia_usb_transferCmd(gspca_dev, cmd);
697 /* find_over_exposure
698 * Finds a suitable value of OverExposure for use with SetFlickerCtrl
699 * Some calculation is required because this value changes with the brightness
700 * set with SetColourParameters
702 * Parameters: Brightness - last brightness value set with SetColourParameters
704 * Returns: OverExposure value to use with SetFlickerCtrl
706 #define FLICKER_MAX_EXPOSURE 250
707 #define FLICKER_ALLOWABLE_OVER_EXPOSURE 146
708 #define FLICKER_BRIGHTNESS_CONSTANT 59
709 static int find_over_exposure(int brightness)
711 int MaxAllowableOverExposure, OverExposure;
713 MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness -
714 FLICKER_BRIGHTNESS_CONSTANT;
716 if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE)
717 OverExposure = MaxAllowableOverExposure;
719 OverExposure = FLICKER_ALLOWABLE_OVER_EXPOSURE;
723 #undef FLICKER_MAX_EXPOSURE
724 #undef FLICKER_ALLOWABLE_OVER_EXPOSURE
725 #undef FLICKER_BRIGHTNESS_CONSTANT
727 /* initialise cam_data structure */
728 static void reset_camera_params(struct gspca_dev *gspca_dev)
730 struct sd *sd = (struct sd *) gspca_dev;
731 struct cam_params *params = &sd->params;
733 /* The following parameter values are the defaults from
734 * "Software Developer's Guide for CPiA Cameras". Any changes
735 * to the defaults are noted in comments. */
736 params->colourParams.brightness = BRIGHTNESS_DEF;
737 params->colourParams.contrast = CONTRAST_DEF;
738 params->colourParams.saturation = SATURATION_DEF;
739 params->exposure.gainMode = 4;
740 params->exposure.expMode = 2; /* AEC */
741 params->exposure.compMode = 1;
742 params->exposure.centreWeight = 1;
743 params->exposure.gain = 0;
744 params->exposure.fineExp = 0;
745 params->exposure.coarseExpLo = 185;
746 params->exposure.coarseExpHi = 0;
747 params->exposure.redComp = COMP_RED;
748 params->exposure.green1Comp = COMP_GREEN1;
749 params->exposure.green2Comp = COMP_GREEN2;
750 params->exposure.blueComp = COMP_BLUE;
751 params->colourBalance.balanceMode = 2; /* ACB */
752 params->colourBalance.redGain = 32;
753 params->colourBalance.greenGain = 6;
754 params->colourBalance.blueGain = 92;
755 params->apcor.gain1 = 0x18;
756 params->apcor.gain2 = 0x16;
757 params->apcor.gain4 = 0x24;
758 params->apcor.gain8 = 0x34;
759 params->flickerControl.flickerMode = 0;
760 params->flickerControl.disabled = 1;
762 params->flickerControl.coarseJump =
763 flicker_jumps[sd->mainsFreq]
764 [params->sensorFps.baserate]
765 [params->sensorFps.divisor];
766 params->flickerControl.allowableOverExposure =
767 find_over_exposure(params->colourParams.brightness);
768 params->vlOffset.gain1 = 20;
769 params->vlOffset.gain2 = 24;
770 params->vlOffset.gain4 = 26;
771 params->vlOffset.gain8 = 26;
772 params->compressionParams.hysteresis = 3;
773 params->compressionParams.threshMax = 11;
774 params->compressionParams.smallStep = 1;
775 params->compressionParams.largeStep = 3;
776 params->compressionParams.decimationHysteresis = 2;
777 params->compressionParams.frDiffStepThresh = 5;
778 params->compressionParams.qDiffStepThresh = 3;
779 params->compressionParams.decimationThreshMod = 2;
780 /* End of default values from Software Developer's Guide */
782 /* Set Sensor FPS to 15fps. This seems better than 30fps
783 * for indoor lighting. */
784 params->sensorFps.divisor = 1;
785 params->sensorFps.baserate = 1;
787 params->yuvThreshold.yThreshold = 6; /* From windows driver */
788 params->yuvThreshold.uvThreshold = 6; /* From windows driver */
790 params->format.subSample = SUBSAMPLE_420;
791 params->format.yuvOrder = YUVORDER_YUYV;
793 params->compression.mode = CPIA_COMPRESSION_AUTO;
794 params->compression.decimation = NO_DECIMATION;
796 params->compressionTarget.frTargeting = COMP_TARGET_DEF;
797 params->compressionTarget.targetFR = 15; /* From windows driver */
798 params->compressionTarget.targetQ = 5; /* From windows driver */
800 params->qx3.qx3_detected = 0;
801 params->qx3.toplight = 0;
802 params->qx3.bottomlight = 0;
803 params->qx3.button = 0;
804 params->qx3.cradled = 0;
807 static void printstatus(struct cam_params *params)
809 PDEBUG(D_PROBE, "status: %02x %02x %02x %02x %02x %02x %02x %02x",
810 params->status.systemState, params->status.grabState,
811 params->status.streamState, params->status.fatalError,
812 params->status.cmdError, params->status.debugFlags,
813 params->status.vpStatus, params->status.errorCode);
816 static int goto_low_power(struct gspca_dev *gspca_dev)
818 struct sd *sd = (struct sd *) gspca_dev;
821 ret = do_command(gspca_dev, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0);
825 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
829 if (sd->params.status.systemState != LO_POWER_STATE) {
830 if (sd->params.status.systemState != WARM_BOOT_STATE) {
832 "unexpected state after lo power cmd: %02x",
833 sd->params.status.systemState);
834 printstatus(&sd->params);
839 PDEBUG(D_CONF, "camera now in LOW power state");
843 static int goto_high_power(struct gspca_dev *gspca_dev)
845 struct sd *sd = (struct sd *) gspca_dev;
848 ret = do_command(gspca_dev, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0);
852 msleep_interruptible(40); /* windows driver does it too */
854 if (signal_pending(current))
857 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
861 if (sd->params.status.systemState != HI_POWER_STATE) {
862 PDEBUG(D_ERR, "unexpected state after hi power cmd: %02x",
863 sd->params.status.systemState);
864 printstatus(&sd->params);
868 PDEBUG(D_CONF, "camera now in HIGH power state");
872 static int get_version_information(struct gspca_dev *gspca_dev)
877 ret = do_command(gspca_dev, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0);
882 return do_command(gspca_dev, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0);
885 static int save_camera_state(struct gspca_dev *gspca_dev)
889 ret = do_command(gspca_dev, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
893 return do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
896 static int command_setformat(struct gspca_dev *gspca_dev)
898 struct sd *sd = (struct sd *) gspca_dev;
901 ret = do_command(gspca_dev, CPIA_COMMAND_SetFormat,
902 sd->params.format.videoSize,
903 sd->params.format.subSample,
904 sd->params.format.yuvOrder, 0);
908 return do_command(gspca_dev, CPIA_COMMAND_SetROI,
909 sd->params.roi.colStart, sd->params.roi.colEnd,
910 sd->params.roi.rowStart, sd->params.roi.rowEnd);
913 static int command_setcolourparams(struct gspca_dev *gspca_dev)
915 struct sd *sd = (struct sd *) gspca_dev;
916 return do_command(gspca_dev, CPIA_COMMAND_SetColourParams,
917 sd->params.colourParams.brightness,
918 sd->params.colourParams.contrast,
919 sd->params.colourParams.saturation, 0);
922 static int command_setapcor(struct gspca_dev *gspca_dev)
924 struct sd *sd = (struct sd *) gspca_dev;
925 return do_command(gspca_dev, CPIA_COMMAND_SetApcor,
926 sd->params.apcor.gain1,
927 sd->params.apcor.gain2,
928 sd->params.apcor.gain4,
929 sd->params.apcor.gain8);
932 static int command_setvloffset(struct gspca_dev *gspca_dev)
934 struct sd *sd = (struct sd *) gspca_dev;
935 return do_command(gspca_dev, CPIA_COMMAND_SetVLOffset,
936 sd->params.vlOffset.gain1,
937 sd->params.vlOffset.gain2,
938 sd->params.vlOffset.gain4,
939 sd->params.vlOffset.gain8);
942 static int command_setexposure(struct gspca_dev *gspca_dev)
944 struct sd *sd = (struct sd *) gspca_dev;
947 ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
948 sd->params.exposure.gainMode,
950 sd->params.exposure.compMode,
951 sd->params.exposure.centreWeight,
952 sd->params.exposure.gain,
953 sd->params.exposure.fineExp,
954 sd->params.exposure.coarseExpLo,
955 sd->params.exposure.coarseExpHi,
956 sd->params.exposure.redComp,
957 sd->params.exposure.green1Comp,
958 sd->params.exposure.green2Comp,
959 sd->params.exposure.blueComp);
963 if (sd->params.exposure.expMode != 1) {
964 ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
966 sd->params.exposure.expMode,
968 sd->params.exposure.gain,
969 sd->params.exposure.fineExp,
970 sd->params.exposure.coarseExpLo,
971 sd->params.exposure.coarseExpHi,
978 static int command_setcolourbalance(struct gspca_dev *gspca_dev)
980 struct sd *sd = (struct sd *) gspca_dev;
982 if (sd->params.colourBalance.balanceMode == 1) {
985 ret = do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
987 sd->params.colourBalance.redGain,
988 sd->params.colourBalance.greenGain,
989 sd->params.colourBalance.blueGain);
993 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
996 if (sd->params.colourBalance.balanceMode == 2) {
997 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
1000 if (sd->params.colourBalance.balanceMode == 3) {
1001 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
1008 static int command_setcompressiontarget(struct gspca_dev *gspca_dev)
1010 struct sd *sd = (struct sd *) gspca_dev;
1012 return do_command(gspca_dev, CPIA_COMMAND_SetCompressionTarget,
1013 sd->params.compressionTarget.frTargeting,
1014 sd->params.compressionTarget.targetFR,
1015 sd->params.compressionTarget.targetQ, 0);
1018 static int command_setyuvtresh(struct gspca_dev *gspca_dev)
1020 struct sd *sd = (struct sd *) gspca_dev;
1022 return do_command(gspca_dev, CPIA_COMMAND_SetYUVThresh,
1023 sd->params.yuvThreshold.yThreshold,
1024 sd->params.yuvThreshold.uvThreshold, 0, 0);
1027 static int command_setcompressionparams(struct gspca_dev *gspca_dev)
1029 struct sd *sd = (struct sd *) gspca_dev;
1031 return do_command_extended(gspca_dev,
1032 CPIA_COMMAND_SetCompressionParams,
1034 sd->params.compressionParams.hysteresis,
1035 sd->params.compressionParams.threshMax,
1036 sd->params.compressionParams.smallStep,
1037 sd->params.compressionParams.largeStep,
1038 sd->params.compressionParams.decimationHysteresis,
1039 sd->params.compressionParams.frDiffStepThresh,
1040 sd->params.compressionParams.qDiffStepThresh,
1041 sd->params.compressionParams.decimationThreshMod);
1044 static int command_setcompression(struct gspca_dev *gspca_dev)
1046 struct sd *sd = (struct sd *) gspca_dev;
1048 return do_command(gspca_dev, CPIA_COMMAND_SetCompression,
1049 sd->params.compression.mode,
1050 sd->params.compression.decimation, 0, 0);
1053 static int command_setsensorfps(struct gspca_dev *gspca_dev)
1055 struct sd *sd = (struct sd *) gspca_dev;
1057 return do_command(gspca_dev, CPIA_COMMAND_SetSensorFPS,
1058 sd->params.sensorFps.divisor,
1059 sd->params.sensorFps.baserate, 0, 0);
1062 static int command_setflickerctrl(struct gspca_dev *gspca_dev)
1064 struct sd *sd = (struct sd *) gspca_dev;
1066 return do_command(gspca_dev, CPIA_COMMAND_SetFlickerCtrl,
1067 sd->params.flickerControl.flickerMode,
1068 sd->params.flickerControl.coarseJump,
1069 sd->params.flickerControl.allowableOverExposure,
1073 static int command_setecptiming(struct gspca_dev *gspca_dev)
1075 struct sd *sd = (struct sd *) gspca_dev;
1077 return do_command(gspca_dev, CPIA_COMMAND_SetECPTiming,
1078 sd->params.ecpTiming, 0, 0, 0);
1081 static int command_pause(struct gspca_dev *gspca_dev)
1083 return do_command(gspca_dev, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
1086 static int command_resume(struct gspca_dev *gspca_dev)
1088 struct sd *sd = (struct sd *) gspca_dev;
1090 return do_command(gspca_dev, CPIA_COMMAND_InitStreamCap,
1091 0, sd->params.streamStartLine, 0, 0);
1094 static int command_setlights(struct gspca_dev *gspca_dev)
1096 struct sd *sd = (struct sd *) gspca_dev;
1099 if (!sd->params.qx3.qx3_detected)
1102 p1 = (sd->params.qx3.bottomlight == 0) << 1;
1103 p2 = (sd->params.qx3.toplight == 0) << 3;
1105 ret = do_command(gspca_dev, CPIA_COMMAND_WriteVCReg,
1106 0x90, 0x8F, 0x50, 0);
1110 return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0,
1114 static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply)
1116 /* Everything in here is from the Windows driver */
1117 /* define for compgain calculation */
1119 #define COMPGAIN(base, curexp, newexp) \
1120 (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
1121 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1122 (u16)((float)curexp * (float)(u8)(curcomp + 128) / \
1123 (float)(u8)(basecomp - 128))
1125 /* equivalent functions without floating point math */
1126 #define COMPGAIN(base, curexp, newexp) \
1127 (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2 * newexp)))
1128 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1129 (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
1132 struct sd *sd = (struct sd *) gspca_dev;
1133 int currentexp = sd->params.exposure.coarseExpLo +
1134 sd->params.exposure.coarseExpHi * 256;
1138 int cj = sd->params.flickerControl.coarseJump;
1139 sd->params.flickerControl.flickerMode = 1;
1140 sd->params.flickerControl.disabled = 0;
1141 if (sd->params.exposure.expMode != 2) {
1142 sd->params.exposure.expMode = 2;
1143 sd->exposure_status = EXPOSURE_NORMAL;
1145 currentexp = currentexp << sd->params.exposure.gain;
1146 sd->params.exposure.gain = 0;
1147 /* round down current exposure to nearest value */
1148 startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj;
1151 startexp = (startexp * cj) - 1;
1152 if (FIRMWARE_VERSION(1, 2))
1153 while (startexp > MAX_EXP_102)
1156 while (startexp > MAX_EXP)
1158 sd->params.exposure.coarseExpLo = startexp & 0xff;
1159 sd->params.exposure.coarseExpHi = startexp >> 8;
1160 if (currentexp > startexp) {
1161 if (currentexp > (2 * startexp))
1162 currentexp = 2 * startexp;
1163 sd->params.exposure.redComp =
1164 COMPGAIN(COMP_RED, currentexp, startexp);
1165 sd->params.exposure.green1Comp =
1166 COMPGAIN(COMP_GREEN1, currentexp, startexp);
1167 sd->params.exposure.green2Comp =
1168 COMPGAIN(COMP_GREEN2, currentexp, startexp);
1169 sd->params.exposure.blueComp =
1170 COMPGAIN(COMP_BLUE, currentexp, startexp);
1172 sd->params.exposure.redComp = COMP_RED;
1173 sd->params.exposure.green1Comp = COMP_GREEN1;
1174 sd->params.exposure.green2Comp = COMP_GREEN2;
1175 sd->params.exposure.blueComp = COMP_BLUE;
1177 if (FIRMWARE_VERSION(1, 2))
1178 sd->params.exposure.compMode = 0;
1180 sd->params.exposure.compMode = 1;
1182 sd->params.apcor.gain1 = 0x18;
1183 sd->params.apcor.gain2 = 0x18;
1184 sd->params.apcor.gain4 = 0x16;
1185 sd->params.apcor.gain8 = 0x14;
1187 sd->params.flickerControl.flickerMode = 0;
1188 sd->params.flickerControl.disabled = 1;
1189 /* Average equivalent coarse for each comp channel */
1190 startexp = EXP_FROM_COMP(COMP_RED,
1191 sd->params.exposure.redComp, currentexp);
1192 startexp += EXP_FROM_COMP(COMP_GREEN1,
1193 sd->params.exposure.green1Comp, currentexp);
1194 startexp += EXP_FROM_COMP(COMP_GREEN2,
1195 sd->params.exposure.green2Comp, currentexp);
1196 startexp += EXP_FROM_COMP(COMP_BLUE,
1197 sd->params.exposure.blueComp, currentexp);
1198 startexp = startexp >> 2;
1199 while (startexp > MAX_EXP && sd->params.exposure.gain <
1200 sd->params.exposure.gainMode - 1) {
1201 startexp = startexp >> 1;
1202 ++sd->params.exposure.gain;
1204 if (FIRMWARE_VERSION(1, 2) && startexp > MAX_EXP_102)
1205 startexp = MAX_EXP_102;
1206 if (startexp > MAX_EXP)
1208 sd->params.exposure.coarseExpLo = startexp & 0xff;
1209 sd->params.exposure.coarseExpHi = startexp >> 8;
1210 sd->params.exposure.redComp = COMP_RED;
1211 sd->params.exposure.green1Comp = COMP_GREEN1;
1212 sd->params.exposure.green2Comp = COMP_GREEN2;
1213 sd->params.exposure.blueComp = COMP_BLUE;
1214 sd->params.exposure.compMode = 1;
1215 sd->params.apcor.gain1 = 0x18;
1216 sd->params.apcor.gain2 = 0x16;
1217 sd->params.apcor.gain4 = 0x24;
1218 sd->params.apcor.gain8 = 0x34;
1220 sd->params.vlOffset.gain1 = 20;
1221 sd->params.vlOffset.gain2 = 24;
1222 sd->params.vlOffset.gain4 = 26;
1223 sd->params.vlOffset.gain8 = 26;
1226 ret = command_setexposure(gspca_dev);
1230 ret = command_setapcor(gspca_dev);
1234 ret = command_setvloffset(gspca_dev);
1238 ret = command_setflickerctrl(gspca_dev);
1244 #undef EXP_FROM_COMP
1248 /* monitor the exposure and adjust the sensor frame rate if needed */
1249 static void monitor_exposure(struct gspca_dev *gspca_dev)
1251 struct sd *sd = (struct sd *) gspca_dev;
1252 u8 exp_acc, bcomp, gain, coarseL, cmd[8];
1253 int ret, light_exp, dark_exp, very_dark_exp;
1254 int old_exposure, new_exposure, framerate;
1255 int setfps = 0, setexp = 0, setflicker = 0;
1257 /* get necessary stats and register settings from camera */
1258 /* do_command can't handle this, so do it ourselves */
1259 cmd[0] = CPIA_COMMAND_ReadVPRegs >> 8;
1260 cmd[1] = CPIA_COMMAND_ReadVPRegs & 0xff;
1267 ret = cpia_usb_transferCmd(gspca_dev, cmd);
1269 err("ReadVPRegs(30,4,9,8) - failed: %d", ret);
1272 exp_acc = gspca_dev->usb_buf[0];
1273 bcomp = gspca_dev->usb_buf[1];
1274 gain = gspca_dev->usb_buf[2];
1275 coarseL = gspca_dev->usb_buf[3];
1277 light_exp = sd->params.colourParams.brightness +
1278 TC - 50 + EXP_ACC_LIGHT;
1279 if (light_exp > 255)
1281 dark_exp = sd->params.colourParams.brightness +
1282 TC - 50 - EXP_ACC_DARK;
1285 very_dark_exp = dark_exp / 2;
1287 old_exposure = sd->params.exposure.coarseExpHi * 256 +
1288 sd->params.exposure.coarseExpLo;
1290 if (!sd->params.flickerControl.disabled) {
1291 /* Flicker control on */
1292 int max_comp = FIRMWARE_VERSION(1, 2) ? MAX_COMP :
1294 bcomp += 128; /* decode */
1295 if (bcomp >= max_comp && exp_acc < dark_exp) {
1297 if (exp_acc < very_dark_exp) {
1299 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1300 ++sd->exposure_count;
1302 sd->exposure_status =
1304 sd->exposure_count = 1;
1308 if (sd->exposure_status == EXPOSURE_DARK)
1309 ++sd->exposure_count;
1311 sd->exposure_status = EXPOSURE_DARK;
1312 sd->exposure_count = 1;
1315 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1317 if (old_exposure <= VERY_LOW_EXP) {
1319 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1320 ++sd->exposure_count;
1322 sd->exposure_status =
1323 EXPOSURE_VERY_LIGHT;
1324 sd->exposure_count = 1;
1328 if (sd->exposure_status == EXPOSURE_LIGHT)
1329 ++sd->exposure_count;
1331 sd->exposure_status = EXPOSURE_LIGHT;
1332 sd->exposure_count = 1;
1336 /* not dark or light */
1337 sd->exposure_status = EXPOSURE_NORMAL;
1340 /* Flicker control off */
1341 if (old_exposure >= MAX_EXP && exp_acc < dark_exp) {
1343 if (exp_acc < very_dark_exp) {
1345 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1346 ++sd->exposure_count;
1348 sd->exposure_status =
1350 sd->exposure_count = 1;
1354 if (sd->exposure_status == EXPOSURE_DARK)
1355 ++sd->exposure_count;
1357 sd->exposure_status = EXPOSURE_DARK;
1358 sd->exposure_count = 1;
1361 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1363 if (old_exposure <= VERY_LOW_EXP) {
1365 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1366 ++sd->exposure_count;
1368 sd->exposure_status =
1369 EXPOSURE_VERY_LIGHT;
1370 sd->exposure_count = 1;
1374 if (sd->exposure_status == EXPOSURE_LIGHT)
1375 ++sd->exposure_count;
1377 sd->exposure_status = EXPOSURE_LIGHT;
1378 sd->exposure_count = 1;
1382 /* not dark or light */
1383 sd->exposure_status = EXPOSURE_NORMAL;
1387 framerate = atomic_read(&sd->fps);
1388 if (framerate > 30 || framerate < 1)
1391 if (!sd->params.flickerControl.disabled) {
1392 /* Flicker control on */
1393 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1394 sd->exposure_status == EXPOSURE_DARK) &&
1395 sd->exposure_count >= DARK_TIME * framerate &&
1396 sd->params.sensorFps.divisor < 3) {
1398 /* dark for too long */
1399 ++sd->params.sensorFps.divisor;
1402 sd->params.flickerControl.coarseJump =
1403 flicker_jumps[sd->mainsFreq]
1404 [sd->params.sensorFps.baserate]
1405 [sd->params.sensorFps.divisor];
1408 new_exposure = sd->params.flickerControl.coarseJump-1;
1409 while (new_exposure < old_exposure / 2)
1411 sd->params.flickerControl.coarseJump;
1412 sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1413 sd->params.exposure.coarseExpHi = new_exposure >> 8;
1415 sd->exposure_status = EXPOSURE_NORMAL;
1416 PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
1418 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1419 sd->exposure_status == EXPOSURE_LIGHT) &&
1420 sd->exposure_count >= LIGHT_TIME * framerate &&
1421 sd->params.sensorFps.divisor > 0) {
1423 /* light for too long */
1424 int max_exp = FIRMWARE_VERSION(1, 2) ? MAX_EXP_102 :
1426 --sd->params.sensorFps.divisor;
1429 sd->params.flickerControl.coarseJump =
1430 flicker_jumps[sd->mainsFreq]
1431 [sd->params.sensorFps.baserate]
1432 [sd->params.sensorFps.divisor];
1435 new_exposure = sd->params.flickerControl.coarseJump-1;
1436 while (new_exposure < 2 * old_exposure &&
1438 sd->params.flickerControl.coarseJump < max_exp)
1440 sd->params.flickerControl.coarseJump;
1441 sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1442 sd->params.exposure.coarseExpHi = new_exposure >> 8;
1444 sd->exposure_status = EXPOSURE_NORMAL;
1445 PDEBUG(D_CONF, "Automatically increasing sensor_fps");
1448 /* Flicker control off */
1449 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1450 sd->exposure_status == EXPOSURE_DARK) &&
1451 sd->exposure_count >= DARK_TIME * framerate &&
1452 sd->params.sensorFps.divisor < 3) {
1454 /* dark for too long */
1455 ++sd->params.sensorFps.divisor;
1458 if (sd->params.exposure.gain > 0) {
1459 --sd->params.exposure.gain;
1462 sd->exposure_status = EXPOSURE_NORMAL;
1463 PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
1465 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1466 sd->exposure_status == EXPOSURE_LIGHT) &&
1467 sd->exposure_count >= LIGHT_TIME * framerate &&
1468 sd->params.sensorFps.divisor > 0) {
1470 /* light for too long */
1471 --sd->params.sensorFps.divisor;
1474 if (sd->params.exposure.gain <
1475 sd->params.exposure.gainMode - 1) {
1476 ++sd->params.exposure.gain;
1479 sd->exposure_status = EXPOSURE_NORMAL;
1480 PDEBUG(D_CONF, "Automatically increasing sensor_fps");
1485 command_setexposure(gspca_dev);
1488 command_setsensorfps(gspca_dev);
1491 command_setflickerctrl(gspca_dev);
1494 /*-----------------------------------------------------------------*/
1495 /* if flicker is switched off, this function switches it back on.It checks,
1496 however, that conditions are suitable before restarting it.
1497 This should only be called for firmware version 1.2.
1499 It also adjust the colour balance when an exposure step is detected - as
1500 long as flicker is running
1502 static void restart_flicker(struct gspca_dev *gspca_dev)
1504 struct sd *sd = (struct sd *) gspca_dev;
1505 int cam_exposure, old_exp;
1507 if (!FIRMWARE_VERSION(1, 2))
1510 cam_exposure = atomic_read(&sd->cam_exposure);
1512 if (sd->params.flickerControl.flickerMode == 0 ||
1516 old_exp = sd->params.exposure.coarseExpLo +
1517 sd->params.exposure.coarseExpHi*256;
1519 see how far away camera exposure is from a valid
1520 flicker exposure value
1522 cam_exposure %= sd->params.flickerControl.coarseJump;
1523 if (!sd->params.flickerControl.disabled &&
1524 cam_exposure <= sd->params.flickerControl.coarseJump - 3) {
1525 /* Flicker control auto-disabled */
1526 sd->params.flickerControl.disabled = 1;
1529 if (sd->params.flickerControl.disabled &&
1530 old_exp > sd->params.flickerControl.coarseJump +
1531 ROUND_UP_EXP_FOR_FLICKER) {
1532 /* exposure is now high enough to switch
1533 flicker control back on */
1534 set_flicker(gspca_dev, 1, 1);
1538 /* this function is called at probe time */
1539 static int sd_config(struct gspca_dev *gspca_dev,
1540 const struct usb_device_id *id)
1544 reset_camera_params(gspca_dev);
1546 PDEBUG(D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)",
1547 id->idVendor, id->idProduct);
1549 cam = &gspca_dev->cam;
1550 cam->cam_mode = mode;
1551 cam->nmodes = ARRAY_SIZE(mode);
1553 sd_setfreq(gspca_dev, FREQ_DEF);
1558 /* -- start the camera -- */
1559 static int sd_start(struct gspca_dev *gspca_dev)
1561 struct sd *sd = (struct sd *) gspca_dev;
1564 /* Start the camera in low power mode */
1565 if (goto_low_power(gspca_dev)) {
1566 if (sd->params.status.systemState != WARM_BOOT_STATE) {
1567 PDEBUG(D_ERR, "unexpected systemstate: %02x",
1568 sd->params.status.systemState);
1569 printstatus(&sd->params);
1573 /* FIXME: this is just dirty trial and error */
1574 ret = goto_high_power(gspca_dev);
1578 ret = do_command(gspca_dev, CPIA_COMMAND_DiscardFrame,
1583 ret = goto_low_power(gspca_dev);
1588 /* procedure described in developer's guide p3-28 */
1590 /* Check the firmware version. */
1591 sd->params.version.firmwareVersion = 0;
1592 get_version_information(gspca_dev);
1593 if (sd->params.version.firmwareVersion != 1) {
1594 PDEBUG(D_ERR, "only firmware version 1 is supported (got: %d)",
1595 sd->params.version.firmwareVersion);
1599 /* A bug in firmware 1-02 limits gainMode to 2 */
1600 if (sd->params.version.firmwareRevision <= 2 &&
1601 sd->params.exposure.gainMode > 2) {
1602 sd->params.exposure.gainMode = 2;
1605 /* set QX3 detected flag */
1606 sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 &&
1607 sd->params.pnpID.product == 0x0001);
1609 /* The fatal error checking should be done after
1610 * the camera powers up (developer's guide p 3-38) */
1612 /* Set streamState before transition to high power to avoid bug
1613 * in firmware 1-02 */
1614 ret = do_command(gspca_dev, CPIA_COMMAND_ModifyCameraStatus,
1615 STREAMSTATE, 0, STREAM_NOT_READY, 0);
1620 ret = goto_high_power(gspca_dev);
1624 /* Check the camera status */
1625 ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1629 if (sd->params.status.fatalError) {
1630 PDEBUG(D_ERR, "fatal_error: %04x, vp_status: %04x",
1631 sd->params.status.fatalError,
1632 sd->params.status.vpStatus);
1636 /* VPVersion can't be retrieved before the camera is in HiPower,
1637 * so get it here instead of in get_version_information. */
1638 ret = do_command(gspca_dev, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0);
1642 /* Determine video mode settings */
1643 sd->params.streamStartLine = 120;
1645 priv = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1646 if (priv & 0x01) { /* crop */
1647 sd->params.roi.colStart = 2;
1648 sd->params.roi.rowStart = 6;
1650 sd->params.roi.colStart = 0;
1651 sd->params.roi.rowStart = 0;
1654 if (priv & 0x02) { /* quarter */
1655 sd->params.format.videoSize = VIDEOSIZE_QCIF;
1656 sd->params.roi.colStart /= 2;
1657 sd->params.roi.rowStart /= 2;
1658 sd->params.streamStartLine /= 2;
1660 sd->params.format.videoSize = VIDEOSIZE_CIF;
1662 sd->params.roi.colEnd = sd->params.roi.colStart +
1663 (gspca_dev->width >> 3);
1664 sd->params.roi.rowEnd = sd->params.roi.rowStart +
1665 (gspca_dev->height >> 2);
1667 /* And now set the camera to a known state */
1668 ret = do_command(gspca_dev, CPIA_COMMAND_SetGrabMode,
1669 CPIA_GRAB_CONTINEOUS, 0, 0, 0);
1672 /* We start with compression disabled, as we need one uncompressed
1673 frame to handle later compressed frames */
1674 ret = do_command(gspca_dev, CPIA_COMMAND_SetCompression,
1675 CPIA_COMPRESSION_NONE,
1676 NO_DECIMATION, 0, 0);
1679 ret = command_setcompressiontarget(gspca_dev);
1682 ret = command_setcolourparams(gspca_dev);
1685 ret = command_setformat(gspca_dev);
1688 ret = command_setyuvtresh(gspca_dev);
1691 ret = command_setecptiming(gspca_dev);
1694 ret = command_setcompressionparams(gspca_dev);
1697 ret = command_setexposure(gspca_dev);
1700 ret = command_setcolourbalance(gspca_dev);
1703 ret = command_setsensorfps(gspca_dev);
1706 ret = command_setapcor(gspca_dev);
1709 ret = command_setflickerctrl(gspca_dev);
1712 ret = command_setvloffset(gspca_dev);
1717 ret = command_resume(gspca_dev);
1721 /* Wait 6 frames before turning compression on for the sensor to get
1722 all settings and AEC/ACB to settle */
1723 sd->first_frame = 6;
1724 sd->exposure_status = EXPOSURE_NORMAL;
1725 sd->exposure_count = 0;
1726 atomic_set(&sd->cam_exposure, 0);
1727 atomic_set(&sd->fps, 0);
1732 static void sd_stopN(struct gspca_dev *gspca_dev)
1734 command_pause(gspca_dev);
1736 /* save camera state for later open (developers guide ch 3.5.3) */
1737 save_camera_state(gspca_dev);
1740 goto_low_power(gspca_dev);
1742 /* Update the camera status */
1743 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1746 /* this function is called at probe and resume time */
1747 static int sd_init(struct gspca_dev *gspca_dev)
1749 struct sd *sd = (struct sd *) gspca_dev;
1752 /* Start / Stop the camera to make sure we are talking to
1753 a supported camera, and to get some information from it
1755 ret = sd_start(gspca_dev);
1759 sd_stopN(gspca_dev);
1761 PDEBUG(D_PROBE, "CPIA Version: %d.%02d (%d.%d)",
1762 sd->params.version.firmwareVersion,
1763 sd->params.version.firmwareRevision,
1764 sd->params.version.vcVersion,
1765 sd->params.version.vcRevision);
1766 PDEBUG(D_PROBE, "CPIA PnP-ID: %04x:%04x:%04x",
1767 sd->params.pnpID.vendor, sd->params.pnpID.product,
1768 sd->params.pnpID.deviceRevision);
1769 PDEBUG(D_PROBE, "VP-Version: %d.%d %04x",
1770 sd->params.vpVersion.vpVersion,
1771 sd->params.vpVersion.vpRevision,
1772 sd->params.vpVersion.cameraHeadID);
1777 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1781 struct sd *sd = (struct sd *) gspca_dev;
1785 data[0] == MAGIC_0 && data[1] == MAGIC_1 &&
1786 data[16] == sd->params.format.videoSize &&
1787 data[17] == sd->params.format.subSample &&
1788 data[18] == sd->params.format.yuvOrder &&
1789 data[24] == sd->params.roi.colStart &&
1790 data[25] == sd->params.roi.colEnd &&
1791 data[26] == sd->params.roi.rowStart &&
1792 data[27] == sd->params.roi.rowEnd) {
1795 atomic_set(&sd->cam_exposure, data[39] * 2);
1796 atomic_set(&sd->fps, data[41]);
1798 /* Check for proper EOF for last frame */
1799 image = gspca_dev->image;
1800 if (image != NULL &&
1801 gspca_dev->image_len > 4 &&
1802 image[gspca_dev->image_len - 4] == 0xff &&
1803 image[gspca_dev->image_len - 3] == 0xff &&
1804 image[gspca_dev->image_len - 2] == 0xff &&
1805 image[gspca_dev->image_len - 1] == 0xff)
1806 gspca_frame_add(gspca_dev, LAST_PACKET,
1809 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
1813 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1816 static void sd_dq_callback(struct gspca_dev *gspca_dev)
1818 struct sd *sd = (struct sd *) gspca_dev;
1820 /* Set the normal compression settings once we have captured a
1821 few uncompressed frames (and AEC has hopefully settled) */
1822 if (sd->first_frame) {
1824 if (sd->first_frame == 0)
1825 command_setcompression(gspca_dev);
1828 /* Switch flicker control back on if it got turned off */
1829 restart_flicker(gspca_dev);
1831 /* If AEC is enabled, monitor the exposure and
1832 adjust the sensor frame rate if needed */
1833 if (sd->params.exposure.expMode == 2)
1834 monitor_exposure(gspca_dev);
1836 /* Update our knowledge of the camera state */
1837 do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
1838 if (sd->params.qx3.qx3_detected)
1839 do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
1842 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1844 struct sd *sd = (struct sd *) gspca_dev;
1847 sd->params.colourParams.brightness = val;
1848 sd->params.flickerControl.allowableOverExposure =
1849 find_over_exposure(sd->params.colourParams.brightness);
1850 if (gspca_dev->streaming) {
1851 ret = command_setcolourparams(gspca_dev);
1854 return command_setflickerctrl(gspca_dev);
1859 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1861 struct sd *sd = (struct sd *) gspca_dev;
1863 *val = sd->params.colourParams.brightness;
1867 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1869 struct sd *sd = (struct sd *) gspca_dev;
1871 sd->params.colourParams.contrast = val;
1872 if (gspca_dev->streaming)
1873 return command_setcolourparams(gspca_dev);
1878 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1880 struct sd *sd = (struct sd *) gspca_dev;
1882 *val = sd->params.colourParams.contrast;
1886 static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val)
1888 struct sd *sd = (struct sd *) gspca_dev;
1890 sd->params.colourParams.saturation = val;
1891 if (gspca_dev->streaming)
1892 return command_setcolourparams(gspca_dev);
1897 static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val)
1899 struct sd *sd = (struct sd *) gspca_dev;
1901 *val = sd->params.colourParams.saturation;
1905 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1907 struct sd *sd = (struct sd *) gspca_dev;
1911 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1914 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1918 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1927 sd->params.flickerControl.coarseJump =
1928 flicker_jumps[sd->mainsFreq]
1929 [sd->params.sensorFps.baserate]
1930 [sd->params.sensorFps.divisor];
1932 return set_flicker(gspca_dev, on, gspca_dev->streaming);
1935 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1937 struct sd *sd = (struct sd *) gspca_dev;
1943 static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val)
1945 struct sd *sd = (struct sd *) gspca_dev;
1947 sd->params.compressionTarget.frTargeting = val;
1948 if (gspca_dev->streaming)
1949 return command_setcompressiontarget(gspca_dev);
1954 static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val)
1956 struct sd *sd = (struct sd *) gspca_dev;
1958 *val = sd->params.compressionTarget.frTargeting;
1962 static int sd_setilluminator(struct gspca_dev *gspca_dev, __s32 val, int n)
1964 struct sd *sd = (struct sd *) gspca_dev;
1967 if (!sd->params.qx3.qx3_detected)
1972 sd->params.qx3.bottomlight = val ? 1 : 0;
1975 sd->params.qx3.toplight = val ? 1 : 0;
1981 ret = command_setlights(gspca_dev);
1982 if (ret && ret != -EINVAL)
1988 static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val)
1990 return sd_setilluminator(gspca_dev, val, 1);
1993 static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val)
1995 return sd_setilluminator(gspca_dev, val, 2);
1998 static int sd_getilluminator(struct gspca_dev *gspca_dev, __s32 *val, int n)
2000 struct sd *sd = (struct sd *) gspca_dev;
2002 if (!sd->params.qx3.qx3_detected)
2007 *val = sd->params.qx3.bottomlight;
2010 *val = sd->params.qx3.toplight;
2018 static int sd_getilluminator1(struct gspca_dev *gspca_dev, __s32 *val)
2020 return sd_getilluminator(gspca_dev, val, 1);
2023 static int sd_getilluminator2(struct gspca_dev *gspca_dev, __s32 *val)
2025 return sd_getilluminator(gspca_dev, val, 2);
2028 static int sd_querymenu(struct gspca_dev *gspca_dev,
2029 struct v4l2_querymenu *menu)
2032 case V4L2_CID_POWER_LINE_FREQUENCY:
2033 switch (menu->index) {
2034 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2035 strcpy((char *) menu->name, "NoFliker");
2037 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2038 strcpy((char *) menu->name, "50 Hz");
2040 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2041 strcpy((char *) menu->name, "60 Hz");
2045 case V4L2_CID_COMP_TARGET:
2046 switch (menu->index) {
2047 case CPIA_COMPRESSION_TARGET_QUALITY:
2048 strcpy((char *) menu->name, "Quality");
2050 case CPIA_COMPRESSION_TARGET_FRAMERATE:
2051 strcpy((char *) menu->name, "Framerate");
2059 /* sub-driver description */
2060 static const struct sd_desc sd_desc = {
2061 .name = MODULE_NAME,
2063 .nctrls = ARRAY_SIZE(sd_ctrls),
2064 .config = sd_config,
2068 .dq_callback = sd_dq_callback,
2069 .pkt_scan = sd_pkt_scan,
2070 .querymenu = sd_querymenu,
2073 /* -- module initialisation -- */
2074 static const __devinitdata struct usb_device_id device_table[] = {
2075 {USB_DEVICE(0x0553, 0x0002)},
2076 {USB_DEVICE(0x0813, 0x0001)},
2079 MODULE_DEVICE_TABLE(usb, device_table);
2081 /* -- device connect -- */
2082 static int sd_probe(struct usb_interface *intf,
2083 const struct usb_device_id *id)
2085 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2089 static struct usb_driver sd_driver = {
2090 .name = MODULE_NAME,
2091 .id_table = device_table,
2093 .disconnect = gspca_disconnect,
2095 .suspend = gspca_suspend,
2096 .resume = gspca_resume,
2100 /* -- module insert / remove -- */
2101 static int __init sd_mod_init(void)
2103 return usb_register(&sd_driver);
2105 static void __exit sd_mod_exit(void)
2107 usb_deregister(&sd_driver);
2110 module_init(sd_mod_init);
2111 module_exit(sd_mod_exit);