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 pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31 #define MODULE_NAME "cpia1"
33 #include <linux/input.h>
36 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
37 MODULE_DESCRIPTION("Vision CPiA");
38 MODULE_LICENSE("GPL");
40 /* constant value's */
45 #define VIDEOSIZE_QCIF 0 /* 176x144 */
46 #define VIDEOSIZE_CIF 1 /* 352x288 */
47 #define SUBSAMPLE_420 0
48 #define SUBSAMPLE_422 1
49 #define YUVORDER_YUYV 0
50 #define YUVORDER_UYVY 1
51 #define NOT_COMPRESSED 0
53 #define NO_DECIMATION 0
54 #define DECIMATION_ENAB 1
55 #define EOI 0xff /* End Of Image */
56 #define EOL 0xfd /* End Of Line */
57 #define FRAME_HEADER_SIZE 64
59 /* Image grab modes */
60 #define CPIA_GRAB_SINGLE 0
61 #define CPIA_GRAB_CONTINEOUS 1
63 /* Compression parameters */
64 #define CPIA_COMPRESSION_NONE 0
65 #define CPIA_COMPRESSION_AUTO 1
66 #define CPIA_COMPRESSION_MANUAL 2
67 #define CPIA_COMPRESSION_TARGET_QUALITY 0
68 #define CPIA_COMPRESSION_TARGET_FRAMERATE 1
70 /* Return offsets for GetCameraState */
81 #define UNINITIALISED_STATE 0
82 #define PASS_THROUGH_STATE 1
83 #define LO_POWER_STATE 2
84 #define HI_POWER_STATE 3
85 #define WARM_BOOT_STATE 4
93 #define STREAM_NOT_READY 0
94 #define STREAM_READY 1
96 #define STREAM_PAUSED 3
97 #define STREAM_FINISHED 4
99 /* Fatal Error, CmdError, and DebugFlags */
101 #define SYSTEM_FLAG 2
102 #define INT_CTRL_FLAG 4
103 #define PROCESS_FLAG 8
105 #define VP_CTRL_FLAG 32
106 #define CAPTURE_FLAG 64
107 #define DEBUG_FLAG 128
110 #define VP_STATE_OK 0x00
112 #define VP_STATE_FAILED_VIDEOINIT 0x01
113 #define VP_STATE_FAILED_AECACBINIT 0x02
114 #define VP_STATE_AEC_MAX 0x04
115 #define VP_STATE_ACB_BMAX 0x08
117 #define VP_STATE_ACB_RMIN 0x10
118 #define VP_STATE_ACB_GMIN 0x20
119 #define VP_STATE_ACB_RMAX 0x40
120 #define VP_STATE_ACB_GMAX 0x80
122 /* default (minimum) compensation values */
124 #define COMP_GREEN1 214
125 #define COMP_GREEN2 COMP_GREEN1
126 #define COMP_BLUE 230
128 /* exposure status */
129 #define EXPOSURE_VERY_LIGHT 0
130 #define EXPOSURE_LIGHT 1
131 #define EXPOSURE_NORMAL 2
132 #define EXPOSURE_DARK 3
133 #define EXPOSURE_VERY_DARK 4
135 #define CPIA_MODULE_CPIA (0 << 5)
136 #define CPIA_MODULE_SYSTEM (1 << 5)
137 #define CPIA_MODULE_VP_CTRL (5 << 5)
138 #define CPIA_MODULE_CAPTURE (6 << 5)
139 #define CPIA_MODULE_DEBUG (7 << 5)
141 #define INPUT (DATA_IN << 8)
142 #define OUTPUT (DATA_OUT << 8)
144 #define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)
145 #define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)
146 #define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)
147 #define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)
148 #define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)
149 #define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)
150 #define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)
151 #define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)
153 #define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)
154 #define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)
155 #define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)
156 #define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)
157 #define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)
158 #define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)
159 #define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)
160 #define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)
161 #define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)
162 #define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)
163 #define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)
164 #define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)
165 #define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
167 #define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
168 #define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)
169 #define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
170 #define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
171 #define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
172 #define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)
173 #define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)
174 #define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)
175 #define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)
176 #define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)
177 #define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)
178 #define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)
179 #define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)
180 #define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)
181 #define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)
182 #define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)
183 #define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)
185 #define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)
186 #define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)
187 #define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)
188 #define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)
189 #define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)
190 #define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)
191 #define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)
192 #define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)
193 #define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)
194 #define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)
195 #define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
196 #define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
197 #define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
198 #define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
199 #define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)
201 #define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
202 #define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
203 #define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)
204 #define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)
205 #define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
206 #define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
207 #define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
208 #define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)
210 #define ROUND_UP_EXP_FOR_FLICKER 15
212 /* Constants for automatic frame rate adjustment */
214 #define MAX_EXP_102 255
216 #define VERY_LOW_EXP 70
218 #define EXP_ACC_DARK 50
219 #define EXP_ACC_LIGHT 90
220 #define HIGH_COMP_102 160
225 #define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \
226 sd->params.version.firmwareRevision == (y))
228 /* Developer's Guide Table 5 p 3-34
229 * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
230 static u8 flicker_jumps
[2][2][4] =
231 { { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
232 { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
301 u8 allowableOverExposure
;
327 u8 decimationHysteresis
;
330 u8 decimationThreshMod
;
333 u8 videoSize
; /* CIF/QCIF */
337 struct { /* Intel QX3 specific data */
338 u8 qx3_detected
; /* a QX3 is present */
339 u8 toplight
; /* top light lit , R/W */
340 u8 bottomlight
; /* bottom light lit, R/W */
341 u8 button
; /* snapshot button pressed (R/O) */
342 u8 cradled
; /* microscope is in cradle (R/O) */
345 u8 colStart
; /* skip first 8*colStart pixels */
346 u8 colEnd
; /* finish at 8*colEnd pixels */
347 u8 rowStart
; /* skip first 4*rowStart lines */
348 u8 rowEnd
; /* finish at 4*rowEnd lines */
354 /* specific webcam descriptor */
356 struct gspca_dev gspca_dev
; /* !! must be the first item */
357 struct cam_params params
; /* camera settings */
359 atomic_t cam_exposure
;
363 u8 mainsFreq
; /* 0 = 50hz, 1 = 60hz */
368 /* V4L2 controls supported by the driver */
369 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
);
370 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
);
371 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
);
372 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
);
373 static int sd_setsaturation(struct gspca_dev
*gspca_dev
, __s32 val
);
374 static int sd_getsaturation(struct gspca_dev
*gspca_dev
, __s32
*val
);
375 static int sd_setfreq(struct gspca_dev
*gspca_dev
, __s32 val
);
376 static int sd_getfreq(struct gspca_dev
*gspca_dev
, __s32
*val
);
377 static int sd_setcomptarget(struct gspca_dev
*gspca_dev
, __s32 val
);
378 static int sd_getcomptarget(struct gspca_dev
*gspca_dev
, __s32
*val
);
379 static int sd_setilluminator1(struct gspca_dev
*gspca_dev
, __s32 val
);
380 static int sd_getilluminator1(struct gspca_dev
*gspca_dev
, __s32
*val
);
381 static int sd_setilluminator2(struct gspca_dev
*gspca_dev
, __s32 val
);
382 static int sd_getilluminator2(struct gspca_dev
*gspca_dev
, __s32
*val
);
384 static const struct ctrl sd_ctrls
[] = {
386 #define BRIGHTNESS_IDX 0
388 .id
= V4L2_CID_BRIGHTNESS
,
389 .type
= V4L2_CTRL_TYPE_INTEGER
,
390 .name
= "Brightness",
394 #define BRIGHTNESS_DEF 50
395 .default_value
= BRIGHTNESS_DEF
,
398 .set
= sd_setbrightness
,
399 .get
= sd_getbrightness
,
401 #define CONTRAST_IDX 1
404 .id
= V4L2_CID_CONTRAST
,
405 .type
= V4L2_CTRL_TYPE_INTEGER
,
410 #define CONTRAST_DEF 48
411 .default_value
= CONTRAST_DEF
,
413 .set
= sd_setcontrast
,
414 .get
= sd_getcontrast
,
416 #define SATURATION_IDX 2
419 .id
= V4L2_CID_SATURATION
,
420 .type
= V4L2_CTRL_TYPE_INTEGER
,
421 .name
= "Saturation",
425 #define SATURATION_DEF 50
426 .default_value
= SATURATION_DEF
,
428 .set
= sd_setsaturation
,
429 .get
= sd_getsaturation
,
431 #define POWER_LINE_FREQUENCY_IDX 3
434 .id
= V4L2_CID_POWER_LINE_FREQUENCY
,
435 .type
= V4L2_CTRL_TYPE_MENU
,
436 .name
= "Light frequency filter",
438 .maximum
= 2, /* 0: 0, 1: 50Hz, 2:60Hz */
441 .default_value
= FREQ_DEF
,
446 #define ILLUMINATORS_1_IDX 4
449 .id
= V4L2_CID_ILLUMINATORS_1
,
450 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
451 .name
= "Illuminator 1",
455 #define ILLUMINATORS_1_DEF 0
456 .default_value
= ILLUMINATORS_1_DEF
,
458 .set
= sd_setilluminator1
,
459 .get
= sd_getilluminator1
,
461 #define ILLUMINATORS_2_IDX 5
464 .id
= V4L2_CID_ILLUMINATORS_2
,
465 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
466 .name
= "Illuminator 2",
470 #define ILLUMINATORS_2_DEF 0
471 .default_value
= ILLUMINATORS_2_DEF
,
473 .set
= sd_setilluminator2
,
474 .get
= sd_getilluminator2
,
476 #define COMP_TARGET_IDX 6
479 #define V4L2_CID_COMP_TARGET V4L2_CID_PRIVATE_BASE
480 .id
= V4L2_CID_COMP_TARGET
,
481 .type
= V4L2_CTRL_TYPE_MENU
,
482 .name
= "Compression Target",
486 #define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY
487 .default_value
= COMP_TARGET_DEF
,
489 .set
= sd_setcomptarget
,
490 .get
= sd_getcomptarget
,
494 static const struct v4l2_pix_format mode
[] = {
495 {160, 120, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
496 /* The sizeimage is trial and error, as with low framerates
497 the camera will pad out usb frames, making the image
498 data larger then strictly necessary */
501 .colorspace
= V4L2_COLORSPACE_SRGB
,
503 {176, 144, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
506 .colorspace
= V4L2_COLORSPACE_SRGB
,
508 {320, 240, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
511 .colorspace
= V4L2_COLORSPACE_SRGB
,
513 {352, 288, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
516 .colorspace
= V4L2_COLORSPACE_SRGB
,
520 /**********************************************************************
524 **********************************************************************/
526 static int cpia_usb_transferCmd(struct gspca_dev
*gspca_dev
, u8
*command
)
530 int ret
, databytes
= command
[6] | (command
[7] << 8);
531 /* Sometimes we see spurious EPIPE errors */
534 if (command
[0] == DATA_IN
) {
535 pipe
= usb_rcvctrlpipe(gspca_dev
->dev
, 0);
536 requesttype
= USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
;
537 } else if (command
[0] == DATA_OUT
) {
538 pipe
= usb_sndctrlpipe(gspca_dev
->dev
, 0);
539 requesttype
= USB_TYPE_VENDOR
| USB_RECIP_DEVICE
;
541 PDEBUG(D_ERR
, "Unexpected first byte of command: %x",
547 ret
= usb_control_msg(gspca_dev
->dev
, pipe
,
550 command
[2] | (command
[3] << 8),
551 command
[4] | (command
[5] << 8),
552 gspca_dev
->usb_buf
, databytes
, 1000);
555 pr_err("usb_control_msg %02x, error %d\n", command
[1], ret
);
557 if (ret
== -EPIPE
&& retries
> 0) {
562 return (ret
< 0) ? ret
: 0;
565 /* send an arbitrary command to the camera */
566 static int do_command(struct gspca_dev
*gspca_dev
, u16 command
,
567 u8 a
, u8 b
, u8 c
, u8 d
)
569 struct sd
*sd
= (struct sd
*) gspca_dev
;
574 case CPIA_COMMAND_GetCPIAVersion
:
575 case CPIA_COMMAND_GetPnPID
:
576 case CPIA_COMMAND_GetCameraStatus
:
577 case CPIA_COMMAND_GetVPVersion
:
578 case CPIA_COMMAND_GetColourParams
:
579 case CPIA_COMMAND_GetColourBalance
:
580 case CPIA_COMMAND_GetExposure
:
583 case CPIA_COMMAND_ReadMCPorts
:
584 case CPIA_COMMAND_ReadVCRegs
:
592 cmd
[0] = command
>> 8;
593 cmd
[1] = command
& 0xff;
601 ret
= cpia_usb_transferCmd(gspca_dev
, cmd
);
606 case CPIA_COMMAND_GetCPIAVersion
:
607 sd
->params
.version
.firmwareVersion
= gspca_dev
->usb_buf
[0];
608 sd
->params
.version
.firmwareRevision
= gspca_dev
->usb_buf
[1];
609 sd
->params
.version
.vcVersion
= gspca_dev
->usb_buf
[2];
610 sd
->params
.version
.vcRevision
= gspca_dev
->usb_buf
[3];
612 case CPIA_COMMAND_GetPnPID
:
613 sd
->params
.pnpID
.vendor
=
614 gspca_dev
->usb_buf
[0] | (gspca_dev
->usb_buf
[1] << 8);
615 sd
->params
.pnpID
.product
=
616 gspca_dev
->usb_buf
[2] | (gspca_dev
->usb_buf
[3] << 8);
617 sd
->params
.pnpID
.deviceRevision
=
618 gspca_dev
->usb_buf
[4] | (gspca_dev
->usb_buf
[5] << 8);
620 case CPIA_COMMAND_GetCameraStatus
:
621 sd
->params
.status
.systemState
= gspca_dev
->usb_buf
[0];
622 sd
->params
.status
.grabState
= gspca_dev
->usb_buf
[1];
623 sd
->params
.status
.streamState
= gspca_dev
->usb_buf
[2];
624 sd
->params
.status
.fatalError
= gspca_dev
->usb_buf
[3];
625 sd
->params
.status
.cmdError
= gspca_dev
->usb_buf
[4];
626 sd
->params
.status
.debugFlags
= gspca_dev
->usb_buf
[5];
627 sd
->params
.status
.vpStatus
= gspca_dev
->usb_buf
[6];
628 sd
->params
.status
.errorCode
= gspca_dev
->usb_buf
[7];
630 case CPIA_COMMAND_GetVPVersion
:
631 sd
->params
.vpVersion
.vpVersion
= gspca_dev
->usb_buf
[0];
632 sd
->params
.vpVersion
.vpRevision
= gspca_dev
->usb_buf
[1];
633 sd
->params
.vpVersion
.cameraHeadID
=
634 gspca_dev
->usb_buf
[2] | (gspca_dev
->usb_buf
[3] << 8);
636 case CPIA_COMMAND_GetColourParams
:
637 sd
->params
.colourParams
.brightness
= gspca_dev
->usb_buf
[0];
638 sd
->params
.colourParams
.contrast
= gspca_dev
->usb_buf
[1];
639 sd
->params
.colourParams
.saturation
= gspca_dev
->usb_buf
[2];
641 case CPIA_COMMAND_GetColourBalance
:
642 sd
->params
.colourBalance
.redGain
= gspca_dev
->usb_buf
[0];
643 sd
->params
.colourBalance
.greenGain
= gspca_dev
->usb_buf
[1];
644 sd
->params
.colourBalance
.blueGain
= gspca_dev
->usb_buf
[2];
646 case CPIA_COMMAND_GetExposure
:
647 sd
->params
.exposure
.gain
= gspca_dev
->usb_buf
[0];
648 sd
->params
.exposure
.fineExp
= gspca_dev
->usb_buf
[1];
649 sd
->params
.exposure
.coarseExpLo
= gspca_dev
->usb_buf
[2];
650 sd
->params
.exposure
.coarseExpHi
= gspca_dev
->usb_buf
[3];
651 sd
->params
.exposure
.redComp
= gspca_dev
->usb_buf
[4];
652 sd
->params
.exposure
.green1Comp
= gspca_dev
->usb_buf
[5];
653 sd
->params
.exposure
.green2Comp
= gspca_dev
->usb_buf
[6];
654 sd
->params
.exposure
.blueComp
= gspca_dev
->usb_buf
[7];
657 case CPIA_COMMAND_ReadMCPorts
:
658 /* test button press */
659 a
= ((gspca_dev
->usb_buf
[1] & 0x02) == 0);
660 if (a
!= sd
->params
.qx3
.button
) {
661 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
662 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, a
);
663 input_sync(gspca_dev
->input_dev
);
665 sd
->params
.qx3
.button
= a
;
667 if (sd
->params
.qx3
.button
) {
668 /* button pressed - unlock the latch */
669 do_command(gspca_dev
, CPIA_COMMAND_WriteMCPort
,
671 do_command(gspca_dev
, CPIA_COMMAND_WriteMCPort
,
675 /* test whether microscope is cradled */
676 sd
->params
.qx3
.cradled
= ((gspca_dev
->usb_buf
[2] & 0x40) == 0);
683 /* send a command to the camera with an additional data transaction */
684 static int do_command_extended(struct gspca_dev
*gspca_dev
, u16 command
,
685 u8 a
, u8 b
, u8 c
, u8 d
,
686 u8 e
, u8 f
, u8 g
, u8 h
,
687 u8 i
, u8 j
, u8 k
, u8 l
)
691 cmd
[0] = command
>> 8;
692 cmd
[1] = command
& 0xff;
699 gspca_dev
->usb_buf
[0] = e
;
700 gspca_dev
->usb_buf
[1] = f
;
701 gspca_dev
->usb_buf
[2] = g
;
702 gspca_dev
->usb_buf
[3] = h
;
703 gspca_dev
->usb_buf
[4] = i
;
704 gspca_dev
->usb_buf
[5] = j
;
705 gspca_dev
->usb_buf
[6] = k
;
706 gspca_dev
->usb_buf
[7] = l
;
708 return cpia_usb_transferCmd(gspca_dev
, cmd
);
711 /* find_over_exposure
712 * Finds a suitable value of OverExposure for use with SetFlickerCtrl
713 * Some calculation is required because this value changes with the brightness
714 * set with SetColourParameters
716 * Parameters: Brightness - last brightness value set with SetColourParameters
718 * Returns: OverExposure value to use with SetFlickerCtrl
720 #define FLICKER_MAX_EXPOSURE 250
721 #define FLICKER_ALLOWABLE_OVER_EXPOSURE 146
722 #define FLICKER_BRIGHTNESS_CONSTANT 59
723 static int find_over_exposure(int brightness
)
725 int MaxAllowableOverExposure
, OverExposure
;
727 MaxAllowableOverExposure
= FLICKER_MAX_EXPOSURE
- brightness
-
728 FLICKER_BRIGHTNESS_CONSTANT
;
730 if (MaxAllowableOverExposure
< FLICKER_ALLOWABLE_OVER_EXPOSURE
)
731 OverExposure
= MaxAllowableOverExposure
;
733 OverExposure
= FLICKER_ALLOWABLE_OVER_EXPOSURE
;
737 #undef FLICKER_MAX_EXPOSURE
738 #undef FLICKER_ALLOWABLE_OVER_EXPOSURE
739 #undef FLICKER_BRIGHTNESS_CONSTANT
741 /* initialise cam_data structure */
742 static void reset_camera_params(struct gspca_dev
*gspca_dev
)
744 struct sd
*sd
= (struct sd
*) gspca_dev
;
745 struct cam_params
*params
= &sd
->params
;
747 /* The following parameter values are the defaults from
748 * "Software Developer's Guide for CPiA Cameras". Any changes
749 * to the defaults are noted in comments. */
750 params
->colourParams
.brightness
= BRIGHTNESS_DEF
;
751 params
->colourParams
.contrast
= CONTRAST_DEF
;
752 params
->colourParams
.saturation
= SATURATION_DEF
;
753 params
->exposure
.gainMode
= 4;
754 params
->exposure
.expMode
= 2; /* AEC */
755 params
->exposure
.compMode
= 1;
756 params
->exposure
.centreWeight
= 1;
757 params
->exposure
.gain
= 0;
758 params
->exposure
.fineExp
= 0;
759 params
->exposure
.coarseExpLo
= 185;
760 params
->exposure
.coarseExpHi
= 0;
761 params
->exposure
.redComp
= COMP_RED
;
762 params
->exposure
.green1Comp
= COMP_GREEN1
;
763 params
->exposure
.green2Comp
= COMP_GREEN2
;
764 params
->exposure
.blueComp
= COMP_BLUE
;
765 params
->colourBalance
.balanceMode
= 2; /* ACB */
766 params
->colourBalance
.redGain
= 32;
767 params
->colourBalance
.greenGain
= 6;
768 params
->colourBalance
.blueGain
= 92;
769 params
->apcor
.gain1
= 0x18;
770 params
->apcor
.gain2
= 0x16;
771 params
->apcor
.gain4
= 0x24;
772 params
->apcor
.gain8
= 0x34;
773 params
->flickerControl
.flickerMode
= 0;
774 params
->flickerControl
.disabled
= 1;
776 params
->flickerControl
.coarseJump
=
777 flicker_jumps
[sd
->mainsFreq
]
778 [params
->sensorFps
.baserate
]
779 [params
->sensorFps
.divisor
];
780 params
->flickerControl
.allowableOverExposure
=
781 find_over_exposure(params
->colourParams
.brightness
);
782 params
->vlOffset
.gain1
= 20;
783 params
->vlOffset
.gain2
= 24;
784 params
->vlOffset
.gain4
= 26;
785 params
->vlOffset
.gain8
= 26;
786 params
->compressionParams
.hysteresis
= 3;
787 params
->compressionParams
.threshMax
= 11;
788 params
->compressionParams
.smallStep
= 1;
789 params
->compressionParams
.largeStep
= 3;
790 params
->compressionParams
.decimationHysteresis
= 2;
791 params
->compressionParams
.frDiffStepThresh
= 5;
792 params
->compressionParams
.qDiffStepThresh
= 3;
793 params
->compressionParams
.decimationThreshMod
= 2;
794 /* End of default values from Software Developer's Guide */
796 /* Set Sensor FPS to 15fps. This seems better than 30fps
797 * for indoor lighting. */
798 params
->sensorFps
.divisor
= 1;
799 params
->sensorFps
.baserate
= 1;
801 params
->yuvThreshold
.yThreshold
= 6; /* From windows driver */
802 params
->yuvThreshold
.uvThreshold
= 6; /* From windows driver */
804 params
->format
.subSample
= SUBSAMPLE_420
;
805 params
->format
.yuvOrder
= YUVORDER_YUYV
;
807 params
->compression
.mode
= CPIA_COMPRESSION_AUTO
;
808 params
->compression
.decimation
= NO_DECIMATION
;
810 params
->compressionTarget
.frTargeting
= COMP_TARGET_DEF
;
811 params
->compressionTarget
.targetFR
= 15; /* From windows driver */
812 params
->compressionTarget
.targetQ
= 5; /* From windows driver */
814 params
->qx3
.qx3_detected
= 0;
815 params
->qx3
.toplight
= 0;
816 params
->qx3
.bottomlight
= 0;
817 params
->qx3
.button
= 0;
818 params
->qx3
.cradled
= 0;
821 static void printstatus(struct cam_params
*params
)
823 PDEBUG(D_PROBE
, "status: %02x %02x %02x %02x %02x %02x %02x %02x",
824 params
->status
.systemState
, params
->status
.grabState
,
825 params
->status
.streamState
, params
->status
.fatalError
,
826 params
->status
.cmdError
, params
->status
.debugFlags
,
827 params
->status
.vpStatus
, params
->status
.errorCode
);
830 static int goto_low_power(struct gspca_dev
*gspca_dev
)
832 struct sd
*sd
= (struct sd
*) gspca_dev
;
835 ret
= do_command(gspca_dev
, CPIA_COMMAND_GotoLoPower
, 0, 0, 0, 0);
839 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
843 if (sd
->params
.status
.systemState
!= LO_POWER_STATE
) {
844 if (sd
->params
.status
.systemState
!= WARM_BOOT_STATE
) {
846 "unexpected state after lo power cmd: %02x",
847 sd
->params
.status
.systemState
);
848 printstatus(&sd
->params
);
853 PDEBUG(D_CONF
, "camera now in LOW power state");
857 static int goto_high_power(struct gspca_dev
*gspca_dev
)
859 struct sd
*sd
= (struct sd
*) gspca_dev
;
862 ret
= do_command(gspca_dev
, CPIA_COMMAND_GotoHiPower
, 0, 0, 0, 0);
866 msleep_interruptible(40); /* windows driver does it too */
868 if (signal_pending(current
))
871 do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
875 if (sd
->params
.status
.systemState
!= HI_POWER_STATE
) {
876 PDEBUG(D_ERR
, "unexpected state after hi power cmd: %02x",
877 sd
->params
.status
.systemState
);
878 printstatus(&sd
->params
);
882 PDEBUG(D_CONF
, "camera now in HIGH power state");
886 static int get_version_information(struct gspca_dev
*gspca_dev
)
891 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetCPIAVersion
, 0, 0, 0, 0);
896 return do_command(gspca_dev
, CPIA_COMMAND_GetPnPID
, 0, 0, 0, 0);
899 static int save_camera_state(struct gspca_dev
*gspca_dev
)
903 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetColourBalance
, 0, 0, 0, 0);
907 return do_command(gspca_dev
, CPIA_COMMAND_GetExposure
, 0, 0, 0, 0);
910 static int command_setformat(struct gspca_dev
*gspca_dev
)
912 struct sd
*sd
= (struct sd
*) gspca_dev
;
915 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetFormat
,
916 sd
->params
.format
.videoSize
,
917 sd
->params
.format
.subSample
,
918 sd
->params
.format
.yuvOrder
, 0);
922 return do_command(gspca_dev
, CPIA_COMMAND_SetROI
,
923 sd
->params
.roi
.colStart
, sd
->params
.roi
.colEnd
,
924 sd
->params
.roi
.rowStart
, sd
->params
.roi
.rowEnd
);
927 static int command_setcolourparams(struct gspca_dev
*gspca_dev
)
929 struct sd
*sd
= (struct sd
*) gspca_dev
;
930 return do_command(gspca_dev
, CPIA_COMMAND_SetColourParams
,
931 sd
->params
.colourParams
.brightness
,
932 sd
->params
.colourParams
.contrast
,
933 sd
->params
.colourParams
.saturation
, 0);
936 static int command_setapcor(struct gspca_dev
*gspca_dev
)
938 struct sd
*sd
= (struct sd
*) gspca_dev
;
939 return do_command(gspca_dev
, CPIA_COMMAND_SetApcor
,
940 sd
->params
.apcor
.gain1
,
941 sd
->params
.apcor
.gain2
,
942 sd
->params
.apcor
.gain4
,
943 sd
->params
.apcor
.gain8
);
946 static int command_setvloffset(struct gspca_dev
*gspca_dev
)
948 struct sd
*sd
= (struct sd
*) gspca_dev
;
949 return do_command(gspca_dev
, CPIA_COMMAND_SetVLOffset
,
950 sd
->params
.vlOffset
.gain1
,
951 sd
->params
.vlOffset
.gain2
,
952 sd
->params
.vlOffset
.gain4
,
953 sd
->params
.vlOffset
.gain8
);
956 static int command_setexposure(struct gspca_dev
*gspca_dev
)
958 struct sd
*sd
= (struct sd
*) gspca_dev
;
961 ret
= do_command_extended(gspca_dev
, CPIA_COMMAND_SetExposure
,
962 sd
->params
.exposure
.gainMode
,
964 sd
->params
.exposure
.compMode
,
965 sd
->params
.exposure
.centreWeight
,
966 sd
->params
.exposure
.gain
,
967 sd
->params
.exposure
.fineExp
,
968 sd
->params
.exposure
.coarseExpLo
,
969 sd
->params
.exposure
.coarseExpHi
,
970 sd
->params
.exposure
.redComp
,
971 sd
->params
.exposure
.green1Comp
,
972 sd
->params
.exposure
.green2Comp
,
973 sd
->params
.exposure
.blueComp
);
977 if (sd
->params
.exposure
.expMode
!= 1) {
978 ret
= do_command_extended(gspca_dev
, CPIA_COMMAND_SetExposure
,
980 sd
->params
.exposure
.expMode
,
982 sd
->params
.exposure
.gain
,
983 sd
->params
.exposure
.fineExp
,
984 sd
->params
.exposure
.coarseExpLo
,
985 sd
->params
.exposure
.coarseExpHi
,
992 static int command_setcolourbalance(struct gspca_dev
*gspca_dev
)
994 struct sd
*sd
= (struct sd
*) gspca_dev
;
996 if (sd
->params
.colourBalance
.balanceMode
== 1) {
999 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
1001 sd
->params
.colourBalance
.redGain
,
1002 sd
->params
.colourBalance
.greenGain
,
1003 sd
->params
.colourBalance
.blueGain
);
1007 return do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
1010 if (sd
->params
.colourBalance
.balanceMode
== 2) {
1011 return do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
1014 if (sd
->params
.colourBalance
.balanceMode
== 3) {
1015 return do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
1022 static int command_setcompressiontarget(struct gspca_dev
*gspca_dev
)
1024 struct sd
*sd
= (struct sd
*) gspca_dev
;
1026 return do_command(gspca_dev
, CPIA_COMMAND_SetCompressionTarget
,
1027 sd
->params
.compressionTarget
.frTargeting
,
1028 sd
->params
.compressionTarget
.targetFR
,
1029 sd
->params
.compressionTarget
.targetQ
, 0);
1032 static int command_setyuvtresh(struct gspca_dev
*gspca_dev
)
1034 struct sd
*sd
= (struct sd
*) gspca_dev
;
1036 return do_command(gspca_dev
, CPIA_COMMAND_SetYUVThresh
,
1037 sd
->params
.yuvThreshold
.yThreshold
,
1038 sd
->params
.yuvThreshold
.uvThreshold
, 0, 0);
1041 static int command_setcompressionparams(struct gspca_dev
*gspca_dev
)
1043 struct sd
*sd
= (struct sd
*) gspca_dev
;
1045 return do_command_extended(gspca_dev
,
1046 CPIA_COMMAND_SetCompressionParams
,
1048 sd
->params
.compressionParams
.hysteresis
,
1049 sd
->params
.compressionParams
.threshMax
,
1050 sd
->params
.compressionParams
.smallStep
,
1051 sd
->params
.compressionParams
.largeStep
,
1052 sd
->params
.compressionParams
.decimationHysteresis
,
1053 sd
->params
.compressionParams
.frDiffStepThresh
,
1054 sd
->params
.compressionParams
.qDiffStepThresh
,
1055 sd
->params
.compressionParams
.decimationThreshMod
);
1058 static int command_setcompression(struct gspca_dev
*gspca_dev
)
1060 struct sd
*sd
= (struct sd
*) gspca_dev
;
1062 return do_command(gspca_dev
, CPIA_COMMAND_SetCompression
,
1063 sd
->params
.compression
.mode
,
1064 sd
->params
.compression
.decimation
, 0, 0);
1067 static int command_setsensorfps(struct gspca_dev
*gspca_dev
)
1069 struct sd
*sd
= (struct sd
*) gspca_dev
;
1071 return do_command(gspca_dev
, CPIA_COMMAND_SetSensorFPS
,
1072 sd
->params
.sensorFps
.divisor
,
1073 sd
->params
.sensorFps
.baserate
, 0, 0);
1076 static int command_setflickerctrl(struct gspca_dev
*gspca_dev
)
1078 struct sd
*sd
= (struct sd
*) gspca_dev
;
1080 return do_command(gspca_dev
, CPIA_COMMAND_SetFlickerCtrl
,
1081 sd
->params
.flickerControl
.flickerMode
,
1082 sd
->params
.flickerControl
.coarseJump
,
1083 sd
->params
.flickerControl
.allowableOverExposure
,
1087 static int command_setecptiming(struct gspca_dev
*gspca_dev
)
1089 struct sd
*sd
= (struct sd
*) gspca_dev
;
1091 return do_command(gspca_dev
, CPIA_COMMAND_SetECPTiming
,
1092 sd
->params
.ecpTiming
, 0, 0, 0);
1095 static int command_pause(struct gspca_dev
*gspca_dev
)
1097 return do_command(gspca_dev
, CPIA_COMMAND_EndStreamCap
, 0, 0, 0, 0);
1100 static int command_resume(struct gspca_dev
*gspca_dev
)
1102 struct sd
*sd
= (struct sd
*) gspca_dev
;
1104 return do_command(gspca_dev
, CPIA_COMMAND_InitStreamCap
,
1105 0, sd
->params
.streamStartLine
, 0, 0);
1108 static int command_setlights(struct gspca_dev
*gspca_dev
)
1110 struct sd
*sd
= (struct sd
*) gspca_dev
;
1113 if (!sd
->params
.qx3
.qx3_detected
)
1116 p1
= (sd
->params
.qx3
.bottomlight
== 0) << 1;
1117 p2
= (sd
->params
.qx3
.toplight
== 0) << 3;
1119 ret
= do_command(gspca_dev
, CPIA_COMMAND_WriteVCReg
,
1120 0x90, 0x8f, 0x50, 0);
1124 return do_command(gspca_dev
, CPIA_COMMAND_WriteMCPort
, 2, 0,
1128 static int set_flicker(struct gspca_dev
*gspca_dev
, int on
, int apply
)
1130 /* Everything in here is from the Windows driver */
1131 /* define for compgain calculation */
1133 #define COMPGAIN(base, curexp, newexp) \
1134 (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
1135 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1136 (u16)((float)curexp * (float)(u8)(curcomp + 128) / \
1137 (float)(u8)(basecomp - 128))
1139 /* equivalent functions without floating point math */
1140 #define COMPGAIN(base, curexp, newexp) \
1141 (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2 * newexp)))
1142 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1143 (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
1146 struct sd
*sd
= (struct sd
*) gspca_dev
;
1147 int currentexp
= sd
->params
.exposure
.coarseExpLo
+
1148 sd
->params
.exposure
.coarseExpHi
* 256;
1152 int cj
= sd
->params
.flickerControl
.coarseJump
;
1153 sd
->params
.flickerControl
.flickerMode
= 1;
1154 sd
->params
.flickerControl
.disabled
= 0;
1155 if (sd
->params
.exposure
.expMode
!= 2) {
1156 sd
->params
.exposure
.expMode
= 2;
1157 sd
->exposure_status
= EXPOSURE_NORMAL
;
1159 currentexp
= currentexp
<< sd
->params
.exposure
.gain
;
1160 sd
->params
.exposure
.gain
= 0;
1161 /* round down current exposure to nearest value */
1162 startexp
= (currentexp
+ ROUND_UP_EXP_FOR_FLICKER
) / cj
;
1165 startexp
= (startexp
* cj
) - 1;
1166 if (FIRMWARE_VERSION(1, 2))
1167 while (startexp
> MAX_EXP_102
)
1170 while (startexp
> MAX_EXP
)
1172 sd
->params
.exposure
.coarseExpLo
= startexp
& 0xff;
1173 sd
->params
.exposure
.coarseExpHi
= startexp
>> 8;
1174 if (currentexp
> startexp
) {
1175 if (currentexp
> (2 * startexp
))
1176 currentexp
= 2 * startexp
;
1177 sd
->params
.exposure
.redComp
=
1178 COMPGAIN(COMP_RED
, currentexp
, startexp
);
1179 sd
->params
.exposure
.green1Comp
=
1180 COMPGAIN(COMP_GREEN1
, currentexp
, startexp
);
1181 sd
->params
.exposure
.green2Comp
=
1182 COMPGAIN(COMP_GREEN2
, currentexp
, startexp
);
1183 sd
->params
.exposure
.blueComp
=
1184 COMPGAIN(COMP_BLUE
, currentexp
, startexp
);
1186 sd
->params
.exposure
.redComp
= COMP_RED
;
1187 sd
->params
.exposure
.green1Comp
= COMP_GREEN1
;
1188 sd
->params
.exposure
.green2Comp
= COMP_GREEN2
;
1189 sd
->params
.exposure
.blueComp
= COMP_BLUE
;
1191 if (FIRMWARE_VERSION(1, 2))
1192 sd
->params
.exposure
.compMode
= 0;
1194 sd
->params
.exposure
.compMode
= 1;
1196 sd
->params
.apcor
.gain1
= 0x18;
1197 sd
->params
.apcor
.gain2
= 0x18;
1198 sd
->params
.apcor
.gain4
= 0x16;
1199 sd
->params
.apcor
.gain8
= 0x14;
1201 sd
->params
.flickerControl
.flickerMode
= 0;
1202 sd
->params
.flickerControl
.disabled
= 1;
1203 /* Average equivalent coarse for each comp channel */
1204 startexp
= EXP_FROM_COMP(COMP_RED
,
1205 sd
->params
.exposure
.redComp
, currentexp
);
1206 startexp
+= EXP_FROM_COMP(COMP_GREEN1
,
1207 sd
->params
.exposure
.green1Comp
, currentexp
);
1208 startexp
+= EXP_FROM_COMP(COMP_GREEN2
,
1209 sd
->params
.exposure
.green2Comp
, currentexp
);
1210 startexp
+= EXP_FROM_COMP(COMP_BLUE
,
1211 sd
->params
.exposure
.blueComp
, currentexp
);
1212 startexp
= startexp
>> 2;
1213 while (startexp
> MAX_EXP
&& sd
->params
.exposure
.gain
<
1214 sd
->params
.exposure
.gainMode
- 1) {
1215 startexp
= startexp
>> 1;
1216 ++sd
->params
.exposure
.gain
;
1218 if (FIRMWARE_VERSION(1, 2) && startexp
> MAX_EXP_102
)
1219 startexp
= MAX_EXP_102
;
1220 if (startexp
> MAX_EXP
)
1222 sd
->params
.exposure
.coarseExpLo
= startexp
& 0xff;
1223 sd
->params
.exposure
.coarseExpHi
= startexp
>> 8;
1224 sd
->params
.exposure
.redComp
= COMP_RED
;
1225 sd
->params
.exposure
.green1Comp
= COMP_GREEN1
;
1226 sd
->params
.exposure
.green2Comp
= COMP_GREEN2
;
1227 sd
->params
.exposure
.blueComp
= COMP_BLUE
;
1228 sd
->params
.exposure
.compMode
= 1;
1229 sd
->params
.apcor
.gain1
= 0x18;
1230 sd
->params
.apcor
.gain2
= 0x16;
1231 sd
->params
.apcor
.gain4
= 0x24;
1232 sd
->params
.apcor
.gain8
= 0x34;
1234 sd
->params
.vlOffset
.gain1
= 20;
1235 sd
->params
.vlOffset
.gain2
= 24;
1236 sd
->params
.vlOffset
.gain4
= 26;
1237 sd
->params
.vlOffset
.gain8
= 26;
1240 ret
= command_setexposure(gspca_dev
);
1244 ret
= command_setapcor(gspca_dev
);
1248 ret
= command_setvloffset(gspca_dev
);
1252 ret
= command_setflickerctrl(gspca_dev
);
1258 #undef EXP_FROM_COMP
1262 /* monitor the exposure and adjust the sensor frame rate if needed */
1263 static void monitor_exposure(struct gspca_dev
*gspca_dev
)
1265 struct sd
*sd
= (struct sd
*) gspca_dev
;
1266 u8 exp_acc
, bcomp
, cmd
[8];
1267 int ret
, light_exp
, dark_exp
, very_dark_exp
;
1268 int old_exposure
, new_exposure
, framerate
;
1269 int setfps
= 0, setexp
= 0, setflicker
= 0;
1271 /* get necessary stats and register settings from camera */
1272 /* do_command can't handle this, so do it ourselves */
1273 cmd
[0] = CPIA_COMMAND_ReadVPRegs
>> 8;
1274 cmd
[1] = CPIA_COMMAND_ReadVPRegs
& 0xff;
1281 ret
= cpia_usb_transferCmd(gspca_dev
, cmd
);
1283 pr_err("ReadVPRegs(30,4,9,8) - failed: %d\n", ret
);
1286 exp_acc
= gspca_dev
->usb_buf
[0];
1287 bcomp
= gspca_dev
->usb_buf
[1];
1289 light_exp
= sd
->params
.colourParams
.brightness
+
1290 TC
- 50 + EXP_ACC_LIGHT
;
1291 if (light_exp
> 255)
1293 dark_exp
= sd
->params
.colourParams
.brightness
+
1294 TC
- 50 - EXP_ACC_DARK
;
1297 very_dark_exp
= dark_exp
/ 2;
1299 old_exposure
= sd
->params
.exposure
.coarseExpHi
* 256 +
1300 sd
->params
.exposure
.coarseExpLo
;
1302 if (!sd
->params
.flickerControl
.disabled
) {
1303 /* Flicker control on */
1304 int max_comp
= FIRMWARE_VERSION(1, 2) ? MAX_COMP
:
1306 bcomp
+= 128; /* decode */
1307 if (bcomp
>= max_comp
&& exp_acc
< dark_exp
) {
1309 if (exp_acc
< very_dark_exp
) {
1311 if (sd
->exposure_status
== EXPOSURE_VERY_DARK
)
1312 ++sd
->exposure_count
;
1314 sd
->exposure_status
=
1316 sd
->exposure_count
= 1;
1320 if (sd
->exposure_status
== EXPOSURE_DARK
)
1321 ++sd
->exposure_count
;
1323 sd
->exposure_status
= EXPOSURE_DARK
;
1324 sd
->exposure_count
= 1;
1327 } else if (old_exposure
<= LOW_EXP
|| exp_acc
> light_exp
) {
1329 if (old_exposure
<= VERY_LOW_EXP
) {
1331 if (sd
->exposure_status
== EXPOSURE_VERY_LIGHT
)
1332 ++sd
->exposure_count
;
1334 sd
->exposure_status
=
1335 EXPOSURE_VERY_LIGHT
;
1336 sd
->exposure_count
= 1;
1340 if (sd
->exposure_status
== EXPOSURE_LIGHT
)
1341 ++sd
->exposure_count
;
1343 sd
->exposure_status
= EXPOSURE_LIGHT
;
1344 sd
->exposure_count
= 1;
1348 /* not dark or light */
1349 sd
->exposure_status
= EXPOSURE_NORMAL
;
1352 /* Flicker control off */
1353 if (old_exposure
>= MAX_EXP
&& exp_acc
< dark_exp
) {
1355 if (exp_acc
< very_dark_exp
) {
1357 if (sd
->exposure_status
== EXPOSURE_VERY_DARK
)
1358 ++sd
->exposure_count
;
1360 sd
->exposure_status
=
1362 sd
->exposure_count
= 1;
1366 if (sd
->exposure_status
== EXPOSURE_DARK
)
1367 ++sd
->exposure_count
;
1369 sd
->exposure_status
= EXPOSURE_DARK
;
1370 sd
->exposure_count
= 1;
1373 } else if (old_exposure
<= LOW_EXP
|| exp_acc
> light_exp
) {
1375 if (old_exposure
<= VERY_LOW_EXP
) {
1377 if (sd
->exposure_status
== EXPOSURE_VERY_LIGHT
)
1378 ++sd
->exposure_count
;
1380 sd
->exposure_status
=
1381 EXPOSURE_VERY_LIGHT
;
1382 sd
->exposure_count
= 1;
1386 if (sd
->exposure_status
== EXPOSURE_LIGHT
)
1387 ++sd
->exposure_count
;
1389 sd
->exposure_status
= EXPOSURE_LIGHT
;
1390 sd
->exposure_count
= 1;
1394 /* not dark or light */
1395 sd
->exposure_status
= EXPOSURE_NORMAL
;
1399 framerate
= atomic_read(&sd
->fps
);
1400 if (framerate
> 30 || framerate
< 1)
1403 if (!sd
->params
.flickerControl
.disabled
) {
1404 /* Flicker control on */
1405 if ((sd
->exposure_status
== EXPOSURE_VERY_DARK
||
1406 sd
->exposure_status
== EXPOSURE_DARK
) &&
1407 sd
->exposure_count
>= DARK_TIME
* framerate
&&
1408 sd
->params
.sensorFps
.divisor
< 2) {
1410 /* dark for too long */
1411 ++sd
->params
.sensorFps
.divisor
;
1414 sd
->params
.flickerControl
.coarseJump
=
1415 flicker_jumps
[sd
->mainsFreq
]
1416 [sd
->params
.sensorFps
.baserate
]
1417 [sd
->params
.sensorFps
.divisor
];
1420 new_exposure
= sd
->params
.flickerControl
.coarseJump
-1;
1421 while (new_exposure
< old_exposure
/ 2)
1423 sd
->params
.flickerControl
.coarseJump
;
1424 sd
->params
.exposure
.coarseExpLo
= new_exposure
& 0xff;
1425 sd
->params
.exposure
.coarseExpHi
= new_exposure
>> 8;
1427 sd
->exposure_status
= EXPOSURE_NORMAL
;
1428 PDEBUG(D_CONF
, "Automatically decreasing sensor_fps");
1430 } else if ((sd
->exposure_status
== EXPOSURE_VERY_LIGHT
||
1431 sd
->exposure_status
== EXPOSURE_LIGHT
) &&
1432 sd
->exposure_count
>= LIGHT_TIME
* framerate
&&
1433 sd
->params
.sensorFps
.divisor
> 0) {
1435 /* light for too long */
1436 int max_exp
= FIRMWARE_VERSION(1, 2) ? MAX_EXP_102
:
1438 --sd
->params
.sensorFps
.divisor
;
1441 sd
->params
.flickerControl
.coarseJump
=
1442 flicker_jumps
[sd
->mainsFreq
]
1443 [sd
->params
.sensorFps
.baserate
]
1444 [sd
->params
.sensorFps
.divisor
];
1447 new_exposure
= sd
->params
.flickerControl
.coarseJump
-1;
1448 while (new_exposure
< 2 * old_exposure
&&
1450 sd
->params
.flickerControl
.coarseJump
< max_exp
)
1452 sd
->params
.flickerControl
.coarseJump
;
1453 sd
->params
.exposure
.coarseExpLo
= new_exposure
& 0xff;
1454 sd
->params
.exposure
.coarseExpHi
= new_exposure
>> 8;
1456 sd
->exposure_status
= EXPOSURE_NORMAL
;
1457 PDEBUG(D_CONF
, "Automatically increasing sensor_fps");
1460 /* Flicker control off */
1461 if ((sd
->exposure_status
== EXPOSURE_VERY_DARK
||
1462 sd
->exposure_status
== EXPOSURE_DARK
) &&
1463 sd
->exposure_count
>= DARK_TIME
* framerate
&&
1464 sd
->params
.sensorFps
.divisor
< 2) {
1466 /* dark for too long */
1467 ++sd
->params
.sensorFps
.divisor
;
1470 if (sd
->params
.exposure
.gain
> 0) {
1471 --sd
->params
.exposure
.gain
;
1474 sd
->exposure_status
= EXPOSURE_NORMAL
;
1475 PDEBUG(D_CONF
, "Automatically decreasing sensor_fps");
1477 } else if ((sd
->exposure_status
== EXPOSURE_VERY_LIGHT
||
1478 sd
->exposure_status
== EXPOSURE_LIGHT
) &&
1479 sd
->exposure_count
>= LIGHT_TIME
* framerate
&&
1480 sd
->params
.sensorFps
.divisor
> 0) {
1482 /* light for too long */
1483 --sd
->params
.sensorFps
.divisor
;
1486 if (sd
->params
.exposure
.gain
<
1487 sd
->params
.exposure
.gainMode
- 1) {
1488 ++sd
->params
.exposure
.gain
;
1491 sd
->exposure_status
= EXPOSURE_NORMAL
;
1492 PDEBUG(D_CONF
, "Automatically increasing sensor_fps");
1497 command_setexposure(gspca_dev
);
1500 command_setsensorfps(gspca_dev
);
1503 command_setflickerctrl(gspca_dev
);
1506 /*-----------------------------------------------------------------*/
1507 /* if flicker is switched off, this function switches it back on.It checks,
1508 however, that conditions are suitable before restarting it.
1509 This should only be called for firmware version 1.2.
1511 It also adjust the colour balance when an exposure step is detected - as
1512 long as flicker is running
1514 static void restart_flicker(struct gspca_dev
*gspca_dev
)
1516 struct sd
*sd
= (struct sd
*) gspca_dev
;
1517 int cam_exposure
, old_exp
;
1519 if (!FIRMWARE_VERSION(1, 2))
1522 cam_exposure
= atomic_read(&sd
->cam_exposure
);
1524 if (sd
->params
.flickerControl
.flickerMode
== 0 ||
1528 old_exp
= sd
->params
.exposure
.coarseExpLo
+
1529 sd
->params
.exposure
.coarseExpHi
*256;
1531 see how far away camera exposure is from a valid
1532 flicker exposure value
1534 cam_exposure
%= sd
->params
.flickerControl
.coarseJump
;
1535 if (!sd
->params
.flickerControl
.disabled
&&
1536 cam_exposure
<= sd
->params
.flickerControl
.coarseJump
- 3) {
1537 /* Flicker control auto-disabled */
1538 sd
->params
.flickerControl
.disabled
= 1;
1541 if (sd
->params
.flickerControl
.disabled
&&
1542 old_exp
> sd
->params
.flickerControl
.coarseJump
+
1543 ROUND_UP_EXP_FOR_FLICKER
) {
1544 /* exposure is now high enough to switch
1545 flicker control back on */
1546 set_flicker(gspca_dev
, 1, 1);
1550 /* this function is called at probe time */
1551 static int sd_config(struct gspca_dev
*gspca_dev
,
1552 const struct usb_device_id
*id
)
1556 reset_camera_params(gspca_dev
);
1558 PDEBUG(D_PROBE
, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)",
1559 id
->idVendor
, id
->idProduct
);
1561 cam
= &gspca_dev
->cam
;
1562 cam
->cam_mode
= mode
;
1563 cam
->nmodes
= ARRAY_SIZE(mode
);
1565 sd_setfreq(gspca_dev
, FREQ_DEF
);
1570 /* -- start the camera -- */
1571 static int sd_start(struct gspca_dev
*gspca_dev
)
1573 struct sd
*sd
= (struct sd
*) gspca_dev
;
1576 /* Start the camera in low power mode */
1577 if (goto_low_power(gspca_dev
)) {
1578 if (sd
->params
.status
.systemState
!= WARM_BOOT_STATE
) {
1579 PDEBUG(D_ERR
, "unexpected systemstate: %02x",
1580 sd
->params
.status
.systemState
);
1581 printstatus(&sd
->params
);
1585 /* FIXME: this is just dirty trial and error */
1586 ret
= goto_high_power(gspca_dev
);
1590 ret
= do_command(gspca_dev
, CPIA_COMMAND_DiscardFrame
,
1595 ret
= goto_low_power(gspca_dev
);
1600 /* procedure described in developer's guide p3-28 */
1602 /* Check the firmware version. */
1603 sd
->params
.version
.firmwareVersion
= 0;
1604 get_version_information(gspca_dev
);
1605 if (sd
->params
.version
.firmwareVersion
!= 1) {
1606 PDEBUG(D_ERR
, "only firmware version 1 is supported (got: %d)",
1607 sd
->params
.version
.firmwareVersion
);
1611 /* A bug in firmware 1-02 limits gainMode to 2 */
1612 if (sd
->params
.version
.firmwareRevision
<= 2 &&
1613 sd
->params
.exposure
.gainMode
> 2) {
1614 sd
->params
.exposure
.gainMode
= 2;
1617 /* set QX3 detected flag */
1618 sd
->params
.qx3
.qx3_detected
= (sd
->params
.pnpID
.vendor
== 0x0813 &&
1619 sd
->params
.pnpID
.product
== 0x0001);
1621 /* The fatal error checking should be done after
1622 * the camera powers up (developer's guide p 3-38) */
1624 /* Set streamState before transition to high power to avoid bug
1625 * in firmware 1-02 */
1626 ret
= do_command(gspca_dev
, CPIA_COMMAND_ModifyCameraStatus
,
1627 STREAMSTATE
, 0, STREAM_NOT_READY
, 0);
1632 ret
= goto_high_power(gspca_dev
);
1636 /* Check the camera status */
1637 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
1641 if (sd
->params
.status
.fatalError
) {
1642 PDEBUG(D_ERR
, "fatal_error: %04x, vp_status: %04x",
1643 sd
->params
.status
.fatalError
,
1644 sd
->params
.status
.vpStatus
);
1648 /* VPVersion can't be retrieved before the camera is in HiPower,
1649 * so get it here instead of in get_version_information. */
1650 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetVPVersion
, 0, 0, 0, 0);
1654 /* Determine video mode settings */
1655 sd
->params
.streamStartLine
= 120;
1657 priv
= gspca_dev
->cam
.cam_mode
[gspca_dev
->curr_mode
].priv
;
1658 if (priv
& 0x01) { /* crop */
1659 sd
->params
.roi
.colStart
= 2;
1660 sd
->params
.roi
.rowStart
= 6;
1662 sd
->params
.roi
.colStart
= 0;
1663 sd
->params
.roi
.rowStart
= 0;
1666 if (priv
& 0x02) { /* quarter */
1667 sd
->params
.format
.videoSize
= VIDEOSIZE_QCIF
;
1668 sd
->params
.roi
.colStart
/= 2;
1669 sd
->params
.roi
.rowStart
/= 2;
1670 sd
->params
.streamStartLine
/= 2;
1672 sd
->params
.format
.videoSize
= VIDEOSIZE_CIF
;
1674 sd
->params
.roi
.colEnd
= sd
->params
.roi
.colStart
+
1675 (gspca_dev
->width
>> 3);
1676 sd
->params
.roi
.rowEnd
= sd
->params
.roi
.rowStart
+
1677 (gspca_dev
->height
>> 2);
1679 /* And now set the camera to a known state */
1680 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetGrabMode
,
1681 CPIA_GRAB_CONTINEOUS
, 0, 0, 0);
1684 /* We start with compression disabled, as we need one uncompressed
1685 frame to handle later compressed frames */
1686 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetCompression
,
1687 CPIA_COMPRESSION_NONE
,
1688 NO_DECIMATION
, 0, 0);
1691 ret
= command_setcompressiontarget(gspca_dev
);
1694 ret
= command_setcolourparams(gspca_dev
);
1697 ret
= command_setformat(gspca_dev
);
1700 ret
= command_setyuvtresh(gspca_dev
);
1703 ret
= command_setecptiming(gspca_dev
);
1706 ret
= command_setcompressionparams(gspca_dev
);
1709 ret
= command_setexposure(gspca_dev
);
1712 ret
= command_setcolourbalance(gspca_dev
);
1715 ret
= command_setsensorfps(gspca_dev
);
1718 ret
= command_setapcor(gspca_dev
);
1721 ret
= command_setflickerctrl(gspca_dev
);
1724 ret
= command_setvloffset(gspca_dev
);
1729 ret
= command_resume(gspca_dev
);
1733 /* Wait 6 frames before turning compression on for the sensor to get
1734 all settings and AEC/ACB to settle */
1735 sd
->first_frame
= 6;
1736 sd
->exposure_status
= EXPOSURE_NORMAL
;
1737 sd
->exposure_count
= 0;
1738 atomic_set(&sd
->cam_exposure
, 0);
1739 atomic_set(&sd
->fps
, 0);
1744 static void sd_stopN(struct gspca_dev
*gspca_dev
)
1746 struct sd
*sd
= (struct sd
*) gspca_dev
;
1748 command_pause(gspca_dev
);
1750 /* save camera state for later open (developers guide ch 3.5.3) */
1751 save_camera_state(gspca_dev
);
1754 goto_low_power(gspca_dev
);
1756 /* Update the camera status */
1757 do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
1759 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1760 /* If the last button state is pressed, release it now! */
1761 if (sd
->params
.qx3
.button
) {
1762 /* The camera latch will hold the pressed state until we reset
1763 the latch, so we do not reset sd->params.qx3.button now, to
1764 avoid a false keypress being reported the next sd_start */
1765 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 0);
1766 input_sync(gspca_dev
->input_dev
);
1771 /* this function is called at probe and resume time */
1772 static int sd_init(struct gspca_dev
*gspca_dev
)
1774 struct sd
*sd
= (struct sd
*) gspca_dev
;
1777 /* Start / Stop the camera to make sure we are talking to
1778 a supported camera, and to get some information from it
1780 ret
= sd_start(gspca_dev
);
1784 /* Ensure the QX3 illuminators' states are restored upon resume,
1785 or disable the illuminator controls, if this isn't a QX3 */
1786 if (sd
->params
.qx3
.qx3_detected
)
1787 command_setlights(gspca_dev
);
1789 gspca_dev
->ctrl_dis
|=
1790 ((1 << ILLUMINATORS_1_IDX
) | (1 << ILLUMINATORS_2_IDX
));
1792 sd_stopN(gspca_dev
);
1794 PDEBUG(D_PROBE
, "CPIA Version: %d.%02d (%d.%d)",
1795 sd
->params
.version
.firmwareVersion
,
1796 sd
->params
.version
.firmwareRevision
,
1797 sd
->params
.version
.vcVersion
,
1798 sd
->params
.version
.vcRevision
);
1799 PDEBUG(D_PROBE
, "CPIA PnP-ID: %04x:%04x:%04x",
1800 sd
->params
.pnpID
.vendor
, sd
->params
.pnpID
.product
,
1801 sd
->params
.pnpID
.deviceRevision
);
1802 PDEBUG(D_PROBE
, "VP-Version: %d.%d %04x",
1803 sd
->params
.vpVersion
.vpVersion
,
1804 sd
->params
.vpVersion
.vpRevision
,
1805 sd
->params
.vpVersion
.cameraHeadID
);
1810 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
1814 struct sd
*sd
= (struct sd
*) gspca_dev
;
1818 data
[0] == MAGIC_0
&& data
[1] == MAGIC_1
&&
1819 data
[16] == sd
->params
.format
.videoSize
&&
1820 data
[17] == sd
->params
.format
.subSample
&&
1821 data
[18] == sd
->params
.format
.yuvOrder
&&
1822 data
[24] == sd
->params
.roi
.colStart
&&
1823 data
[25] == sd
->params
.roi
.colEnd
&&
1824 data
[26] == sd
->params
.roi
.rowStart
&&
1825 data
[27] == sd
->params
.roi
.rowEnd
) {
1828 atomic_set(&sd
->cam_exposure
, data
[39] * 2);
1829 atomic_set(&sd
->fps
, data
[41]);
1831 /* Check for proper EOF for last frame */
1832 image
= gspca_dev
->image
;
1833 if (image
!= NULL
&&
1834 gspca_dev
->image_len
> 4 &&
1835 image
[gspca_dev
->image_len
- 4] == 0xff &&
1836 image
[gspca_dev
->image_len
- 3] == 0xff &&
1837 image
[gspca_dev
->image_len
- 2] == 0xff &&
1838 image
[gspca_dev
->image_len
- 1] == 0xff)
1839 gspca_frame_add(gspca_dev
, LAST_PACKET
,
1842 gspca_frame_add(gspca_dev
, FIRST_PACKET
, data
, len
);
1846 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
1849 static void sd_dq_callback(struct gspca_dev
*gspca_dev
)
1851 struct sd
*sd
= (struct sd
*) gspca_dev
;
1853 /* Set the normal compression settings once we have captured a
1854 few uncompressed frames (and AEC has hopefully settled) */
1855 if (sd
->first_frame
) {
1857 if (sd
->first_frame
== 0)
1858 command_setcompression(gspca_dev
);
1861 /* Switch flicker control back on if it got turned off */
1862 restart_flicker(gspca_dev
);
1864 /* If AEC is enabled, monitor the exposure and
1865 adjust the sensor frame rate if needed */
1866 if (sd
->params
.exposure
.expMode
== 2)
1867 monitor_exposure(gspca_dev
);
1869 /* Update our knowledge of the camera state */
1870 do_command(gspca_dev
, CPIA_COMMAND_GetExposure
, 0, 0, 0, 0);
1871 do_command(gspca_dev
, CPIA_COMMAND_ReadMCPorts
, 0, 0, 0, 0);
1874 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
)
1876 struct sd
*sd
= (struct sd
*) gspca_dev
;
1879 sd
->params
.colourParams
.brightness
= val
;
1880 sd
->params
.flickerControl
.allowableOverExposure
=
1881 find_over_exposure(sd
->params
.colourParams
.brightness
);
1882 if (gspca_dev
->streaming
) {
1883 ret
= command_setcolourparams(gspca_dev
);
1886 return command_setflickerctrl(gspca_dev
);
1891 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
)
1893 struct sd
*sd
= (struct sd
*) gspca_dev
;
1895 *val
= sd
->params
.colourParams
.brightness
;
1899 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
)
1901 struct sd
*sd
= (struct sd
*) gspca_dev
;
1903 sd
->params
.colourParams
.contrast
= val
;
1904 if (gspca_dev
->streaming
)
1905 return command_setcolourparams(gspca_dev
);
1910 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
)
1912 struct sd
*sd
= (struct sd
*) gspca_dev
;
1914 *val
= sd
->params
.colourParams
.contrast
;
1918 static int sd_setsaturation(struct gspca_dev
*gspca_dev
, __s32 val
)
1920 struct sd
*sd
= (struct sd
*) gspca_dev
;
1922 sd
->params
.colourParams
.saturation
= val
;
1923 if (gspca_dev
->streaming
)
1924 return command_setcolourparams(gspca_dev
);
1929 static int sd_getsaturation(struct gspca_dev
*gspca_dev
, __s32
*val
)
1931 struct sd
*sd
= (struct sd
*) gspca_dev
;
1933 *val
= sd
->params
.colourParams
.saturation
;
1937 static int sd_setfreq(struct gspca_dev
*gspca_dev
, __s32 val
)
1939 struct sd
*sd
= (struct sd
*) gspca_dev
;
1943 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1946 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1950 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1959 sd
->params
.flickerControl
.coarseJump
=
1960 flicker_jumps
[sd
->mainsFreq
]
1961 [sd
->params
.sensorFps
.baserate
]
1962 [sd
->params
.sensorFps
.divisor
];
1964 return set_flicker(gspca_dev
, on
, gspca_dev
->streaming
);
1967 static int sd_getfreq(struct gspca_dev
*gspca_dev
, __s32
*val
)
1969 struct sd
*sd
= (struct sd
*) gspca_dev
;
1975 static int sd_setcomptarget(struct gspca_dev
*gspca_dev
, __s32 val
)
1977 struct sd
*sd
= (struct sd
*) gspca_dev
;
1979 sd
->params
.compressionTarget
.frTargeting
= val
;
1980 if (gspca_dev
->streaming
)
1981 return command_setcompressiontarget(gspca_dev
);
1986 static int sd_getcomptarget(struct gspca_dev
*gspca_dev
, __s32
*val
)
1988 struct sd
*sd
= (struct sd
*) gspca_dev
;
1990 *val
= sd
->params
.compressionTarget
.frTargeting
;
1994 static int sd_setilluminator(struct gspca_dev
*gspca_dev
, __s32 val
, int n
)
1996 struct sd
*sd
= (struct sd
*) gspca_dev
;
1999 if (!sd
->params
.qx3
.qx3_detected
)
2004 sd
->params
.qx3
.bottomlight
= val
? 1 : 0;
2007 sd
->params
.qx3
.toplight
= val
? 1 : 0;
2013 ret
= command_setlights(gspca_dev
);
2014 if (ret
&& ret
!= -EINVAL
)
2020 static int sd_setilluminator1(struct gspca_dev
*gspca_dev
, __s32 val
)
2022 return sd_setilluminator(gspca_dev
, val
, 1);
2025 static int sd_setilluminator2(struct gspca_dev
*gspca_dev
, __s32 val
)
2027 return sd_setilluminator(gspca_dev
, val
, 2);
2030 static int sd_getilluminator(struct gspca_dev
*gspca_dev
, __s32
*val
, int n
)
2032 struct sd
*sd
= (struct sd
*) gspca_dev
;
2034 if (!sd
->params
.qx3
.qx3_detected
)
2039 *val
= sd
->params
.qx3
.bottomlight
;
2042 *val
= sd
->params
.qx3
.toplight
;
2050 static int sd_getilluminator1(struct gspca_dev
*gspca_dev
, __s32
*val
)
2052 return sd_getilluminator(gspca_dev
, val
, 1);
2055 static int sd_getilluminator2(struct gspca_dev
*gspca_dev
, __s32
*val
)
2057 return sd_getilluminator(gspca_dev
, val
, 2);
2060 static int sd_querymenu(struct gspca_dev
*gspca_dev
,
2061 struct v4l2_querymenu
*menu
)
2064 case V4L2_CID_POWER_LINE_FREQUENCY
:
2065 switch (menu
->index
) {
2066 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2067 strcpy((char *) menu
->name
, "NoFliker");
2069 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2070 strcpy((char *) menu
->name
, "50 Hz");
2072 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2073 strcpy((char *) menu
->name
, "60 Hz");
2077 case V4L2_CID_COMP_TARGET
:
2078 switch (menu
->index
) {
2079 case CPIA_COMPRESSION_TARGET_QUALITY
:
2080 strcpy((char *) menu
->name
, "Quality");
2082 case CPIA_COMPRESSION_TARGET_FRAMERATE
:
2083 strcpy((char *) menu
->name
, "Framerate");
2091 /* sub-driver description */
2092 static const struct sd_desc sd_desc
= {
2093 .name
= MODULE_NAME
,
2095 .nctrls
= ARRAY_SIZE(sd_ctrls
),
2096 .config
= sd_config
,
2100 .dq_callback
= sd_dq_callback
,
2101 .pkt_scan
= sd_pkt_scan
,
2102 .querymenu
= sd_querymenu
,
2103 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2108 /* -- module initialisation -- */
2109 static const struct usb_device_id device_table
[] = {
2110 {USB_DEVICE(0x0553, 0x0002)},
2111 {USB_DEVICE(0x0813, 0x0001)},
2114 MODULE_DEVICE_TABLE(usb
, device_table
);
2116 /* -- device connect -- */
2117 static int sd_probe(struct usb_interface
*intf
,
2118 const struct usb_device_id
*id
)
2120 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
2124 static struct usb_driver sd_driver
= {
2125 .name
= MODULE_NAME
,
2126 .id_table
= device_table
,
2128 .disconnect
= gspca_disconnect
,
2130 .suspend
= gspca_suspend
,
2131 .resume
= gspca_resume
,
2135 module_usb_driver(sd_driver
);