2 * cpia CPiA (1) gspca driver
4 * Copyright (C) 2010-2011 Hans de Goede <hdegoede@redhat.com>
6 * This module is adapted from the in kernel v4l1 cpia driver which is :
8 * (C) Copyright 1999-2000 Peter Pregler
9 * (C) Copyright 1999-2000 Scott J. Bertin
10 * (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.com>
11 * (C) Copyright 2000 STMicroelectronics
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
25 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
27 #define MODULE_NAME "cpia1"
29 #include <linux/input.h>
30 #include <linux/sched/signal.h>
31 #include <linux/bitops.h>
35 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
36 MODULE_DESCRIPTION("Vision CPiA");
37 MODULE_LICENSE("GPL");
39 /* constant value's */
44 #define VIDEOSIZE_QCIF 0 /* 176x144 */
45 #define VIDEOSIZE_CIF 1 /* 352x288 */
46 #define SUBSAMPLE_420 0
47 #define SUBSAMPLE_422 1
48 #define YUVORDER_YUYV 0
49 #define YUVORDER_UYVY 1
50 #define NOT_COMPRESSED 0
52 #define NO_DECIMATION 0
53 #define DECIMATION_ENAB 1
54 #define EOI 0xff /* End Of Image */
55 #define EOL 0xfd /* End Of Line */
56 #define FRAME_HEADER_SIZE 64
58 /* Image grab modes */
59 #define CPIA_GRAB_SINGLE 0
60 #define CPIA_GRAB_CONTINEOUS 1
62 /* Compression parameters */
63 #define CPIA_COMPRESSION_NONE 0
64 #define CPIA_COMPRESSION_AUTO 1
65 #define CPIA_COMPRESSION_MANUAL 2
66 #define CPIA_COMPRESSION_TARGET_QUALITY 0
67 #define CPIA_COMPRESSION_TARGET_FRAMERATE 1
69 /* Return offsets for GetCameraState */
80 #define UNINITIALISED_STATE 0
81 #define PASS_THROUGH_STATE 1
82 #define LO_POWER_STATE 2
83 #define HI_POWER_STATE 3
84 #define WARM_BOOT_STATE 4
92 #define STREAM_NOT_READY 0
93 #define STREAM_READY 1
95 #define STREAM_PAUSED 3
96 #define STREAM_FINISHED 4
98 /* Fatal Error, CmdError, and DebugFlags */
100 #define SYSTEM_FLAG 2
101 #define INT_CTRL_FLAG 4
102 #define PROCESS_FLAG 8
104 #define VP_CTRL_FLAG 32
105 #define CAPTURE_FLAG 64
106 #define DEBUG_FLAG 128
109 #define VP_STATE_OK 0x00
111 #define VP_STATE_FAILED_VIDEOINIT 0x01
112 #define VP_STATE_FAILED_AECACBINIT 0x02
113 #define VP_STATE_AEC_MAX 0x04
114 #define VP_STATE_ACB_BMAX 0x08
116 #define VP_STATE_ACB_RMIN 0x10
117 #define VP_STATE_ACB_GMIN 0x20
118 #define VP_STATE_ACB_RMAX 0x40
119 #define VP_STATE_ACB_GMAX 0x80
121 /* default (minimum) compensation values */
123 #define COMP_GREEN1 214
124 #define COMP_GREEN2 COMP_GREEN1
125 #define COMP_BLUE 230
127 /* exposure status */
128 #define EXPOSURE_VERY_LIGHT 0
129 #define EXPOSURE_LIGHT 1
130 #define EXPOSURE_NORMAL 2
131 #define EXPOSURE_DARK 3
132 #define EXPOSURE_VERY_DARK 4
134 #define CPIA_MODULE_CPIA (0 << 5)
135 #define CPIA_MODULE_SYSTEM (1 << 5)
136 #define CPIA_MODULE_VP_CTRL (5 << 5)
137 #define CPIA_MODULE_CAPTURE (6 << 5)
138 #define CPIA_MODULE_DEBUG (7 << 5)
140 #define INPUT (DATA_IN << 8)
141 #define OUTPUT (DATA_OUT << 8)
143 #define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)
144 #define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)
145 #define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)
146 #define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)
147 #define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)
148 #define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)
149 #define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)
150 #define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)
152 #define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)
153 #define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)
154 #define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)
155 #define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)
156 #define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)
157 #define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)
158 #define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)
159 #define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)
160 #define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)
161 #define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)
162 #define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)
163 #define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)
164 #define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
166 #define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
167 #define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)
168 #define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
169 #define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
170 #define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
171 #define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)
172 #define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)
173 #define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)
174 #define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)
175 #define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)
176 #define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)
177 #define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)
178 #define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)
179 #define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)
180 #define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)
181 #define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)
182 #define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)
184 #define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)
185 #define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)
186 #define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)
187 #define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)
188 #define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)
189 #define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)
190 #define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)
191 #define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)
192 #define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)
193 #define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)
194 #define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
195 #define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
196 #define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
197 #define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
198 #define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)
200 #define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
201 #define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
202 #define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)
203 #define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)
204 #define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
205 #define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
206 #define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
207 #define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)
209 #define ROUND_UP_EXP_FOR_FLICKER 15
211 /* Constants for automatic frame rate adjustment */
213 #define MAX_EXP_102 255
215 #define VERY_LOW_EXP 70
217 #define EXP_ACC_DARK 50
218 #define EXP_ACC_LIGHT 90
219 #define HIGH_COMP_102 160
224 #define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \
225 sd->params.version.firmwareRevision == (y))
227 #define CPIA1_CID_COMP_TARGET (V4L2_CTRL_CLASS_USER + 0x1000)
228 #define BRIGHTNESS_DEF 50
229 #define CONTRAST_DEF 48
230 #define SATURATION_DEF 50
231 #define FREQ_DEF V4L2_CID_POWER_LINE_FREQUENCY_50HZ
232 #define ILLUMINATORS_1_DEF 0
233 #define ILLUMINATORS_2_DEF 0
234 #define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY
236 /* Developer's Guide Table 5 p 3-34
237 * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
238 static u8 flicker_jumps[2][2][4] =
239 { { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
240 { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
309 u8 allowableOverExposure;
335 u8 decimationHysteresis;
338 u8 decimationThreshMod;
341 u8 videoSize; /* CIF/QCIF */
345 struct { /* Intel QX3 specific data */
346 u8 qx3_detected; /* a QX3 is present */
347 u8 toplight; /* top light lit , R/W */
348 u8 bottomlight; /* bottom light lit, R/W */
349 u8 button; /* snapshot button pressed (R/O) */
350 u8 cradled; /* microscope is in cradle (R/O) */
353 u8 colStart; /* skip first 8*colStart pixels */
354 u8 colEnd; /* finish at 8*colEnd pixels */
355 u8 rowStart; /* skip first 4*rowStart lines */
356 u8 rowEnd; /* finish at 4*rowEnd lines */
362 /* specific webcam descriptor */
364 struct gspca_dev gspca_dev; /* !! must be the first item */
365 struct cam_params params; /* camera settings */
367 atomic_t cam_exposure;
371 struct v4l2_ctrl *freq;
372 u8 mainsFreq; /* 0 = 50hz, 1 = 60hz */
376 static const struct v4l2_pix_format mode[] = {
377 {160, 120, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
378 /* The sizeimage is trial and error, as with low framerates
379 the camera will pad out usb frames, making the image
380 data larger then strictly necessary */
383 .colorspace = V4L2_COLORSPACE_SRGB,
385 {176, 144, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
388 .colorspace = V4L2_COLORSPACE_SRGB,
390 {320, 240, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
393 .colorspace = V4L2_COLORSPACE_SRGB,
395 {352, 288, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
398 .colorspace = V4L2_COLORSPACE_SRGB,
402 /**********************************************************************
406 **********************************************************************/
408 static int cpia_usb_transferCmd(struct gspca_dev *gspca_dev, u8 *command)
412 int ret, databytes = command[6] | (command[7] << 8);
413 /* Sometimes we see spurious EPIPE errors */
416 if (command[0] == DATA_IN) {
417 pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
418 requesttype = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
419 } else if (command[0] == DATA_OUT) {
420 pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
421 requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE;
423 PERR("Unexpected first byte of command: %x", command[0]);
428 ret = usb_control_msg(gspca_dev->dev, pipe,
431 command[2] | (command[3] << 8),
432 command[4] | (command[5] << 8),
433 gspca_dev->usb_buf, databytes, 1000);
436 pr_err("usb_control_msg %02x, error %d\n", command[1], ret);
438 if (ret == -EPIPE && retries > 0) {
443 return (ret < 0) ? ret : 0;
446 /* send an arbitrary command to the camera */
447 static int do_command(struct gspca_dev *gspca_dev, u16 command,
448 u8 a, u8 b, u8 c, u8 d)
450 struct sd *sd = (struct sd *) gspca_dev;
455 case CPIA_COMMAND_GetCPIAVersion:
456 case CPIA_COMMAND_GetPnPID:
457 case CPIA_COMMAND_GetCameraStatus:
458 case CPIA_COMMAND_GetVPVersion:
459 case CPIA_COMMAND_GetColourParams:
460 case CPIA_COMMAND_GetColourBalance:
461 case CPIA_COMMAND_GetExposure:
464 case CPIA_COMMAND_ReadMCPorts:
465 case CPIA_COMMAND_ReadVCRegs:
473 cmd[0] = command >> 8;
474 cmd[1] = command & 0xff;
482 ret = cpia_usb_transferCmd(gspca_dev, cmd);
487 case CPIA_COMMAND_GetCPIAVersion:
488 sd->params.version.firmwareVersion = gspca_dev->usb_buf[0];
489 sd->params.version.firmwareRevision = gspca_dev->usb_buf[1];
490 sd->params.version.vcVersion = gspca_dev->usb_buf[2];
491 sd->params.version.vcRevision = gspca_dev->usb_buf[3];
493 case CPIA_COMMAND_GetPnPID:
494 sd->params.pnpID.vendor =
495 gspca_dev->usb_buf[0] | (gspca_dev->usb_buf[1] << 8);
496 sd->params.pnpID.product =
497 gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
498 sd->params.pnpID.deviceRevision =
499 gspca_dev->usb_buf[4] | (gspca_dev->usb_buf[5] << 8);
501 case CPIA_COMMAND_GetCameraStatus:
502 sd->params.status.systemState = gspca_dev->usb_buf[0];
503 sd->params.status.grabState = gspca_dev->usb_buf[1];
504 sd->params.status.streamState = gspca_dev->usb_buf[2];
505 sd->params.status.fatalError = gspca_dev->usb_buf[3];
506 sd->params.status.cmdError = gspca_dev->usb_buf[4];
507 sd->params.status.debugFlags = gspca_dev->usb_buf[5];
508 sd->params.status.vpStatus = gspca_dev->usb_buf[6];
509 sd->params.status.errorCode = gspca_dev->usb_buf[7];
511 case CPIA_COMMAND_GetVPVersion:
512 sd->params.vpVersion.vpVersion = gspca_dev->usb_buf[0];
513 sd->params.vpVersion.vpRevision = gspca_dev->usb_buf[1];
514 sd->params.vpVersion.cameraHeadID =
515 gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
517 case CPIA_COMMAND_GetColourParams:
518 sd->params.colourParams.brightness = gspca_dev->usb_buf[0];
519 sd->params.colourParams.contrast = gspca_dev->usb_buf[1];
520 sd->params.colourParams.saturation = gspca_dev->usb_buf[2];
522 case CPIA_COMMAND_GetColourBalance:
523 sd->params.colourBalance.redGain = gspca_dev->usb_buf[0];
524 sd->params.colourBalance.greenGain = gspca_dev->usb_buf[1];
525 sd->params.colourBalance.blueGain = gspca_dev->usb_buf[2];
527 case CPIA_COMMAND_GetExposure:
528 sd->params.exposure.gain = gspca_dev->usb_buf[0];
529 sd->params.exposure.fineExp = gspca_dev->usb_buf[1];
530 sd->params.exposure.coarseExpLo = gspca_dev->usb_buf[2];
531 sd->params.exposure.coarseExpHi = gspca_dev->usb_buf[3];
532 sd->params.exposure.redComp = gspca_dev->usb_buf[4];
533 sd->params.exposure.green1Comp = gspca_dev->usb_buf[5];
534 sd->params.exposure.green2Comp = gspca_dev->usb_buf[6];
535 sd->params.exposure.blueComp = gspca_dev->usb_buf[7];
538 case CPIA_COMMAND_ReadMCPorts:
539 /* test button press */
540 a = ((gspca_dev->usb_buf[1] & 0x02) == 0);
541 if (a != sd->params.qx3.button) {
542 #if IS_ENABLED(CONFIG_INPUT)
543 input_report_key(gspca_dev->input_dev, KEY_CAMERA, a);
544 input_sync(gspca_dev->input_dev);
546 sd->params.qx3.button = a;
548 if (sd->params.qx3.button) {
549 /* button pressed - unlock the latch */
550 do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
552 do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
556 /* test whether microscope is cradled */
557 sd->params.qx3.cradled = ((gspca_dev->usb_buf[2] & 0x40) == 0);
564 /* send a command to the camera with an additional data transaction */
565 static int do_command_extended(struct gspca_dev *gspca_dev, u16 command,
566 u8 a, u8 b, u8 c, u8 d,
567 u8 e, u8 f, u8 g, u8 h,
568 u8 i, u8 j, u8 k, u8 l)
572 cmd[0] = command >> 8;
573 cmd[1] = command & 0xff;
580 gspca_dev->usb_buf[0] = e;
581 gspca_dev->usb_buf[1] = f;
582 gspca_dev->usb_buf[2] = g;
583 gspca_dev->usb_buf[3] = h;
584 gspca_dev->usb_buf[4] = i;
585 gspca_dev->usb_buf[5] = j;
586 gspca_dev->usb_buf[6] = k;
587 gspca_dev->usb_buf[7] = l;
589 return cpia_usb_transferCmd(gspca_dev, cmd);
592 /* find_over_exposure
593 * Finds a suitable value of OverExposure for use with SetFlickerCtrl
594 * Some calculation is required because this value changes with the brightness
595 * set with SetColourParameters
597 * Parameters: Brightness - last brightness value set with SetColourParameters
599 * Returns: OverExposure value to use with SetFlickerCtrl
601 #define FLICKER_MAX_EXPOSURE 250
602 #define FLICKER_ALLOWABLE_OVER_EXPOSURE 146
603 #define FLICKER_BRIGHTNESS_CONSTANT 59
604 static int find_over_exposure(int brightness)
606 int MaxAllowableOverExposure, OverExposure;
608 MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness -
609 FLICKER_BRIGHTNESS_CONSTANT;
611 if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE)
612 OverExposure = MaxAllowableOverExposure;
614 OverExposure = FLICKER_ALLOWABLE_OVER_EXPOSURE;
618 #undef FLICKER_MAX_EXPOSURE
619 #undef FLICKER_ALLOWABLE_OVER_EXPOSURE
620 #undef FLICKER_BRIGHTNESS_CONSTANT
622 /* initialise cam_data structure */
623 static void reset_camera_params(struct gspca_dev *gspca_dev)
625 struct sd *sd = (struct sd *) gspca_dev;
626 struct cam_params *params = &sd->params;
628 /* The following parameter values are the defaults from
629 * "Software Developer's Guide for CPiA Cameras". Any changes
630 * to the defaults are noted in comments. */
631 params->colourParams.brightness = BRIGHTNESS_DEF;
632 params->colourParams.contrast = CONTRAST_DEF;
633 params->colourParams.saturation = SATURATION_DEF;
634 params->exposure.gainMode = 4;
635 params->exposure.expMode = 2; /* AEC */
636 params->exposure.compMode = 1;
637 params->exposure.centreWeight = 1;
638 params->exposure.gain = 0;
639 params->exposure.fineExp = 0;
640 params->exposure.coarseExpLo = 185;
641 params->exposure.coarseExpHi = 0;
642 params->exposure.redComp = COMP_RED;
643 params->exposure.green1Comp = COMP_GREEN1;
644 params->exposure.green2Comp = COMP_GREEN2;
645 params->exposure.blueComp = COMP_BLUE;
646 params->colourBalance.balanceMode = 2; /* ACB */
647 params->colourBalance.redGain = 32;
648 params->colourBalance.greenGain = 6;
649 params->colourBalance.blueGain = 92;
650 params->apcor.gain1 = 0x18;
651 params->apcor.gain2 = 0x16;
652 params->apcor.gain4 = 0x24;
653 params->apcor.gain8 = 0x34;
654 params->vlOffset.gain1 = 20;
655 params->vlOffset.gain2 = 24;
656 params->vlOffset.gain4 = 26;
657 params->vlOffset.gain8 = 26;
658 params->compressionParams.hysteresis = 3;
659 params->compressionParams.threshMax = 11;
660 params->compressionParams.smallStep = 1;
661 params->compressionParams.largeStep = 3;
662 params->compressionParams.decimationHysteresis = 2;
663 params->compressionParams.frDiffStepThresh = 5;
664 params->compressionParams.qDiffStepThresh = 3;
665 params->compressionParams.decimationThreshMod = 2;
666 /* End of default values from Software Developer's Guide */
668 /* Set Sensor FPS to 15fps. This seems better than 30fps
669 * for indoor lighting. */
670 params->sensorFps.divisor = 1;
671 params->sensorFps.baserate = 1;
673 params->flickerControl.flickerMode = 0;
674 params->flickerControl.disabled = 1;
675 params->flickerControl.coarseJump =
676 flicker_jumps[sd->mainsFreq]
677 [params->sensorFps.baserate]
678 [params->sensorFps.divisor];
679 params->flickerControl.allowableOverExposure =
680 find_over_exposure(params->colourParams.brightness);
682 params->yuvThreshold.yThreshold = 6; /* From windows driver */
683 params->yuvThreshold.uvThreshold = 6; /* From windows driver */
685 params->format.subSample = SUBSAMPLE_420;
686 params->format.yuvOrder = YUVORDER_YUYV;
688 params->compression.mode = CPIA_COMPRESSION_AUTO;
689 params->compression.decimation = NO_DECIMATION;
691 params->compressionTarget.frTargeting = COMP_TARGET_DEF;
692 params->compressionTarget.targetFR = 15; /* From windows driver */
693 params->compressionTarget.targetQ = 5; /* From windows driver */
695 params->qx3.qx3_detected = 0;
696 params->qx3.toplight = 0;
697 params->qx3.bottomlight = 0;
698 params->qx3.button = 0;
699 params->qx3.cradled = 0;
702 static void printstatus(struct gspca_dev *gspca_dev, struct cam_params *params)
704 PDEBUG(D_PROBE, "status: %02x %02x %02x %02x %02x %02x %02x %02x",
705 params->status.systemState, params->status.grabState,
706 params->status.streamState, params->status.fatalError,
707 params->status.cmdError, params->status.debugFlags,
708 params->status.vpStatus, params->status.errorCode);
711 static int goto_low_power(struct gspca_dev *gspca_dev)
713 struct sd *sd = (struct sd *) gspca_dev;
716 ret = do_command(gspca_dev, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0);
720 ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
724 if (sd->params.status.systemState != LO_POWER_STATE) {
725 if (sd->params.status.systemState != WARM_BOOT_STATE) {
726 PERR("unexpected state after lo power cmd: %02x",
727 sd->params.status.systemState);
728 printstatus(gspca_dev, &sd->params);
733 PDEBUG(D_CONF, "camera now in LOW power state");
737 static int goto_high_power(struct gspca_dev *gspca_dev)
739 struct sd *sd = (struct sd *) gspca_dev;
742 ret = do_command(gspca_dev, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0);
746 msleep_interruptible(40); /* windows driver does it too */
748 if (signal_pending(current))
751 ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
755 if (sd->params.status.systemState != HI_POWER_STATE) {
756 PERR("unexpected state after hi power cmd: %02x",
757 sd->params.status.systemState);
758 printstatus(gspca_dev, &sd->params);
762 PDEBUG(D_CONF, "camera now in HIGH power state");
766 static int get_version_information(struct gspca_dev *gspca_dev)
771 ret = do_command(gspca_dev, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0);
776 return do_command(gspca_dev, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0);
779 static int save_camera_state(struct gspca_dev *gspca_dev)
783 ret = do_command(gspca_dev, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
787 return do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
790 static int command_setformat(struct gspca_dev *gspca_dev)
792 struct sd *sd = (struct sd *) gspca_dev;
795 ret = do_command(gspca_dev, CPIA_COMMAND_SetFormat,
796 sd->params.format.videoSize,
797 sd->params.format.subSample,
798 sd->params.format.yuvOrder, 0);
802 return do_command(gspca_dev, CPIA_COMMAND_SetROI,
803 sd->params.roi.colStart, sd->params.roi.colEnd,
804 sd->params.roi.rowStart, sd->params.roi.rowEnd);
807 static int command_setcolourparams(struct gspca_dev *gspca_dev)
809 struct sd *sd = (struct sd *) gspca_dev;
810 return do_command(gspca_dev, CPIA_COMMAND_SetColourParams,
811 sd->params.colourParams.brightness,
812 sd->params.colourParams.contrast,
813 sd->params.colourParams.saturation, 0);
816 static int command_setapcor(struct gspca_dev *gspca_dev)
818 struct sd *sd = (struct sd *) gspca_dev;
819 return do_command(gspca_dev, CPIA_COMMAND_SetApcor,
820 sd->params.apcor.gain1,
821 sd->params.apcor.gain2,
822 sd->params.apcor.gain4,
823 sd->params.apcor.gain8);
826 static int command_setvloffset(struct gspca_dev *gspca_dev)
828 struct sd *sd = (struct sd *) gspca_dev;
829 return do_command(gspca_dev, CPIA_COMMAND_SetVLOffset,
830 sd->params.vlOffset.gain1,
831 sd->params.vlOffset.gain2,
832 sd->params.vlOffset.gain4,
833 sd->params.vlOffset.gain8);
836 static int command_setexposure(struct gspca_dev *gspca_dev)
838 struct sd *sd = (struct sd *) gspca_dev;
841 ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
842 sd->params.exposure.gainMode,
844 sd->params.exposure.compMode,
845 sd->params.exposure.centreWeight,
846 sd->params.exposure.gain,
847 sd->params.exposure.fineExp,
848 sd->params.exposure.coarseExpLo,
849 sd->params.exposure.coarseExpHi,
850 sd->params.exposure.redComp,
851 sd->params.exposure.green1Comp,
852 sd->params.exposure.green2Comp,
853 sd->params.exposure.blueComp);
857 if (sd->params.exposure.expMode != 1) {
858 ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
860 sd->params.exposure.expMode,
862 sd->params.exposure.gain,
863 sd->params.exposure.fineExp,
864 sd->params.exposure.coarseExpLo,
865 sd->params.exposure.coarseExpHi,
872 static int command_setcolourbalance(struct gspca_dev *gspca_dev)
874 struct sd *sd = (struct sd *) gspca_dev;
876 if (sd->params.colourBalance.balanceMode == 1) {
879 ret = do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
881 sd->params.colourBalance.redGain,
882 sd->params.colourBalance.greenGain,
883 sd->params.colourBalance.blueGain);
887 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
890 if (sd->params.colourBalance.balanceMode == 2) {
891 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
894 if (sd->params.colourBalance.balanceMode == 3) {
895 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
902 static int command_setcompressiontarget(struct gspca_dev *gspca_dev)
904 struct sd *sd = (struct sd *) gspca_dev;
906 return do_command(gspca_dev, CPIA_COMMAND_SetCompressionTarget,
907 sd->params.compressionTarget.frTargeting,
908 sd->params.compressionTarget.targetFR,
909 sd->params.compressionTarget.targetQ, 0);
912 static int command_setyuvtresh(struct gspca_dev *gspca_dev)
914 struct sd *sd = (struct sd *) gspca_dev;
916 return do_command(gspca_dev, CPIA_COMMAND_SetYUVThresh,
917 sd->params.yuvThreshold.yThreshold,
918 sd->params.yuvThreshold.uvThreshold, 0, 0);
921 static int command_setcompressionparams(struct gspca_dev *gspca_dev)
923 struct sd *sd = (struct sd *) gspca_dev;
925 return do_command_extended(gspca_dev,
926 CPIA_COMMAND_SetCompressionParams,
928 sd->params.compressionParams.hysteresis,
929 sd->params.compressionParams.threshMax,
930 sd->params.compressionParams.smallStep,
931 sd->params.compressionParams.largeStep,
932 sd->params.compressionParams.decimationHysteresis,
933 sd->params.compressionParams.frDiffStepThresh,
934 sd->params.compressionParams.qDiffStepThresh,
935 sd->params.compressionParams.decimationThreshMod);
938 static int command_setcompression(struct gspca_dev *gspca_dev)
940 struct sd *sd = (struct sd *) gspca_dev;
942 return do_command(gspca_dev, CPIA_COMMAND_SetCompression,
943 sd->params.compression.mode,
944 sd->params.compression.decimation, 0, 0);
947 static int command_setsensorfps(struct gspca_dev *gspca_dev)
949 struct sd *sd = (struct sd *) gspca_dev;
951 return do_command(gspca_dev, CPIA_COMMAND_SetSensorFPS,
952 sd->params.sensorFps.divisor,
953 sd->params.sensorFps.baserate, 0, 0);
956 static int command_setflickerctrl(struct gspca_dev *gspca_dev)
958 struct sd *sd = (struct sd *) gspca_dev;
960 return do_command(gspca_dev, CPIA_COMMAND_SetFlickerCtrl,
961 sd->params.flickerControl.flickerMode,
962 sd->params.flickerControl.coarseJump,
963 sd->params.flickerControl.allowableOverExposure,
967 static int command_setecptiming(struct gspca_dev *gspca_dev)
969 struct sd *sd = (struct sd *) gspca_dev;
971 return do_command(gspca_dev, CPIA_COMMAND_SetECPTiming,
972 sd->params.ecpTiming, 0, 0, 0);
975 static int command_pause(struct gspca_dev *gspca_dev)
977 return do_command(gspca_dev, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
980 static int command_resume(struct gspca_dev *gspca_dev)
982 struct sd *sd = (struct sd *) gspca_dev;
984 return do_command(gspca_dev, CPIA_COMMAND_InitStreamCap,
985 0, sd->params.streamStartLine, 0, 0);
988 static int command_setlights(struct gspca_dev *gspca_dev)
990 struct sd *sd = (struct sd *) gspca_dev;
993 p1 = (sd->params.qx3.bottomlight == 0) << 1;
994 p2 = (sd->params.qx3.toplight == 0) << 3;
996 ret = do_command(gspca_dev, CPIA_COMMAND_WriteVCReg,
997 0x90, 0x8f, 0x50, 0);
1001 return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0,
1005 static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply)
1007 /* Everything in here is from the Windows driver */
1008 /* define for compgain calculation */
1010 #define COMPGAIN(base, curexp, newexp) \
1011 (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
1012 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1013 (u16)((float)curexp * (float)(u8)(curcomp + 128) / \
1014 (float)(u8)(basecomp - 128))
1016 /* equivalent functions without floating point math */
1017 #define COMPGAIN(base, curexp, newexp) \
1018 (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2 * newexp)))
1019 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1020 (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
1023 struct sd *sd = (struct sd *) gspca_dev;
1024 int currentexp = sd->params.exposure.coarseExpLo +
1025 sd->params.exposure.coarseExpHi * 256;
1029 int cj = sd->params.flickerControl.coarseJump;
1030 sd->params.flickerControl.flickerMode = 1;
1031 sd->params.flickerControl.disabled = 0;
1032 if (sd->params.exposure.expMode != 2) {
1033 sd->params.exposure.expMode = 2;
1034 sd->exposure_status = EXPOSURE_NORMAL;
1036 if (sd->params.exposure.gain >= BITS_PER_TYPE(currentexp))
1038 currentexp = currentexp << sd->params.exposure.gain;
1039 sd->params.exposure.gain = 0;
1040 /* round down current exposure to nearest value */
1041 startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj;
1044 startexp = (startexp * cj) - 1;
1045 if (FIRMWARE_VERSION(1, 2))
1046 while (startexp > MAX_EXP_102)
1049 while (startexp > MAX_EXP)
1051 sd->params.exposure.coarseExpLo = startexp & 0xff;
1052 sd->params.exposure.coarseExpHi = startexp >> 8;
1053 if (currentexp > startexp) {
1054 if (currentexp > (2 * startexp))
1055 currentexp = 2 * startexp;
1056 sd->params.exposure.redComp =
1057 COMPGAIN(COMP_RED, currentexp, startexp);
1058 sd->params.exposure.green1Comp =
1059 COMPGAIN(COMP_GREEN1, currentexp, startexp);
1060 sd->params.exposure.green2Comp =
1061 COMPGAIN(COMP_GREEN2, currentexp, startexp);
1062 sd->params.exposure.blueComp =
1063 COMPGAIN(COMP_BLUE, currentexp, startexp);
1065 sd->params.exposure.redComp = COMP_RED;
1066 sd->params.exposure.green1Comp = COMP_GREEN1;
1067 sd->params.exposure.green2Comp = COMP_GREEN2;
1068 sd->params.exposure.blueComp = COMP_BLUE;
1070 if (FIRMWARE_VERSION(1, 2))
1071 sd->params.exposure.compMode = 0;
1073 sd->params.exposure.compMode = 1;
1075 sd->params.apcor.gain1 = 0x18;
1076 sd->params.apcor.gain2 = 0x18;
1077 sd->params.apcor.gain4 = 0x16;
1078 sd->params.apcor.gain8 = 0x14;
1080 sd->params.flickerControl.flickerMode = 0;
1081 sd->params.flickerControl.disabled = 1;
1082 /* Average equivalent coarse for each comp channel */
1083 startexp = EXP_FROM_COMP(COMP_RED,
1084 sd->params.exposure.redComp, currentexp);
1085 startexp += EXP_FROM_COMP(COMP_GREEN1,
1086 sd->params.exposure.green1Comp, currentexp);
1087 startexp += EXP_FROM_COMP(COMP_GREEN2,
1088 sd->params.exposure.green2Comp, currentexp);
1089 startexp += EXP_FROM_COMP(COMP_BLUE,
1090 sd->params.exposure.blueComp, currentexp);
1091 startexp = startexp >> 2;
1092 while (startexp > MAX_EXP && sd->params.exposure.gain <
1093 sd->params.exposure.gainMode - 1) {
1094 startexp = startexp >> 1;
1095 ++sd->params.exposure.gain;
1097 if (FIRMWARE_VERSION(1, 2) && startexp > MAX_EXP_102)
1098 startexp = MAX_EXP_102;
1099 if (startexp > MAX_EXP)
1101 sd->params.exposure.coarseExpLo = startexp & 0xff;
1102 sd->params.exposure.coarseExpHi = startexp >> 8;
1103 sd->params.exposure.redComp = COMP_RED;
1104 sd->params.exposure.green1Comp = COMP_GREEN1;
1105 sd->params.exposure.green2Comp = COMP_GREEN2;
1106 sd->params.exposure.blueComp = COMP_BLUE;
1107 sd->params.exposure.compMode = 1;
1108 sd->params.apcor.gain1 = 0x18;
1109 sd->params.apcor.gain2 = 0x16;
1110 sd->params.apcor.gain4 = 0x24;
1111 sd->params.apcor.gain8 = 0x34;
1113 sd->params.vlOffset.gain1 = 20;
1114 sd->params.vlOffset.gain2 = 24;
1115 sd->params.vlOffset.gain4 = 26;
1116 sd->params.vlOffset.gain8 = 26;
1119 ret = command_setexposure(gspca_dev);
1123 ret = command_setapcor(gspca_dev);
1127 ret = command_setvloffset(gspca_dev);
1131 ret = command_setflickerctrl(gspca_dev);
1137 #undef EXP_FROM_COMP
1141 /* monitor the exposure and adjust the sensor frame rate if needed */
1142 static void monitor_exposure(struct gspca_dev *gspca_dev)
1144 struct sd *sd = (struct sd *) gspca_dev;
1145 u8 exp_acc, bcomp, cmd[8];
1146 int ret, light_exp, dark_exp, very_dark_exp;
1147 int old_exposure, new_exposure, framerate;
1148 int setfps = 0, setexp = 0, setflicker = 0;
1150 /* get necessary stats and register settings from camera */
1151 /* do_command can't handle this, so do it ourselves */
1152 cmd[0] = CPIA_COMMAND_ReadVPRegs >> 8;
1153 cmd[1] = CPIA_COMMAND_ReadVPRegs & 0xff;
1160 ret = cpia_usb_transferCmd(gspca_dev, cmd);
1162 pr_err("ReadVPRegs(30,4,9,8) - failed: %d\n", ret);
1165 exp_acc = gspca_dev->usb_buf[0];
1166 bcomp = gspca_dev->usb_buf[1];
1168 light_exp = sd->params.colourParams.brightness +
1169 TC - 50 + EXP_ACC_LIGHT;
1170 if (light_exp > 255)
1172 dark_exp = sd->params.colourParams.brightness +
1173 TC - 50 - EXP_ACC_DARK;
1176 very_dark_exp = dark_exp / 2;
1178 old_exposure = sd->params.exposure.coarseExpHi * 256 +
1179 sd->params.exposure.coarseExpLo;
1181 if (!sd->params.flickerControl.disabled) {
1182 /* Flicker control on */
1183 int max_comp = FIRMWARE_VERSION(1, 2) ? MAX_COMP :
1185 bcomp += 128; /* decode */
1186 if (bcomp >= max_comp && exp_acc < dark_exp) {
1188 if (exp_acc < very_dark_exp) {
1190 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1191 ++sd->exposure_count;
1193 sd->exposure_status =
1195 sd->exposure_count = 1;
1199 if (sd->exposure_status == EXPOSURE_DARK)
1200 ++sd->exposure_count;
1202 sd->exposure_status = EXPOSURE_DARK;
1203 sd->exposure_count = 1;
1206 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1208 if (old_exposure <= VERY_LOW_EXP) {
1210 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1211 ++sd->exposure_count;
1213 sd->exposure_status =
1214 EXPOSURE_VERY_LIGHT;
1215 sd->exposure_count = 1;
1219 if (sd->exposure_status == EXPOSURE_LIGHT)
1220 ++sd->exposure_count;
1222 sd->exposure_status = EXPOSURE_LIGHT;
1223 sd->exposure_count = 1;
1227 /* not dark or light */
1228 sd->exposure_status = EXPOSURE_NORMAL;
1231 /* Flicker control off */
1232 if (old_exposure >= MAX_EXP && exp_acc < dark_exp) {
1234 if (exp_acc < very_dark_exp) {
1236 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1237 ++sd->exposure_count;
1239 sd->exposure_status =
1241 sd->exposure_count = 1;
1245 if (sd->exposure_status == EXPOSURE_DARK)
1246 ++sd->exposure_count;
1248 sd->exposure_status = EXPOSURE_DARK;
1249 sd->exposure_count = 1;
1252 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1254 if (old_exposure <= VERY_LOW_EXP) {
1256 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1257 ++sd->exposure_count;
1259 sd->exposure_status =
1260 EXPOSURE_VERY_LIGHT;
1261 sd->exposure_count = 1;
1265 if (sd->exposure_status == EXPOSURE_LIGHT)
1266 ++sd->exposure_count;
1268 sd->exposure_status = EXPOSURE_LIGHT;
1269 sd->exposure_count = 1;
1273 /* not dark or light */
1274 sd->exposure_status = EXPOSURE_NORMAL;
1278 framerate = atomic_read(&sd->fps);
1279 if (framerate > 30 || framerate < 1)
1282 if (!sd->params.flickerControl.disabled) {
1283 /* Flicker control on */
1284 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1285 sd->exposure_status == EXPOSURE_DARK) &&
1286 sd->exposure_count >= DARK_TIME * framerate &&
1287 sd->params.sensorFps.divisor < 2) {
1289 /* dark for too long */
1290 ++sd->params.sensorFps.divisor;
1293 sd->params.flickerControl.coarseJump =
1294 flicker_jumps[sd->mainsFreq]
1295 [sd->params.sensorFps.baserate]
1296 [sd->params.sensorFps.divisor];
1299 new_exposure = sd->params.flickerControl.coarseJump-1;
1300 while (new_exposure < old_exposure / 2)
1302 sd->params.flickerControl.coarseJump;
1303 sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1304 sd->params.exposure.coarseExpHi = new_exposure >> 8;
1306 sd->exposure_status = EXPOSURE_NORMAL;
1307 PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
1309 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1310 sd->exposure_status == EXPOSURE_LIGHT) &&
1311 sd->exposure_count >= LIGHT_TIME * framerate &&
1312 sd->params.sensorFps.divisor > 0) {
1314 /* light for too long */
1315 int max_exp = FIRMWARE_VERSION(1, 2) ? MAX_EXP_102 :
1317 --sd->params.sensorFps.divisor;
1320 sd->params.flickerControl.coarseJump =
1321 flicker_jumps[sd->mainsFreq]
1322 [sd->params.sensorFps.baserate]
1323 [sd->params.sensorFps.divisor];
1326 new_exposure = sd->params.flickerControl.coarseJump-1;
1327 while (new_exposure < 2 * old_exposure &&
1329 sd->params.flickerControl.coarseJump < max_exp)
1331 sd->params.flickerControl.coarseJump;
1332 sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1333 sd->params.exposure.coarseExpHi = new_exposure >> 8;
1335 sd->exposure_status = EXPOSURE_NORMAL;
1336 PDEBUG(D_CONF, "Automatically increasing sensor_fps");
1339 /* Flicker control off */
1340 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1341 sd->exposure_status == EXPOSURE_DARK) &&
1342 sd->exposure_count >= DARK_TIME * framerate &&
1343 sd->params.sensorFps.divisor < 2) {
1345 /* dark for too long */
1346 ++sd->params.sensorFps.divisor;
1349 if (sd->params.exposure.gain > 0) {
1350 --sd->params.exposure.gain;
1353 sd->exposure_status = EXPOSURE_NORMAL;
1354 PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
1356 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1357 sd->exposure_status == EXPOSURE_LIGHT) &&
1358 sd->exposure_count >= LIGHT_TIME * framerate &&
1359 sd->params.sensorFps.divisor > 0) {
1361 /* light for too long */
1362 --sd->params.sensorFps.divisor;
1365 if (sd->params.exposure.gain <
1366 sd->params.exposure.gainMode - 1) {
1367 ++sd->params.exposure.gain;
1370 sd->exposure_status = EXPOSURE_NORMAL;
1371 PDEBUG(D_CONF, "Automatically increasing sensor_fps");
1376 command_setexposure(gspca_dev);
1379 command_setsensorfps(gspca_dev);
1382 command_setflickerctrl(gspca_dev);
1385 /*-----------------------------------------------------------------*/
1386 /* if flicker is switched off, this function switches it back on.It checks,
1387 however, that conditions are suitable before restarting it.
1388 This should only be called for firmware version 1.2.
1390 It also adjust the colour balance when an exposure step is detected - as
1391 long as flicker is running
1393 static void restart_flicker(struct gspca_dev *gspca_dev)
1395 struct sd *sd = (struct sd *) gspca_dev;
1396 int cam_exposure, old_exp;
1398 if (!FIRMWARE_VERSION(1, 2))
1401 cam_exposure = atomic_read(&sd->cam_exposure);
1403 if (sd->params.flickerControl.flickerMode == 0 ||
1407 old_exp = sd->params.exposure.coarseExpLo +
1408 sd->params.exposure.coarseExpHi*256;
1410 see how far away camera exposure is from a valid
1411 flicker exposure value
1413 cam_exposure %= sd->params.flickerControl.coarseJump;
1414 if (!sd->params.flickerControl.disabled &&
1415 cam_exposure <= sd->params.flickerControl.coarseJump - 3) {
1416 /* Flicker control auto-disabled */
1417 sd->params.flickerControl.disabled = 1;
1420 if (sd->params.flickerControl.disabled &&
1421 old_exp > sd->params.flickerControl.coarseJump +
1422 ROUND_UP_EXP_FOR_FLICKER) {
1423 /* exposure is now high enough to switch
1424 flicker control back on */
1425 set_flicker(gspca_dev, 1, 1);
1429 /* this function is called at probe time */
1430 static int sd_config(struct gspca_dev *gspca_dev,
1431 const struct usb_device_id *id)
1433 struct sd *sd = (struct sd *) gspca_dev;
1436 sd->mainsFreq = FREQ_DEF == V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
1437 reset_camera_params(gspca_dev);
1439 PDEBUG(D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)",
1440 id->idVendor, id->idProduct);
1442 cam = &gspca_dev->cam;
1443 cam->cam_mode = mode;
1444 cam->nmodes = ARRAY_SIZE(mode);
1446 goto_low_power(gspca_dev);
1447 /* Check the firmware version. */
1448 sd->params.version.firmwareVersion = 0;
1449 get_version_information(gspca_dev);
1450 if (sd->params.version.firmwareVersion != 1) {
1451 PERR("only firmware version 1 is supported (got: %d)",
1452 sd->params.version.firmwareVersion);
1456 /* A bug in firmware 1-02 limits gainMode to 2 */
1457 if (sd->params.version.firmwareRevision <= 2 &&
1458 sd->params.exposure.gainMode > 2) {
1459 sd->params.exposure.gainMode = 2;
1462 /* set QX3 detected flag */
1463 sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 &&
1464 sd->params.pnpID.product == 0x0001);
1468 /* -- start the camera -- */
1469 static int sd_start(struct gspca_dev *gspca_dev)
1471 struct sd *sd = (struct sd *) gspca_dev;
1474 /* Start the camera in low power mode */
1475 if (goto_low_power(gspca_dev)) {
1476 if (sd->params.status.systemState != WARM_BOOT_STATE) {
1477 PERR("unexpected systemstate: %02x",
1478 sd->params.status.systemState);
1479 printstatus(gspca_dev, &sd->params);
1483 /* FIXME: this is just dirty trial and error */
1484 ret = goto_high_power(gspca_dev);
1488 ret = do_command(gspca_dev, CPIA_COMMAND_DiscardFrame,
1493 ret = goto_low_power(gspca_dev);
1498 /* procedure described in developer's guide p3-28 */
1500 /* Check the firmware version. */
1501 sd->params.version.firmwareVersion = 0;
1502 get_version_information(gspca_dev);
1504 /* The fatal error checking should be done after
1505 * the camera powers up (developer's guide p 3-38) */
1507 /* Set streamState before transition to high power to avoid bug
1508 * in firmware 1-02 */
1509 ret = do_command(gspca_dev, CPIA_COMMAND_ModifyCameraStatus,
1510 STREAMSTATE, 0, STREAM_NOT_READY, 0);
1515 ret = goto_high_power(gspca_dev);
1519 /* Check the camera status */
1520 ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1524 if (sd->params.status.fatalError) {
1525 PERR("fatal_error: %04x, vp_status: %04x",
1526 sd->params.status.fatalError, sd->params.status.vpStatus);
1530 /* VPVersion can't be retrieved before the camera is in HiPower,
1531 * so get it here instead of in get_version_information. */
1532 ret = do_command(gspca_dev, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0);
1536 /* Determine video mode settings */
1537 sd->params.streamStartLine = 120;
1539 priv = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1540 if (priv & 0x01) { /* crop */
1541 sd->params.roi.colStart = 2;
1542 sd->params.roi.rowStart = 6;
1544 sd->params.roi.colStart = 0;
1545 sd->params.roi.rowStart = 0;
1548 if (priv & 0x02) { /* quarter */
1549 sd->params.format.videoSize = VIDEOSIZE_QCIF;
1550 sd->params.roi.colStart /= 2;
1551 sd->params.roi.rowStart /= 2;
1552 sd->params.streamStartLine /= 2;
1554 sd->params.format.videoSize = VIDEOSIZE_CIF;
1556 sd->params.roi.colEnd = sd->params.roi.colStart +
1557 (gspca_dev->pixfmt.width >> 3);
1558 sd->params.roi.rowEnd = sd->params.roi.rowStart +
1559 (gspca_dev->pixfmt.height >> 2);
1561 /* And now set the camera to a known state */
1562 ret = do_command(gspca_dev, CPIA_COMMAND_SetGrabMode,
1563 CPIA_GRAB_CONTINEOUS, 0, 0, 0);
1566 /* We start with compression disabled, as we need one uncompressed
1567 frame to handle later compressed frames */
1568 ret = do_command(gspca_dev, CPIA_COMMAND_SetCompression,
1569 CPIA_COMPRESSION_NONE,
1570 NO_DECIMATION, 0, 0);
1573 ret = command_setcompressiontarget(gspca_dev);
1576 ret = command_setcolourparams(gspca_dev);
1579 ret = command_setformat(gspca_dev);
1582 ret = command_setyuvtresh(gspca_dev);
1585 ret = command_setecptiming(gspca_dev);
1588 ret = command_setcompressionparams(gspca_dev);
1591 ret = command_setexposure(gspca_dev);
1594 ret = command_setcolourbalance(gspca_dev);
1597 ret = command_setsensorfps(gspca_dev);
1600 ret = command_setapcor(gspca_dev);
1603 ret = command_setflickerctrl(gspca_dev);
1606 ret = command_setvloffset(gspca_dev);
1611 ret = command_resume(gspca_dev);
1615 /* Wait 6 frames before turning compression on for the sensor to get
1616 all settings and AEC/ACB to settle */
1617 sd->first_frame = 6;
1618 sd->exposure_status = EXPOSURE_NORMAL;
1619 sd->exposure_count = 0;
1620 atomic_set(&sd->cam_exposure, 0);
1621 atomic_set(&sd->fps, 0);
1626 static void sd_stopN(struct gspca_dev *gspca_dev)
1628 struct sd *sd __maybe_unused = (struct sd *) gspca_dev;
1630 command_pause(gspca_dev);
1632 /* save camera state for later open (developers guide ch 3.5.3) */
1633 save_camera_state(gspca_dev);
1636 goto_low_power(gspca_dev);
1638 /* Update the camera status */
1639 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1641 #if IS_ENABLED(CONFIG_INPUT)
1642 /* If the last button state is pressed, release it now! */
1643 if (sd->params.qx3.button) {
1644 /* The camera latch will hold the pressed state until we reset
1645 the latch, so we do not reset sd->params.qx3.button now, to
1646 avoid a false keypress being reported the next sd_start */
1647 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1648 input_sync(gspca_dev->input_dev);
1653 /* this function is called at probe and resume time */
1654 static int sd_init(struct gspca_dev *gspca_dev)
1656 struct sd *sd = (struct sd *) gspca_dev;
1659 /* Start / Stop the camera to make sure we are talking to
1660 a supported camera, and to get some information from it
1662 ret = sd_start(gspca_dev);
1666 /* Ensure the QX3 illuminators' states are restored upon resume,
1667 or disable the illuminator controls, if this isn't a QX3 */
1668 if (sd->params.qx3.qx3_detected)
1669 command_setlights(gspca_dev);
1671 sd_stopN(gspca_dev);
1673 PDEBUG(D_PROBE, "CPIA Version: %d.%02d (%d.%d)",
1674 sd->params.version.firmwareVersion,
1675 sd->params.version.firmwareRevision,
1676 sd->params.version.vcVersion,
1677 sd->params.version.vcRevision);
1678 PDEBUG(D_PROBE, "CPIA PnP-ID: %04x:%04x:%04x",
1679 sd->params.pnpID.vendor, sd->params.pnpID.product,
1680 sd->params.pnpID.deviceRevision);
1681 PDEBUG(D_PROBE, "VP-Version: %d.%d %04x",
1682 sd->params.vpVersion.vpVersion,
1683 sd->params.vpVersion.vpRevision,
1684 sd->params.vpVersion.cameraHeadID);
1689 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1693 struct sd *sd = (struct sd *) gspca_dev;
1697 data[0] == MAGIC_0 && data[1] == MAGIC_1 &&
1698 data[16] == sd->params.format.videoSize &&
1699 data[17] == sd->params.format.subSample &&
1700 data[18] == sd->params.format.yuvOrder &&
1701 data[24] == sd->params.roi.colStart &&
1702 data[25] == sd->params.roi.colEnd &&
1703 data[26] == sd->params.roi.rowStart &&
1704 data[27] == sd->params.roi.rowEnd) {
1707 atomic_set(&sd->cam_exposure, data[39] * 2);
1708 atomic_set(&sd->fps, data[41]);
1710 /* Check for proper EOF for last frame */
1711 image = gspca_dev->image;
1712 if (image != NULL &&
1713 gspca_dev->image_len > 4 &&
1714 image[gspca_dev->image_len - 4] == 0xff &&
1715 image[gspca_dev->image_len - 3] == 0xff &&
1716 image[gspca_dev->image_len - 2] == 0xff &&
1717 image[gspca_dev->image_len - 1] == 0xff)
1718 gspca_frame_add(gspca_dev, LAST_PACKET,
1721 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
1725 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1728 static void sd_dq_callback(struct gspca_dev *gspca_dev)
1730 struct sd *sd = (struct sd *) gspca_dev;
1732 /* Set the normal compression settings once we have captured a
1733 few uncompressed frames (and AEC has hopefully settled) */
1734 if (sd->first_frame) {
1736 if (sd->first_frame == 0)
1737 command_setcompression(gspca_dev);
1740 /* Switch flicker control back on if it got turned off */
1741 restart_flicker(gspca_dev);
1743 /* If AEC is enabled, monitor the exposure and
1744 adjust the sensor frame rate if needed */
1745 if (sd->params.exposure.expMode == 2)
1746 monitor_exposure(gspca_dev);
1748 /* Update our knowledge of the camera state */
1749 do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
1750 do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
1753 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1755 struct gspca_dev *gspca_dev =
1756 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1757 struct sd *sd = (struct sd *)gspca_dev;
1759 gspca_dev->usb_err = 0;
1761 if (!gspca_dev->streaming && ctrl->id != V4L2_CID_POWER_LINE_FREQUENCY)
1765 case V4L2_CID_BRIGHTNESS:
1766 sd->params.colourParams.brightness = ctrl->val;
1767 sd->params.flickerControl.allowableOverExposure =
1768 find_over_exposure(sd->params.colourParams.brightness);
1769 gspca_dev->usb_err = command_setcolourparams(gspca_dev);
1770 if (!gspca_dev->usb_err)
1771 gspca_dev->usb_err = command_setflickerctrl(gspca_dev);
1773 case V4L2_CID_CONTRAST:
1774 sd->params.colourParams.contrast = ctrl->val;
1775 gspca_dev->usb_err = command_setcolourparams(gspca_dev);
1777 case V4L2_CID_SATURATION:
1778 sd->params.colourParams.saturation = ctrl->val;
1779 gspca_dev->usb_err = command_setcolourparams(gspca_dev);
1781 case V4L2_CID_POWER_LINE_FREQUENCY:
1782 sd->mainsFreq = ctrl->val == V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
1783 sd->params.flickerControl.coarseJump =
1784 flicker_jumps[sd->mainsFreq]
1785 [sd->params.sensorFps.baserate]
1786 [sd->params.sensorFps.divisor];
1788 gspca_dev->usb_err = set_flicker(gspca_dev,
1789 ctrl->val != V4L2_CID_POWER_LINE_FREQUENCY_DISABLED,
1790 gspca_dev->streaming);
1792 case V4L2_CID_ILLUMINATORS_1:
1793 sd->params.qx3.bottomlight = ctrl->val;
1794 gspca_dev->usb_err = command_setlights(gspca_dev);
1796 case V4L2_CID_ILLUMINATORS_2:
1797 sd->params.qx3.toplight = ctrl->val;
1798 gspca_dev->usb_err = command_setlights(gspca_dev);
1800 case CPIA1_CID_COMP_TARGET:
1801 sd->params.compressionTarget.frTargeting = ctrl->val;
1802 gspca_dev->usb_err = command_setcompressiontarget(gspca_dev);
1805 return gspca_dev->usb_err;
1808 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1809 .s_ctrl = sd_s_ctrl,
1812 static int sd_init_controls(struct gspca_dev *gspca_dev)
1814 struct sd *sd = (struct sd *)gspca_dev;
1815 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1816 static const char * const comp_target_menu[] = {
1821 static const struct v4l2_ctrl_config comp_target = {
1822 .ops = &sd_ctrl_ops,
1823 .id = CPIA1_CID_COMP_TARGET,
1824 .type = V4L2_CTRL_TYPE_MENU,
1825 .name = "Compression Target",
1826 .qmenu = comp_target_menu,
1828 .def = COMP_TARGET_DEF,
1831 gspca_dev->vdev.ctrl_handler = hdl;
1832 v4l2_ctrl_handler_init(hdl, 7);
1833 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1834 V4L2_CID_BRIGHTNESS, 0, 100, 1, BRIGHTNESS_DEF);
1835 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1836 V4L2_CID_CONTRAST, 0, 96, 8, CONTRAST_DEF);
1837 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1838 V4L2_CID_SATURATION, 0, 100, 1, SATURATION_DEF);
1839 sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
1840 V4L2_CID_POWER_LINE_FREQUENCY,
1841 V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
1843 if (sd->params.qx3.qx3_detected) {
1844 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1845 V4L2_CID_ILLUMINATORS_1, 0, 1, 1,
1846 ILLUMINATORS_1_DEF);
1847 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1848 V4L2_CID_ILLUMINATORS_2, 0, 1, 1,
1849 ILLUMINATORS_2_DEF);
1851 v4l2_ctrl_new_custom(hdl, &comp_target, NULL);
1854 pr_err("Could not initialize controls\n");
1860 /* sub-driver description */
1861 static const struct sd_desc sd_desc = {
1862 .name = MODULE_NAME,
1863 .config = sd_config,
1865 .init_controls = sd_init_controls,
1868 .dq_callback = sd_dq_callback,
1869 .pkt_scan = sd_pkt_scan,
1870 #if IS_ENABLED(CONFIG_INPUT)
1875 /* -- module initialisation -- */
1876 static const struct usb_device_id device_table[] = {
1877 {USB_DEVICE(0x0553, 0x0002)},
1878 {USB_DEVICE(0x0813, 0x0001)},
1881 MODULE_DEVICE_TABLE(usb, device_table);
1883 /* -- device connect -- */
1884 static int sd_probe(struct usb_interface *intf,
1885 const struct usb_device_id *id)
1887 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1891 static struct usb_driver sd_driver = {
1892 .name = MODULE_NAME,
1893 .id_table = device_table,
1895 .disconnect = gspca_disconnect,
1897 .suspend = gspca_suspend,
1898 .resume = gspca_resume,
1899 .reset_resume = gspca_resume,
1903 module_usb_driver(sd_driver);