1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * cpia CPiA (1) gspca driver
5 * Copyright (C) 2010-2011 Hans de Goede <hdegoede@redhat.com>
7 * This module is adapted from the in kernel v4l1 cpia driver which is :
9 * (C) Copyright 1999-2000 Peter Pregler
10 * (C) Copyright 1999-2000 Scott J. Bertin
11 * (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.com>
12 * (C) Copyright 2000 STMicroelectronics
15 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17 #define MODULE_NAME "cpia1"
19 #include <linux/input.h>
20 #include <linux/sched/signal.h>
24 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
25 MODULE_DESCRIPTION("Vision CPiA");
26 MODULE_LICENSE("GPL");
28 /* constant value's */
33 #define VIDEOSIZE_QCIF 0 /* 176x144 */
34 #define VIDEOSIZE_CIF 1 /* 352x288 */
35 #define SUBSAMPLE_420 0
36 #define SUBSAMPLE_422 1
37 #define YUVORDER_YUYV 0
38 #define YUVORDER_UYVY 1
39 #define NOT_COMPRESSED 0
41 #define NO_DECIMATION 0
42 #define DECIMATION_ENAB 1
43 #define EOI 0xff /* End Of Image */
44 #define EOL 0xfd /* End Of Line */
45 #define FRAME_HEADER_SIZE 64
47 /* Image grab modes */
48 #define CPIA_GRAB_SINGLE 0
49 #define CPIA_GRAB_CONTINEOUS 1
51 /* Compression parameters */
52 #define CPIA_COMPRESSION_NONE 0
53 #define CPIA_COMPRESSION_AUTO 1
54 #define CPIA_COMPRESSION_MANUAL 2
55 #define CPIA_COMPRESSION_TARGET_QUALITY 0
56 #define CPIA_COMPRESSION_TARGET_FRAMERATE 1
58 /* Return offsets for GetCameraState */
69 #define UNINITIALISED_STATE 0
70 #define PASS_THROUGH_STATE 1
71 #define LO_POWER_STATE 2
72 #define HI_POWER_STATE 3
73 #define WARM_BOOT_STATE 4
81 #define STREAM_NOT_READY 0
82 #define STREAM_READY 1
84 #define STREAM_PAUSED 3
85 #define STREAM_FINISHED 4
87 /* Fatal Error, CmdError, and DebugFlags */
90 #define INT_CTRL_FLAG 4
91 #define PROCESS_FLAG 8
93 #define VP_CTRL_FLAG 32
94 #define CAPTURE_FLAG 64
95 #define DEBUG_FLAG 128
98 #define VP_STATE_OK 0x00
100 #define VP_STATE_FAILED_VIDEOINIT 0x01
101 #define VP_STATE_FAILED_AECACBINIT 0x02
102 #define VP_STATE_AEC_MAX 0x04
103 #define VP_STATE_ACB_BMAX 0x08
105 #define VP_STATE_ACB_RMIN 0x10
106 #define VP_STATE_ACB_GMIN 0x20
107 #define VP_STATE_ACB_RMAX 0x40
108 #define VP_STATE_ACB_GMAX 0x80
110 /* default (minimum) compensation values */
112 #define COMP_GREEN1 214
113 #define COMP_GREEN2 COMP_GREEN1
114 #define COMP_BLUE 230
116 /* exposure status */
117 #define EXPOSURE_VERY_LIGHT 0
118 #define EXPOSURE_LIGHT 1
119 #define EXPOSURE_NORMAL 2
120 #define EXPOSURE_DARK 3
121 #define EXPOSURE_VERY_DARK 4
123 #define CPIA_MODULE_CPIA (0 << 5)
124 #define CPIA_MODULE_SYSTEM (1 << 5)
125 #define CPIA_MODULE_VP_CTRL (5 << 5)
126 #define CPIA_MODULE_CAPTURE (6 << 5)
127 #define CPIA_MODULE_DEBUG (7 << 5)
129 #define INPUT (DATA_IN << 8)
130 #define OUTPUT (DATA_OUT << 8)
132 #define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)
133 #define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)
134 #define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)
135 #define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)
136 #define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)
137 #define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)
138 #define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)
139 #define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)
141 #define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)
142 #define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)
143 #define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)
144 #define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)
145 #define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)
146 #define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)
147 #define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)
148 #define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)
149 #define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)
150 #define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)
151 #define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)
152 #define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)
153 #define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
155 #define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
156 #define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)
157 #define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
158 #define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
159 #define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
160 #define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)
161 #define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)
162 #define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)
163 #define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)
164 #define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)
165 #define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)
166 #define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)
167 #define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)
168 #define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)
169 #define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)
170 #define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)
171 #define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)
173 #define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)
174 #define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)
175 #define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)
176 #define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)
177 #define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)
178 #define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)
179 #define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)
180 #define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)
181 #define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)
182 #define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)
183 #define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
184 #define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
185 #define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
186 #define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
187 #define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)
189 #define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
190 #define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
191 #define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)
192 #define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)
193 #define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
194 #define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
195 #define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
196 #define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)
198 #define ROUND_UP_EXP_FOR_FLICKER 15
200 /* Constants for automatic frame rate adjustment */
202 #define MAX_EXP_102 255
204 #define VERY_LOW_EXP 70
206 #define EXP_ACC_DARK 50
207 #define EXP_ACC_LIGHT 90
208 #define HIGH_COMP_102 160
213 #define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \
214 sd->params.version.firmwareRevision == (y))
216 #define CPIA1_CID_COMP_TARGET (V4L2_CTRL_CLASS_USER + 0x1000)
217 #define BRIGHTNESS_DEF 50
218 #define CONTRAST_DEF 48
219 #define SATURATION_DEF 50
220 #define FREQ_DEF V4L2_CID_POWER_LINE_FREQUENCY_50HZ
221 #define ILLUMINATORS_1_DEF 0
222 #define ILLUMINATORS_2_DEF 0
223 #define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY
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 struct v4l2_ctrl
*freq
;
361 u8 mainsFreq
; /* 0 = 50hz, 1 = 60hz */
365 static const struct v4l2_pix_format mode
[] = {
366 {160, 120, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
367 /* The sizeimage is trial and error, as with low framerates
368 the camera will pad out usb frames, making the image
369 data larger then strictly necessary */
372 .colorspace
= V4L2_COLORSPACE_SRGB
,
374 {176, 144, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
377 .colorspace
= V4L2_COLORSPACE_SRGB
,
379 {320, 240, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
382 .colorspace
= V4L2_COLORSPACE_SRGB
,
384 {352, 288, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
387 .colorspace
= V4L2_COLORSPACE_SRGB
,
391 /**********************************************************************
395 **********************************************************************/
397 static int cpia_usb_transferCmd(struct gspca_dev
*gspca_dev
, u8
*command
)
401 int ret
, databytes
= command
[6] | (command
[7] << 8);
402 /* Sometimes we see spurious EPIPE errors */
405 if (command
[0] == DATA_IN
) {
406 pipe
= usb_rcvctrlpipe(gspca_dev
->dev
, 0);
407 requesttype
= USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
;
408 } else if (command
[0] == DATA_OUT
) {
409 pipe
= usb_sndctrlpipe(gspca_dev
->dev
, 0);
410 requesttype
= USB_TYPE_VENDOR
| USB_RECIP_DEVICE
;
412 gspca_err(gspca_dev
, "Unexpected first byte of command: %x\n",
418 ret
= usb_control_msg(gspca_dev
->dev
, pipe
,
421 command
[2] | (command
[3] << 8),
422 command
[4] | (command
[5] << 8),
423 gspca_dev
->usb_buf
, databytes
, 1000);
426 pr_err("usb_control_msg %02x, error %d\n", command
[1], ret
);
428 if (ret
== -EPIPE
&& retries
> 0) {
433 return (ret
< 0) ? ret
: 0;
436 /* send an arbitrary command to the camera */
437 static int do_command(struct gspca_dev
*gspca_dev
, u16 command
,
438 u8 a
, u8 b
, u8 c
, u8 d
)
440 struct sd
*sd
= (struct sd
*) gspca_dev
;
445 case CPIA_COMMAND_GetCPIAVersion
:
446 case CPIA_COMMAND_GetPnPID
:
447 case CPIA_COMMAND_GetCameraStatus
:
448 case CPIA_COMMAND_GetVPVersion
:
449 case CPIA_COMMAND_GetColourParams
:
450 case CPIA_COMMAND_GetColourBalance
:
451 case CPIA_COMMAND_GetExposure
:
454 case CPIA_COMMAND_ReadMCPorts
:
455 case CPIA_COMMAND_ReadVCRegs
:
463 cmd
[0] = command
>> 8;
464 cmd
[1] = command
& 0xff;
472 ret
= cpia_usb_transferCmd(gspca_dev
, cmd
);
477 case CPIA_COMMAND_GetCPIAVersion
:
478 sd
->params
.version
.firmwareVersion
= gspca_dev
->usb_buf
[0];
479 sd
->params
.version
.firmwareRevision
= gspca_dev
->usb_buf
[1];
480 sd
->params
.version
.vcVersion
= gspca_dev
->usb_buf
[2];
481 sd
->params
.version
.vcRevision
= gspca_dev
->usb_buf
[3];
483 case CPIA_COMMAND_GetPnPID
:
484 sd
->params
.pnpID
.vendor
=
485 gspca_dev
->usb_buf
[0] | (gspca_dev
->usb_buf
[1] << 8);
486 sd
->params
.pnpID
.product
=
487 gspca_dev
->usb_buf
[2] | (gspca_dev
->usb_buf
[3] << 8);
488 sd
->params
.pnpID
.deviceRevision
=
489 gspca_dev
->usb_buf
[4] | (gspca_dev
->usb_buf
[5] << 8);
491 case CPIA_COMMAND_GetCameraStatus
:
492 sd
->params
.status
.systemState
= gspca_dev
->usb_buf
[0];
493 sd
->params
.status
.grabState
= gspca_dev
->usb_buf
[1];
494 sd
->params
.status
.streamState
= gspca_dev
->usb_buf
[2];
495 sd
->params
.status
.fatalError
= gspca_dev
->usb_buf
[3];
496 sd
->params
.status
.cmdError
= gspca_dev
->usb_buf
[4];
497 sd
->params
.status
.debugFlags
= gspca_dev
->usb_buf
[5];
498 sd
->params
.status
.vpStatus
= gspca_dev
->usb_buf
[6];
499 sd
->params
.status
.errorCode
= gspca_dev
->usb_buf
[7];
501 case CPIA_COMMAND_GetVPVersion
:
502 sd
->params
.vpVersion
.vpVersion
= gspca_dev
->usb_buf
[0];
503 sd
->params
.vpVersion
.vpRevision
= gspca_dev
->usb_buf
[1];
504 sd
->params
.vpVersion
.cameraHeadID
=
505 gspca_dev
->usb_buf
[2] | (gspca_dev
->usb_buf
[3] << 8);
507 case CPIA_COMMAND_GetColourParams
:
508 sd
->params
.colourParams
.brightness
= gspca_dev
->usb_buf
[0];
509 sd
->params
.colourParams
.contrast
= gspca_dev
->usb_buf
[1];
510 sd
->params
.colourParams
.saturation
= gspca_dev
->usb_buf
[2];
512 case CPIA_COMMAND_GetColourBalance
:
513 sd
->params
.colourBalance
.redGain
= gspca_dev
->usb_buf
[0];
514 sd
->params
.colourBalance
.greenGain
= gspca_dev
->usb_buf
[1];
515 sd
->params
.colourBalance
.blueGain
= gspca_dev
->usb_buf
[2];
517 case CPIA_COMMAND_GetExposure
:
518 sd
->params
.exposure
.gain
= gspca_dev
->usb_buf
[0];
519 sd
->params
.exposure
.fineExp
= gspca_dev
->usb_buf
[1];
520 sd
->params
.exposure
.coarseExpLo
= gspca_dev
->usb_buf
[2];
521 sd
->params
.exposure
.coarseExpHi
= gspca_dev
->usb_buf
[3];
522 sd
->params
.exposure
.redComp
= gspca_dev
->usb_buf
[4];
523 sd
->params
.exposure
.green1Comp
= gspca_dev
->usb_buf
[5];
524 sd
->params
.exposure
.green2Comp
= gspca_dev
->usb_buf
[6];
525 sd
->params
.exposure
.blueComp
= gspca_dev
->usb_buf
[7];
528 case CPIA_COMMAND_ReadMCPorts
:
529 /* test button press */
530 a
= ((gspca_dev
->usb_buf
[1] & 0x02) == 0);
531 if (a
!= sd
->params
.qx3
.button
) {
532 #if IS_ENABLED(CONFIG_INPUT)
533 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, a
);
534 input_sync(gspca_dev
->input_dev
);
536 sd
->params
.qx3
.button
= a
;
538 if (sd
->params
.qx3
.button
) {
539 /* button pressed - unlock the latch */
540 ret
= do_command(gspca_dev
, CPIA_COMMAND_WriteMCPort
,
544 ret
= do_command(gspca_dev
, CPIA_COMMAND_WriteMCPort
,
550 /* test whether microscope is cradled */
551 sd
->params
.qx3
.cradled
= ((gspca_dev
->usb_buf
[2] & 0x40) == 0);
558 /* send a command to the camera with an additional data transaction */
559 static int do_command_extended(struct gspca_dev
*gspca_dev
, u16 command
,
560 u8 a
, u8 b
, u8 c
, u8 d
,
561 u8 e
, u8 f
, u8 g
, u8 h
,
562 u8 i
, u8 j
, u8 k
, u8 l
)
566 cmd
[0] = command
>> 8;
567 cmd
[1] = command
& 0xff;
574 gspca_dev
->usb_buf
[0] = e
;
575 gspca_dev
->usb_buf
[1] = f
;
576 gspca_dev
->usb_buf
[2] = g
;
577 gspca_dev
->usb_buf
[3] = h
;
578 gspca_dev
->usb_buf
[4] = i
;
579 gspca_dev
->usb_buf
[5] = j
;
580 gspca_dev
->usb_buf
[6] = k
;
581 gspca_dev
->usb_buf
[7] = l
;
583 return cpia_usb_transferCmd(gspca_dev
, cmd
);
586 /* find_over_exposure
587 * Finds a suitable value of OverExposure for use with SetFlickerCtrl
588 * Some calculation is required because this value changes with the brightness
589 * set with SetColourParameters
591 * Parameters: Brightness - last brightness value set with SetColourParameters
593 * Returns: OverExposure value to use with SetFlickerCtrl
595 #define FLICKER_MAX_EXPOSURE 250
596 #define FLICKER_ALLOWABLE_OVER_EXPOSURE 146
597 #define FLICKER_BRIGHTNESS_CONSTANT 59
598 static int find_over_exposure(int brightness
)
600 int MaxAllowableOverExposure
, OverExposure
;
602 MaxAllowableOverExposure
= FLICKER_MAX_EXPOSURE
- brightness
-
603 FLICKER_BRIGHTNESS_CONSTANT
;
605 if (MaxAllowableOverExposure
< FLICKER_ALLOWABLE_OVER_EXPOSURE
)
606 OverExposure
= MaxAllowableOverExposure
;
608 OverExposure
= FLICKER_ALLOWABLE_OVER_EXPOSURE
;
612 #undef FLICKER_MAX_EXPOSURE
613 #undef FLICKER_ALLOWABLE_OVER_EXPOSURE
614 #undef FLICKER_BRIGHTNESS_CONSTANT
616 /* initialise cam_data structure */
617 static void reset_camera_params(struct gspca_dev
*gspca_dev
)
619 struct sd
*sd
= (struct sd
*) gspca_dev
;
620 struct cam_params
*params
= &sd
->params
;
622 /* The following parameter values are the defaults from
623 * "Software Developer's Guide for CPiA Cameras". Any changes
624 * to the defaults are noted in comments. */
625 params
->colourParams
.brightness
= BRIGHTNESS_DEF
;
626 params
->colourParams
.contrast
= CONTRAST_DEF
;
627 params
->colourParams
.saturation
= SATURATION_DEF
;
628 params
->exposure
.gainMode
= 4;
629 params
->exposure
.expMode
= 2; /* AEC */
630 params
->exposure
.compMode
= 1;
631 params
->exposure
.centreWeight
= 1;
632 params
->exposure
.gain
= 0;
633 params
->exposure
.fineExp
= 0;
634 params
->exposure
.coarseExpLo
= 185;
635 params
->exposure
.coarseExpHi
= 0;
636 params
->exposure
.redComp
= COMP_RED
;
637 params
->exposure
.green1Comp
= COMP_GREEN1
;
638 params
->exposure
.green2Comp
= COMP_GREEN2
;
639 params
->exposure
.blueComp
= COMP_BLUE
;
640 params
->colourBalance
.balanceMode
= 2; /* ACB */
641 params
->colourBalance
.redGain
= 32;
642 params
->colourBalance
.greenGain
= 6;
643 params
->colourBalance
.blueGain
= 92;
644 params
->apcor
.gain1
= 0x18;
645 params
->apcor
.gain2
= 0x16;
646 params
->apcor
.gain4
= 0x24;
647 params
->apcor
.gain8
= 0x34;
648 params
->vlOffset
.gain1
= 20;
649 params
->vlOffset
.gain2
= 24;
650 params
->vlOffset
.gain4
= 26;
651 params
->vlOffset
.gain8
= 26;
652 params
->compressionParams
.hysteresis
= 3;
653 params
->compressionParams
.threshMax
= 11;
654 params
->compressionParams
.smallStep
= 1;
655 params
->compressionParams
.largeStep
= 3;
656 params
->compressionParams
.decimationHysteresis
= 2;
657 params
->compressionParams
.frDiffStepThresh
= 5;
658 params
->compressionParams
.qDiffStepThresh
= 3;
659 params
->compressionParams
.decimationThreshMod
= 2;
660 /* End of default values from Software Developer's Guide */
662 /* Set Sensor FPS to 15fps. This seems better than 30fps
663 * for indoor lighting. */
664 params
->sensorFps
.divisor
= 1;
665 params
->sensorFps
.baserate
= 1;
667 params
->flickerControl
.flickerMode
= 0;
668 params
->flickerControl
.disabled
= 1;
669 params
->flickerControl
.coarseJump
=
670 flicker_jumps
[sd
->mainsFreq
]
671 [params
->sensorFps
.baserate
]
672 [params
->sensorFps
.divisor
];
673 params
->flickerControl
.allowableOverExposure
=
674 find_over_exposure(params
->colourParams
.brightness
);
676 params
->yuvThreshold
.yThreshold
= 6; /* From windows driver */
677 params
->yuvThreshold
.uvThreshold
= 6; /* From windows driver */
679 params
->format
.subSample
= SUBSAMPLE_420
;
680 params
->format
.yuvOrder
= YUVORDER_YUYV
;
682 params
->compression
.mode
= CPIA_COMPRESSION_AUTO
;
683 params
->compression
.decimation
= NO_DECIMATION
;
685 params
->compressionTarget
.frTargeting
= COMP_TARGET_DEF
;
686 params
->compressionTarget
.targetFR
= 15; /* From windows driver */
687 params
->compressionTarget
.targetQ
= 5; /* From windows driver */
689 params
->qx3
.qx3_detected
= 0;
690 params
->qx3
.toplight
= 0;
691 params
->qx3
.bottomlight
= 0;
692 params
->qx3
.button
= 0;
693 params
->qx3
.cradled
= 0;
696 static void printstatus(struct gspca_dev
*gspca_dev
, struct cam_params
*params
)
698 gspca_dbg(gspca_dev
, D_PROBE
, "status: %02x %02x %02x %02x %02x %02x %02x %02x\n",
699 params
->status
.systemState
, params
->status
.grabState
,
700 params
->status
.streamState
, params
->status
.fatalError
,
701 params
->status
.cmdError
, params
->status
.debugFlags
,
702 params
->status
.vpStatus
, params
->status
.errorCode
);
705 static int goto_low_power(struct gspca_dev
*gspca_dev
)
707 struct sd
*sd
= (struct sd
*) gspca_dev
;
710 ret
= do_command(gspca_dev
, CPIA_COMMAND_GotoLoPower
, 0, 0, 0, 0);
714 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
718 if (sd
->params
.status
.systemState
!= LO_POWER_STATE
) {
719 if (sd
->params
.status
.systemState
!= WARM_BOOT_STATE
) {
720 gspca_err(gspca_dev
, "unexpected state after lo power cmd: %02x\n",
721 sd
->params
.status
.systemState
);
722 printstatus(gspca_dev
, &sd
->params
);
727 gspca_dbg(gspca_dev
, D_CONF
, "camera now in LOW power state\n");
731 static int goto_high_power(struct gspca_dev
*gspca_dev
)
733 struct sd
*sd
= (struct sd
*) gspca_dev
;
736 ret
= do_command(gspca_dev
, CPIA_COMMAND_GotoHiPower
, 0, 0, 0, 0);
740 msleep_interruptible(40); /* windows driver does it too */
742 if (signal_pending(current
))
745 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
749 if (sd
->params
.status
.systemState
!= HI_POWER_STATE
) {
750 gspca_err(gspca_dev
, "unexpected state after hi power cmd: %02x\n",
751 sd
->params
.status
.systemState
);
752 printstatus(gspca_dev
, &sd
->params
);
756 gspca_dbg(gspca_dev
, D_CONF
, "camera now in HIGH power state\n");
760 static int get_version_information(struct gspca_dev
*gspca_dev
)
765 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetCPIAVersion
, 0, 0, 0, 0);
770 return do_command(gspca_dev
, CPIA_COMMAND_GetPnPID
, 0, 0, 0, 0);
773 static int save_camera_state(struct gspca_dev
*gspca_dev
)
777 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetColourBalance
, 0, 0, 0, 0);
781 return do_command(gspca_dev
, CPIA_COMMAND_GetExposure
, 0, 0, 0, 0);
784 static int command_setformat(struct gspca_dev
*gspca_dev
)
786 struct sd
*sd
= (struct sd
*) gspca_dev
;
789 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetFormat
,
790 sd
->params
.format
.videoSize
,
791 sd
->params
.format
.subSample
,
792 sd
->params
.format
.yuvOrder
, 0);
796 return do_command(gspca_dev
, CPIA_COMMAND_SetROI
,
797 sd
->params
.roi
.colStart
, sd
->params
.roi
.colEnd
,
798 sd
->params
.roi
.rowStart
, sd
->params
.roi
.rowEnd
);
801 static int command_setcolourparams(struct gspca_dev
*gspca_dev
)
803 struct sd
*sd
= (struct sd
*) gspca_dev
;
804 return do_command(gspca_dev
, CPIA_COMMAND_SetColourParams
,
805 sd
->params
.colourParams
.brightness
,
806 sd
->params
.colourParams
.contrast
,
807 sd
->params
.colourParams
.saturation
, 0);
810 static int command_setapcor(struct gspca_dev
*gspca_dev
)
812 struct sd
*sd
= (struct sd
*) gspca_dev
;
813 return do_command(gspca_dev
, CPIA_COMMAND_SetApcor
,
814 sd
->params
.apcor
.gain1
,
815 sd
->params
.apcor
.gain2
,
816 sd
->params
.apcor
.gain4
,
817 sd
->params
.apcor
.gain8
);
820 static int command_setvloffset(struct gspca_dev
*gspca_dev
)
822 struct sd
*sd
= (struct sd
*) gspca_dev
;
823 return do_command(gspca_dev
, CPIA_COMMAND_SetVLOffset
,
824 sd
->params
.vlOffset
.gain1
,
825 sd
->params
.vlOffset
.gain2
,
826 sd
->params
.vlOffset
.gain4
,
827 sd
->params
.vlOffset
.gain8
);
830 static int command_setexposure(struct gspca_dev
*gspca_dev
)
832 struct sd
*sd
= (struct sd
*) gspca_dev
;
835 ret
= do_command_extended(gspca_dev
, CPIA_COMMAND_SetExposure
,
836 sd
->params
.exposure
.gainMode
,
838 sd
->params
.exposure
.compMode
,
839 sd
->params
.exposure
.centreWeight
,
840 sd
->params
.exposure
.gain
,
841 sd
->params
.exposure
.fineExp
,
842 sd
->params
.exposure
.coarseExpLo
,
843 sd
->params
.exposure
.coarseExpHi
,
844 sd
->params
.exposure
.redComp
,
845 sd
->params
.exposure
.green1Comp
,
846 sd
->params
.exposure
.green2Comp
,
847 sd
->params
.exposure
.blueComp
);
851 if (sd
->params
.exposure
.expMode
!= 1) {
852 ret
= do_command_extended(gspca_dev
, CPIA_COMMAND_SetExposure
,
854 sd
->params
.exposure
.expMode
,
856 sd
->params
.exposure
.gain
,
857 sd
->params
.exposure
.fineExp
,
858 sd
->params
.exposure
.coarseExpLo
,
859 sd
->params
.exposure
.coarseExpHi
,
866 static int command_setcolourbalance(struct gspca_dev
*gspca_dev
)
868 struct sd
*sd
= (struct sd
*) gspca_dev
;
870 if (sd
->params
.colourBalance
.balanceMode
== 1) {
873 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
875 sd
->params
.colourBalance
.redGain
,
876 sd
->params
.colourBalance
.greenGain
,
877 sd
->params
.colourBalance
.blueGain
);
881 return do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
884 if (sd
->params
.colourBalance
.balanceMode
== 2) {
885 return do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
888 if (sd
->params
.colourBalance
.balanceMode
== 3) {
889 return do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
896 static int command_setcompressiontarget(struct gspca_dev
*gspca_dev
)
898 struct sd
*sd
= (struct sd
*) gspca_dev
;
900 return do_command(gspca_dev
, CPIA_COMMAND_SetCompressionTarget
,
901 sd
->params
.compressionTarget
.frTargeting
,
902 sd
->params
.compressionTarget
.targetFR
,
903 sd
->params
.compressionTarget
.targetQ
, 0);
906 static int command_setyuvtresh(struct gspca_dev
*gspca_dev
)
908 struct sd
*sd
= (struct sd
*) gspca_dev
;
910 return do_command(gspca_dev
, CPIA_COMMAND_SetYUVThresh
,
911 sd
->params
.yuvThreshold
.yThreshold
,
912 sd
->params
.yuvThreshold
.uvThreshold
, 0, 0);
915 static int command_setcompressionparams(struct gspca_dev
*gspca_dev
)
917 struct sd
*sd
= (struct sd
*) gspca_dev
;
919 return do_command_extended(gspca_dev
,
920 CPIA_COMMAND_SetCompressionParams
,
922 sd
->params
.compressionParams
.hysteresis
,
923 sd
->params
.compressionParams
.threshMax
,
924 sd
->params
.compressionParams
.smallStep
,
925 sd
->params
.compressionParams
.largeStep
,
926 sd
->params
.compressionParams
.decimationHysteresis
,
927 sd
->params
.compressionParams
.frDiffStepThresh
,
928 sd
->params
.compressionParams
.qDiffStepThresh
,
929 sd
->params
.compressionParams
.decimationThreshMod
);
932 static int command_setcompression(struct gspca_dev
*gspca_dev
)
934 struct sd
*sd
= (struct sd
*) gspca_dev
;
936 return do_command(gspca_dev
, CPIA_COMMAND_SetCompression
,
937 sd
->params
.compression
.mode
,
938 sd
->params
.compression
.decimation
, 0, 0);
941 static int command_setsensorfps(struct gspca_dev
*gspca_dev
)
943 struct sd
*sd
= (struct sd
*) gspca_dev
;
945 return do_command(gspca_dev
, CPIA_COMMAND_SetSensorFPS
,
946 sd
->params
.sensorFps
.divisor
,
947 sd
->params
.sensorFps
.baserate
, 0, 0);
950 static int command_setflickerctrl(struct gspca_dev
*gspca_dev
)
952 struct sd
*sd
= (struct sd
*) gspca_dev
;
954 return do_command(gspca_dev
, CPIA_COMMAND_SetFlickerCtrl
,
955 sd
->params
.flickerControl
.flickerMode
,
956 sd
->params
.flickerControl
.coarseJump
,
957 sd
->params
.flickerControl
.allowableOverExposure
,
961 static int command_setecptiming(struct gspca_dev
*gspca_dev
)
963 struct sd
*sd
= (struct sd
*) gspca_dev
;
965 return do_command(gspca_dev
, CPIA_COMMAND_SetECPTiming
,
966 sd
->params
.ecpTiming
, 0, 0, 0);
969 static int command_pause(struct gspca_dev
*gspca_dev
)
971 return do_command(gspca_dev
, CPIA_COMMAND_EndStreamCap
, 0, 0, 0, 0);
974 static int command_resume(struct gspca_dev
*gspca_dev
)
976 struct sd
*sd
= (struct sd
*) gspca_dev
;
978 return do_command(gspca_dev
, CPIA_COMMAND_InitStreamCap
,
979 0, sd
->params
.streamStartLine
, 0, 0);
982 static int command_setlights(struct gspca_dev
*gspca_dev
)
984 struct sd
*sd
= (struct sd
*) gspca_dev
;
987 p1
= (sd
->params
.qx3
.bottomlight
== 0) << 1;
988 p2
= (sd
->params
.qx3
.toplight
== 0) << 3;
990 ret
= do_command(gspca_dev
, CPIA_COMMAND_WriteVCReg
,
991 0x90, 0x8f, 0x50, 0);
995 return do_command(gspca_dev
, CPIA_COMMAND_WriteMCPort
, 2, 0,
999 static int set_flicker(struct gspca_dev
*gspca_dev
, int on
, int apply
)
1001 /* Everything in here is from the Windows driver */
1002 /* define for compgain calculation */
1004 #define COMPGAIN(base, curexp, newexp) \
1005 (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
1006 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1007 (u16)((float)curexp * (float)(u8)(curcomp + 128) / \
1008 (float)(u8)(basecomp - 128))
1010 /* equivalent functions without floating point math */
1011 #define COMPGAIN(base, curexp, newexp) \
1012 (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2 * newexp)))
1013 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1014 (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
1017 struct sd
*sd
= (struct sd
*) gspca_dev
;
1018 int currentexp
= sd
->params
.exposure
.coarseExpLo
+
1019 sd
->params
.exposure
.coarseExpHi
* 256;
1023 int cj
= sd
->params
.flickerControl
.coarseJump
;
1024 sd
->params
.flickerControl
.flickerMode
= 1;
1025 sd
->params
.flickerControl
.disabled
= 0;
1026 if (sd
->params
.exposure
.expMode
!= 2) {
1027 sd
->params
.exposure
.expMode
= 2;
1028 sd
->exposure_status
= EXPOSURE_NORMAL
;
1030 currentexp
= currentexp
<< sd
->params
.exposure
.gain
;
1031 sd
->params
.exposure
.gain
= 0;
1032 /* round down current exposure to nearest value */
1033 startexp
= (currentexp
+ ROUND_UP_EXP_FOR_FLICKER
) / cj
;
1036 startexp
= (startexp
* cj
) - 1;
1037 if (FIRMWARE_VERSION(1, 2))
1038 while (startexp
> MAX_EXP_102
)
1041 while (startexp
> MAX_EXP
)
1043 sd
->params
.exposure
.coarseExpLo
= startexp
& 0xff;
1044 sd
->params
.exposure
.coarseExpHi
= startexp
>> 8;
1045 if (currentexp
> startexp
) {
1046 if (currentexp
> (2 * startexp
))
1047 currentexp
= 2 * startexp
;
1048 sd
->params
.exposure
.redComp
=
1049 COMPGAIN(COMP_RED
, currentexp
, startexp
);
1050 sd
->params
.exposure
.green1Comp
=
1051 COMPGAIN(COMP_GREEN1
, currentexp
, startexp
);
1052 sd
->params
.exposure
.green2Comp
=
1053 COMPGAIN(COMP_GREEN2
, currentexp
, startexp
);
1054 sd
->params
.exposure
.blueComp
=
1055 COMPGAIN(COMP_BLUE
, currentexp
, startexp
);
1057 sd
->params
.exposure
.redComp
= COMP_RED
;
1058 sd
->params
.exposure
.green1Comp
= COMP_GREEN1
;
1059 sd
->params
.exposure
.green2Comp
= COMP_GREEN2
;
1060 sd
->params
.exposure
.blueComp
= COMP_BLUE
;
1062 if (FIRMWARE_VERSION(1, 2))
1063 sd
->params
.exposure
.compMode
= 0;
1065 sd
->params
.exposure
.compMode
= 1;
1067 sd
->params
.apcor
.gain1
= 0x18;
1068 sd
->params
.apcor
.gain2
= 0x18;
1069 sd
->params
.apcor
.gain4
= 0x16;
1070 sd
->params
.apcor
.gain8
= 0x14;
1072 sd
->params
.flickerControl
.flickerMode
= 0;
1073 sd
->params
.flickerControl
.disabled
= 1;
1074 /* Average equivalent coarse for each comp channel */
1075 startexp
= EXP_FROM_COMP(COMP_RED
,
1076 sd
->params
.exposure
.redComp
, currentexp
);
1077 startexp
+= EXP_FROM_COMP(COMP_GREEN1
,
1078 sd
->params
.exposure
.green1Comp
, currentexp
);
1079 startexp
+= EXP_FROM_COMP(COMP_GREEN2
,
1080 sd
->params
.exposure
.green2Comp
, currentexp
);
1081 startexp
+= EXP_FROM_COMP(COMP_BLUE
,
1082 sd
->params
.exposure
.blueComp
, currentexp
);
1083 startexp
= startexp
>> 2;
1084 while (startexp
> MAX_EXP
&& sd
->params
.exposure
.gain
<
1085 sd
->params
.exposure
.gainMode
- 1) {
1086 startexp
= startexp
>> 1;
1087 ++sd
->params
.exposure
.gain
;
1089 if (FIRMWARE_VERSION(1, 2) && startexp
> MAX_EXP_102
)
1090 startexp
= MAX_EXP_102
;
1091 if (startexp
> MAX_EXP
)
1093 sd
->params
.exposure
.coarseExpLo
= startexp
& 0xff;
1094 sd
->params
.exposure
.coarseExpHi
= startexp
>> 8;
1095 sd
->params
.exposure
.redComp
= COMP_RED
;
1096 sd
->params
.exposure
.green1Comp
= COMP_GREEN1
;
1097 sd
->params
.exposure
.green2Comp
= COMP_GREEN2
;
1098 sd
->params
.exposure
.blueComp
= COMP_BLUE
;
1099 sd
->params
.exposure
.compMode
= 1;
1100 sd
->params
.apcor
.gain1
= 0x18;
1101 sd
->params
.apcor
.gain2
= 0x16;
1102 sd
->params
.apcor
.gain4
= 0x24;
1103 sd
->params
.apcor
.gain8
= 0x34;
1105 sd
->params
.vlOffset
.gain1
= 20;
1106 sd
->params
.vlOffset
.gain2
= 24;
1107 sd
->params
.vlOffset
.gain4
= 26;
1108 sd
->params
.vlOffset
.gain8
= 26;
1111 ret
= command_setexposure(gspca_dev
);
1115 ret
= command_setapcor(gspca_dev
);
1119 ret
= command_setvloffset(gspca_dev
);
1123 ret
= command_setflickerctrl(gspca_dev
);
1129 #undef EXP_FROM_COMP
1133 /* monitor the exposure and adjust the sensor frame rate if needed */
1134 static void monitor_exposure(struct gspca_dev
*gspca_dev
)
1136 struct sd
*sd
= (struct sd
*) gspca_dev
;
1137 u8 exp_acc
, bcomp
, cmd
[8];
1138 int ret
, light_exp
, dark_exp
, very_dark_exp
;
1139 int old_exposure
, new_exposure
, framerate
;
1140 int setfps
= 0, setexp
= 0, setflicker
= 0;
1142 /* get necessary stats and register settings from camera */
1143 /* do_command can't handle this, so do it ourselves */
1144 cmd
[0] = CPIA_COMMAND_ReadVPRegs
>> 8;
1145 cmd
[1] = CPIA_COMMAND_ReadVPRegs
& 0xff;
1152 ret
= cpia_usb_transferCmd(gspca_dev
, cmd
);
1154 pr_err("ReadVPRegs(30,4,9,8) - failed: %d\n", ret
);
1157 exp_acc
= gspca_dev
->usb_buf
[0];
1158 bcomp
= gspca_dev
->usb_buf
[1];
1160 light_exp
= sd
->params
.colourParams
.brightness
+
1161 TC
- 50 + EXP_ACC_LIGHT
;
1162 if (light_exp
> 255)
1164 dark_exp
= sd
->params
.colourParams
.brightness
+
1165 TC
- 50 - EXP_ACC_DARK
;
1168 very_dark_exp
= dark_exp
/ 2;
1170 old_exposure
= sd
->params
.exposure
.coarseExpHi
* 256 +
1171 sd
->params
.exposure
.coarseExpLo
;
1173 if (!sd
->params
.flickerControl
.disabled
) {
1174 /* Flicker control on */
1175 int max_comp
= FIRMWARE_VERSION(1, 2) ? MAX_COMP
:
1177 bcomp
+= 128; /* decode */
1178 if (bcomp
>= max_comp
&& exp_acc
< dark_exp
) {
1180 if (exp_acc
< very_dark_exp
) {
1182 if (sd
->exposure_status
== EXPOSURE_VERY_DARK
)
1183 ++sd
->exposure_count
;
1185 sd
->exposure_status
=
1187 sd
->exposure_count
= 1;
1191 if (sd
->exposure_status
== EXPOSURE_DARK
)
1192 ++sd
->exposure_count
;
1194 sd
->exposure_status
= EXPOSURE_DARK
;
1195 sd
->exposure_count
= 1;
1198 } else if (old_exposure
<= LOW_EXP
|| exp_acc
> light_exp
) {
1200 if (old_exposure
<= VERY_LOW_EXP
) {
1202 if (sd
->exposure_status
== EXPOSURE_VERY_LIGHT
)
1203 ++sd
->exposure_count
;
1205 sd
->exposure_status
=
1206 EXPOSURE_VERY_LIGHT
;
1207 sd
->exposure_count
= 1;
1211 if (sd
->exposure_status
== EXPOSURE_LIGHT
)
1212 ++sd
->exposure_count
;
1214 sd
->exposure_status
= EXPOSURE_LIGHT
;
1215 sd
->exposure_count
= 1;
1219 /* not dark or light */
1220 sd
->exposure_status
= EXPOSURE_NORMAL
;
1223 /* Flicker control off */
1224 if (old_exposure
>= MAX_EXP
&& exp_acc
< dark_exp
) {
1226 if (exp_acc
< very_dark_exp
) {
1228 if (sd
->exposure_status
== EXPOSURE_VERY_DARK
)
1229 ++sd
->exposure_count
;
1231 sd
->exposure_status
=
1233 sd
->exposure_count
= 1;
1237 if (sd
->exposure_status
== EXPOSURE_DARK
)
1238 ++sd
->exposure_count
;
1240 sd
->exposure_status
= EXPOSURE_DARK
;
1241 sd
->exposure_count
= 1;
1244 } else if (old_exposure
<= LOW_EXP
|| exp_acc
> light_exp
) {
1246 if (old_exposure
<= VERY_LOW_EXP
) {
1248 if (sd
->exposure_status
== EXPOSURE_VERY_LIGHT
)
1249 ++sd
->exposure_count
;
1251 sd
->exposure_status
=
1252 EXPOSURE_VERY_LIGHT
;
1253 sd
->exposure_count
= 1;
1257 if (sd
->exposure_status
== EXPOSURE_LIGHT
)
1258 ++sd
->exposure_count
;
1260 sd
->exposure_status
= EXPOSURE_LIGHT
;
1261 sd
->exposure_count
= 1;
1265 /* not dark or light */
1266 sd
->exposure_status
= EXPOSURE_NORMAL
;
1270 framerate
= atomic_read(&sd
->fps
);
1271 if (framerate
> 30 || framerate
< 1)
1274 if (!sd
->params
.flickerControl
.disabled
) {
1275 /* Flicker control on */
1276 if ((sd
->exposure_status
== EXPOSURE_VERY_DARK
||
1277 sd
->exposure_status
== EXPOSURE_DARK
) &&
1278 sd
->exposure_count
>= DARK_TIME
* framerate
&&
1279 sd
->params
.sensorFps
.divisor
< 2) {
1281 /* dark for too long */
1282 ++sd
->params
.sensorFps
.divisor
;
1285 sd
->params
.flickerControl
.coarseJump
=
1286 flicker_jumps
[sd
->mainsFreq
]
1287 [sd
->params
.sensorFps
.baserate
]
1288 [sd
->params
.sensorFps
.divisor
];
1291 new_exposure
= sd
->params
.flickerControl
.coarseJump
-1;
1292 while (new_exposure
< old_exposure
/ 2)
1294 sd
->params
.flickerControl
.coarseJump
;
1295 sd
->params
.exposure
.coarseExpLo
= new_exposure
& 0xff;
1296 sd
->params
.exposure
.coarseExpHi
= new_exposure
>> 8;
1298 sd
->exposure_status
= EXPOSURE_NORMAL
;
1299 gspca_dbg(gspca_dev
, D_CONF
, "Automatically decreasing sensor_fps\n");
1301 } else if ((sd
->exposure_status
== EXPOSURE_VERY_LIGHT
||
1302 sd
->exposure_status
== EXPOSURE_LIGHT
) &&
1303 sd
->exposure_count
>= LIGHT_TIME
* framerate
&&
1304 sd
->params
.sensorFps
.divisor
> 0) {
1306 /* light for too long */
1307 int max_exp
= FIRMWARE_VERSION(1, 2) ? MAX_EXP_102
:
1309 --sd
->params
.sensorFps
.divisor
;
1312 sd
->params
.flickerControl
.coarseJump
=
1313 flicker_jumps
[sd
->mainsFreq
]
1314 [sd
->params
.sensorFps
.baserate
]
1315 [sd
->params
.sensorFps
.divisor
];
1318 new_exposure
= sd
->params
.flickerControl
.coarseJump
-1;
1319 while (new_exposure
< 2 * old_exposure
&&
1321 sd
->params
.flickerControl
.coarseJump
< max_exp
)
1323 sd
->params
.flickerControl
.coarseJump
;
1324 sd
->params
.exposure
.coarseExpLo
= new_exposure
& 0xff;
1325 sd
->params
.exposure
.coarseExpHi
= new_exposure
>> 8;
1327 sd
->exposure_status
= EXPOSURE_NORMAL
;
1328 gspca_dbg(gspca_dev
, D_CONF
, "Automatically increasing sensor_fps\n");
1331 /* Flicker control off */
1332 if ((sd
->exposure_status
== EXPOSURE_VERY_DARK
||
1333 sd
->exposure_status
== EXPOSURE_DARK
) &&
1334 sd
->exposure_count
>= DARK_TIME
* framerate
&&
1335 sd
->params
.sensorFps
.divisor
< 2) {
1337 /* dark for too long */
1338 ++sd
->params
.sensorFps
.divisor
;
1341 if (sd
->params
.exposure
.gain
> 0) {
1342 --sd
->params
.exposure
.gain
;
1345 sd
->exposure_status
= EXPOSURE_NORMAL
;
1346 gspca_dbg(gspca_dev
, D_CONF
, "Automatically decreasing sensor_fps\n");
1348 } else if ((sd
->exposure_status
== EXPOSURE_VERY_LIGHT
||
1349 sd
->exposure_status
== EXPOSURE_LIGHT
) &&
1350 sd
->exposure_count
>= LIGHT_TIME
* framerate
&&
1351 sd
->params
.sensorFps
.divisor
> 0) {
1353 /* light for too long */
1354 --sd
->params
.sensorFps
.divisor
;
1357 if (sd
->params
.exposure
.gain
<
1358 sd
->params
.exposure
.gainMode
- 1) {
1359 ++sd
->params
.exposure
.gain
;
1362 sd
->exposure_status
= EXPOSURE_NORMAL
;
1363 gspca_dbg(gspca_dev
, D_CONF
, "Automatically increasing sensor_fps\n");
1368 command_setexposure(gspca_dev
);
1371 command_setsensorfps(gspca_dev
);
1374 command_setflickerctrl(gspca_dev
);
1377 /*-----------------------------------------------------------------*/
1378 /* if flicker is switched off, this function switches it back on.It checks,
1379 however, that conditions are suitable before restarting it.
1380 This should only be called for firmware version 1.2.
1382 It also adjust the colour balance when an exposure step is detected - as
1383 long as flicker is running
1385 static void restart_flicker(struct gspca_dev
*gspca_dev
)
1387 struct sd
*sd
= (struct sd
*) gspca_dev
;
1388 int cam_exposure
, old_exp
;
1390 if (!FIRMWARE_VERSION(1, 2))
1393 cam_exposure
= atomic_read(&sd
->cam_exposure
);
1395 if (sd
->params
.flickerControl
.flickerMode
== 0 ||
1399 old_exp
= sd
->params
.exposure
.coarseExpLo
+
1400 sd
->params
.exposure
.coarseExpHi
*256;
1402 see how far away camera exposure is from a valid
1403 flicker exposure value
1405 cam_exposure
%= sd
->params
.flickerControl
.coarseJump
;
1406 if (!sd
->params
.flickerControl
.disabled
&&
1407 cam_exposure
<= sd
->params
.flickerControl
.coarseJump
- 3) {
1408 /* Flicker control auto-disabled */
1409 sd
->params
.flickerControl
.disabled
= 1;
1412 if (sd
->params
.flickerControl
.disabled
&&
1413 old_exp
> sd
->params
.flickerControl
.coarseJump
+
1414 ROUND_UP_EXP_FOR_FLICKER
) {
1415 /* exposure is now high enough to switch
1416 flicker control back on */
1417 set_flicker(gspca_dev
, 1, 1);
1421 /* this function is called at probe time */
1422 static int sd_config(struct gspca_dev
*gspca_dev
,
1423 const struct usb_device_id
*id
)
1425 struct sd
*sd
= (struct sd
*) gspca_dev
;
1429 sd
->mainsFreq
= FREQ_DEF
== V4L2_CID_POWER_LINE_FREQUENCY_60HZ
;
1430 reset_camera_params(gspca_dev
);
1432 gspca_dbg(gspca_dev
, D_PROBE
, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)\n",
1433 id
->idVendor
, id
->idProduct
);
1435 cam
= &gspca_dev
->cam
;
1436 cam
->cam_mode
= mode
;
1437 cam
->nmodes
= ARRAY_SIZE(mode
);
1439 ret
= goto_low_power(gspca_dev
);
1441 gspca_err(gspca_dev
, "Cannot go to low power mode: %d\n",
1443 /* Check the firmware version. */
1444 sd
->params
.version
.firmwareVersion
= 0;
1445 get_version_information(gspca_dev
);
1446 if (sd
->params
.version
.firmwareVersion
!= 1) {
1447 gspca_err(gspca_dev
, "only firmware version 1 is supported (got: %d)\n",
1448 sd
->params
.version
.firmwareVersion
);
1452 /* A bug in firmware 1-02 limits gainMode to 2 */
1453 if (sd
->params
.version
.firmwareRevision
<= 2 &&
1454 sd
->params
.exposure
.gainMode
> 2) {
1455 sd
->params
.exposure
.gainMode
= 2;
1458 /* set QX3 detected flag */
1459 sd
->params
.qx3
.qx3_detected
= (sd
->params
.pnpID
.vendor
== 0x0813 &&
1460 sd
->params
.pnpID
.product
== 0x0001);
1464 /* -- start the camera -- */
1465 static int sd_start(struct gspca_dev
*gspca_dev
)
1467 struct sd
*sd
= (struct sd
*) gspca_dev
;
1470 /* Start the camera in low power mode */
1471 if (goto_low_power(gspca_dev
)) {
1472 if (sd
->params
.status
.systemState
!= WARM_BOOT_STATE
) {
1473 gspca_err(gspca_dev
, "unexpected systemstate: %02x\n",
1474 sd
->params
.status
.systemState
);
1475 printstatus(gspca_dev
, &sd
->params
);
1479 /* FIXME: this is just dirty trial and error */
1480 ret
= goto_high_power(gspca_dev
);
1484 ret
= do_command(gspca_dev
, CPIA_COMMAND_DiscardFrame
,
1489 ret
= goto_low_power(gspca_dev
);
1494 /* procedure described in developer's guide p3-28 */
1496 /* Check the firmware version. */
1497 sd
->params
.version
.firmwareVersion
= 0;
1498 get_version_information(gspca_dev
);
1500 /* The fatal error checking should be done after
1501 * the camera powers up (developer's guide p 3-38) */
1503 /* Set streamState before transition to high power to avoid bug
1504 * in firmware 1-02 */
1505 ret
= do_command(gspca_dev
, CPIA_COMMAND_ModifyCameraStatus
,
1506 STREAMSTATE
, 0, STREAM_NOT_READY
, 0);
1511 ret
= goto_high_power(gspca_dev
);
1515 /* Check the camera status */
1516 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
1520 if (sd
->params
.status
.fatalError
) {
1521 gspca_err(gspca_dev
, "fatal_error: %04x, vp_status: %04x\n",
1522 sd
->params
.status
.fatalError
,
1523 sd
->params
.status
.vpStatus
);
1527 /* VPVersion can't be retrieved before the camera is in HiPower,
1528 * so get it here instead of in get_version_information. */
1529 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetVPVersion
, 0, 0, 0, 0);
1533 /* Determine video mode settings */
1534 sd
->params
.streamStartLine
= 120;
1536 priv
= gspca_dev
->cam
.cam_mode
[gspca_dev
->curr_mode
].priv
;
1537 if (priv
& 0x01) { /* crop */
1538 sd
->params
.roi
.colStart
= 2;
1539 sd
->params
.roi
.rowStart
= 6;
1541 sd
->params
.roi
.colStart
= 0;
1542 sd
->params
.roi
.rowStart
= 0;
1545 if (priv
& 0x02) { /* quarter */
1546 sd
->params
.format
.videoSize
= VIDEOSIZE_QCIF
;
1547 sd
->params
.roi
.colStart
/= 2;
1548 sd
->params
.roi
.rowStart
/= 2;
1549 sd
->params
.streamStartLine
/= 2;
1551 sd
->params
.format
.videoSize
= VIDEOSIZE_CIF
;
1553 sd
->params
.roi
.colEnd
= sd
->params
.roi
.colStart
+
1554 (gspca_dev
->pixfmt
.width
>> 3);
1555 sd
->params
.roi
.rowEnd
= sd
->params
.roi
.rowStart
+
1556 (gspca_dev
->pixfmt
.height
>> 2);
1558 /* And now set the camera to a known state */
1559 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetGrabMode
,
1560 CPIA_GRAB_CONTINEOUS
, 0, 0, 0);
1563 /* We start with compression disabled, as we need one uncompressed
1564 frame to handle later compressed frames */
1565 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetCompression
,
1566 CPIA_COMPRESSION_NONE
,
1567 NO_DECIMATION
, 0, 0);
1570 ret
= command_setcompressiontarget(gspca_dev
);
1573 ret
= command_setcolourparams(gspca_dev
);
1576 ret
= command_setformat(gspca_dev
);
1579 ret
= command_setyuvtresh(gspca_dev
);
1582 ret
= command_setecptiming(gspca_dev
);
1585 ret
= command_setcompressionparams(gspca_dev
);
1588 ret
= command_setexposure(gspca_dev
);
1591 ret
= command_setcolourbalance(gspca_dev
);
1594 ret
= command_setsensorfps(gspca_dev
);
1597 ret
= command_setapcor(gspca_dev
);
1600 ret
= command_setflickerctrl(gspca_dev
);
1603 ret
= command_setvloffset(gspca_dev
);
1608 ret
= command_resume(gspca_dev
);
1612 /* Wait 6 frames before turning compression on for the sensor to get
1613 all settings and AEC/ACB to settle */
1614 sd
->first_frame
= 6;
1615 sd
->exposure_status
= EXPOSURE_NORMAL
;
1616 sd
->exposure_count
= 0;
1617 atomic_set(&sd
->cam_exposure
, 0);
1618 atomic_set(&sd
->fps
, 0);
1623 static void sd_stopN(struct gspca_dev
*gspca_dev
)
1625 struct sd
*sd __maybe_unused
= (struct sd
*) gspca_dev
;
1627 command_pause(gspca_dev
);
1629 /* save camera state for later open (developers guide ch 3.5.3) */
1630 save_camera_state(gspca_dev
);
1633 goto_low_power(gspca_dev
);
1635 /* Update the camera status */
1636 do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
1638 #if IS_ENABLED(CONFIG_INPUT)
1639 /* If the last button state is pressed, release it now! */
1640 if (sd
->params
.qx3
.button
) {
1641 /* The camera latch will hold the pressed state until we reset
1642 the latch, so we do not reset sd->params.qx3.button now, to
1643 avoid a false keypress being reported the next sd_start */
1644 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 0);
1645 input_sync(gspca_dev
->input_dev
);
1650 /* this function is called at probe and resume time */
1651 static int sd_init(struct gspca_dev
*gspca_dev
)
1653 struct sd
*sd
= (struct sd
*) gspca_dev
;
1656 /* Start / Stop the camera to make sure we are talking to
1657 a supported camera, and to get some information from it
1659 ret
= sd_start(gspca_dev
);
1663 /* Ensure the QX3 illuminators' states are restored upon resume,
1664 or disable the illuminator controls, if this isn't a QX3 */
1665 if (sd
->params
.qx3
.qx3_detected
)
1666 command_setlights(gspca_dev
);
1668 sd_stopN(gspca_dev
);
1670 gspca_dbg(gspca_dev
, D_PROBE
, "CPIA Version: %d.%02d (%d.%d)\n",
1671 sd
->params
.version
.firmwareVersion
,
1672 sd
->params
.version
.firmwareRevision
,
1673 sd
->params
.version
.vcVersion
,
1674 sd
->params
.version
.vcRevision
);
1675 gspca_dbg(gspca_dev
, D_PROBE
, "CPIA PnP-ID: %04x:%04x:%04x",
1676 sd
->params
.pnpID
.vendor
, sd
->params
.pnpID
.product
,
1677 sd
->params
.pnpID
.deviceRevision
);
1678 gspca_dbg(gspca_dev
, D_PROBE
, "VP-Version: %d.%d %04x",
1679 sd
->params
.vpVersion
.vpVersion
,
1680 sd
->params
.vpVersion
.vpRevision
,
1681 sd
->params
.vpVersion
.cameraHeadID
);
1686 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
1690 struct sd
*sd
= (struct sd
*) gspca_dev
;
1694 data
[0] == MAGIC_0
&& data
[1] == MAGIC_1
&&
1695 data
[16] == sd
->params
.format
.videoSize
&&
1696 data
[17] == sd
->params
.format
.subSample
&&
1697 data
[18] == sd
->params
.format
.yuvOrder
&&
1698 data
[24] == sd
->params
.roi
.colStart
&&
1699 data
[25] == sd
->params
.roi
.colEnd
&&
1700 data
[26] == sd
->params
.roi
.rowStart
&&
1701 data
[27] == sd
->params
.roi
.rowEnd
) {
1704 atomic_set(&sd
->cam_exposure
, data
[39] * 2);
1705 atomic_set(&sd
->fps
, data
[41]);
1707 /* Check for proper EOF for last frame */
1708 image
= gspca_dev
->image
;
1709 if (image
!= NULL
&&
1710 gspca_dev
->image_len
> 4 &&
1711 image
[gspca_dev
->image_len
- 4] == 0xff &&
1712 image
[gspca_dev
->image_len
- 3] == 0xff &&
1713 image
[gspca_dev
->image_len
- 2] == 0xff &&
1714 image
[gspca_dev
->image_len
- 1] == 0xff)
1715 gspca_frame_add(gspca_dev
, LAST_PACKET
,
1718 gspca_frame_add(gspca_dev
, FIRST_PACKET
, data
, len
);
1722 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
1725 static void sd_dq_callback(struct gspca_dev
*gspca_dev
)
1727 struct sd
*sd
= (struct sd
*) gspca_dev
;
1729 /* Set the normal compression settings once we have captured a
1730 few uncompressed frames (and AEC has hopefully settled) */
1731 if (sd
->first_frame
) {
1733 if (sd
->first_frame
== 0)
1734 command_setcompression(gspca_dev
);
1737 /* Switch flicker control back on if it got turned off */
1738 restart_flicker(gspca_dev
);
1740 /* If AEC is enabled, monitor the exposure and
1741 adjust the sensor frame rate if needed */
1742 if (sd
->params
.exposure
.expMode
== 2)
1743 monitor_exposure(gspca_dev
);
1745 /* Update our knowledge of the camera state */
1746 do_command(gspca_dev
, CPIA_COMMAND_GetExposure
, 0, 0, 0, 0);
1747 do_command(gspca_dev
, CPIA_COMMAND_ReadMCPorts
, 0, 0, 0, 0);
1750 static int sd_s_ctrl(struct v4l2_ctrl
*ctrl
)
1752 struct gspca_dev
*gspca_dev
=
1753 container_of(ctrl
->handler
, struct gspca_dev
, ctrl_handler
);
1754 struct sd
*sd
= (struct sd
*)gspca_dev
;
1756 gspca_dev
->usb_err
= 0;
1758 if (!gspca_dev
->streaming
&& ctrl
->id
!= V4L2_CID_POWER_LINE_FREQUENCY
)
1762 case V4L2_CID_BRIGHTNESS
:
1763 sd
->params
.colourParams
.brightness
= ctrl
->val
;
1764 sd
->params
.flickerControl
.allowableOverExposure
=
1765 find_over_exposure(sd
->params
.colourParams
.brightness
);
1766 gspca_dev
->usb_err
= command_setcolourparams(gspca_dev
);
1767 if (!gspca_dev
->usb_err
)
1768 gspca_dev
->usb_err
= command_setflickerctrl(gspca_dev
);
1770 case V4L2_CID_CONTRAST
:
1771 sd
->params
.colourParams
.contrast
= ctrl
->val
;
1772 gspca_dev
->usb_err
= command_setcolourparams(gspca_dev
);
1774 case V4L2_CID_SATURATION
:
1775 sd
->params
.colourParams
.saturation
= ctrl
->val
;
1776 gspca_dev
->usb_err
= command_setcolourparams(gspca_dev
);
1778 case V4L2_CID_POWER_LINE_FREQUENCY
:
1779 sd
->mainsFreq
= ctrl
->val
== V4L2_CID_POWER_LINE_FREQUENCY_60HZ
;
1780 sd
->params
.flickerControl
.coarseJump
=
1781 flicker_jumps
[sd
->mainsFreq
]
1782 [sd
->params
.sensorFps
.baserate
]
1783 [sd
->params
.sensorFps
.divisor
];
1785 gspca_dev
->usb_err
= set_flicker(gspca_dev
,
1786 ctrl
->val
!= V4L2_CID_POWER_LINE_FREQUENCY_DISABLED
,
1787 gspca_dev
->streaming
);
1789 case V4L2_CID_ILLUMINATORS_1
:
1790 sd
->params
.qx3
.bottomlight
= ctrl
->val
;
1791 gspca_dev
->usb_err
= command_setlights(gspca_dev
);
1793 case V4L2_CID_ILLUMINATORS_2
:
1794 sd
->params
.qx3
.toplight
= ctrl
->val
;
1795 gspca_dev
->usb_err
= command_setlights(gspca_dev
);
1797 case CPIA1_CID_COMP_TARGET
:
1798 sd
->params
.compressionTarget
.frTargeting
= ctrl
->val
;
1799 gspca_dev
->usb_err
= command_setcompressiontarget(gspca_dev
);
1802 return gspca_dev
->usb_err
;
1805 static const struct v4l2_ctrl_ops sd_ctrl_ops
= {
1806 .s_ctrl
= sd_s_ctrl
,
1809 static int sd_init_controls(struct gspca_dev
*gspca_dev
)
1811 struct sd
*sd
= (struct sd
*)gspca_dev
;
1812 struct v4l2_ctrl_handler
*hdl
= &gspca_dev
->ctrl_handler
;
1813 static const char * const comp_target_menu
[] = {
1818 static const struct v4l2_ctrl_config comp_target
= {
1819 .ops
= &sd_ctrl_ops
,
1820 .id
= CPIA1_CID_COMP_TARGET
,
1821 .type
= V4L2_CTRL_TYPE_MENU
,
1822 .name
= "Compression Target",
1823 .qmenu
= comp_target_menu
,
1825 .def
= COMP_TARGET_DEF
,
1828 gspca_dev
->vdev
.ctrl_handler
= hdl
;
1829 v4l2_ctrl_handler_init(hdl
, 7);
1830 v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1831 V4L2_CID_BRIGHTNESS
, 0, 100, 1, BRIGHTNESS_DEF
);
1832 v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1833 V4L2_CID_CONTRAST
, 0, 96, 8, CONTRAST_DEF
);
1834 v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1835 V4L2_CID_SATURATION
, 0, 100, 1, SATURATION_DEF
);
1836 sd
->freq
= v4l2_ctrl_new_std_menu(hdl
, &sd_ctrl_ops
,
1837 V4L2_CID_POWER_LINE_FREQUENCY
,
1838 V4L2_CID_POWER_LINE_FREQUENCY_60HZ
, 0,
1840 if (sd
->params
.qx3
.qx3_detected
) {
1841 v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1842 V4L2_CID_ILLUMINATORS_1
, 0, 1, 1,
1843 ILLUMINATORS_1_DEF
);
1844 v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1845 V4L2_CID_ILLUMINATORS_2
, 0, 1, 1,
1846 ILLUMINATORS_2_DEF
);
1848 v4l2_ctrl_new_custom(hdl
, &comp_target
, NULL
);
1851 pr_err("Could not initialize controls\n");
1857 /* sub-driver description */
1858 static const struct sd_desc sd_desc
= {
1859 .name
= MODULE_NAME
,
1860 .config
= sd_config
,
1862 .init_controls
= sd_init_controls
,
1865 .dq_callback
= sd_dq_callback
,
1866 .pkt_scan
= sd_pkt_scan
,
1867 #if IS_ENABLED(CONFIG_INPUT)
1872 /* -- module initialisation -- */
1873 static const struct usb_device_id device_table
[] = {
1874 {USB_DEVICE(0x0553, 0x0002)},
1875 {USB_DEVICE(0x0813, 0x0001)},
1878 MODULE_DEVICE_TABLE(usb
, device_table
);
1880 /* -- device connect -- */
1881 static int sd_probe(struct usb_interface
*intf
,
1882 const struct usb_device_id
*id
)
1884 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
1888 static struct usb_driver sd_driver
= {
1889 .name
= MODULE_NAME
,
1890 .id_table
= device_table
,
1892 .disconnect
= gspca_disconnect
,
1894 .suspend
= gspca_suspend
,
1895 .resume
= gspca_resume
,
1896 .reset_resume
= gspca_resume
,
1900 module_usb_driver(sd_driver
);