2 * cpia CPiA (1) gspca driver
4 * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com>
6 * This module is adapted from the in kernel v4l1 cpia driver which is :
8 * (C) Copyright 1999-2000 Peter Pregler
9 * (C) Copyright 1999-2000 Scott J. Bertin
10 * (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.com>
11 * (C) Copyright 2000 STMicroelectronics
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #define MODULE_NAME "cpia1"
33 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
34 MODULE_DESCRIPTION("Vision CPiA");
35 MODULE_LICENSE("GPL");
37 /* constant value's */
42 #define VIDEOSIZE_QCIF 0 /* 176x144 */
43 #define VIDEOSIZE_CIF 1 /* 352x288 */
44 #define SUBSAMPLE_420 0
45 #define SUBSAMPLE_422 1
46 #define YUVORDER_YUYV 0
47 #define YUVORDER_UYVY 1
48 #define NOT_COMPRESSED 0
50 #define NO_DECIMATION 0
51 #define DECIMATION_ENAB 1
52 #define EOI 0xff /* End Of Image */
53 #define EOL 0xfd /* End Of Line */
54 #define FRAME_HEADER_SIZE 64
56 /* Image grab modes */
57 #define CPIA_GRAB_SINGLE 0
58 #define CPIA_GRAB_CONTINEOUS 1
60 /* Compression parameters */
61 #define CPIA_COMPRESSION_NONE 0
62 #define CPIA_COMPRESSION_AUTO 1
63 #define CPIA_COMPRESSION_MANUAL 2
64 #define CPIA_COMPRESSION_TARGET_QUALITY 0
65 #define CPIA_COMPRESSION_TARGET_FRAMERATE 1
67 /* Return offsets for GetCameraState */
78 #define UNINITIALISED_STATE 0
79 #define PASS_THROUGH_STATE 1
80 #define LO_POWER_STATE 2
81 #define HI_POWER_STATE 3
82 #define WARM_BOOT_STATE 4
90 #define STREAM_NOT_READY 0
91 #define STREAM_READY 1
93 #define STREAM_PAUSED 3
94 #define STREAM_FINISHED 4
96 /* Fatal Error, CmdError, and DebugFlags */
99 #define INT_CTRL_FLAG 4
100 #define PROCESS_FLAG 8
102 #define VP_CTRL_FLAG 32
103 #define CAPTURE_FLAG 64
104 #define DEBUG_FLAG 128
107 #define VP_STATE_OK 0x00
109 #define VP_STATE_FAILED_VIDEOINIT 0x01
110 #define VP_STATE_FAILED_AECACBINIT 0x02
111 #define VP_STATE_AEC_MAX 0x04
112 #define VP_STATE_ACB_BMAX 0x08
114 #define VP_STATE_ACB_RMIN 0x10
115 #define VP_STATE_ACB_GMIN 0x20
116 #define VP_STATE_ACB_RMAX 0x40
117 #define VP_STATE_ACB_GMAX 0x80
119 /* default (minimum) compensation values */
121 #define COMP_GREEN1 214
122 #define COMP_GREEN2 COMP_GREEN1
123 #define COMP_BLUE 230
125 /* exposure status */
126 #define EXPOSURE_VERY_LIGHT 0
127 #define EXPOSURE_LIGHT 1
128 #define EXPOSURE_NORMAL 2
129 #define EXPOSURE_DARK 3
130 #define EXPOSURE_VERY_DARK 4
132 #define CPIA_MODULE_CPIA (0 << 5)
133 #define CPIA_MODULE_SYSTEM (1 << 5)
134 #define CPIA_MODULE_VP_CTRL (5 << 5)
135 #define CPIA_MODULE_CAPTURE (6 << 5)
136 #define CPIA_MODULE_DEBUG (7 << 5)
138 #define INPUT (DATA_IN << 8)
139 #define OUTPUT (DATA_OUT << 8)
141 #define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)
142 #define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)
143 #define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)
144 #define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)
145 #define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)
146 #define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)
147 #define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)
148 #define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)
150 #define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)
151 #define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)
152 #define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)
153 #define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)
154 #define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)
155 #define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)
156 #define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)
157 #define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)
158 #define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)
159 #define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)
160 #define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)
161 #define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)
162 #define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
164 #define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
165 #define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)
166 #define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
167 #define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
168 #define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
169 #define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)
170 #define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)
171 #define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)
172 #define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)
173 #define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)
174 #define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)
175 #define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)
176 #define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)
177 #define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)
178 #define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)
179 #define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)
180 #define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)
182 #define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)
183 #define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)
184 #define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)
185 #define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)
186 #define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)
187 #define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)
188 #define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)
189 #define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)
190 #define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)
191 #define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)
192 #define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
193 #define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
194 #define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
195 #define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
196 #define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)
198 #define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
199 #define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
200 #define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)
201 #define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)
202 #define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
203 #define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
204 #define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
205 #define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)
207 #define ROUND_UP_EXP_FOR_FLICKER 15
209 /* Constants for automatic frame rate adjustment */
211 #define MAX_EXP_102 255
213 #define VERY_LOW_EXP 70
215 #define EXP_ACC_DARK 50
216 #define EXP_ACC_LIGHT 90
217 #define HIGH_COMP_102 160
222 #define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \
223 sd->params.version.firmwareRevision == (y))
225 /* Developer's Guide Table 5 p 3-34
226 * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
227 static u8 flicker_jumps
[2][2][4] =
228 { { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
229 { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
298 u8 allowableOverExposure
;
324 u8 decimationHysteresis
;
327 u8 decimationThreshMod
;
330 u8 videoSize
; /* CIF/QCIF */
334 struct { /* Intel QX3 specific data */
335 u8 qx3_detected
; /* a QX3 is present */
336 u8 toplight
; /* top light lit , R/W */
337 u8 bottomlight
; /* bottom light lit, R/W */
338 u8 button
; /* snapshot button pressed (R/O) */
339 u8 cradled
; /* microscope is in cradle (R/O) */
342 u8 colStart
; /* skip first 8*colStart pixels */
343 u8 colEnd
; /* finish at 8*colEnd pixels */
344 u8 rowStart
; /* skip first 4*rowStart lines */
345 u8 rowEnd
; /* finish at 4*rowEnd lines */
351 /* specific webcam descriptor */
353 struct gspca_dev gspca_dev
; /* !! must be the first item */
354 struct cam_params params
; /* camera settings */
356 atomic_t cam_exposure
;
360 u8 mainsFreq
; /* 0 = 50hz, 1 = 60hz */
365 /* V4L2 controls supported by the driver */
366 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
);
367 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
);
368 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
);
369 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
);
370 static int sd_setsaturation(struct gspca_dev
*gspca_dev
, __s32 val
);
371 static int sd_getsaturation(struct gspca_dev
*gspca_dev
, __s32
*val
);
372 static int sd_setfreq(struct gspca_dev
*gspca_dev
, __s32 val
);
373 static int sd_getfreq(struct gspca_dev
*gspca_dev
, __s32
*val
);
374 static int sd_setcomptarget(struct gspca_dev
*gspca_dev
, __s32 val
);
375 static int sd_getcomptarget(struct gspca_dev
*gspca_dev
, __s32
*val
);
376 static int sd_setilluminator1(struct gspca_dev
*gspca_dev
, __s32 val
);
377 static int sd_getilluminator1(struct gspca_dev
*gspca_dev
, __s32
*val
);
378 static int sd_setilluminator2(struct gspca_dev
*gspca_dev
, __s32 val
);
379 static int sd_getilluminator2(struct gspca_dev
*gspca_dev
, __s32
*val
);
381 static const struct ctrl sd_ctrls
[] = {
383 #define BRIGHTNESS_IDX 0
385 .id
= V4L2_CID_BRIGHTNESS
,
386 .type
= V4L2_CTRL_TYPE_INTEGER
,
387 .name
= "Brightness",
391 #define BRIGHTNESS_DEF 50
392 .default_value
= BRIGHTNESS_DEF
,
395 .set
= sd_setbrightness
,
396 .get
= sd_getbrightness
,
398 #define CONTRAST_IDX 1
401 .id
= V4L2_CID_CONTRAST
,
402 .type
= V4L2_CTRL_TYPE_INTEGER
,
407 #define CONTRAST_DEF 48
408 .default_value
= CONTRAST_DEF
,
410 .set
= sd_setcontrast
,
411 .get
= sd_getcontrast
,
413 #define SATURATION_IDX 2
416 .id
= V4L2_CID_SATURATION
,
417 .type
= V4L2_CTRL_TYPE_INTEGER
,
418 .name
= "Saturation",
422 #define SATURATION_DEF 50
423 .default_value
= SATURATION_DEF
,
425 .set
= sd_setsaturation
,
426 .get
= sd_getsaturation
,
428 #define POWER_LINE_FREQUENCY_IDX 3
431 .id
= V4L2_CID_POWER_LINE_FREQUENCY
,
432 .type
= V4L2_CTRL_TYPE_MENU
,
433 .name
= "Light frequency filter",
435 .maximum
= 2, /* 0: 0, 1: 50Hz, 2:60Hz */
438 .default_value
= FREQ_DEF
,
443 #define ILLUMINATORS_1_IDX 4
446 .id
= V4L2_CID_ILLUMINATORS_1
,
447 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
448 .name
= "Illuminator 1",
452 #define ILLUMINATORS_1_DEF 0
453 .default_value
= ILLUMINATORS_1_DEF
,
455 .set
= sd_setilluminator1
,
456 .get
= sd_getilluminator1
,
458 #define ILLUMINATORS_2_IDX 5
461 .id
= V4L2_CID_ILLUMINATORS_2
,
462 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
463 .name
= "Illuminator 2",
467 #define ILLUMINATORS_2_DEF 0
468 .default_value
= ILLUMINATORS_2_DEF
,
470 .set
= sd_setilluminator2
,
471 .get
= sd_getilluminator2
,
473 #define COMP_TARGET_IDX 6
476 #define V4L2_CID_COMP_TARGET V4L2_CID_PRIVATE_BASE
477 .id
= V4L2_CID_COMP_TARGET
,
478 .type
= V4L2_CTRL_TYPE_MENU
,
479 .name
= "Compression Target",
483 #define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY
484 .default_value
= COMP_TARGET_DEF
,
486 .set
= sd_setcomptarget
,
487 .get
= sd_getcomptarget
,
491 static const struct v4l2_pix_format mode
[] = {
492 {160, 120, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
493 /* The sizeimage is trial and error, as with low framerates
494 the camera will pad out usb frames, making the image
495 data larger then strictly necessary */
498 .colorspace
= V4L2_COLORSPACE_SRGB
,
500 {176, 144, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
503 .colorspace
= V4L2_COLORSPACE_SRGB
,
505 {320, 240, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
508 .colorspace
= V4L2_COLORSPACE_SRGB
,
510 {352, 288, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
513 .colorspace
= V4L2_COLORSPACE_SRGB
,
517 /**********************************************************************
521 **********************************************************************/
523 static int cpia_usb_transferCmd(struct gspca_dev
*gspca_dev
, u8
*command
)
527 int ret
, databytes
= command
[6] | (command
[7] << 8);
528 /* Sometimes we see spurious EPIPE errors */
531 if (command
[0] == DATA_IN
) {
532 pipe
= usb_rcvctrlpipe(gspca_dev
->dev
, 0);
533 requesttype
= USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
;
534 } else if (command
[0] == DATA_OUT
) {
535 pipe
= usb_sndctrlpipe(gspca_dev
->dev
, 0);
536 requesttype
= USB_TYPE_VENDOR
| USB_RECIP_DEVICE
;
538 PDEBUG(D_ERR
, "Unexpected first byte of command: %x",
544 ret
= usb_control_msg(gspca_dev
->dev
, pipe
,
547 command
[2] | (command
[3] << 8),
548 command
[4] | (command
[5] << 8),
549 gspca_dev
->usb_buf
, databytes
, 1000);
552 err("usb_control_msg %02x, error %d", command
[1],
555 if (ret
== -EPIPE
&& retries
> 0) {
560 return (ret
< 0) ? ret
: 0;
563 /* send an arbitrary command to the camera */
564 static int do_command(struct gspca_dev
*gspca_dev
, u16 command
,
565 u8 a
, u8 b
, u8 c
, u8 d
)
567 struct sd
*sd
= (struct sd
*) gspca_dev
;
572 case CPIA_COMMAND_GetCPIAVersion
:
573 case CPIA_COMMAND_GetPnPID
:
574 case CPIA_COMMAND_GetCameraStatus
:
575 case CPIA_COMMAND_GetVPVersion
:
576 case CPIA_COMMAND_GetColourParams
:
577 case CPIA_COMMAND_GetColourBalance
:
578 case CPIA_COMMAND_GetExposure
:
581 case CPIA_COMMAND_ReadMCPorts
:
582 case CPIA_COMMAND_ReadVCRegs
:
590 cmd
[0] = command
>> 8;
591 cmd
[1] = command
& 0xff;
599 ret
= cpia_usb_transferCmd(gspca_dev
, cmd
);
604 case CPIA_COMMAND_GetCPIAVersion
:
605 sd
->params
.version
.firmwareVersion
= gspca_dev
->usb_buf
[0];
606 sd
->params
.version
.firmwareRevision
= gspca_dev
->usb_buf
[1];
607 sd
->params
.version
.vcVersion
= gspca_dev
->usb_buf
[2];
608 sd
->params
.version
.vcRevision
= gspca_dev
->usb_buf
[3];
610 case CPIA_COMMAND_GetPnPID
:
611 sd
->params
.pnpID
.vendor
=
612 gspca_dev
->usb_buf
[0] | (gspca_dev
->usb_buf
[1] << 8);
613 sd
->params
.pnpID
.product
=
614 gspca_dev
->usb_buf
[2] | (gspca_dev
->usb_buf
[3] << 8);
615 sd
->params
.pnpID
.deviceRevision
=
616 gspca_dev
->usb_buf
[4] | (gspca_dev
->usb_buf
[5] << 8);
618 case CPIA_COMMAND_GetCameraStatus
:
619 sd
->params
.status
.systemState
= gspca_dev
->usb_buf
[0];
620 sd
->params
.status
.grabState
= gspca_dev
->usb_buf
[1];
621 sd
->params
.status
.streamState
= gspca_dev
->usb_buf
[2];
622 sd
->params
.status
.fatalError
= gspca_dev
->usb_buf
[3];
623 sd
->params
.status
.cmdError
= gspca_dev
->usb_buf
[4];
624 sd
->params
.status
.debugFlags
= gspca_dev
->usb_buf
[5];
625 sd
->params
.status
.vpStatus
= gspca_dev
->usb_buf
[6];
626 sd
->params
.status
.errorCode
= gspca_dev
->usb_buf
[7];
628 case CPIA_COMMAND_GetVPVersion
:
629 sd
->params
.vpVersion
.vpVersion
= gspca_dev
->usb_buf
[0];
630 sd
->params
.vpVersion
.vpRevision
= gspca_dev
->usb_buf
[1];
631 sd
->params
.vpVersion
.cameraHeadID
=
632 gspca_dev
->usb_buf
[2] | (gspca_dev
->usb_buf
[3] << 8);
634 case CPIA_COMMAND_GetColourParams
:
635 sd
->params
.colourParams
.brightness
= gspca_dev
->usb_buf
[0];
636 sd
->params
.colourParams
.contrast
= gspca_dev
->usb_buf
[1];
637 sd
->params
.colourParams
.saturation
= gspca_dev
->usb_buf
[2];
639 case CPIA_COMMAND_GetColourBalance
:
640 sd
->params
.colourBalance
.redGain
= gspca_dev
->usb_buf
[0];
641 sd
->params
.colourBalance
.greenGain
= gspca_dev
->usb_buf
[1];
642 sd
->params
.colourBalance
.blueGain
= gspca_dev
->usb_buf
[2];
644 case CPIA_COMMAND_GetExposure
:
645 sd
->params
.exposure
.gain
= gspca_dev
->usb_buf
[0];
646 sd
->params
.exposure
.fineExp
= gspca_dev
->usb_buf
[1];
647 sd
->params
.exposure
.coarseExpLo
= gspca_dev
->usb_buf
[2];
648 sd
->params
.exposure
.coarseExpHi
= gspca_dev
->usb_buf
[3];
649 sd
->params
.exposure
.redComp
= gspca_dev
->usb_buf
[4];
650 sd
->params
.exposure
.green1Comp
= gspca_dev
->usb_buf
[5];
651 sd
->params
.exposure
.green2Comp
= gspca_dev
->usb_buf
[6];
652 sd
->params
.exposure
.blueComp
= gspca_dev
->usb_buf
[7];
655 case CPIA_COMMAND_ReadMCPorts
:
656 if (!sd
->params
.qx3
.qx3_detected
)
658 /* test button press */
659 sd
->params
.qx3
.button
= ((gspca_dev
->usb_buf
[1] & 0x02) == 0);
660 if (sd
->params
.qx3
.button
) {
661 /* button pressed - unlock the latch */
662 do_command(gspca_dev
, CPIA_COMMAND_WriteMCPort
,
664 do_command(gspca_dev
, CPIA_COMMAND_WriteMCPort
,
668 /* test whether microscope is cradled */
669 sd
->params
.qx3
.cradled
= ((gspca_dev
->usb_buf
[2] & 0x40) == 0);
676 /* send a command to the camera with an additional data transaction */
677 static int do_command_extended(struct gspca_dev
*gspca_dev
, u16 command
,
678 u8 a
, u8 b
, u8 c
, u8 d
,
679 u8 e
, u8 f
, u8 g
, u8 h
,
680 u8 i
, u8 j
, u8 k
, u8 l
)
684 cmd
[0] = command
>> 8;
685 cmd
[1] = command
& 0xff;
692 gspca_dev
->usb_buf
[0] = e
;
693 gspca_dev
->usb_buf
[1] = f
;
694 gspca_dev
->usb_buf
[2] = g
;
695 gspca_dev
->usb_buf
[3] = h
;
696 gspca_dev
->usb_buf
[4] = i
;
697 gspca_dev
->usb_buf
[5] = j
;
698 gspca_dev
->usb_buf
[6] = k
;
699 gspca_dev
->usb_buf
[7] = l
;
701 return cpia_usb_transferCmd(gspca_dev
, cmd
);
704 /* find_over_exposure
705 * Finds a suitable value of OverExposure for use with SetFlickerCtrl
706 * Some calculation is required because this value changes with the brightness
707 * set with SetColourParameters
709 * Parameters: Brightness - last brightness value set with SetColourParameters
711 * Returns: OverExposure value to use with SetFlickerCtrl
713 #define FLICKER_MAX_EXPOSURE 250
714 #define FLICKER_ALLOWABLE_OVER_EXPOSURE 146
715 #define FLICKER_BRIGHTNESS_CONSTANT 59
716 static int find_over_exposure(int brightness
)
718 int MaxAllowableOverExposure
, OverExposure
;
720 MaxAllowableOverExposure
= FLICKER_MAX_EXPOSURE
- brightness
-
721 FLICKER_BRIGHTNESS_CONSTANT
;
723 if (MaxAllowableOverExposure
< FLICKER_ALLOWABLE_OVER_EXPOSURE
)
724 OverExposure
= MaxAllowableOverExposure
;
726 OverExposure
= FLICKER_ALLOWABLE_OVER_EXPOSURE
;
730 #undef FLICKER_MAX_EXPOSURE
731 #undef FLICKER_ALLOWABLE_OVER_EXPOSURE
732 #undef FLICKER_BRIGHTNESS_CONSTANT
734 /* initialise cam_data structure */
735 static void reset_camera_params(struct gspca_dev
*gspca_dev
)
737 struct sd
*sd
= (struct sd
*) gspca_dev
;
738 struct cam_params
*params
= &sd
->params
;
740 /* The following parameter values are the defaults from
741 * "Software Developer's Guide for CPiA Cameras". Any changes
742 * to the defaults are noted in comments. */
743 params
->colourParams
.brightness
= BRIGHTNESS_DEF
;
744 params
->colourParams
.contrast
= CONTRAST_DEF
;
745 params
->colourParams
.saturation
= SATURATION_DEF
;
746 params
->exposure
.gainMode
= 4;
747 params
->exposure
.expMode
= 2; /* AEC */
748 params
->exposure
.compMode
= 1;
749 params
->exposure
.centreWeight
= 1;
750 params
->exposure
.gain
= 0;
751 params
->exposure
.fineExp
= 0;
752 params
->exposure
.coarseExpLo
= 185;
753 params
->exposure
.coarseExpHi
= 0;
754 params
->exposure
.redComp
= COMP_RED
;
755 params
->exposure
.green1Comp
= COMP_GREEN1
;
756 params
->exposure
.green2Comp
= COMP_GREEN2
;
757 params
->exposure
.blueComp
= COMP_BLUE
;
758 params
->colourBalance
.balanceMode
= 2; /* ACB */
759 params
->colourBalance
.redGain
= 32;
760 params
->colourBalance
.greenGain
= 6;
761 params
->colourBalance
.blueGain
= 92;
762 params
->apcor
.gain1
= 0x18;
763 params
->apcor
.gain2
= 0x16;
764 params
->apcor
.gain4
= 0x24;
765 params
->apcor
.gain8
= 0x34;
766 params
->flickerControl
.flickerMode
= 0;
767 params
->flickerControl
.disabled
= 1;
769 params
->flickerControl
.coarseJump
=
770 flicker_jumps
[sd
->mainsFreq
]
771 [params
->sensorFps
.baserate
]
772 [params
->sensorFps
.divisor
];
773 params
->flickerControl
.allowableOverExposure
=
774 find_over_exposure(params
->colourParams
.brightness
);
775 params
->vlOffset
.gain1
= 20;
776 params
->vlOffset
.gain2
= 24;
777 params
->vlOffset
.gain4
= 26;
778 params
->vlOffset
.gain8
= 26;
779 params
->compressionParams
.hysteresis
= 3;
780 params
->compressionParams
.threshMax
= 11;
781 params
->compressionParams
.smallStep
= 1;
782 params
->compressionParams
.largeStep
= 3;
783 params
->compressionParams
.decimationHysteresis
= 2;
784 params
->compressionParams
.frDiffStepThresh
= 5;
785 params
->compressionParams
.qDiffStepThresh
= 3;
786 params
->compressionParams
.decimationThreshMod
= 2;
787 /* End of default values from Software Developer's Guide */
789 /* Set Sensor FPS to 15fps. This seems better than 30fps
790 * for indoor lighting. */
791 params
->sensorFps
.divisor
= 1;
792 params
->sensorFps
.baserate
= 1;
794 params
->yuvThreshold
.yThreshold
= 6; /* From windows driver */
795 params
->yuvThreshold
.uvThreshold
= 6; /* From windows driver */
797 params
->format
.subSample
= SUBSAMPLE_420
;
798 params
->format
.yuvOrder
= YUVORDER_YUYV
;
800 params
->compression
.mode
= CPIA_COMPRESSION_AUTO
;
801 params
->compression
.decimation
= NO_DECIMATION
;
803 params
->compressionTarget
.frTargeting
= COMP_TARGET_DEF
;
804 params
->compressionTarget
.targetFR
= 15; /* From windows driver */
805 params
->compressionTarget
.targetQ
= 5; /* From windows driver */
807 params
->qx3
.qx3_detected
= 0;
808 params
->qx3
.toplight
= 0;
809 params
->qx3
.bottomlight
= 0;
810 params
->qx3
.button
= 0;
811 params
->qx3
.cradled
= 0;
814 static void printstatus(struct cam_params
*params
)
816 PDEBUG(D_PROBE
, "status: %02x %02x %02x %02x %02x %02x %02x %02x",
817 params
->status
.systemState
, params
->status
.grabState
,
818 params
->status
.streamState
, params
->status
.fatalError
,
819 params
->status
.cmdError
, params
->status
.debugFlags
,
820 params
->status
.vpStatus
, params
->status
.errorCode
);
823 static int goto_low_power(struct gspca_dev
*gspca_dev
)
825 struct sd
*sd
= (struct sd
*) gspca_dev
;
828 ret
= do_command(gspca_dev
, CPIA_COMMAND_GotoLoPower
, 0, 0, 0, 0);
832 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
836 if (sd
->params
.status
.systemState
!= LO_POWER_STATE
) {
837 if (sd
->params
.status
.systemState
!= WARM_BOOT_STATE
) {
839 "unexpected state after lo power cmd: %02x",
840 sd
->params
.status
.systemState
);
841 printstatus(&sd
->params
);
846 PDEBUG(D_CONF
, "camera now in LOW power state");
850 static int goto_high_power(struct gspca_dev
*gspca_dev
)
852 struct sd
*sd
= (struct sd
*) gspca_dev
;
855 ret
= do_command(gspca_dev
, CPIA_COMMAND_GotoHiPower
, 0, 0, 0, 0);
859 msleep_interruptible(40); /* windows driver does it too */
861 if (signal_pending(current
))
864 do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
868 if (sd
->params
.status
.systemState
!= HI_POWER_STATE
) {
869 PDEBUG(D_ERR
, "unexpected state after hi power cmd: %02x",
870 sd
->params
.status
.systemState
);
871 printstatus(&sd
->params
);
875 PDEBUG(D_CONF
, "camera now in HIGH power state");
879 static int get_version_information(struct gspca_dev
*gspca_dev
)
884 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetCPIAVersion
, 0, 0, 0, 0);
889 return do_command(gspca_dev
, CPIA_COMMAND_GetPnPID
, 0, 0, 0, 0);
892 static int save_camera_state(struct gspca_dev
*gspca_dev
)
896 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetColourBalance
, 0, 0, 0, 0);
900 return do_command(gspca_dev
, CPIA_COMMAND_GetExposure
, 0, 0, 0, 0);
903 static int command_setformat(struct gspca_dev
*gspca_dev
)
905 struct sd
*sd
= (struct sd
*) gspca_dev
;
908 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetFormat
,
909 sd
->params
.format
.videoSize
,
910 sd
->params
.format
.subSample
,
911 sd
->params
.format
.yuvOrder
, 0);
915 return do_command(gspca_dev
, CPIA_COMMAND_SetROI
,
916 sd
->params
.roi
.colStart
, sd
->params
.roi
.colEnd
,
917 sd
->params
.roi
.rowStart
, sd
->params
.roi
.rowEnd
);
920 static int command_setcolourparams(struct gspca_dev
*gspca_dev
)
922 struct sd
*sd
= (struct sd
*) gspca_dev
;
923 return do_command(gspca_dev
, CPIA_COMMAND_SetColourParams
,
924 sd
->params
.colourParams
.brightness
,
925 sd
->params
.colourParams
.contrast
,
926 sd
->params
.colourParams
.saturation
, 0);
929 static int command_setapcor(struct gspca_dev
*gspca_dev
)
931 struct sd
*sd
= (struct sd
*) gspca_dev
;
932 return do_command(gspca_dev
, CPIA_COMMAND_SetApcor
,
933 sd
->params
.apcor
.gain1
,
934 sd
->params
.apcor
.gain2
,
935 sd
->params
.apcor
.gain4
,
936 sd
->params
.apcor
.gain8
);
939 static int command_setvloffset(struct gspca_dev
*gspca_dev
)
941 struct sd
*sd
= (struct sd
*) gspca_dev
;
942 return do_command(gspca_dev
, CPIA_COMMAND_SetVLOffset
,
943 sd
->params
.vlOffset
.gain1
,
944 sd
->params
.vlOffset
.gain2
,
945 sd
->params
.vlOffset
.gain4
,
946 sd
->params
.vlOffset
.gain8
);
949 static int command_setexposure(struct gspca_dev
*gspca_dev
)
951 struct sd
*sd
= (struct sd
*) gspca_dev
;
954 ret
= do_command_extended(gspca_dev
, CPIA_COMMAND_SetExposure
,
955 sd
->params
.exposure
.gainMode
,
957 sd
->params
.exposure
.compMode
,
958 sd
->params
.exposure
.centreWeight
,
959 sd
->params
.exposure
.gain
,
960 sd
->params
.exposure
.fineExp
,
961 sd
->params
.exposure
.coarseExpLo
,
962 sd
->params
.exposure
.coarseExpHi
,
963 sd
->params
.exposure
.redComp
,
964 sd
->params
.exposure
.green1Comp
,
965 sd
->params
.exposure
.green2Comp
,
966 sd
->params
.exposure
.blueComp
);
970 if (sd
->params
.exposure
.expMode
!= 1) {
971 ret
= do_command_extended(gspca_dev
, CPIA_COMMAND_SetExposure
,
973 sd
->params
.exposure
.expMode
,
975 sd
->params
.exposure
.gain
,
976 sd
->params
.exposure
.fineExp
,
977 sd
->params
.exposure
.coarseExpLo
,
978 sd
->params
.exposure
.coarseExpHi
,
985 static int command_setcolourbalance(struct gspca_dev
*gspca_dev
)
987 struct sd
*sd
= (struct sd
*) gspca_dev
;
989 if (sd
->params
.colourBalance
.balanceMode
== 1) {
992 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
994 sd
->params
.colourBalance
.redGain
,
995 sd
->params
.colourBalance
.greenGain
,
996 sd
->params
.colourBalance
.blueGain
);
1000 return do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
1003 if (sd
->params
.colourBalance
.balanceMode
== 2) {
1004 return do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
1007 if (sd
->params
.colourBalance
.balanceMode
== 3) {
1008 return do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
1015 static int command_setcompressiontarget(struct gspca_dev
*gspca_dev
)
1017 struct sd
*sd
= (struct sd
*) gspca_dev
;
1019 return do_command(gspca_dev
, CPIA_COMMAND_SetCompressionTarget
,
1020 sd
->params
.compressionTarget
.frTargeting
,
1021 sd
->params
.compressionTarget
.targetFR
,
1022 sd
->params
.compressionTarget
.targetQ
, 0);
1025 static int command_setyuvtresh(struct gspca_dev
*gspca_dev
)
1027 struct sd
*sd
= (struct sd
*) gspca_dev
;
1029 return do_command(gspca_dev
, CPIA_COMMAND_SetYUVThresh
,
1030 sd
->params
.yuvThreshold
.yThreshold
,
1031 sd
->params
.yuvThreshold
.uvThreshold
, 0, 0);
1034 static int command_setcompressionparams(struct gspca_dev
*gspca_dev
)
1036 struct sd
*sd
= (struct sd
*) gspca_dev
;
1038 return do_command_extended(gspca_dev
,
1039 CPIA_COMMAND_SetCompressionParams
,
1041 sd
->params
.compressionParams
.hysteresis
,
1042 sd
->params
.compressionParams
.threshMax
,
1043 sd
->params
.compressionParams
.smallStep
,
1044 sd
->params
.compressionParams
.largeStep
,
1045 sd
->params
.compressionParams
.decimationHysteresis
,
1046 sd
->params
.compressionParams
.frDiffStepThresh
,
1047 sd
->params
.compressionParams
.qDiffStepThresh
,
1048 sd
->params
.compressionParams
.decimationThreshMod
);
1051 static int command_setcompression(struct gspca_dev
*gspca_dev
)
1053 struct sd
*sd
= (struct sd
*) gspca_dev
;
1055 return do_command(gspca_dev
, CPIA_COMMAND_SetCompression
,
1056 sd
->params
.compression
.mode
,
1057 sd
->params
.compression
.decimation
, 0, 0);
1060 static int command_setsensorfps(struct gspca_dev
*gspca_dev
)
1062 struct sd
*sd
= (struct sd
*) gspca_dev
;
1064 return do_command(gspca_dev
, CPIA_COMMAND_SetSensorFPS
,
1065 sd
->params
.sensorFps
.divisor
,
1066 sd
->params
.sensorFps
.baserate
, 0, 0);
1069 static int command_setflickerctrl(struct gspca_dev
*gspca_dev
)
1071 struct sd
*sd
= (struct sd
*) gspca_dev
;
1073 return do_command(gspca_dev
, CPIA_COMMAND_SetFlickerCtrl
,
1074 sd
->params
.flickerControl
.flickerMode
,
1075 sd
->params
.flickerControl
.coarseJump
,
1076 sd
->params
.flickerControl
.allowableOverExposure
,
1080 static int command_setecptiming(struct gspca_dev
*gspca_dev
)
1082 struct sd
*sd
= (struct sd
*) gspca_dev
;
1084 return do_command(gspca_dev
, CPIA_COMMAND_SetECPTiming
,
1085 sd
->params
.ecpTiming
, 0, 0, 0);
1088 static int command_pause(struct gspca_dev
*gspca_dev
)
1090 return do_command(gspca_dev
, CPIA_COMMAND_EndStreamCap
, 0, 0, 0, 0);
1093 static int command_resume(struct gspca_dev
*gspca_dev
)
1095 struct sd
*sd
= (struct sd
*) gspca_dev
;
1097 return do_command(gspca_dev
, CPIA_COMMAND_InitStreamCap
,
1098 0, sd
->params
.streamStartLine
, 0, 0);
1101 static int command_setlights(struct gspca_dev
*gspca_dev
)
1103 struct sd
*sd
= (struct sd
*) gspca_dev
;
1106 if (!sd
->params
.qx3
.qx3_detected
)
1109 p1
= (sd
->params
.qx3
.bottomlight
== 0) << 1;
1110 p2
= (sd
->params
.qx3
.toplight
== 0) << 3;
1112 ret
= do_command(gspca_dev
, CPIA_COMMAND_WriteVCReg
,
1113 0x90, 0x8f, 0x50, 0);
1117 return do_command(gspca_dev
, CPIA_COMMAND_WriteMCPort
, 2, 0,
1121 static int set_flicker(struct gspca_dev
*gspca_dev
, int on
, int apply
)
1123 /* Everything in here is from the Windows driver */
1124 /* define for compgain calculation */
1126 #define COMPGAIN(base, curexp, newexp) \
1127 (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
1128 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1129 (u16)((float)curexp * (float)(u8)(curcomp + 128) / \
1130 (float)(u8)(basecomp - 128))
1132 /* equivalent functions without floating point math */
1133 #define COMPGAIN(base, curexp, newexp) \
1134 (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2 * newexp)))
1135 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1136 (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
1139 struct sd
*sd
= (struct sd
*) gspca_dev
;
1140 int currentexp
= sd
->params
.exposure
.coarseExpLo
+
1141 sd
->params
.exposure
.coarseExpHi
* 256;
1145 int cj
= sd
->params
.flickerControl
.coarseJump
;
1146 sd
->params
.flickerControl
.flickerMode
= 1;
1147 sd
->params
.flickerControl
.disabled
= 0;
1148 if (sd
->params
.exposure
.expMode
!= 2) {
1149 sd
->params
.exposure
.expMode
= 2;
1150 sd
->exposure_status
= EXPOSURE_NORMAL
;
1152 currentexp
= currentexp
<< sd
->params
.exposure
.gain
;
1153 sd
->params
.exposure
.gain
= 0;
1154 /* round down current exposure to nearest value */
1155 startexp
= (currentexp
+ ROUND_UP_EXP_FOR_FLICKER
) / cj
;
1158 startexp
= (startexp
* cj
) - 1;
1159 if (FIRMWARE_VERSION(1, 2))
1160 while (startexp
> MAX_EXP_102
)
1163 while (startexp
> MAX_EXP
)
1165 sd
->params
.exposure
.coarseExpLo
= startexp
& 0xff;
1166 sd
->params
.exposure
.coarseExpHi
= startexp
>> 8;
1167 if (currentexp
> startexp
) {
1168 if (currentexp
> (2 * startexp
))
1169 currentexp
= 2 * startexp
;
1170 sd
->params
.exposure
.redComp
=
1171 COMPGAIN(COMP_RED
, currentexp
, startexp
);
1172 sd
->params
.exposure
.green1Comp
=
1173 COMPGAIN(COMP_GREEN1
, currentexp
, startexp
);
1174 sd
->params
.exposure
.green2Comp
=
1175 COMPGAIN(COMP_GREEN2
, currentexp
, startexp
);
1176 sd
->params
.exposure
.blueComp
=
1177 COMPGAIN(COMP_BLUE
, currentexp
, startexp
);
1179 sd
->params
.exposure
.redComp
= COMP_RED
;
1180 sd
->params
.exposure
.green1Comp
= COMP_GREEN1
;
1181 sd
->params
.exposure
.green2Comp
= COMP_GREEN2
;
1182 sd
->params
.exposure
.blueComp
= COMP_BLUE
;
1184 if (FIRMWARE_VERSION(1, 2))
1185 sd
->params
.exposure
.compMode
= 0;
1187 sd
->params
.exposure
.compMode
= 1;
1189 sd
->params
.apcor
.gain1
= 0x18;
1190 sd
->params
.apcor
.gain2
= 0x18;
1191 sd
->params
.apcor
.gain4
= 0x16;
1192 sd
->params
.apcor
.gain8
= 0x14;
1194 sd
->params
.flickerControl
.flickerMode
= 0;
1195 sd
->params
.flickerControl
.disabled
= 1;
1196 /* Average equivalent coarse for each comp channel */
1197 startexp
= EXP_FROM_COMP(COMP_RED
,
1198 sd
->params
.exposure
.redComp
, currentexp
);
1199 startexp
+= EXP_FROM_COMP(COMP_GREEN1
,
1200 sd
->params
.exposure
.green1Comp
, currentexp
);
1201 startexp
+= EXP_FROM_COMP(COMP_GREEN2
,
1202 sd
->params
.exposure
.green2Comp
, currentexp
);
1203 startexp
+= EXP_FROM_COMP(COMP_BLUE
,
1204 sd
->params
.exposure
.blueComp
, currentexp
);
1205 startexp
= startexp
>> 2;
1206 while (startexp
> MAX_EXP
&& sd
->params
.exposure
.gain
<
1207 sd
->params
.exposure
.gainMode
- 1) {
1208 startexp
= startexp
>> 1;
1209 ++sd
->params
.exposure
.gain
;
1211 if (FIRMWARE_VERSION(1, 2) && startexp
> MAX_EXP_102
)
1212 startexp
= MAX_EXP_102
;
1213 if (startexp
> MAX_EXP
)
1215 sd
->params
.exposure
.coarseExpLo
= startexp
& 0xff;
1216 sd
->params
.exposure
.coarseExpHi
= startexp
>> 8;
1217 sd
->params
.exposure
.redComp
= COMP_RED
;
1218 sd
->params
.exposure
.green1Comp
= COMP_GREEN1
;
1219 sd
->params
.exposure
.green2Comp
= COMP_GREEN2
;
1220 sd
->params
.exposure
.blueComp
= COMP_BLUE
;
1221 sd
->params
.exposure
.compMode
= 1;
1222 sd
->params
.apcor
.gain1
= 0x18;
1223 sd
->params
.apcor
.gain2
= 0x16;
1224 sd
->params
.apcor
.gain4
= 0x24;
1225 sd
->params
.apcor
.gain8
= 0x34;
1227 sd
->params
.vlOffset
.gain1
= 20;
1228 sd
->params
.vlOffset
.gain2
= 24;
1229 sd
->params
.vlOffset
.gain4
= 26;
1230 sd
->params
.vlOffset
.gain8
= 26;
1233 ret
= command_setexposure(gspca_dev
);
1237 ret
= command_setapcor(gspca_dev
);
1241 ret
= command_setvloffset(gspca_dev
);
1245 ret
= command_setflickerctrl(gspca_dev
);
1251 #undef EXP_FROM_COMP
1255 /* monitor the exposure and adjust the sensor frame rate if needed */
1256 static void monitor_exposure(struct gspca_dev
*gspca_dev
)
1258 struct sd
*sd
= (struct sd
*) gspca_dev
;
1259 u8 exp_acc
, bcomp
, gain
, coarseL
, cmd
[8];
1260 int ret
, light_exp
, dark_exp
, very_dark_exp
;
1261 int old_exposure
, new_exposure
, framerate
;
1262 int setfps
= 0, setexp
= 0, setflicker
= 0;
1264 /* get necessary stats and register settings from camera */
1265 /* do_command can't handle this, so do it ourselves */
1266 cmd
[0] = CPIA_COMMAND_ReadVPRegs
>> 8;
1267 cmd
[1] = CPIA_COMMAND_ReadVPRegs
& 0xff;
1274 ret
= cpia_usb_transferCmd(gspca_dev
, cmd
);
1276 err("ReadVPRegs(30,4,9,8) - failed: %d", ret
);
1279 exp_acc
= gspca_dev
->usb_buf
[0];
1280 bcomp
= gspca_dev
->usb_buf
[1];
1281 gain
= gspca_dev
->usb_buf
[2];
1282 coarseL
= gspca_dev
->usb_buf
[3];
1284 light_exp
= sd
->params
.colourParams
.brightness
+
1285 TC
- 50 + EXP_ACC_LIGHT
;
1286 if (light_exp
> 255)
1288 dark_exp
= sd
->params
.colourParams
.brightness
+
1289 TC
- 50 - EXP_ACC_DARK
;
1292 very_dark_exp
= dark_exp
/ 2;
1294 old_exposure
= sd
->params
.exposure
.coarseExpHi
* 256 +
1295 sd
->params
.exposure
.coarseExpLo
;
1297 if (!sd
->params
.flickerControl
.disabled
) {
1298 /* Flicker control on */
1299 int max_comp
= FIRMWARE_VERSION(1, 2) ? MAX_COMP
:
1301 bcomp
+= 128; /* decode */
1302 if (bcomp
>= max_comp
&& exp_acc
< dark_exp
) {
1304 if (exp_acc
< very_dark_exp
) {
1306 if (sd
->exposure_status
== EXPOSURE_VERY_DARK
)
1307 ++sd
->exposure_count
;
1309 sd
->exposure_status
=
1311 sd
->exposure_count
= 1;
1315 if (sd
->exposure_status
== EXPOSURE_DARK
)
1316 ++sd
->exposure_count
;
1318 sd
->exposure_status
= EXPOSURE_DARK
;
1319 sd
->exposure_count
= 1;
1322 } else if (old_exposure
<= LOW_EXP
|| exp_acc
> light_exp
) {
1324 if (old_exposure
<= VERY_LOW_EXP
) {
1326 if (sd
->exposure_status
== EXPOSURE_VERY_LIGHT
)
1327 ++sd
->exposure_count
;
1329 sd
->exposure_status
=
1330 EXPOSURE_VERY_LIGHT
;
1331 sd
->exposure_count
= 1;
1335 if (sd
->exposure_status
== EXPOSURE_LIGHT
)
1336 ++sd
->exposure_count
;
1338 sd
->exposure_status
= EXPOSURE_LIGHT
;
1339 sd
->exposure_count
= 1;
1343 /* not dark or light */
1344 sd
->exposure_status
= EXPOSURE_NORMAL
;
1347 /* Flicker control off */
1348 if (old_exposure
>= MAX_EXP
&& exp_acc
< dark_exp
) {
1350 if (exp_acc
< very_dark_exp
) {
1352 if (sd
->exposure_status
== EXPOSURE_VERY_DARK
)
1353 ++sd
->exposure_count
;
1355 sd
->exposure_status
=
1357 sd
->exposure_count
= 1;
1361 if (sd
->exposure_status
== EXPOSURE_DARK
)
1362 ++sd
->exposure_count
;
1364 sd
->exposure_status
= EXPOSURE_DARK
;
1365 sd
->exposure_count
= 1;
1368 } else if (old_exposure
<= LOW_EXP
|| exp_acc
> light_exp
) {
1370 if (old_exposure
<= VERY_LOW_EXP
) {
1372 if (sd
->exposure_status
== EXPOSURE_VERY_LIGHT
)
1373 ++sd
->exposure_count
;
1375 sd
->exposure_status
=
1376 EXPOSURE_VERY_LIGHT
;
1377 sd
->exposure_count
= 1;
1381 if (sd
->exposure_status
== EXPOSURE_LIGHT
)
1382 ++sd
->exposure_count
;
1384 sd
->exposure_status
= EXPOSURE_LIGHT
;
1385 sd
->exposure_count
= 1;
1389 /* not dark or light */
1390 sd
->exposure_status
= EXPOSURE_NORMAL
;
1394 framerate
= atomic_read(&sd
->fps
);
1395 if (framerate
> 30 || framerate
< 1)
1398 if (!sd
->params
.flickerControl
.disabled
) {
1399 /* Flicker control on */
1400 if ((sd
->exposure_status
== EXPOSURE_VERY_DARK
||
1401 sd
->exposure_status
== EXPOSURE_DARK
) &&
1402 sd
->exposure_count
>= DARK_TIME
* framerate
&&
1403 sd
->params
.sensorFps
.divisor
< 3) {
1405 /* dark for too long */
1406 ++sd
->params
.sensorFps
.divisor
;
1409 sd
->params
.flickerControl
.coarseJump
=
1410 flicker_jumps
[sd
->mainsFreq
]
1411 [sd
->params
.sensorFps
.baserate
]
1412 [sd
->params
.sensorFps
.divisor
];
1415 new_exposure
= sd
->params
.flickerControl
.coarseJump
-1;
1416 while (new_exposure
< old_exposure
/ 2)
1418 sd
->params
.flickerControl
.coarseJump
;
1419 sd
->params
.exposure
.coarseExpLo
= new_exposure
& 0xff;
1420 sd
->params
.exposure
.coarseExpHi
= new_exposure
>> 8;
1422 sd
->exposure_status
= EXPOSURE_NORMAL
;
1423 PDEBUG(D_CONF
, "Automatically decreasing sensor_fps");
1425 } else if ((sd
->exposure_status
== EXPOSURE_VERY_LIGHT
||
1426 sd
->exposure_status
== EXPOSURE_LIGHT
) &&
1427 sd
->exposure_count
>= LIGHT_TIME
* framerate
&&
1428 sd
->params
.sensorFps
.divisor
> 0) {
1430 /* light for too long */
1431 int max_exp
= FIRMWARE_VERSION(1, 2) ? MAX_EXP_102
:
1433 --sd
->params
.sensorFps
.divisor
;
1436 sd
->params
.flickerControl
.coarseJump
=
1437 flicker_jumps
[sd
->mainsFreq
]
1438 [sd
->params
.sensorFps
.baserate
]
1439 [sd
->params
.sensorFps
.divisor
];
1442 new_exposure
= sd
->params
.flickerControl
.coarseJump
-1;
1443 while (new_exposure
< 2 * old_exposure
&&
1445 sd
->params
.flickerControl
.coarseJump
< max_exp
)
1447 sd
->params
.flickerControl
.coarseJump
;
1448 sd
->params
.exposure
.coarseExpLo
= new_exposure
& 0xff;
1449 sd
->params
.exposure
.coarseExpHi
= new_exposure
>> 8;
1451 sd
->exposure_status
= EXPOSURE_NORMAL
;
1452 PDEBUG(D_CONF
, "Automatically increasing sensor_fps");
1455 /* Flicker control off */
1456 if ((sd
->exposure_status
== EXPOSURE_VERY_DARK
||
1457 sd
->exposure_status
== EXPOSURE_DARK
) &&
1458 sd
->exposure_count
>= DARK_TIME
* framerate
&&
1459 sd
->params
.sensorFps
.divisor
< 3) {
1461 /* dark for too long */
1462 ++sd
->params
.sensorFps
.divisor
;
1465 if (sd
->params
.exposure
.gain
> 0) {
1466 --sd
->params
.exposure
.gain
;
1469 sd
->exposure_status
= EXPOSURE_NORMAL
;
1470 PDEBUG(D_CONF
, "Automatically decreasing sensor_fps");
1472 } else if ((sd
->exposure_status
== EXPOSURE_VERY_LIGHT
||
1473 sd
->exposure_status
== EXPOSURE_LIGHT
) &&
1474 sd
->exposure_count
>= LIGHT_TIME
* framerate
&&
1475 sd
->params
.sensorFps
.divisor
> 0) {
1477 /* light for too long */
1478 --sd
->params
.sensorFps
.divisor
;
1481 if (sd
->params
.exposure
.gain
<
1482 sd
->params
.exposure
.gainMode
- 1) {
1483 ++sd
->params
.exposure
.gain
;
1486 sd
->exposure_status
= EXPOSURE_NORMAL
;
1487 PDEBUG(D_CONF
, "Automatically increasing sensor_fps");
1492 command_setexposure(gspca_dev
);
1495 command_setsensorfps(gspca_dev
);
1498 command_setflickerctrl(gspca_dev
);
1501 /*-----------------------------------------------------------------*/
1502 /* if flicker is switched off, this function switches it back on.It checks,
1503 however, that conditions are suitable before restarting it.
1504 This should only be called for firmware version 1.2.
1506 It also adjust the colour balance when an exposure step is detected - as
1507 long as flicker is running
1509 static void restart_flicker(struct gspca_dev
*gspca_dev
)
1511 struct sd
*sd
= (struct sd
*) gspca_dev
;
1512 int cam_exposure
, old_exp
;
1514 if (!FIRMWARE_VERSION(1, 2))
1517 cam_exposure
= atomic_read(&sd
->cam_exposure
);
1519 if (sd
->params
.flickerControl
.flickerMode
== 0 ||
1523 old_exp
= sd
->params
.exposure
.coarseExpLo
+
1524 sd
->params
.exposure
.coarseExpHi
*256;
1526 see how far away camera exposure is from a valid
1527 flicker exposure value
1529 cam_exposure
%= sd
->params
.flickerControl
.coarseJump
;
1530 if (!sd
->params
.flickerControl
.disabled
&&
1531 cam_exposure
<= sd
->params
.flickerControl
.coarseJump
- 3) {
1532 /* Flicker control auto-disabled */
1533 sd
->params
.flickerControl
.disabled
= 1;
1536 if (sd
->params
.flickerControl
.disabled
&&
1537 old_exp
> sd
->params
.flickerControl
.coarseJump
+
1538 ROUND_UP_EXP_FOR_FLICKER
) {
1539 /* exposure is now high enough to switch
1540 flicker control back on */
1541 set_flicker(gspca_dev
, 1, 1);
1545 /* this function is called at probe time */
1546 static int sd_config(struct gspca_dev
*gspca_dev
,
1547 const struct usb_device_id
*id
)
1551 reset_camera_params(gspca_dev
);
1553 PDEBUG(D_PROBE
, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)",
1554 id
->idVendor
, id
->idProduct
);
1556 cam
= &gspca_dev
->cam
;
1557 cam
->cam_mode
= mode
;
1558 cam
->nmodes
= ARRAY_SIZE(mode
);
1560 sd_setfreq(gspca_dev
, FREQ_DEF
);
1565 /* -- start the camera -- */
1566 static int sd_start(struct gspca_dev
*gspca_dev
)
1568 struct sd
*sd
= (struct sd
*) gspca_dev
;
1571 /* Start the camera in low power mode */
1572 if (goto_low_power(gspca_dev
)) {
1573 if (sd
->params
.status
.systemState
!= WARM_BOOT_STATE
) {
1574 PDEBUG(D_ERR
, "unexpected systemstate: %02x",
1575 sd
->params
.status
.systemState
);
1576 printstatus(&sd
->params
);
1580 /* FIXME: this is just dirty trial and error */
1581 ret
= goto_high_power(gspca_dev
);
1585 ret
= do_command(gspca_dev
, CPIA_COMMAND_DiscardFrame
,
1590 ret
= goto_low_power(gspca_dev
);
1595 /* procedure described in developer's guide p3-28 */
1597 /* Check the firmware version. */
1598 sd
->params
.version
.firmwareVersion
= 0;
1599 get_version_information(gspca_dev
);
1600 if (sd
->params
.version
.firmwareVersion
!= 1) {
1601 PDEBUG(D_ERR
, "only firmware version 1 is supported (got: %d)",
1602 sd
->params
.version
.firmwareVersion
);
1606 /* A bug in firmware 1-02 limits gainMode to 2 */
1607 if (sd
->params
.version
.firmwareRevision
<= 2 &&
1608 sd
->params
.exposure
.gainMode
> 2) {
1609 sd
->params
.exposure
.gainMode
= 2;
1612 /* set QX3 detected flag */
1613 sd
->params
.qx3
.qx3_detected
= (sd
->params
.pnpID
.vendor
== 0x0813 &&
1614 sd
->params
.pnpID
.product
== 0x0001);
1616 /* The fatal error checking should be done after
1617 * the camera powers up (developer's guide p 3-38) */
1619 /* Set streamState before transition to high power to avoid bug
1620 * in firmware 1-02 */
1621 ret
= do_command(gspca_dev
, CPIA_COMMAND_ModifyCameraStatus
,
1622 STREAMSTATE
, 0, STREAM_NOT_READY
, 0);
1627 ret
= goto_high_power(gspca_dev
);
1631 /* Check the camera status */
1632 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
1636 if (sd
->params
.status
.fatalError
) {
1637 PDEBUG(D_ERR
, "fatal_error: %04x, vp_status: %04x",
1638 sd
->params
.status
.fatalError
,
1639 sd
->params
.status
.vpStatus
);
1643 /* VPVersion can't be retrieved before the camera is in HiPower,
1644 * so get it here instead of in get_version_information. */
1645 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetVPVersion
, 0, 0, 0, 0);
1649 /* Determine video mode settings */
1650 sd
->params
.streamStartLine
= 120;
1652 priv
= gspca_dev
->cam
.cam_mode
[gspca_dev
->curr_mode
].priv
;
1653 if (priv
& 0x01) { /* crop */
1654 sd
->params
.roi
.colStart
= 2;
1655 sd
->params
.roi
.rowStart
= 6;
1657 sd
->params
.roi
.colStart
= 0;
1658 sd
->params
.roi
.rowStart
= 0;
1661 if (priv
& 0x02) { /* quarter */
1662 sd
->params
.format
.videoSize
= VIDEOSIZE_QCIF
;
1663 sd
->params
.roi
.colStart
/= 2;
1664 sd
->params
.roi
.rowStart
/= 2;
1665 sd
->params
.streamStartLine
/= 2;
1667 sd
->params
.format
.videoSize
= VIDEOSIZE_CIF
;
1669 sd
->params
.roi
.colEnd
= sd
->params
.roi
.colStart
+
1670 (gspca_dev
->width
>> 3);
1671 sd
->params
.roi
.rowEnd
= sd
->params
.roi
.rowStart
+
1672 (gspca_dev
->height
>> 2);
1674 /* And now set the camera to a known state */
1675 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetGrabMode
,
1676 CPIA_GRAB_CONTINEOUS
, 0, 0, 0);
1679 /* We start with compression disabled, as we need one uncompressed
1680 frame to handle later compressed frames */
1681 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetCompression
,
1682 CPIA_COMPRESSION_NONE
,
1683 NO_DECIMATION
, 0, 0);
1686 ret
= command_setcompressiontarget(gspca_dev
);
1689 ret
= command_setcolourparams(gspca_dev
);
1692 ret
= command_setformat(gspca_dev
);
1695 ret
= command_setyuvtresh(gspca_dev
);
1698 ret
= command_setecptiming(gspca_dev
);
1701 ret
= command_setcompressionparams(gspca_dev
);
1704 ret
= command_setexposure(gspca_dev
);
1707 ret
= command_setcolourbalance(gspca_dev
);
1710 ret
= command_setsensorfps(gspca_dev
);
1713 ret
= command_setapcor(gspca_dev
);
1716 ret
= command_setflickerctrl(gspca_dev
);
1719 ret
= command_setvloffset(gspca_dev
);
1724 ret
= command_resume(gspca_dev
);
1728 /* Wait 6 frames before turning compression on for the sensor to get
1729 all settings and AEC/ACB to settle */
1730 sd
->first_frame
= 6;
1731 sd
->exposure_status
= EXPOSURE_NORMAL
;
1732 sd
->exposure_count
= 0;
1733 atomic_set(&sd
->cam_exposure
, 0);
1734 atomic_set(&sd
->fps
, 0);
1739 static void sd_stopN(struct gspca_dev
*gspca_dev
)
1741 command_pause(gspca_dev
);
1743 /* save camera state for later open (developers guide ch 3.5.3) */
1744 save_camera_state(gspca_dev
);
1747 goto_low_power(gspca_dev
);
1749 /* Update the camera status */
1750 do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
1753 /* this function is called at probe and resume time */
1754 static int sd_init(struct gspca_dev
*gspca_dev
)
1757 struct sd
*sd
= (struct sd
*) gspca_dev
;
1761 /* Start / Stop the camera to make sure we are talking to
1762 a supported camera, and to get some information from it
1764 ret
= sd_start(gspca_dev
);
1768 /* Ensure the QX3 illuminators' states are restored upon resume,
1769 or disable the illuminator controls, if this isn't a QX3 */
1770 if (sd
->params
.qx3
.qx3_detected
)
1771 command_setlights(gspca_dev
);
1773 gspca_dev
->ctrl_dis
|=
1774 ((1 << ILLUMINATORS_1_IDX
) | (1 << ILLUMINATORS_2_IDX
));
1776 sd_stopN(gspca_dev
);
1778 PDEBUG(D_PROBE
, "CPIA Version: %d.%02d (%d.%d)",
1779 sd
->params
.version
.firmwareVersion
,
1780 sd
->params
.version
.firmwareRevision
,
1781 sd
->params
.version
.vcVersion
,
1782 sd
->params
.version
.vcRevision
);
1783 PDEBUG(D_PROBE
, "CPIA PnP-ID: %04x:%04x:%04x",
1784 sd
->params
.pnpID
.vendor
, sd
->params
.pnpID
.product
,
1785 sd
->params
.pnpID
.deviceRevision
);
1786 PDEBUG(D_PROBE
, "VP-Version: %d.%d %04x",
1787 sd
->params
.vpVersion
.vpVersion
,
1788 sd
->params
.vpVersion
.vpRevision
,
1789 sd
->params
.vpVersion
.cameraHeadID
);
1794 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
1798 struct sd
*sd
= (struct sd
*) gspca_dev
;
1802 data
[0] == MAGIC_0
&& data
[1] == MAGIC_1
&&
1803 data
[16] == sd
->params
.format
.videoSize
&&
1804 data
[17] == sd
->params
.format
.subSample
&&
1805 data
[18] == sd
->params
.format
.yuvOrder
&&
1806 data
[24] == sd
->params
.roi
.colStart
&&
1807 data
[25] == sd
->params
.roi
.colEnd
&&
1808 data
[26] == sd
->params
.roi
.rowStart
&&
1809 data
[27] == sd
->params
.roi
.rowEnd
) {
1812 atomic_set(&sd
->cam_exposure
, data
[39] * 2);
1813 atomic_set(&sd
->fps
, data
[41]);
1815 /* Check for proper EOF for last frame */
1816 image
= gspca_dev
->image
;
1817 if (image
!= NULL
&&
1818 gspca_dev
->image_len
> 4 &&
1819 image
[gspca_dev
->image_len
- 4] == 0xff &&
1820 image
[gspca_dev
->image_len
- 3] == 0xff &&
1821 image
[gspca_dev
->image_len
- 2] == 0xff &&
1822 image
[gspca_dev
->image_len
- 1] == 0xff)
1823 gspca_frame_add(gspca_dev
, LAST_PACKET
,
1826 gspca_frame_add(gspca_dev
, FIRST_PACKET
, data
, len
);
1830 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
1833 static void sd_dq_callback(struct gspca_dev
*gspca_dev
)
1835 struct sd
*sd
= (struct sd
*) gspca_dev
;
1837 /* Set the normal compression settings once we have captured a
1838 few uncompressed frames (and AEC has hopefully settled) */
1839 if (sd
->first_frame
) {
1841 if (sd
->first_frame
== 0)
1842 command_setcompression(gspca_dev
);
1845 /* Switch flicker control back on if it got turned off */
1846 restart_flicker(gspca_dev
);
1848 /* If AEC is enabled, monitor the exposure and
1849 adjust the sensor frame rate if needed */
1850 if (sd
->params
.exposure
.expMode
== 2)
1851 monitor_exposure(gspca_dev
);
1853 /* Update our knowledge of the camera state */
1854 do_command(gspca_dev
, CPIA_COMMAND_GetExposure
, 0, 0, 0, 0);
1855 if (sd
->params
.qx3
.qx3_detected
)
1856 do_command(gspca_dev
, CPIA_COMMAND_ReadMCPorts
, 0, 0, 0, 0);
1859 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
)
1861 struct sd
*sd
= (struct sd
*) gspca_dev
;
1864 sd
->params
.colourParams
.brightness
= val
;
1865 sd
->params
.flickerControl
.allowableOverExposure
=
1866 find_over_exposure(sd
->params
.colourParams
.brightness
);
1867 if (gspca_dev
->streaming
) {
1868 ret
= command_setcolourparams(gspca_dev
);
1871 return command_setflickerctrl(gspca_dev
);
1876 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
)
1878 struct sd
*sd
= (struct sd
*) gspca_dev
;
1880 *val
= sd
->params
.colourParams
.brightness
;
1884 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
)
1886 struct sd
*sd
= (struct sd
*) gspca_dev
;
1888 sd
->params
.colourParams
.contrast
= val
;
1889 if (gspca_dev
->streaming
)
1890 return command_setcolourparams(gspca_dev
);
1895 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
)
1897 struct sd
*sd
= (struct sd
*) gspca_dev
;
1899 *val
= sd
->params
.colourParams
.contrast
;
1903 static int sd_setsaturation(struct gspca_dev
*gspca_dev
, __s32 val
)
1905 struct sd
*sd
= (struct sd
*) gspca_dev
;
1907 sd
->params
.colourParams
.saturation
= val
;
1908 if (gspca_dev
->streaming
)
1909 return command_setcolourparams(gspca_dev
);
1914 static int sd_getsaturation(struct gspca_dev
*gspca_dev
, __s32
*val
)
1916 struct sd
*sd
= (struct sd
*) gspca_dev
;
1918 *val
= sd
->params
.colourParams
.saturation
;
1922 static int sd_setfreq(struct gspca_dev
*gspca_dev
, __s32 val
)
1924 struct sd
*sd
= (struct sd
*) gspca_dev
;
1928 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1931 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1935 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1944 sd
->params
.flickerControl
.coarseJump
=
1945 flicker_jumps
[sd
->mainsFreq
]
1946 [sd
->params
.sensorFps
.baserate
]
1947 [sd
->params
.sensorFps
.divisor
];
1949 return set_flicker(gspca_dev
, on
, gspca_dev
->streaming
);
1952 static int sd_getfreq(struct gspca_dev
*gspca_dev
, __s32
*val
)
1954 struct sd
*sd
= (struct sd
*) gspca_dev
;
1960 static int sd_setcomptarget(struct gspca_dev
*gspca_dev
, __s32 val
)
1962 struct sd
*sd
= (struct sd
*) gspca_dev
;
1964 sd
->params
.compressionTarget
.frTargeting
= val
;
1965 if (gspca_dev
->streaming
)
1966 return command_setcompressiontarget(gspca_dev
);
1971 static int sd_getcomptarget(struct gspca_dev
*gspca_dev
, __s32
*val
)
1973 struct sd
*sd
= (struct sd
*) gspca_dev
;
1975 *val
= sd
->params
.compressionTarget
.frTargeting
;
1979 static int sd_setilluminator(struct gspca_dev
*gspca_dev
, __s32 val
, int n
)
1981 struct sd
*sd
= (struct sd
*) gspca_dev
;
1984 if (!sd
->params
.qx3
.qx3_detected
)
1989 sd
->params
.qx3
.bottomlight
= val
? 1 : 0;
1992 sd
->params
.qx3
.toplight
= val
? 1 : 0;
1998 ret
= command_setlights(gspca_dev
);
1999 if (ret
&& ret
!= -EINVAL
)
2005 static int sd_setilluminator1(struct gspca_dev
*gspca_dev
, __s32 val
)
2007 return sd_setilluminator(gspca_dev
, val
, 1);
2010 static int sd_setilluminator2(struct gspca_dev
*gspca_dev
, __s32 val
)
2012 return sd_setilluminator(gspca_dev
, val
, 2);
2015 static int sd_getilluminator(struct gspca_dev
*gspca_dev
, __s32
*val
, int n
)
2017 struct sd
*sd
= (struct sd
*) gspca_dev
;
2019 if (!sd
->params
.qx3
.qx3_detected
)
2024 *val
= sd
->params
.qx3
.bottomlight
;
2027 *val
= sd
->params
.qx3
.toplight
;
2035 static int sd_getilluminator1(struct gspca_dev
*gspca_dev
, __s32
*val
)
2037 return sd_getilluminator(gspca_dev
, val
, 1);
2040 static int sd_getilluminator2(struct gspca_dev
*gspca_dev
, __s32
*val
)
2042 return sd_getilluminator(gspca_dev
, val
, 2);
2045 static int sd_querymenu(struct gspca_dev
*gspca_dev
,
2046 struct v4l2_querymenu
*menu
)
2049 case V4L2_CID_POWER_LINE_FREQUENCY
:
2050 switch (menu
->index
) {
2051 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2052 strcpy((char *) menu
->name
, "NoFliker");
2054 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2055 strcpy((char *) menu
->name
, "50 Hz");
2057 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2058 strcpy((char *) menu
->name
, "60 Hz");
2062 case V4L2_CID_COMP_TARGET
:
2063 switch (menu
->index
) {
2064 case CPIA_COMPRESSION_TARGET_QUALITY
:
2065 strcpy((char *) menu
->name
, "Quality");
2067 case CPIA_COMPRESSION_TARGET_FRAMERATE
:
2068 strcpy((char *) menu
->name
, "Framerate");
2076 /* sub-driver description */
2077 static const struct sd_desc sd_desc
= {
2078 .name
= MODULE_NAME
,
2080 .nctrls
= ARRAY_SIZE(sd_ctrls
),
2081 .config
= sd_config
,
2085 .dq_callback
= sd_dq_callback
,
2086 .pkt_scan
= sd_pkt_scan
,
2087 .querymenu
= sd_querymenu
,
2090 /* -- module initialisation -- */
2091 static const struct usb_device_id device_table
[] = {
2092 {USB_DEVICE(0x0553, 0x0002)},
2093 {USB_DEVICE(0x0813, 0x0001)},
2096 MODULE_DEVICE_TABLE(usb
, device_table
);
2098 /* -- device connect -- */
2099 static int sd_probe(struct usb_interface
*intf
,
2100 const struct usb_device_id
*id
)
2102 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
2106 static struct usb_driver sd_driver
= {
2107 .name
= MODULE_NAME
,
2108 .id_table
= device_table
,
2110 .disconnect
= gspca_disconnect
,
2112 .suspend
= gspca_suspend
,
2113 .resume
= gspca_resume
,
2117 /* -- module insert / remove -- */
2118 static int __init
sd_mod_init(void)
2120 return usb_register(&sd_driver
);
2122 static void __exit
sd_mod_exit(void)
2124 usb_deregister(&sd_driver
);
2127 module_init(sd_mod_init
);
2128 module_exit(sd_mod_exit
);