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.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #define MODULE_NAME "cpia1"
31 #include <linux/input.h>
34 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
35 MODULE_DESCRIPTION("Vision CPiA");
36 MODULE_LICENSE("GPL");
38 /* constant value's */
43 #define VIDEOSIZE_QCIF 0 /* 176x144 */
44 #define VIDEOSIZE_CIF 1 /* 352x288 */
45 #define SUBSAMPLE_420 0
46 #define SUBSAMPLE_422 1
47 #define YUVORDER_YUYV 0
48 #define YUVORDER_UYVY 1
49 #define NOT_COMPRESSED 0
51 #define NO_DECIMATION 0
52 #define DECIMATION_ENAB 1
53 #define EOI 0xff /* End Of Image */
54 #define EOL 0xfd /* End Of Line */
55 #define FRAME_HEADER_SIZE 64
57 /* Image grab modes */
58 #define CPIA_GRAB_SINGLE 0
59 #define CPIA_GRAB_CONTINEOUS 1
61 /* Compression parameters */
62 #define CPIA_COMPRESSION_NONE 0
63 #define CPIA_COMPRESSION_AUTO 1
64 #define CPIA_COMPRESSION_MANUAL 2
65 #define CPIA_COMPRESSION_TARGET_QUALITY 0
66 #define CPIA_COMPRESSION_TARGET_FRAMERATE 1
68 /* Return offsets for GetCameraState */
79 #define UNINITIALISED_STATE 0
80 #define PASS_THROUGH_STATE 1
81 #define LO_POWER_STATE 2
82 #define HI_POWER_STATE 3
83 #define WARM_BOOT_STATE 4
91 #define STREAM_NOT_READY 0
92 #define STREAM_READY 1
94 #define STREAM_PAUSED 3
95 #define STREAM_FINISHED 4
97 /* Fatal Error, CmdError, and DebugFlags */
100 #define INT_CTRL_FLAG 4
101 #define PROCESS_FLAG 8
103 #define VP_CTRL_FLAG 32
104 #define CAPTURE_FLAG 64
105 #define DEBUG_FLAG 128
108 #define VP_STATE_OK 0x00
110 #define VP_STATE_FAILED_VIDEOINIT 0x01
111 #define VP_STATE_FAILED_AECACBINIT 0x02
112 #define VP_STATE_AEC_MAX 0x04
113 #define VP_STATE_ACB_BMAX 0x08
115 #define VP_STATE_ACB_RMIN 0x10
116 #define VP_STATE_ACB_GMIN 0x20
117 #define VP_STATE_ACB_RMAX 0x40
118 #define VP_STATE_ACB_GMAX 0x80
120 /* default (minimum) compensation values */
122 #define COMP_GREEN1 214
123 #define COMP_GREEN2 COMP_GREEN1
124 #define COMP_BLUE 230
126 /* exposure status */
127 #define EXPOSURE_VERY_LIGHT 0
128 #define EXPOSURE_LIGHT 1
129 #define EXPOSURE_NORMAL 2
130 #define EXPOSURE_DARK 3
131 #define EXPOSURE_VERY_DARK 4
133 #define CPIA_MODULE_CPIA (0 << 5)
134 #define CPIA_MODULE_SYSTEM (1 << 5)
135 #define CPIA_MODULE_VP_CTRL (5 << 5)
136 #define CPIA_MODULE_CAPTURE (6 << 5)
137 #define CPIA_MODULE_DEBUG (7 << 5)
139 #define INPUT (DATA_IN << 8)
140 #define OUTPUT (DATA_OUT << 8)
142 #define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)
143 #define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)
144 #define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)
145 #define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)
146 #define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)
147 #define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)
148 #define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)
149 #define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)
151 #define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)
152 #define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)
153 #define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)
154 #define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)
155 #define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)
156 #define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)
157 #define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)
158 #define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)
159 #define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)
160 #define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)
161 #define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)
162 #define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)
163 #define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
165 #define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
166 #define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)
167 #define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
168 #define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
169 #define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
170 #define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)
171 #define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)
172 #define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)
173 #define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)
174 #define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)
175 #define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)
176 #define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)
177 #define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)
178 #define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)
179 #define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)
180 #define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)
181 #define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)
183 #define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)
184 #define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)
185 #define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)
186 #define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)
187 #define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)
188 #define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)
189 #define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)
190 #define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)
191 #define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)
192 #define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)
193 #define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
194 #define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
195 #define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
196 #define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
197 #define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)
199 #define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
200 #define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
201 #define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)
202 #define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)
203 #define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
204 #define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
205 #define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
206 #define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)
208 #define ROUND_UP_EXP_FOR_FLICKER 15
210 /* Constants for automatic frame rate adjustment */
212 #define MAX_EXP_102 255
214 #define VERY_LOW_EXP 70
216 #define EXP_ACC_DARK 50
217 #define EXP_ACC_LIGHT 90
218 #define HIGH_COMP_102 160
223 #define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \
224 sd->params.version.firmwareRevision == (y))
226 /* Developer's Guide Table 5 p 3-34
227 * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
228 static u8 flicker_jumps
[2][2][4] =
229 { { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
230 { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
299 u8 allowableOverExposure
;
325 u8 decimationHysteresis
;
328 u8 decimationThreshMod
;
331 u8 videoSize
; /* CIF/QCIF */
335 struct { /* Intel QX3 specific data */
336 u8 qx3_detected
; /* a QX3 is present */
337 u8 toplight
; /* top light lit , R/W */
338 u8 bottomlight
; /* bottom light lit, R/W */
339 u8 button
; /* snapshot button pressed (R/O) */
340 u8 cradled
; /* microscope is in cradle (R/O) */
343 u8 colStart
; /* skip first 8*colStart pixels */
344 u8 colEnd
; /* finish at 8*colEnd pixels */
345 u8 rowStart
; /* skip first 4*rowStart lines */
346 u8 rowEnd
; /* finish at 4*rowEnd lines */
352 /* specific webcam descriptor */
354 struct gspca_dev gspca_dev
; /* !! must be the first item */
355 struct cam_params params
; /* camera settings */
357 atomic_t cam_exposure
;
361 u8 mainsFreq
; /* 0 = 50hz, 1 = 60hz */
366 /* V4L2 controls supported by the driver */
367 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
);
368 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
);
369 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
);
370 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
);
371 static int sd_setsaturation(struct gspca_dev
*gspca_dev
, __s32 val
);
372 static int sd_getsaturation(struct gspca_dev
*gspca_dev
, __s32
*val
);
373 static int sd_setfreq(struct gspca_dev
*gspca_dev
, __s32 val
);
374 static int sd_getfreq(struct gspca_dev
*gspca_dev
, __s32
*val
);
375 static int sd_setcomptarget(struct gspca_dev
*gspca_dev
, __s32 val
);
376 static int sd_getcomptarget(struct gspca_dev
*gspca_dev
, __s32
*val
);
377 static int sd_setilluminator1(struct gspca_dev
*gspca_dev
, __s32 val
);
378 static int sd_getilluminator1(struct gspca_dev
*gspca_dev
, __s32
*val
);
379 static int sd_setilluminator2(struct gspca_dev
*gspca_dev
, __s32 val
);
380 static int sd_getilluminator2(struct gspca_dev
*gspca_dev
, __s32
*val
);
382 static const struct ctrl sd_ctrls
[] = {
384 #define BRIGHTNESS_IDX 0
386 .id
= V4L2_CID_BRIGHTNESS
,
387 .type
= V4L2_CTRL_TYPE_INTEGER
,
388 .name
= "Brightness",
392 #define BRIGHTNESS_DEF 50
393 .default_value
= BRIGHTNESS_DEF
,
396 .set
= sd_setbrightness
,
397 .get
= sd_getbrightness
,
399 #define CONTRAST_IDX 1
402 .id
= V4L2_CID_CONTRAST
,
403 .type
= V4L2_CTRL_TYPE_INTEGER
,
408 #define CONTRAST_DEF 48
409 .default_value
= CONTRAST_DEF
,
411 .set
= sd_setcontrast
,
412 .get
= sd_getcontrast
,
414 #define SATURATION_IDX 2
417 .id
= V4L2_CID_SATURATION
,
418 .type
= V4L2_CTRL_TYPE_INTEGER
,
419 .name
= "Saturation",
423 #define SATURATION_DEF 50
424 .default_value
= SATURATION_DEF
,
426 .set
= sd_setsaturation
,
427 .get
= sd_getsaturation
,
429 #define POWER_LINE_FREQUENCY_IDX 3
432 .id
= V4L2_CID_POWER_LINE_FREQUENCY
,
433 .type
= V4L2_CTRL_TYPE_MENU
,
434 .name
= "Light frequency filter",
436 .maximum
= 2, /* 0: 0, 1: 50Hz, 2:60Hz */
439 .default_value
= FREQ_DEF
,
444 #define ILLUMINATORS_1_IDX 4
447 .id
= V4L2_CID_ILLUMINATORS_1
,
448 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
449 .name
= "Illuminator 1",
453 #define ILLUMINATORS_1_DEF 0
454 .default_value
= ILLUMINATORS_1_DEF
,
456 .set
= sd_setilluminator1
,
457 .get
= sd_getilluminator1
,
459 #define ILLUMINATORS_2_IDX 5
462 .id
= V4L2_CID_ILLUMINATORS_2
,
463 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
464 .name
= "Illuminator 2",
468 #define ILLUMINATORS_2_DEF 0
469 .default_value
= ILLUMINATORS_2_DEF
,
471 .set
= sd_setilluminator2
,
472 .get
= sd_getilluminator2
,
474 #define COMP_TARGET_IDX 6
477 #define V4L2_CID_COMP_TARGET V4L2_CID_PRIVATE_BASE
478 .id
= V4L2_CID_COMP_TARGET
,
479 .type
= V4L2_CTRL_TYPE_MENU
,
480 .name
= "Compression Target",
484 #define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY
485 .default_value
= COMP_TARGET_DEF
,
487 .set
= sd_setcomptarget
,
488 .get
= sd_getcomptarget
,
492 static const struct v4l2_pix_format mode
[] = {
493 {160, 120, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
494 /* The sizeimage is trial and error, as with low framerates
495 the camera will pad out usb frames, making the image
496 data larger then strictly necessary */
499 .colorspace
= V4L2_COLORSPACE_SRGB
,
501 {176, 144, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
504 .colorspace
= V4L2_COLORSPACE_SRGB
,
506 {320, 240, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
509 .colorspace
= V4L2_COLORSPACE_SRGB
,
511 {352, 288, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
514 .colorspace
= V4L2_COLORSPACE_SRGB
,
518 /**********************************************************************
522 **********************************************************************/
524 static int cpia_usb_transferCmd(struct gspca_dev
*gspca_dev
, u8
*command
)
528 int ret
, databytes
= command
[6] | (command
[7] << 8);
529 /* Sometimes we see spurious EPIPE errors */
532 if (command
[0] == DATA_IN
) {
533 pipe
= usb_rcvctrlpipe(gspca_dev
->dev
, 0);
534 requesttype
= USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
;
535 } else if (command
[0] == DATA_OUT
) {
536 pipe
= usb_sndctrlpipe(gspca_dev
->dev
, 0);
537 requesttype
= USB_TYPE_VENDOR
| USB_RECIP_DEVICE
;
539 PDEBUG(D_ERR
, "Unexpected first byte of command: %x",
545 ret
= usb_control_msg(gspca_dev
->dev
, pipe
,
548 command
[2] | (command
[3] << 8),
549 command
[4] | (command
[5] << 8),
550 gspca_dev
->usb_buf
, databytes
, 1000);
553 err("usb_control_msg %02x, error %d", command
[1],
556 if (ret
== -EPIPE
&& retries
> 0) {
561 return (ret
< 0) ? ret
: 0;
564 /* send an arbitrary command to the camera */
565 static int do_command(struct gspca_dev
*gspca_dev
, u16 command
,
566 u8 a
, u8 b
, u8 c
, u8 d
)
568 struct sd
*sd
= (struct sd
*) gspca_dev
;
573 case CPIA_COMMAND_GetCPIAVersion
:
574 case CPIA_COMMAND_GetPnPID
:
575 case CPIA_COMMAND_GetCameraStatus
:
576 case CPIA_COMMAND_GetVPVersion
:
577 case CPIA_COMMAND_GetColourParams
:
578 case CPIA_COMMAND_GetColourBalance
:
579 case CPIA_COMMAND_GetExposure
:
582 case CPIA_COMMAND_ReadMCPorts
:
583 case CPIA_COMMAND_ReadVCRegs
:
591 cmd
[0] = command
>> 8;
592 cmd
[1] = command
& 0xff;
600 ret
= cpia_usb_transferCmd(gspca_dev
, cmd
);
605 case CPIA_COMMAND_GetCPIAVersion
:
606 sd
->params
.version
.firmwareVersion
= gspca_dev
->usb_buf
[0];
607 sd
->params
.version
.firmwareRevision
= gspca_dev
->usb_buf
[1];
608 sd
->params
.version
.vcVersion
= gspca_dev
->usb_buf
[2];
609 sd
->params
.version
.vcRevision
= gspca_dev
->usb_buf
[3];
611 case CPIA_COMMAND_GetPnPID
:
612 sd
->params
.pnpID
.vendor
=
613 gspca_dev
->usb_buf
[0] | (gspca_dev
->usb_buf
[1] << 8);
614 sd
->params
.pnpID
.product
=
615 gspca_dev
->usb_buf
[2] | (gspca_dev
->usb_buf
[3] << 8);
616 sd
->params
.pnpID
.deviceRevision
=
617 gspca_dev
->usb_buf
[4] | (gspca_dev
->usb_buf
[5] << 8);
619 case CPIA_COMMAND_GetCameraStatus
:
620 sd
->params
.status
.systemState
= gspca_dev
->usb_buf
[0];
621 sd
->params
.status
.grabState
= gspca_dev
->usb_buf
[1];
622 sd
->params
.status
.streamState
= gspca_dev
->usb_buf
[2];
623 sd
->params
.status
.fatalError
= gspca_dev
->usb_buf
[3];
624 sd
->params
.status
.cmdError
= gspca_dev
->usb_buf
[4];
625 sd
->params
.status
.debugFlags
= gspca_dev
->usb_buf
[5];
626 sd
->params
.status
.vpStatus
= gspca_dev
->usb_buf
[6];
627 sd
->params
.status
.errorCode
= gspca_dev
->usb_buf
[7];
629 case CPIA_COMMAND_GetVPVersion
:
630 sd
->params
.vpVersion
.vpVersion
= gspca_dev
->usb_buf
[0];
631 sd
->params
.vpVersion
.vpRevision
= gspca_dev
->usb_buf
[1];
632 sd
->params
.vpVersion
.cameraHeadID
=
633 gspca_dev
->usb_buf
[2] | (gspca_dev
->usb_buf
[3] << 8);
635 case CPIA_COMMAND_GetColourParams
:
636 sd
->params
.colourParams
.brightness
= gspca_dev
->usb_buf
[0];
637 sd
->params
.colourParams
.contrast
= gspca_dev
->usb_buf
[1];
638 sd
->params
.colourParams
.saturation
= gspca_dev
->usb_buf
[2];
640 case CPIA_COMMAND_GetColourBalance
:
641 sd
->params
.colourBalance
.redGain
= gspca_dev
->usb_buf
[0];
642 sd
->params
.colourBalance
.greenGain
= gspca_dev
->usb_buf
[1];
643 sd
->params
.colourBalance
.blueGain
= gspca_dev
->usb_buf
[2];
645 case CPIA_COMMAND_GetExposure
:
646 sd
->params
.exposure
.gain
= gspca_dev
->usb_buf
[0];
647 sd
->params
.exposure
.fineExp
= gspca_dev
->usb_buf
[1];
648 sd
->params
.exposure
.coarseExpLo
= gspca_dev
->usb_buf
[2];
649 sd
->params
.exposure
.coarseExpHi
= gspca_dev
->usb_buf
[3];
650 sd
->params
.exposure
.redComp
= gspca_dev
->usb_buf
[4];
651 sd
->params
.exposure
.green1Comp
= gspca_dev
->usb_buf
[5];
652 sd
->params
.exposure
.green2Comp
= gspca_dev
->usb_buf
[6];
653 sd
->params
.exposure
.blueComp
= gspca_dev
->usb_buf
[7];
656 case CPIA_COMMAND_ReadMCPorts
:
657 /* test button press */
658 a
= ((gspca_dev
->usb_buf
[1] & 0x02) == 0);
659 if (a
!= sd
->params
.qx3
.button
) {
660 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
661 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, a
);
662 input_sync(gspca_dev
->input_dev
);
664 sd
->params
.qx3
.button
= a
;
666 if (sd
->params
.qx3
.button
) {
667 /* button pressed - unlock the latch */
668 do_command(gspca_dev
, CPIA_COMMAND_WriteMCPort
,
670 do_command(gspca_dev
, CPIA_COMMAND_WriteMCPort
,
674 /* test whether microscope is cradled */
675 sd
->params
.qx3
.cradled
= ((gspca_dev
->usb_buf
[2] & 0x40) == 0);
682 /* send a command to the camera with an additional data transaction */
683 static int do_command_extended(struct gspca_dev
*gspca_dev
, u16 command
,
684 u8 a
, u8 b
, u8 c
, u8 d
,
685 u8 e
, u8 f
, u8 g
, u8 h
,
686 u8 i
, u8 j
, u8 k
, u8 l
)
690 cmd
[0] = command
>> 8;
691 cmd
[1] = command
& 0xff;
698 gspca_dev
->usb_buf
[0] = e
;
699 gspca_dev
->usb_buf
[1] = f
;
700 gspca_dev
->usb_buf
[2] = g
;
701 gspca_dev
->usb_buf
[3] = h
;
702 gspca_dev
->usb_buf
[4] = i
;
703 gspca_dev
->usb_buf
[5] = j
;
704 gspca_dev
->usb_buf
[6] = k
;
705 gspca_dev
->usb_buf
[7] = l
;
707 return cpia_usb_transferCmd(gspca_dev
, cmd
);
710 /* find_over_exposure
711 * Finds a suitable value of OverExposure for use with SetFlickerCtrl
712 * Some calculation is required because this value changes with the brightness
713 * set with SetColourParameters
715 * Parameters: Brightness - last brightness value set with SetColourParameters
717 * Returns: OverExposure value to use with SetFlickerCtrl
719 #define FLICKER_MAX_EXPOSURE 250
720 #define FLICKER_ALLOWABLE_OVER_EXPOSURE 146
721 #define FLICKER_BRIGHTNESS_CONSTANT 59
722 static int find_over_exposure(int brightness
)
724 int MaxAllowableOverExposure
, OverExposure
;
726 MaxAllowableOverExposure
= FLICKER_MAX_EXPOSURE
- brightness
-
727 FLICKER_BRIGHTNESS_CONSTANT
;
729 if (MaxAllowableOverExposure
< FLICKER_ALLOWABLE_OVER_EXPOSURE
)
730 OverExposure
= MaxAllowableOverExposure
;
732 OverExposure
= FLICKER_ALLOWABLE_OVER_EXPOSURE
;
736 #undef FLICKER_MAX_EXPOSURE
737 #undef FLICKER_ALLOWABLE_OVER_EXPOSURE
738 #undef FLICKER_BRIGHTNESS_CONSTANT
740 /* initialise cam_data structure */
741 static void reset_camera_params(struct gspca_dev
*gspca_dev
)
743 struct sd
*sd
= (struct sd
*) gspca_dev
;
744 struct cam_params
*params
= &sd
->params
;
746 /* The following parameter values are the defaults from
747 * "Software Developer's Guide for CPiA Cameras". Any changes
748 * to the defaults are noted in comments. */
749 params
->colourParams
.brightness
= BRIGHTNESS_DEF
;
750 params
->colourParams
.contrast
= CONTRAST_DEF
;
751 params
->colourParams
.saturation
= SATURATION_DEF
;
752 params
->exposure
.gainMode
= 4;
753 params
->exposure
.expMode
= 2; /* AEC */
754 params
->exposure
.compMode
= 1;
755 params
->exposure
.centreWeight
= 1;
756 params
->exposure
.gain
= 0;
757 params
->exposure
.fineExp
= 0;
758 params
->exposure
.coarseExpLo
= 185;
759 params
->exposure
.coarseExpHi
= 0;
760 params
->exposure
.redComp
= COMP_RED
;
761 params
->exposure
.green1Comp
= COMP_GREEN1
;
762 params
->exposure
.green2Comp
= COMP_GREEN2
;
763 params
->exposure
.blueComp
= COMP_BLUE
;
764 params
->colourBalance
.balanceMode
= 2; /* ACB */
765 params
->colourBalance
.redGain
= 32;
766 params
->colourBalance
.greenGain
= 6;
767 params
->colourBalance
.blueGain
= 92;
768 params
->apcor
.gain1
= 0x18;
769 params
->apcor
.gain2
= 0x16;
770 params
->apcor
.gain4
= 0x24;
771 params
->apcor
.gain8
= 0x34;
772 params
->flickerControl
.flickerMode
= 0;
773 params
->flickerControl
.disabled
= 1;
775 params
->flickerControl
.coarseJump
=
776 flicker_jumps
[sd
->mainsFreq
]
777 [params
->sensorFps
.baserate
]
778 [params
->sensorFps
.divisor
];
779 params
->flickerControl
.allowableOverExposure
=
780 find_over_exposure(params
->colourParams
.brightness
);
781 params
->vlOffset
.gain1
= 20;
782 params
->vlOffset
.gain2
= 24;
783 params
->vlOffset
.gain4
= 26;
784 params
->vlOffset
.gain8
= 26;
785 params
->compressionParams
.hysteresis
= 3;
786 params
->compressionParams
.threshMax
= 11;
787 params
->compressionParams
.smallStep
= 1;
788 params
->compressionParams
.largeStep
= 3;
789 params
->compressionParams
.decimationHysteresis
= 2;
790 params
->compressionParams
.frDiffStepThresh
= 5;
791 params
->compressionParams
.qDiffStepThresh
= 3;
792 params
->compressionParams
.decimationThreshMod
= 2;
793 /* End of default values from Software Developer's Guide */
795 /* Set Sensor FPS to 15fps. This seems better than 30fps
796 * for indoor lighting. */
797 params
->sensorFps
.divisor
= 1;
798 params
->sensorFps
.baserate
= 1;
800 params
->yuvThreshold
.yThreshold
= 6; /* From windows driver */
801 params
->yuvThreshold
.uvThreshold
= 6; /* From windows driver */
803 params
->format
.subSample
= SUBSAMPLE_420
;
804 params
->format
.yuvOrder
= YUVORDER_YUYV
;
806 params
->compression
.mode
= CPIA_COMPRESSION_AUTO
;
807 params
->compression
.decimation
= NO_DECIMATION
;
809 params
->compressionTarget
.frTargeting
= COMP_TARGET_DEF
;
810 params
->compressionTarget
.targetFR
= 15; /* From windows driver */
811 params
->compressionTarget
.targetQ
= 5; /* From windows driver */
813 params
->qx3
.qx3_detected
= 0;
814 params
->qx3
.toplight
= 0;
815 params
->qx3
.bottomlight
= 0;
816 params
->qx3
.button
= 0;
817 params
->qx3
.cradled
= 0;
820 static void printstatus(struct cam_params
*params
)
822 PDEBUG(D_PROBE
, "status: %02x %02x %02x %02x %02x %02x %02x %02x",
823 params
->status
.systemState
, params
->status
.grabState
,
824 params
->status
.streamState
, params
->status
.fatalError
,
825 params
->status
.cmdError
, params
->status
.debugFlags
,
826 params
->status
.vpStatus
, params
->status
.errorCode
);
829 static int goto_low_power(struct gspca_dev
*gspca_dev
)
831 struct sd
*sd
= (struct sd
*) gspca_dev
;
834 ret
= do_command(gspca_dev
, CPIA_COMMAND_GotoLoPower
, 0, 0, 0, 0);
838 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
842 if (sd
->params
.status
.systemState
!= LO_POWER_STATE
) {
843 if (sd
->params
.status
.systemState
!= WARM_BOOT_STATE
) {
845 "unexpected state after lo power cmd: %02x",
846 sd
->params
.status
.systemState
);
847 printstatus(&sd
->params
);
852 PDEBUG(D_CONF
, "camera now in LOW power state");
856 static int goto_high_power(struct gspca_dev
*gspca_dev
)
858 struct sd
*sd
= (struct sd
*) gspca_dev
;
861 ret
= do_command(gspca_dev
, CPIA_COMMAND_GotoHiPower
, 0, 0, 0, 0);
865 msleep_interruptible(40); /* windows driver does it too */
867 if (signal_pending(current
))
870 do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
874 if (sd
->params
.status
.systemState
!= HI_POWER_STATE
) {
875 PDEBUG(D_ERR
, "unexpected state after hi power cmd: %02x",
876 sd
->params
.status
.systemState
);
877 printstatus(&sd
->params
);
881 PDEBUG(D_CONF
, "camera now in HIGH power state");
885 static int get_version_information(struct gspca_dev
*gspca_dev
)
890 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetCPIAVersion
, 0, 0, 0, 0);
895 return do_command(gspca_dev
, CPIA_COMMAND_GetPnPID
, 0, 0, 0, 0);
898 static int save_camera_state(struct gspca_dev
*gspca_dev
)
902 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetColourBalance
, 0, 0, 0, 0);
906 return do_command(gspca_dev
, CPIA_COMMAND_GetExposure
, 0, 0, 0, 0);
909 static int command_setformat(struct gspca_dev
*gspca_dev
)
911 struct sd
*sd
= (struct sd
*) gspca_dev
;
914 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetFormat
,
915 sd
->params
.format
.videoSize
,
916 sd
->params
.format
.subSample
,
917 sd
->params
.format
.yuvOrder
, 0);
921 return do_command(gspca_dev
, CPIA_COMMAND_SetROI
,
922 sd
->params
.roi
.colStart
, sd
->params
.roi
.colEnd
,
923 sd
->params
.roi
.rowStart
, sd
->params
.roi
.rowEnd
);
926 static int command_setcolourparams(struct gspca_dev
*gspca_dev
)
928 struct sd
*sd
= (struct sd
*) gspca_dev
;
929 return do_command(gspca_dev
, CPIA_COMMAND_SetColourParams
,
930 sd
->params
.colourParams
.brightness
,
931 sd
->params
.colourParams
.contrast
,
932 sd
->params
.colourParams
.saturation
, 0);
935 static int command_setapcor(struct gspca_dev
*gspca_dev
)
937 struct sd
*sd
= (struct sd
*) gspca_dev
;
938 return do_command(gspca_dev
, CPIA_COMMAND_SetApcor
,
939 sd
->params
.apcor
.gain1
,
940 sd
->params
.apcor
.gain2
,
941 sd
->params
.apcor
.gain4
,
942 sd
->params
.apcor
.gain8
);
945 static int command_setvloffset(struct gspca_dev
*gspca_dev
)
947 struct sd
*sd
= (struct sd
*) gspca_dev
;
948 return do_command(gspca_dev
, CPIA_COMMAND_SetVLOffset
,
949 sd
->params
.vlOffset
.gain1
,
950 sd
->params
.vlOffset
.gain2
,
951 sd
->params
.vlOffset
.gain4
,
952 sd
->params
.vlOffset
.gain8
);
955 static int command_setexposure(struct gspca_dev
*gspca_dev
)
957 struct sd
*sd
= (struct sd
*) gspca_dev
;
960 ret
= do_command_extended(gspca_dev
, CPIA_COMMAND_SetExposure
,
961 sd
->params
.exposure
.gainMode
,
963 sd
->params
.exposure
.compMode
,
964 sd
->params
.exposure
.centreWeight
,
965 sd
->params
.exposure
.gain
,
966 sd
->params
.exposure
.fineExp
,
967 sd
->params
.exposure
.coarseExpLo
,
968 sd
->params
.exposure
.coarseExpHi
,
969 sd
->params
.exposure
.redComp
,
970 sd
->params
.exposure
.green1Comp
,
971 sd
->params
.exposure
.green2Comp
,
972 sd
->params
.exposure
.blueComp
);
976 if (sd
->params
.exposure
.expMode
!= 1) {
977 ret
= do_command_extended(gspca_dev
, CPIA_COMMAND_SetExposure
,
979 sd
->params
.exposure
.expMode
,
981 sd
->params
.exposure
.gain
,
982 sd
->params
.exposure
.fineExp
,
983 sd
->params
.exposure
.coarseExpLo
,
984 sd
->params
.exposure
.coarseExpHi
,
991 static int command_setcolourbalance(struct gspca_dev
*gspca_dev
)
993 struct sd
*sd
= (struct sd
*) gspca_dev
;
995 if (sd
->params
.colourBalance
.balanceMode
== 1) {
998 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
1000 sd
->params
.colourBalance
.redGain
,
1001 sd
->params
.colourBalance
.greenGain
,
1002 sd
->params
.colourBalance
.blueGain
);
1006 return do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
1009 if (sd
->params
.colourBalance
.balanceMode
== 2) {
1010 return do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
1013 if (sd
->params
.colourBalance
.balanceMode
== 3) {
1014 return do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
1021 static int command_setcompressiontarget(struct gspca_dev
*gspca_dev
)
1023 struct sd
*sd
= (struct sd
*) gspca_dev
;
1025 return do_command(gspca_dev
, CPIA_COMMAND_SetCompressionTarget
,
1026 sd
->params
.compressionTarget
.frTargeting
,
1027 sd
->params
.compressionTarget
.targetFR
,
1028 sd
->params
.compressionTarget
.targetQ
, 0);
1031 static int command_setyuvtresh(struct gspca_dev
*gspca_dev
)
1033 struct sd
*sd
= (struct sd
*) gspca_dev
;
1035 return do_command(gspca_dev
, CPIA_COMMAND_SetYUVThresh
,
1036 sd
->params
.yuvThreshold
.yThreshold
,
1037 sd
->params
.yuvThreshold
.uvThreshold
, 0, 0);
1040 static int command_setcompressionparams(struct gspca_dev
*gspca_dev
)
1042 struct sd
*sd
= (struct sd
*) gspca_dev
;
1044 return do_command_extended(gspca_dev
,
1045 CPIA_COMMAND_SetCompressionParams
,
1047 sd
->params
.compressionParams
.hysteresis
,
1048 sd
->params
.compressionParams
.threshMax
,
1049 sd
->params
.compressionParams
.smallStep
,
1050 sd
->params
.compressionParams
.largeStep
,
1051 sd
->params
.compressionParams
.decimationHysteresis
,
1052 sd
->params
.compressionParams
.frDiffStepThresh
,
1053 sd
->params
.compressionParams
.qDiffStepThresh
,
1054 sd
->params
.compressionParams
.decimationThreshMod
);
1057 static int command_setcompression(struct gspca_dev
*gspca_dev
)
1059 struct sd
*sd
= (struct sd
*) gspca_dev
;
1061 return do_command(gspca_dev
, CPIA_COMMAND_SetCompression
,
1062 sd
->params
.compression
.mode
,
1063 sd
->params
.compression
.decimation
, 0, 0);
1066 static int command_setsensorfps(struct gspca_dev
*gspca_dev
)
1068 struct sd
*sd
= (struct sd
*) gspca_dev
;
1070 return do_command(gspca_dev
, CPIA_COMMAND_SetSensorFPS
,
1071 sd
->params
.sensorFps
.divisor
,
1072 sd
->params
.sensorFps
.baserate
, 0, 0);
1075 static int command_setflickerctrl(struct gspca_dev
*gspca_dev
)
1077 struct sd
*sd
= (struct sd
*) gspca_dev
;
1079 return do_command(gspca_dev
, CPIA_COMMAND_SetFlickerCtrl
,
1080 sd
->params
.flickerControl
.flickerMode
,
1081 sd
->params
.flickerControl
.coarseJump
,
1082 sd
->params
.flickerControl
.allowableOverExposure
,
1086 static int command_setecptiming(struct gspca_dev
*gspca_dev
)
1088 struct sd
*sd
= (struct sd
*) gspca_dev
;
1090 return do_command(gspca_dev
, CPIA_COMMAND_SetECPTiming
,
1091 sd
->params
.ecpTiming
, 0, 0, 0);
1094 static int command_pause(struct gspca_dev
*gspca_dev
)
1096 return do_command(gspca_dev
, CPIA_COMMAND_EndStreamCap
, 0, 0, 0, 0);
1099 static int command_resume(struct gspca_dev
*gspca_dev
)
1101 struct sd
*sd
= (struct sd
*) gspca_dev
;
1103 return do_command(gspca_dev
, CPIA_COMMAND_InitStreamCap
,
1104 0, sd
->params
.streamStartLine
, 0, 0);
1107 static int command_setlights(struct gspca_dev
*gspca_dev
)
1109 struct sd
*sd
= (struct sd
*) gspca_dev
;
1112 if (!sd
->params
.qx3
.qx3_detected
)
1115 p1
= (sd
->params
.qx3
.bottomlight
== 0) << 1;
1116 p2
= (sd
->params
.qx3
.toplight
== 0) << 3;
1118 ret
= do_command(gspca_dev
, CPIA_COMMAND_WriteVCReg
,
1119 0x90, 0x8f, 0x50, 0);
1123 return do_command(gspca_dev
, CPIA_COMMAND_WriteMCPort
, 2, 0,
1127 static int set_flicker(struct gspca_dev
*gspca_dev
, int on
, int apply
)
1129 /* Everything in here is from the Windows driver */
1130 /* define for compgain calculation */
1132 #define COMPGAIN(base, curexp, newexp) \
1133 (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
1134 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1135 (u16)((float)curexp * (float)(u8)(curcomp + 128) / \
1136 (float)(u8)(basecomp - 128))
1138 /* equivalent functions without floating point math */
1139 #define COMPGAIN(base, curexp, newexp) \
1140 (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2 * newexp)))
1141 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1142 (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
1145 struct sd
*sd
= (struct sd
*) gspca_dev
;
1146 int currentexp
= sd
->params
.exposure
.coarseExpLo
+
1147 sd
->params
.exposure
.coarseExpHi
* 256;
1151 int cj
= sd
->params
.flickerControl
.coarseJump
;
1152 sd
->params
.flickerControl
.flickerMode
= 1;
1153 sd
->params
.flickerControl
.disabled
= 0;
1154 if (sd
->params
.exposure
.expMode
!= 2) {
1155 sd
->params
.exposure
.expMode
= 2;
1156 sd
->exposure_status
= EXPOSURE_NORMAL
;
1158 currentexp
= currentexp
<< sd
->params
.exposure
.gain
;
1159 sd
->params
.exposure
.gain
= 0;
1160 /* round down current exposure to nearest value */
1161 startexp
= (currentexp
+ ROUND_UP_EXP_FOR_FLICKER
) / cj
;
1164 startexp
= (startexp
* cj
) - 1;
1165 if (FIRMWARE_VERSION(1, 2))
1166 while (startexp
> MAX_EXP_102
)
1169 while (startexp
> MAX_EXP
)
1171 sd
->params
.exposure
.coarseExpLo
= startexp
& 0xff;
1172 sd
->params
.exposure
.coarseExpHi
= startexp
>> 8;
1173 if (currentexp
> startexp
) {
1174 if (currentexp
> (2 * startexp
))
1175 currentexp
= 2 * startexp
;
1176 sd
->params
.exposure
.redComp
=
1177 COMPGAIN(COMP_RED
, currentexp
, startexp
);
1178 sd
->params
.exposure
.green1Comp
=
1179 COMPGAIN(COMP_GREEN1
, currentexp
, startexp
);
1180 sd
->params
.exposure
.green2Comp
=
1181 COMPGAIN(COMP_GREEN2
, currentexp
, startexp
);
1182 sd
->params
.exposure
.blueComp
=
1183 COMPGAIN(COMP_BLUE
, currentexp
, startexp
);
1185 sd
->params
.exposure
.redComp
= COMP_RED
;
1186 sd
->params
.exposure
.green1Comp
= COMP_GREEN1
;
1187 sd
->params
.exposure
.green2Comp
= COMP_GREEN2
;
1188 sd
->params
.exposure
.blueComp
= COMP_BLUE
;
1190 if (FIRMWARE_VERSION(1, 2))
1191 sd
->params
.exposure
.compMode
= 0;
1193 sd
->params
.exposure
.compMode
= 1;
1195 sd
->params
.apcor
.gain1
= 0x18;
1196 sd
->params
.apcor
.gain2
= 0x18;
1197 sd
->params
.apcor
.gain4
= 0x16;
1198 sd
->params
.apcor
.gain8
= 0x14;
1200 sd
->params
.flickerControl
.flickerMode
= 0;
1201 sd
->params
.flickerControl
.disabled
= 1;
1202 /* Average equivalent coarse for each comp channel */
1203 startexp
= EXP_FROM_COMP(COMP_RED
,
1204 sd
->params
.exposure
.redComp
, currentexp
);
1205 startexp
+= EXP_FROM_COMP(COMP_GREEN1
,
1206 sd
->params
.exposure
.green1Comp
, currentexp
);
1207 startexp
+= EXP_FROM_COMP(COMP_GREEN2
,
1208 sd
->params
.exposure
.green2Comp
, currentexp
);
1209 startexp
+= EXP_FROM_COMP(COMP_BLUE
,
1210 sd
->params
.exposure
.blueComp
, currentexp
);
1211 startexp
= startexp
>> 2;
1212 while (startexp
> MAX_EXP
&& sd
->params
.exposure
.gain
<
1213 sd
->params
.exposure
.gainMode
- 1) {
1214 startexp
= startexp
>> 1;
1215 ++sd
->params
.exposure
.gain
;
1217 if (FIRMWARE_VERSION(1, 2) && startexp
> MAX_EXP_102
)
1218 startexp
= MAX_EXP_102
;
1219 if (startexp
> MAX_EXP
)
1221 sd
->params
.exposure
.coarseExpLo
= startexp
& 0xff;
1222 sd
->params
.exposure
.coarseExpHi
= startexp
>> 8;
1223 sd
->params
.exposure
.redComp
= COMP_RED
;
1224 sd
->params
.exposure
.green1Comp
= COMP_GREEN1
;
1225 sd
->params
.exposure
.green2Comp
= COMP_GREEN2
;
1226 sd
->params
.exposure
.blueComp
= COMP_BLUE
;
1227 sd
->params
.exposure
.compMode
= 1;
1228 sd
->params
.apcor
.gain1
= 0x18;
1229 sd
->params
.apcor
.gain2
= 0x16;
1230 sd
->params
.apcor
.gain4
= 0x24;
1231 sd
->params
.apcor
.gain8
= 0x34;
1233 sd
->params
.vlOffset
.gain1
= 20;
1234 sd
->params
.vlOffset
.gain2
= 24;
1235 sd
->params
.vlOffset
.gain4
= 26;
1236 sd
->params
.vlOffset
.gain8
= 26;
1239 ret
= command_setexposure(gspca_dev
);
1243 ret
= command_setapcor(gspca_dev
);
1247 ret
= command_setvloffset(gspca_dev
);
1251 ret
= command_setflickerctrl(gspca_dev
);
1257 #undef EXP_FROM_COMP
1261 /* monitor the exposure and adjust the sensor frame rate if needed */
1262 static void monitor_exposure(struct gspca_dev
*gspca_dev
)
1264 struct sd
*sd
= (struct sd
*) gspca_dev
;
1265 u8 exp_acc
, bcomp
, cmd
[8];
1266 int ret
, light_exp
, dark_exp
, very_dark_exp
;
1267 int old_exposure
, new_exposure
, framerate
;
1268 int setfps
= 0, setexp
= 0, setflicker
= 0;
1270 /* get necessary stats and register settings from camera */
1271 /* do_command can't handle this, so do it ourselves */
1272 cmd
[0] = CPIA_COMMAND_ReadVPRegs
>> 8;
1273 cmd
[1] = CPIA_COMMAND_ReadVPRegs
& 0xff;
1280 ret
= cpia_usb_transferCmd(gspca_dev
, cmd
);
1282 err("ReadVPRegs(30,4,9,8) - failed: %d", ret
);
1285 exp_acc
= gspca_dev
->usb_buf
[0];
1286 bcomp
= gspca_dev
->usb_buf
[1];
1288 light_exp
= sd
->params
.colourParams
.brightness
+
1289 TC
- 50 + EXP_ACC_LIGHT
;
1290 if (light_exp
> 255)
1292 dark_exp
= sd
->params
.colourParams
.brightness
+
1293 TC
- 50 - EXP_ACC_DARK
;
1296 very_dark_exp
= dark_exp
/ 2;
1298 old_exposure
= sd
->params
.exposure
.coarseExpHi
* 256 +
1299 sd
->params
.exposure
.coarseExpLo
;
1301 if (!sd
->params
.flickerControl
.disabled
) {
1302 /* Flicker control on */
1303 int max_comp
= FIRMWARE_VERSION(1, 2) ? MAX_COMP
:
1305 bcomp
+= 128; /* decode */
1306 if (bcomp
>= max_comp
&& exp_acc
< dark_exp
) {
1308 if (exp_acc
< very_dark_exp
) {
1310 if (sd
->exposure_status
== EXPOSURE_VERY_DARK
)
1311 ++sd
->exposure_count
;
1313 sd
->exposure_status
=
1315 sd
->exposure_count
= 1;
1319 if (sd
->exposure_status
== EXPOSURE_DARK
)
1320 ++sd
->exposure_count
;
1322 sd
->exposure_status
= EXPOSURE_DARK
;
1323 sd
->exposure_count
= 1;
1326 } else if (old_exposure
<= LOW_EXP
|| exp_acc
> light_exp
) {
1328 if (old_exposure
<= VERY_LOW_EXP
) {
1330 if (sd
->exposure_status
== EXPOSURE_VERY_LIGHT
)
1331 ++sd
->exposure_count
;
1333 sd
->exposure_status
=
1334 EXPOSURE_VERY_LIGHT
;
1335 sd
->exposure_count
= 1;
1339 if (sd
->exposure_status
== EXPOSURE_LIGHT
)
1340 ++sd
->exposure_count
;
1342 sd
->exposure_status
= EXPOSURE_LIGHT
;
1343 sd
->exposure_count
= 1;
1347 /* not dark or light */
1348 sd
->exposure_status
= EXPOSURE_NORMAL
;
1351 /* Flicker control off */
1352 if (old_exposure
>= MAX_EXP
&& exp_acc
< dark_exp
) {
1354 if (exp_acc
< very_dark_exp
) {
1356 if (sd
->exposure_status
== EXPOSURE_VERY_DARK
)
1357 ++sd
->exposure_count
;
1359 sd
->exposure_status
=
1361 sd
->exposure_count
= 1;
1365 if (sd
->exposure_status
== EXPOSURE_DARK
)
1366 ++sd
->exposure_count
;
1368 sd
->exposure_status
= EXPOSURE_DARK
;
1369 sd
->exposure_count
= 1;
1372 } else if (old_exposure
<= LOW_EXP
|| exp_acc
> light_exp
) {
1374 if (old_exposure
<= VERY_LOW_EXP
) {
1376 if (sd
->exposure_status
== EXPOSURE_VERY_LIGHT
)
1377 ++sd
->exposure_count
;
1379 sd
->exposure_status
=
1380 EXPOSURE_VERY_LIGHT
;
1381 sd
->exposure_count
= 1;
1385 if (sd
->exposure_status
== EXPOSURE_LIGHT
)
1386 ++sd
->exposure_count
;
1388 sd
->exposure_status
= EXPOSURE_LIGHT
;
1389 sd
->exposure_count
= 1;
1393 /* not dark or light */
1394 sd
->exposure_status
= EXPOSURE_NORMAL
;
1398 framerate
= atomic_read(&sd
->fps
);
1399 if (framerate
> 30 || framerate
< 1)
1402 if (!sd
->params
.flickerControl
.disabled
) {
1403 /* Flicker control on */
1404 if ((sd
->exposure_status
== EXPOSURE_VERY_DARK
||
1405 sd
->exposure_status
== EXPOSURE_DARK
) &&
1406 sd
->exposure_count
>= DARK_TIME
* framerate
&&
1407 sd
->params
.sensorFps
.divisor
< 2) {
1409 /* dark for too long */
1410 ++sd
->params
.sensorFps
.divisor
;
1413 sd
->params
.flickerControl
.coarseJump
=
1414 flicker_jumps
[sd
->mainsFreq
]
1415 [sd
->params
.sensorFps
.baserate
]
1416 [sd
->params
.sensorFps
.divisor
];
1419 new_exposure
= sd
->params
.flickerControl
.coarseJump
-1;
1420 while (new_exposure
< old_exposure
/ 2)
1422 sd
->params
.flickerControl
.coarseJump
;
1423 sd
->params
.exposure
.coarseExpLo
= new_exposure
& 0xff;
1424 sd
->params
.exposure
.coarseExpHi
= new_exposure
>> 8;
1426 sd
->exposure_status
= EXPOSURE_NORMAL
;
1427 PDEBUG(D_CONF
, "Automatically decreasing sensor_fps");
1429 } else if ((sd
->exposure_status
== EXPOSURE_VERY_LIGHT
||
1430 sd
->exposure_status
== EXPOSURE_LIGHT
) &&
1431 sd
->exposure_count
>= LIGHT_TIME
* framerate
&&
1432 sd
->params
.sensorFps
.divisor
> 0) {
1434 /* light for too long */
1435 int max_exp
= FIRMWARE_VERSION(1, 2) ? MAX_EXP_102
:
1437 --sd
->params
.sensorFps
.divisor
;
1440 sd
->params
.flickerControl
.coarseJump
=
1441 flicker_jumps
[sd
->mainsFreq
]
1442 [sd
->params
.sensorFps
.baserate
]
1443 [sd
->params
.sensorFps
.divisor
];
1446 new_exposure
= sd
->params
.flickerControl
.coarseJump
-1;
1447 while (new_exposure
< 2 * old_exposure
&&
1449 sd
->params
.flickerControl
.coarseJump
< max_exp
)
1451 sd
->params
.flickerControl
.coarseJump
;
1452 sd
->params
.exposure
.coarseExpLo
= new_exposure
& 0xff;
1453 sd
->params
.exposure
.coarseExpHi
= new_exposure
>> 8;
1455 sd
->exposure_status
= EXPOSURE_NORMAL
;
1456 PDEBUG(D_CONF
, "Automatically increasing sensor_fps");
1459 /* Flicker control off */
1460 if ((sd
->exposure_status
== EXPOSURE_VERY_DARK
||
1461 sd
->exposure_status
== EXPOSURE_DARK
) &&
1462 sd
->exposure_count
>= DARK_TIME
* framerate
&&
1463 sd
->params
.sensorFps
.divisor
< 2) {
1465 /* dark for too long */
1466 ++sd
->params
.sensorFps
.divisor
;
1469 if (sd
->params
.exposure
.gain
> 0) {
1470 --sd
->params
.exposure
.gain
;
1473 sd
->exposure_status
= EXPOSURE_NORMAL
;
1474 PDEBUG(D_CONF
, "Automatically decreasing sensor_fps");
1476 } else if ((sd
->exposure_status
== EXPOSURE_VERY_LIGHT
||
1477 sd
->exposure_status
== EXPOSURE_LIGHT
) &&
1478 sd
->exposure_count
>= LIGHT_TIME
* framerate
&&
1479 sd
->params
.sensorFps
.divisor
> 0) {
1481 /* light for too long */
1482 --sd
->params
.sensorFps
.divisor
;
1485 if (sd
->params
.exposure
.gain
<
1486 sd
->params
.exposure
.gainMode
- 1) {
1487 ++sd
->params
.exposure
.gain
;
1490 sd
->exposure_status
= EXPOSURE_NORMAL
;
1491 PDEBUG(D_CONF
, "Automatically increasing sensor_fps");
1496 command_setexposure(gspca_dev
);
1499 command_setsensorfps(gspca_dev
);
1502 command_setflickerctrl(gspca_dev
);
1505 /*-----------------------------------------------------------------*/
1506 /* if flicker is switched off, this function switches it back on.It checks,
1507 however, that conditions are suitable before restarting it.
1508 This should only be called for firmware version 1.2.
1510 It also adjust the colour balance when an exposure step is detected - as
1511 long as flicker is running
1513 static void restart_flicker(struct gspca_dev
*gspca_dev
)
1515 struct sd
*sd
= (struct sd
*) gspca_dev
;
1516 int cam_exposure
, old_exp
;
1518 if (!FIRMWARE_VERSION(1, 2))
1521 cam_exposure
= atomic_read(&sd
->cam_exposure
);
1523 if (sd
->params
.flickerControl
.flickerMode
== 0 ||
1527 old_exp
= sd
->params
.exposure
.coarseExpLo
+
1528 sd
->params
.exposure
.coarseExpHi
*256;
1530 see how far away camera exposure is from a valid
1531 flicker exposure value
1533 cam_exposure
%= sd
->params
.flickerControl
.coarseJump
;
1534 if (!sd
->params
.flickerControl
.disabled
&&
1535 cam_exposure
<= sd
->params
.flickerControl
.coarseJump
- 3) {
1536 /* Flicker control auto-disabled */
1537 sd
->params
.flickerControl
.disabled
= 1;
1540 if (sd
->params
.flickerControl
.disabled
&&
1541 old_exp
> sd
->params
.flickerControl
.coarseJump
+
1542 ROUND_UP_EXP_FOR_FLICKER
) {
1543 /* exposure is now high enough to switch
1544 flicker control back on */
1545 set_flicker(gspca_dev
, 1, 1);
1549 /* this function is called at probe time */
1550 static int sd_config(struct gspca_dev
*gspca_dev
,
1551 const struct usb_device_id
*id
)
1555 reset_camera_params(gspca_dev
);
1557 PDEBUG(D_PROBE
, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)",
1558 id
->idVendor
, id
->idProduct
);
1560 cam
= &gspca_dev
->cam
;
1561 cam
->cam_mode
= mode
;
1562 cam
->nmodes
= ARRAY_SIZE(mode
);
1564 sd_setfreq(gspca_dev
, FREQ_DEF
);
1569 /* -- start the camera -- */
1570 static int sd_start(struct gspca_dev
*gspca_dev
)
1572 struct sd
*sd
= (struct sd
*) gspca_dev
;
1575 /* Start the camera in low power mode */
1576 if (goto_low_power(gspca_dev
)) {
1577 if (sd
->params
.status
.systemState
!= WARM_BOOT_STATE
) {
1578 PDEBUG(D_ERR
, "unexpected systemstate: %02x",
1579 sd
->params
.status
.systemState
);
1580 printstatus(&sd
->params
);
1584 /* FIXME: this is just dirty trial and error */
1585 ret
= goto_high_power(gspca_dev
);
1589 ret
= do_command(gspca_dev
, CPIA_COMMAND_DiscardFrame
,
1594 ret
= goto_low_power(gspca_dev
);
1599 /* procedure described in developer's guide p3-28 */
1601 /* Check the firmware version. */
1602 sd
->params
.version
.firmwareVersion
= 0;
1603 get_version_information(gspca_dev
);
1604 if (sd
->params
.version
.firmwareVersion
!= 1) {
1605 PDEBUG(D_ERR
, "only firmware version 1 is supported (got: %d)",
1606 sd
->params
.version
.firmwareVersion
);
1610 /* A bug in firmware 1-02 limits gainMode to 2 */
1611 if (sd
->params
.version
.firmwareRevision
<= 2 &&
1612 sd
->params
.exposure
.gainMode
> 2) {
1613 sd
->params
.exposure
.gainMode
= 2;
1616 /* set QX3 detected flag */
1617 sd
->params
.qx3
.qx3_detected
= (sd
->params
.pnpID
.vendor
== 0x0813 &&
1618 sd
->params
.pnpID
.product
== 0x0001);
1620 /* The fatal error checking should be done after
1621 * the camera powers up (developer's guide p 3-38) */
1623 /* Set streamState before transition to high power to avoid bug
1624 * in firmware 1-02 */
1625 ret
= do_command(gspca_dev
, CPIA_COMMAND_ModifyCameraStatus
,
1626 STREAMSTATE
, 0, STREAM_NOT_READY
, 0);
1631 ret
= goto_high_power(gspca_dev
);
1635 /* Check the camera status */
1636 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
1640 if (sd
->params
.status
.fatalError
) {
1641 PDEBUG(D_ERR
, "fatal_error: %04x, vp_status: %04x",
1642 sd
->params
.status
.fatalError
,
1643 sd
->params
.status
.vpStatus
);
1647 /* VPVersion can't be retrieved before the camera is in HiPower,
1648 * so get it here instead of in get_version_information. */
1649 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetVPVersion
, 0, 0, 0, 0);
1653 /* Determine video mode settings */
1654 sd
->params
.streamStartLine
= 120;
1656 priv
= gspca_dev
->cam
.cam_mode
[gspca_dev
->curr_mode
].priv
;
1657 if (priv
& 0x01) { /* crop */
1658 sd
->params
.roi
.colStart
= 2;
1659 sd
->params
.roi
.rowStart
= 6;
1661 sd
->params
.roi
.colStart
= 0;
1662 sd
->params
.roi
.rowStart
= 0;
1665 if (priv
& 0x02) { /* quarter */
1666 sd
->params
.format
.videoSize
= VIDEOSIZE_QCIF
;
1667 sd
->params
.roi
.colStart
/= 2;
1668 sd
->params
.roi
.rowStart
/= 2;
1669 sd
->params
.streamStartLine
/= 2;
1671 sd
->params
.format
.videoSize
= VIDEOSIZE_CIF
;
1673 sd
->params
.roi
.colEnd
= sd
->params
.roi
.colStart
+
1674 (gspca_dev
->width
>> 3);
1675 sd
->params
.roi
.rowEnd
= sd
->params
.roi
.rowStart
+
1676 (gspca_dev
->height
>> 2);
1678 /* And now set the camera to a known state */
1679 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetGrabMode
,
1680 CPIA_GRAB_CONTINEOUS
, 0, 0, 0);
1683 /* We start with compression disabled, as we need one uncompressed
1684 frame to handle later compressed frames */
1685 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetCompression
,
1686 CPIA_COMPRESSION_NONE
,
1687 NO_DECIMATION
, 0, 0);
1690 ret
= command_setcompressiontarget(gspca_dev
);
1693 ret
= command_setcolourparams(gspca_dev
);
1696 ret
= command_setformat(gspca_dev
);
1699 ret
= command_setyuvtresh(gspca_dev
);
1702 ret
= command_setecptiming(gspca_dev
);
1705 ret
= command_setcompressionparams(gspca_dev
);
1708 ret
= command_setexposure(gspca_dev
);
1711 ret
= command_setcolourbalance(gspca_dev
);
1714 ret
= command_setsensorfps(gspca_dev
);
1717 ret
= command_setapcor(gspca_dev
);
1720 ret
= command_setflickerctrl(gspca_dev
);
1723 ret
= command_setvloffset(gspca_dev
);
1728 ret
= command_resume(gspca_dev
);
1732 /* Wait 6 frames before turning compression on for the sensor to get
1733 all settings and AEC/ACB to settle */
1734 sd
->first_frame
= 6;
1735 sd
->exposure_status
= EXPOSURE_NORMAL
;
1736 sd
->exposure_count
= 0;
1737 atomic_set(&sd
->cam_exposure
, 0);
1738 atomic_set(&sd
->fps
, 0);
1743 static void sd_stopN(struct gspca_dev
*gspca_dev
)
1745 struct sd
*sd
= (struct sd
*) gspca_dev
;
1747 command_pause(gspca_dev
);
1749 /* save camera state for later open (developers guide ch 3.5.3) */
1750 save_camera_state(gspca_dev
);
1753 goto_low_power(gspca_dev
);
1755 /* Update the camera status */
1756 do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
1758 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1759 /* If the last button state is pressed, release it now! */
1760 if (sd
->params
.qx3
.button
) {
1761 /* The camera latch will hold the pressed state until we reset
1762 the latch, so we do not reset sd->params.qx3.button now, to
1763 avoid a false keypress being reported the next sd_start */
1764 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 0);
1765 input_sync(gspca_dev
->input_dev
);
1770 /* this function is called at probe and resume time */
1771 static int sd_init(struct gspca_dev
*gspca_dev
)
1773 struct sd
*sd
= (struct sd
*) gspca_dev
;
1776 /* Start / Stop the camera to make sure we are talking to
1777 a supported camera, and to get some information from it
1779 ret
= sd_start(gspca_dev
);
1783 /* Ensure the QX3 illuminators' states are restored upon resume,
1784 or disable the illuminator controls, if this isn't a QX3 */
1785 if (sd
->params
.qx3
.qx3_detected
)
1786 command_setlights(gspca_dev
);
1788 gspca_dev
->ctrl_dis
|=
1789 ((1 << ILLUMINATORS_1_IDX
) | (1 << ILLUMINATORS_2_IDX
));
1791 sd_stopN(gspca_dev
);
1793 PDEBUG(D_PROBE
, "CPIA Version: %d.%02d (%d.%d)",
1794 sd
->params
.version
.firmwareVersion
,
1795 sd
->params
.version
.firmwareRevision
,
1796 sd
->params
.version
.vcVersion
,
1797 sd
->params
.version
.vcRevision
);
1798 PDEBUG(D_PROBE
, "CPIA PnP-ID: %04x:%04x:%04x",
1799 sd
->params
.pnpID
.vendor
, sd
->params
.pnpID
.product
,
1800 sd
->params
.pnpID
.deviceRevision
);
1801 PDEBUG(D_PROBE
, "VP-Version: %d.%d %04x",
1802 sd
->params
.vpVersion
.vpVersion
,
1803 sd
->params
.vpVersion
.vpRevision
,
1804 sd
->params
.vpVersion
.cameraHeadID
);
1809 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
1813 struct sd
*sd
= (struct sd
*) gspca_dev
;
1817 data
[0] == MAGIC_0
&& data
[1] == MAGIC_1
&&
1818 data
[16] == sd
->params
.format
.videoSize
&&
1819 data
[17] == sd
->params
.format
.subSample
&&
1820 data
[18] == sd
->params
.format
.yuvOrder
&&
1821 data
[24] == sd
->params
.roi
.colStart
&&
1822 data
[25] == sd
->params
.roi
.colEnd
&&
1823 data
[26] == sd
->params
.roi
.rowStart
&&
1824 data
[27] == sd
->params
.roi
.rowEnd
) {
1827 atomic_set(&sd
->cam_exposure
, data
[39] * 2);
1828 atomic_set(&sd
->fps
, data
[41]);
1830 /* Check for proper EOF for last frame */
1831 image
= gspca_dev
->image
;
1832 if (image
!= NULL
&&
1833 gspca_dev
->image_len
> 4 &&
1834 image
[gspca_dev
->image_len
- 4] == 0xff &&
1835 image
[gspca_dev
->image_len
- 3] == 0xff &&
1836 image
[gspca_dev
->image_len
- 2] == 0xff &&
1837 image
[gspca_dev
->image_len
- 1] == 0xff)
1838 gspca_frame_add(gspca_dev
, LAST_PACKET
,
1841 gspca_frame_add(gspca_dev
, FIRST_PACKET
, data
, len
);
1845 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
1848 static void sd_dq_callback(struct gspca_dev
*gspca_dev
)
1850 struct sd
*sd
= (struct sd
*) gspca_dev
;
1852 /* Set the normal compression settings once we have captured a
1853 few uncompressed frames (and AEC has hopefully settled) */
1854 if (sd
->first_frame
) {
1856 if (sd
->first_frame
== 0)
1857 command_setcompression(gspca_dev
);
1860 /* Switch flicker control back on if it got turned off */
1861 restart_flicker(gspca_dev
);
1863 /* If AEC is enabled, monitor the exposure and
1864 adjust the sensor frame rate if needed */
1865 if (sd
->params
.exposure
.expMode
== 2)
1866 monitor_exposure(gspca_dev
);
1868 /* Update our knowledge of the camera state */
1869 do_command(gspca_dev
, CPIA_COMMAND_GetExposure
, 0, 0, 0, 0);
1870 do_command(gspca_dev
, CPIA_COMMAND_ReadMCPorts
, 0, 0, 0, 0);
1873 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
)
1875 struct sd
*sd
= (struct sd
*) gspca_dev
;
1878 sd
->params
.colourParams
.brightness
= val
;
1879 sd
->params
.flickerControl
.allowableOverExposure
=
1880 find_over_exposure(sd
->params
.colourParams
.brightness
);
1881 if (gspca_dev
->streaming
) {
1882 ret
= command_setcolourparams(gspca_dev
);
1885 return command_setflickerctrl(gspca_dev
);
1890 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
)
1892 struct sd
*sd
= (struct sd
*) gspca_dev
;
1894 *val
= sd
->params
.colourParams
.brightness
;
1898 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
)
1900 struct sd
*sd
= (struct sd
*) gspca_dev
;
1902 sd
->params
.colourParams
.contrast
= val
;
1903 if (gspca_dev
->streaming
)
1904 return command_setcolourparams(gspca_dev
);
1909 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
)
1911 struct sd
*sd
= (struct sd
*) gspca_dev
;
1913 *val
= sd
->params
.colourParams
.contrast
;
1917 static int sd_setsaturation(struct gspca_dev
*gspca_dev
, __s32 val
)
1919 struct sd
*sd
= (struct sd
*) gspca_dev
;
1921 sd
->params
.colourParams
.saturation
= val
;
1922 if (gspca_dev
->streaming
)
1923 return command_setcolourparams(gspca_dev
);
1928 static int sd_getsaturation(struct gspca_dev
*gspca_dev
, __s32
*val
)
1930 struct sd
*sd
= (struct sd
*) gspca_dev
;
1932 *val
= sd
->params
.colourParams
.saturation
;
1936 static int sd_setfreq(struct gspca_dev
*gspca_dev
, __s32 val
)
1938 struct sd
*sd
= (struct sd
*) gspca_dev
;
1942 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1945 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1949 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1958 sd
->params
.flickerControl
.coarseJump
=
1959 flicker_jumps
[sd
->mainsFreq
]
1960 [sd
->params
.sensorFps
.baserate
]
1961 [sd
->params
.sensorFps
.divisor
];
1963 return set_flicker(gspca_dev
, on
, gspca_dev
->streaming
);
1966 static int sd_getfreq(struct gspca_dev
*gspca_dev
, __s32
*val
)
1968 struct sd
*sd
= (struct sd
*) gspca_dev
;
1974 static int sd_setcomptarget(struct gspca_dev
*gspca_dev
, __s32 val
)
1976 struct sd
*sd
= (struct sd
*) gspca_dev
;
1978 sd
->params
.compressionTarget
.frTargeting
= val
;
1979 if (gspca_dev
->streaming
)
1980 return command_setcompressiontarget(gspca_dev
);
1985 static int sd_getcomptarget(struct gspca_dev
*gspca_dev
, __s32
*val
)
1987 struct sd
*sd
= (struct sd
*) gspca_dev
;
1989 *val
= sd
->params
.compressionTarget
.frTargeting
;
1993 static int sd_setilluminator(struct gspca_dev
*gspca_dev
, __s32 val
, int n
)
1995 struct sd
*sd
= (struct sd
*) gspca_dev
;
1998 if (!sd
->params
.qx3
.qx3_detected
)
2003 sd
->params
.qx3
.bottomlight
= val
? 1 : 0;
2006 sd
->params
.qx3
.toplight
= val
? 1 : 0;
2012 ret
= command_setlights(gspca_dev
);
2013 if (ret
&& ret
!= -EINVAL
)
2019 static int sd_setilluminator1(struct gspca_dev
*gspca_dev
, __s32 val
)
2021 return sd_setilluminator(gspca_dev
, val
, 1);
2024 static int sd_setilluminator2(struct gspca_dev
*gspca_dev
, __s32 val
)
2026 return sd_setilluminator(gspca_dev
, val
, 2);
2029 static int sd_getilluminator(struct gspca_dev
*gspca_dev
, __s32
*val
, int n
)
2031 struct sd
*sd
= (struct sd
*) gspca_dev
;
2033 if (!sd
->params
.qx3
.qx3_detected
)
2038 *val
= sd
->params
.qx3
.bottomlight
;
2041 *val
= sd
->params
.qx3
.toplight
;
2049 static int sd_getilluminator1(struct gspca_dev
*gspca_dev
, __s32
*val
)
2051 return sd_getilluminator(gspca_dev
, val
, 1);
2054 static int sd_getilluminator2(struct gspca_dev
*gspca_dev
, __s32
*val
)
2056 return sd_getilluminator(gspca_dev
, val
, 2);
2059 static int sd_querymenu(struct gspca_dev
*gspca_dev
,
2060 struct v4l2_querymenu
*menu
)
2063 case V4L2_CID_POWER_LINE_FREQUENCY
:
2064 switch (menu
->index
) {
2065 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2066 strcpy((char *) menu
->name
, "NoFliker");
2068 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2069 strcpy((char *) menu
->name
, "50 Hz");
2071 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2072 strcpy((char *) menu
->name
, "60 Hz");
2076 case V4L2_CID_COMP_TARGET
:
2077 switch (menu
->index
) {
2078 case CPIA_COMPRESSION_TARGET_QUALITY
:
2079 strcpy((char *) menu
->name
, "Quality");
2081 case CPIA_COMPRESSION_TARGET_FRAMERATE
:
2082 strcpy((char *) menu
->name
, "Framerate");
2090 /* sub-driver description */
2091 static const struct sd_desc sd_desc
= {
2092 .name
= MODULE_NAME
,
2094 .nctrls
= ARRAY_SIZE(sd_ctrls
),
2095 .config
= sd_config
,
2099 .dq_callback
= sd_dq_callback
,
2100 .pkt_scan
= sd_pkt_scan
,
2101 .querymenu
= sd_querymenu
,
2102 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2107 /* -- module initialisation -- */
2108 static const struct usb_device_id device_table
[] = {
2109 {USB_DEVICE(0x0553, 0x0002)},
2110 {USB_DEVICE(0x0813, 0x0001)},
2113 MODULE_DEVICE_TABLE(usb
, device_table
);
2115 /* -- device connect -- */
2116 static int sd_probe(struct usb_interface
*intf
,
2117 const struct usb_device_id
*id
)
2119 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
2123 static struct usb_driver sd_driver
= {
2124 .name
= MODULE_NAME
,
2125 .id_table
= device_table
,
2127 .disconnect
= gspca_disconnect
,
2129 .suspend
= gspca_suspend
,
2130 .resume
= gspca_resume
,
2134 /* -- module insert / remove -- */
2135 static int __init
sd_mod_init(void)
2137 return usb_register(&sd_driver
);
2139 static void __exit
sd_mod_exit(void)
2141 usb_deregister(&sd_driver
);
2144 module_init(sd_mod_init
);
2145 module_exit(sd_mod_exit
);