2 * cpia CPiA (1) gspca driver
4 * Copyright (C) 2010 Hans de Goede <hdgoede@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 <hdgoede@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
);
377 static struct ctrl sd_ctrls
[] = {
380 .id
= V4L2_CID_BRIGHTNESS
,
381 .type
= V4L2_CTRL_TYPE_INTEGER
,
382 .name
= "Brightness",
386 #define BRIGHTNESS_DEF 50
387 .default_value
= BRIGHTNESS_DEF
,
390 .set
= sd_setbrightness
,
391 .get
= sd_getbrightness
,
395 .id
= V4L2_CID_CONTRAST
,
396 .type
= V4L2_CTRL_TYPE_INTEGER
,
401 #define CONTRAST_DEF 48
402 .default_value
= CONTRAST_DEF
,
404 .set
= sd_setcontrast
,
405 .get
= sd_getcontrast
,
409 .id
= V4L2_CID_SATURATION
,
410 .type
= V4L2_CTRL_TYPE_INTEGER
,
411 .name
= "Saturation",
415 #define SATURATION_DEF 50
416 .default_value
= SATURATION_DEF
,
418 .set
= sd_setsaturation
,
419 .get
= sd_getsaturation
,
423 .id
= V4L2_CID_POWER_LINE_FREQUENCY
,
424 .type
= V4L2_CTRL_TYPE_MENU
,
425 .name
= "Light frequency filter",
427 .maximum
= 2, /* 0: 0, 1: 50Hz, 2:60Hz */
430 .default_value
= FREQ_DEF
,
437 #define V4L2_CID_COMP_TARGET V4L2_CID_PRIVATE_BASE
438 .id
= V4L2_CID_COMP_TARGET
,
439 .type
= V4L2_CTRL_TYPE_MENU
,
440 .name
= "Compression Target",
444 #define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY
445 .default_value
= COMP_TARGET_DEF
,
447 .set
= sd_setcomptarget
,
448 .get
= sd_getcomptarget
,
452 static const struct v4l2_pix_format mode
[] = {
453 {160, 120, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
454 /* The sizeimage is trial and error, as with low framerates
455 the camera will pad out usb frames, making the image
456 data larger then strictly necessary */
459 .colorspace
= V4L2_COLORSPACE_SRGB
,
461 {176, 144, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
464 .colorspace
= V4L2_COLORSPACE_SRGB
,
466 {320, 240, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
469 .colorspace
= V4L2_COLORSPACE_SRGB
,
471 {352, 288, V4L2_PIX_FMT_CPIA1
, V4L2_FIELD_NONE
,
474 .colorspace
= V4L2_COLORSPACE_SRGB
,
478 /**********************************************************************
482 **********************************************************************/
484 static int cpia_usb_transferCmd(struct gspca_dev
*gspca_dev
, u8
*command
)
488 int ret
, databytes
= command
[6] | (command
[7] << 8);
489 /* Sometimes we see spurious EPIPE errors */
492 if (command
[0] == DATA_IN
) {
493 pipe
= usb_rcvctrlpipe(gspca_dev
->dev
, 0);
494 requesttype
= USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
;
495 } else if (command
[0] == DATA_OUT
) {
496 pipe
= usb_sndctrlpipe(gspca_dev
->dev
, 0);
497 requesttype
= USB_TYPE_VENDOR
| USB_RECIP_DEVICE
;
499 PDEBUG(D_ERR
, "Unexpected first byte of command: %x",
505 ret
= usb_control_msg(gspca_dev
->dev
, pipe
,
508 command
[2] | (command
[3] << 8),
509 command
[4] | (command
[5] << 8),
510 gspca_dev
->usb_buf
, databytes
, 1000);
513 PDEBUG(D_ERR
, "usb_control_msg %02x, error %d", command
[1],
516 if (ret
== -EPIPE
&& retries
> 0) {
521 return (ret
< 0) ? ret
: 0;
524 /* send an arbitrary command to the camera */
525 static int do_command(struct gspca_dev
*gspca_dev
, u16 command
,
526 u8 a
, u8 b
, u8 c
, u8 d
)
528 struct sd
*sd
= (struct sd
*) gspca_dev
;
533 case CPIA_COMMAND_GetCPIAVersion
:
534 case CPIA_COMMAND_GetPnPID
:
535 case CPIA_COMMAND_GetCameraStatus
:
536 case CPIA_COMMAND_GetVPVersion
:
537 case CPIA_COMMAND_GetColourParams
:
538 case CPIA_COMMAND_GetColourBalance
:
539 case CPIA_COMMAND_GetExposure
:
542 case CPIA_COMMAND_ReadMCPorts
:
543 case CPIA_COMMAND_ReadVCRegs
:
551 cmd
[0] = command
>> 8;
552 cmd
[1] = command
& 0xff;
560 ret
= cpia_usb_transferCmd(gspca_dev
, cmd
);
565 case CPIA_COMMAND_GetCPIAVersion
:
566 sd
->params
.version
.firmwareVersion
= gspca_dev
->usb_buf
[0];
567 sd
->params
.version
.firmwareRevision
= gspca_dev
->usb_buf
[1];
568 sd
->params
.version
.vcVersion
= gspca_dev
->usb_buf
[2];
569 sd
->params
.version
.vcRevision
= gspca_dev
->usb_buf
[3];
571 case CPIA_COMMAND_GetPnPID
:
572 sd
->params
.pnpID
.vendor
=
573 gspca_dev
->usb_buf
[0] | (gspca_dev
->usb_buf
[1] << 8);
574 sd
->params
.pnpID
.product
=
575 gspca_dev
->usb_buf
[2] | (gspca_dev
->usb_buf
[3] << 8);
576 sd
->params
.pnpID
.deviceRevision
=
577 gspca_dev
->usb_buf
[4] | (gspca_dev
->usb_buf
[5] << 8);
579 case CPIA_COMMAND_GetCameraStatus
:
580 sd
->params
.status
.systemState
= gspca_dev
->usb_buf
[0];
581 sd
->params
.status
.grabState
= gspca_dev
->usb_buf
[1];
582 sd
->params
.status
.streamState
= gspca_dev
->usb_buf
[2];
583 sd
->params
.status
.fatalError
= gspca_dev
->usb_buf
[3];
584 sd
->params
.status
.cmdError
= gspca_dev
->usb_buf
[4];
585 sd
->params
.status
.debugFlags
= gspca_dev
->usb_buf
[5];
586 sd
->params
.status
.vpStatus
= gspca_dev
->usb_buf
[6];
587 sd
->params
.status
.errorCode
= gspca_dev
->usb_buf
[7];
589 case CPIA_COMMAND_GetVPVersion
:
590 sd
->params
.vpVersion
.vpVersion
= gspca_dev
->usb_buf
[0];
591 sd
->params
.vpVersion
.vpRevision
= gspca_dev
->usb_buf
[1];
592 sd
->params
.vpVersion
.cameraHeadID
=
593 gspca_dev
->usb_buf
[2] | (gspca_dev
->usb_buf
[3] << 8);
595 case CPIA_COMMAND_GetColourParams
:
596 sd
->params
.colourParams
.brightness
= gspca_dev
->usb_buf
[0];
597 sd
->params
.colourParams
.contrast
= gspca_dev
->usb_buf
[1];
598 sd
->params
.colourParams
.saturation
= gspca_dev
->usb_buf
[2];
600 case CPIA_COMMAND_GetColourBalance
:
601 sd
->params
.colourBalance
.redGain
= gspca_dev
->usb_buf
[0];
602 sd
->params
.colourBalance
.greenGain
= gspca_dev
->usb_buf
[1];
603 sd
->params
.colourBalance
.blueGain
= gspca_dev
->usb_buf
[2];
605 case CPIA_COMMAND_GetExposure
:
606 sd
->params
.exposure
.gain
= gspca_dev
->usb_buf
[0];
607 sd
->params
.exposure
.fineExp
= gspca_dev
->usb_buf
[1];
608 sd
->params
.exposure
.coarseExpLo
= gspca_dev
->usb_buf
[2];
609 sd
->params
.exposure
.coarseExpHi
= gspca_dev
->usb_buf
[3];
610 sd
->params
.exposure
.redComp
= gspca_dev
->usb_buf
[4];
611 sd
->params
.exposure
.green1Comp
= gspca_dev
->usb_buf
[5];
612 sd
->params
.exposure
.green2Comp
= gspca_dev
->usb_buf
[6];
613 sd
->params
.exposure
.blueComp
= gspca_dev
->usb_buf
[7];
616 case CPIA_COMMAND_ReadMCPorts
:
617 if (!sd
->params
.qx3
.qx3_detected
)
619 /* test button press */
620 sd
->params
.qx3
.button
= ((gspca_dev
->usb_buf
[1] & 0x02) == 0);
621 if (sd
->params
.qx3
.button
) {
622 /* button pressed - unlock the latch */
623 do_command(gspca_dev
, CPIA_COMMAND_WriteMCPort
,
625 do_command(gspca_dev
, CPIA_COMMAND_WriteMCPort
,
629 /* test whether microscope is cradled */
630 sd
->params
.qx3
.cradled
= ((gspca_dev
->usb_buf
[2] & 0x40) == 0);
637 /* send a command to the camera with an additional data transaction */
638 static int do_command_extended(struct gspca_dev
*gspca_dev
, u16 command
,
639 u8 a
, u8 b
, u8 c
, u8 d
,
640 u8 e
, u8 f
, u8 g
, u8 h
,
641 u8 i
, u8 j
, u8 k
, u8 l
)
645 cmd
[0] = command
>> 8;
646 cmd
[1] = command
& 0xff;
653 gspca_dev
->usb_buf
[0] = e
;
654 gspca_dev
->usb_buf
[1] = f
;
655 gspca_dev
->usb_buf
[2] = g
;
656 gspca_dev
->usb_buf
[3] = h
;
657 gspca_dev
->usb_buf
[4] = i
;
658 gspca_dev
->usb_buf
[5] = j
;
659 gspca_dev
->usb_buf
[6] = k
;
660 gspca_dev
->usb_buf
[7] = l
;
662 return cpia_usb_transferCmd(gspca_dev
, cmd
);
665 /* find_over_exposure
666 * Finds a suitable value of OverExposure for use with SetFlickerCtrl
667 * Some calculation is required because this value changes with the brightness
668 * set with SetColourParameters
670 * Parameters: Brightness - last brightness value set with SetColourParameters
672 * Returns: OverExposure value to use with SetFlickerCtrl
674 #define FLICKER_MAX_EXPOSURE 250
675 #define FLICKER_ALLOWABLE_OVER_EXPOSURE 146
676 #define FLICKER_BRIGHTNESS_CONSTANT 59
677 static int find_over_exposure(int brightness
)
679 int MaxAllowableOverExposure
, OverExposure
;
681 MaxAllowableOverExposure
= FLICKER_MAX_EXPOSURE
- brightness
-
682 FLICKER_BRIGHTNESS_CONSTANT
;
684 if (MaxAllowableOverExposure
< FLICKER_ALLOWABLE_OVER_EXPOSURE
)
685 OverExposure
= MaxAllowableOverExposure
;
687 OverExposure
= FLICKER_ALLOWABLE_OVER_EXPOSURE
;
691 #undef FLICKER_MAX_EXPOSURE
692 #undef FLICKER_ALLOWABLE_OVER_EXPOSURE
693 #undef FLICKER_BRIGHTNESS_CONSTANT
695 /* initialise cam_data structure */
696 static void reset_camera_params(struct gspca_dev
*gspca_dev
)
698 struct sd
*sd
= (struct sd
*) gspca_dev
;
699 struct cam_params
*params
= &sd
->params
;
701 /* The following parameter values are the defaults from
702 * "Software Developer's Guide for CPiA Cameras". Any changes
703 * to the defaults are noted in comments. */
704 params
->colourParams
.brightness
= BRIGHTNESS_DEF
;
705 params
->colourParams
.contrast
= CONTRAST_DEF
;
706 params
->colourParams
.saturation
= SATURATION_DEF
;
707 params
->exposure
.gainMode
= 4;
708 params
->exposure
.expMode
= 2; /* AEC */
709 params
->exposure
.compMode
= 1;
710 params
->exposure
.centreWeight
= 1;
711 params
->exposure
.gain
= 0;
712 params
->exposure
.fineExp
= 0;
713 params
->exposure
.coarseExpLo
= 185;
714 params
->exposure
.coarseExpHi
= 0;
715 params
->exposure
.redComp
= COMP_RED
;
716 params
->exposure
.green1Comp
= COMP_GREEN1
;
717 params
->exposure
.green2Comp
= COMP_GREEN2
;
718 params
->exposure
.blueComp
= COMP_BLUE
;
719 params
->colourBalance
.balanceMode
= 2; /* ACB */
720 params
->colourBalance
.redGain
= 32;
721 params
->colourBalance
.greenGain
= 6;
722 params
->colourBalance
.blueGain
= 92;
723 params
->apcor
.gain1
= 0x18;
724 params
->apcor
.gain2
= 0x16;
725 params
->apcor
.gain4
= 0x24;
726 params
->apcor
.gain8
= 0x34;
727 params
->flickerControl
.flickerMode
= 0;
728 params
->flickerControl
.disabled
= 1;
730 params
->flickerControl
.coarseJump
=
731 flicker_jumps
[sd
->mainsFreq
]
732 [params
->sensorFps
.baserate
]
733 [params
->sensorFps
.divisor
];
734 params
->flickerControl
.allowableOverExposure
=
735 find_over_exposure(params
->colourParams
.brightness
);
736 params
->vlOffset
.gain1
= 20;
737 params
->vlOffset
.gain2
= 24;
738 params
->vlOffset
.gain4
= 26;
739 params
->vlOffset
.gain8
= 26;
740 params
->compressionParams
.hysteresis
= 3;
741 params
->compressionParams
.threshMax
= 11;
742 params
->compressionParams
.smallStep
= 1;
743 params
->compressionParams
.largeStep
= 3;
744 params
->compressionParams
.decimationHysteresis
= 2;
745 params
->compressionParams
.frDiffStepThresh
= 5;
746 params
->compressionParams
.qDiffStepThresh
= 3;
747 params
->compressionParams
.decimationThreshMod
= 2;
748 /* End of default values from Software Developer's Guide */
750 /* Set Sensor FPS to 15fps. This seems better than 30fps
751 * for indoor lighting. */
752 params
->sensorFps
.divisor
= 1;
753 params
->sensorFps
.baserate
= 1;
755 params
->yuvThreshold
.yThreshold
= 6; /* From windows driver */
756 params
->yuvThreshold
.uvThreshold
= 6; /* From windows driver */
758 params
->format
.subSample
= SUBSAMPLE_420
;
759 params
->format
.yuvOrder
= YUVORDER_YUYV
;
761 params
->compression
.mode
= CPIA_COMPRESSION_AUTO
;
762 params
->compression
.decimation
= NO_DECIMATION
;
764 params
->compressionTarget
.frTargeting
= COMP_TARGET_DEF
;
765 params
->compressionTarget
.targetFR
= 15; /* From windows driver */
766 params
->compressionTarget
.targetQ
= 5; /* From windows driver */
768 params
->qx3
.qx3_detected
= 0;
769 params
->qx3
.toplight
= 0;
770 params
->qx3
.bottomlight
= 0;
771 params
->qx3
.button
= 0;
772 params
->qx3
.cradled
= 0;
775 static void printstatus(struct cam_params
*params
)
777 PDEBUG(D_PROBE
, "status: %02x %02x %02x %02x %02x %02x %02x %02x",
778 params
->status
.systemState
, params
->status
.grabState
,
779 params
->status
.streamState
, params
->status
.fatalError
,
780 params
->status
.cmdError
, params
->status
.debugFlags
,
781 params
->status
.vpStatus
, params
->status
.errorCode
);
784 static int goto_low_power(struct gspca_dev
*gspca_dev
)
786 struct sd
*sd
= (struct sd
*) gspca_dev
;
789 ret
= do_command(gspca_dev
, CPIA_COMMAND_GotoLoPower
, 0, 0, 0, 0);
793 do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
797 if (sd
->params
.status
.systemState
!= LO_POWER_STATE
) {
798 if (sd
->params
.status
.systemState
!= WARM_BOOT_STATE
) {
800 "unexpected state after lo power cmd: %02x",
801 sd
->params
.status
.systemState
);
802 printstatus(&sd
->params
);
807 PDEBUG(D_CONF
, "camera now in LOW power state");
811 static int goto_high_power(struct gspca_dev
*gspca_dev
)
813 struct sd
*sd
= (struct sd
*) gspca_dev
;
816 ret
= do_command(gspca_dev
, CPIA_COMMAND_GotoHiPower
, 0, 0, 0, 0);
820 msleep_interruptible(40); /* windows driver does it too */
822 if (signal_pending(current
))
825 do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
829 if (sd
->params
.status
.systemState
!= HI_POWER_STATE
) {
830 PDEBUG(D_ERR
, "unexpected state after hi power cmd: %02x",
831 sd
->params
.status
.systemState
);
832 printstatus(&sd
->params
);
836 PDEBUG(D_CONF
, "camera now in HIGH power state");
840 static int get_version_information(struct gspca_dev
*gspca_dev
)
845 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetCPIAVersion
, 0, 0, 0, 0);
850 return do_command(gspca_dev
, CPIA_COMMAND_GetPnPID
, 0, 0, 0, 0);
853 static int save_camera_state(struct gspca_dev
*gspca_dev
)
857 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetColourBalance
, 0, 0, 0, 0);
861 return do_command(gspca_dev
, CPIA_COMMAND_GetExposure
, 0, 0, 0, 0);
864 int command_setformat(struct gspca_dev
*gspca_dev
)
866 struct sd
*sd
= (struct sd
*) gspca_dev
;
869 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetFormat
,
870 sd
->params
.format
.videoSize
,
871 sd
->params
.format
.subSample
,
872 sd
->params
.format
.yuvOrder
, 0);
876 return do_command(gspca_dev
, CPIA_COMMAND_SetROI
,
877 sd
->params
.roi
.colStart
, sd
->params
.roi
.colEnd
,
878 sd
->params
.roi
.rowStart
, sd
->params
.roi
.rowEnd
);
881 int command_setcolourparams(struct gspca_dev
*gspca_dev
)
883 struct sd
*sd
= (struct sd
*) gspca_dev
;
884 return do_command(gspca_dev
, CPIA_COMMAND_SetColourParams
,
885 sd
->params
.colourParams
.brightness
,
886 sd
->params
.colourParams
.contrast
,
887 sd
->params
.colourParams
.saturation
, 0);
890 int command_setapcor(struct gspca_dev
*gspca_dev
)
892 struct sd
*sd
= (struct sd
*) gspca_dev
;
893 return do_command(gspca_dev
, CPIA_COMMAND_SetApcor
,
894 sd
->params
.apcor
.gain1
,
895 sd
->params
.apcor
.gain2
,
896 sd
->params
.apcor
.gain4
,
897 sd
->params
.apcor
.gain8
);
900 int command_setvloffset(struct gspca_dev
*gspca_dev
)
902 struct sd
*sd
= (struct sd
*) gspca_dev
;
903 return do_command(gspca_dev
, CPIA_COMMAND_SetVLOffset
,
904 sd
->params
.vlOffset
.gain1
,
905 sd
->params
.vlOffset
.gain2
,
906 sd
->params
.vlOffset
.gain4
,
907 sd
->params
.vlOffset
.gain8
);
910 int command_setexposure(struct gspca_dev
*gspca_dev
)
912 struct sd
*sd
= (struct sd
*) gspca_dev
;
915 ret
= do_command_extended(gspca_dev
, CPIA_COMMAND_SetExposure
,
916 sd
->params
.exposure
.gainMode
,
918 sd
->params
.exposure
.compMode
,
919 sd
->params
.exposure
.centreWeight
,
920 sd
->params
.exposure
.gain
,
921 sd
->params
.exposure
.fineExp
,
922 sd
->params
.exposure
.coarseExpLo
,
923 sd
->params
.exposure
.coarseExpHi
,
924 sd
->params
.exposure
.redComp
,
925 sd
->params
.exposure
.green1Comp
,
926 sd
->params
.exposure
.green2Comp
,
927 sd
->params
.exposure
.blueComp
);
931 if (sd
->params
.exposure
.expMode
!= 1) {
932 ret
= do_command_extended(gspca_dev
, CPIA_COMMAND_SetExposure
,
934 sd
->params
.exposure
.expMode
,
936 sd
->params
.exposure
.gain
,
937 sd
->params
.exposure
.fineExp
,
938 sd
->params
.exposure
.coarseExpLo
,
939 sd
->params
.exposure
.coarseExpHi
,
946 int command_setcolourbalance(struct gspca_dev
*gspca_dev
)
948 struct sd
*sd
= (struct sd
*) gspca_dev
;
950 if (sd
->params
.colourBalance
.balanceMode
== 1) {
953 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
955 sd
->params
.colourBalance
.redGain
,
956 sd
->params
.colourBalance
.greenGain
,
957 sd
->params
.colourBalance
.blueGain
);
961 return do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
964 if (sd
->params
.colourBalance
.balanceMode
== 2) {
965 return do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
968 if (sd
->params
.colourBalance
.balanceMode
== 3) {
969 return do_command(gspca_dev
, CPIA_COMMAND_SetColourBalance
,
976 int command_setcompressiontarget(struct gspca_dev
*gspca_dev
)
978 struct sd
*sd
= (struct sd
*) gspca_dev
;
980 return do_command(gspca_dev
, CPIA_COMMAND_SetCompressionTarget
,
981 sd
->params
.compressionTarget
.frTargeting
,
982 sd
->params
.compressionTarget
.targetFR
,
983 sd
->params
.compressionTarget
.targetQ
, 0);
986 int command_setyuvtresh(struct gspca_dev
*gspca_dev
)
988 struct sd
*sd
= (struct sd
*) gspca_dev
;
990 return do_command(gspca_dev
, CPIA_COMMAND_SetYUVThresh
,
991 sd
->params
.yuvThreshold
.yThreshold
,
992 sd
->params
.yuvThreshold
.uvThreshold
, 0, 0);
995 int command_setcompressionparams(struct gspca_dev
*gspca_dev
)
997 struct sd
*sd
= (struct sd
*) gspca_dev
;
999 return do_command_extended(gspca_dev
,
1000 CPIA_COMMAND_SetCompressionParams
,
1002 sd
->params
.compressionParams
.hysteresis
,
1003 sd
->params
.compressionParams
.threshMax
,
1004 sd
->params
.compressionParams
.smallStep
,
1005 sd
->params
.compressionParams
.largeStep
,
1006 sd
->params
.compressionParams
.decimationHysteresis
,
1007 sd
->params
.compressionParams
.frDiffStepThresh
,
1008 sd
->params
.compressionParams
.qDiffStepThresh
,
1009 sd
->params
.compressionParams
.decimationThreshMod
);
1012 int command_setcompression(struct gspca_dev
*gspca_dev
)
1014 struct sd
*sd
= (struct sd
*) gspca_dev
;
1016 return do_command(gspca_dev
, CPIA_COMMAND_SetCompression
,
1017 sd
->params
.compression
.mode
,
1018 sd
->params
.compression
.decimation
, 0, 0);
1021 int command_setsensorfps(struct gspca_dev
*gspca_dev
)
1023 struct sd
*sd
= (struct sd
*) gspca_dev
;
1025 return do_command(gspca_dev
, CPIA_COMMAND_SetSensorFPS
,
1026 sd
->params
.sensorFps
.divisor
,
1027 sd
->params
.sensorFps
.baserate
, 0, 0);
1030 int command_setflickerctrl(struct gspca_dev
*gspca_dev
)
1032 struct sd
*sd
= (struct sd
*) gspca_dev
;
1034 return do_command(gspca_dev
, CPIA_COMMAND_SetFlickerCtrl
,
1035 sd
->params
.flickerControl
.flickerMode
,
1036 sd
->params
.flickerControl
.coarseJump
,
1037 sd
->params
.flickerControl
.allowableOverExposure
,
1041 int command_setecptiming(struct gspca_dev
*gspca_dev
)
1043 struct sd
*sd
= (struct sd
*) gspca_dev
;
1045 return do_command(gspca_dev
, CPIA_COMMAND_SetECPTiming
,
1046 sd
->params
.ecpTiming
, 0, 0, 0);
1049 int command_pause(struct gspca_dev
*gspca_dev
)
1051 return do_command(gspca_dev
, CPIA_COMMAND_EndStreamCap
, 0, 0, 0, 0);
1054 int command_resume(struct gspca_dev
*gspca_dev
)
1056 struct sd
*sd
= (struct sd
*) gspca_dev
;
1058 return do_command(gspca_dev
, CPIA_COMMAND_InitStreamCap
,
1059 0, sd
->params
.streamStartLine
, 0, 0);
1062 int command_setlights(struct gspca_dev
*gspca_dev
)
1064 struct sd
*sd
= (struct sd
*) gspca_dev
;
1067 if (!sd
->params
.qx3
.qx3_detected
)
1070 p1
= (sd
->params
.qx3
.bottomlight
== 0) << 1;
1071 p2
= (sd
->params
.qx3
.toplight
== 0) << 3;
1073 ret
= do_command(gspca_dev
, CPIA_COMMAND_WriteVCReg
,
1074 0x90, 0x8F, 0x50, 0);
1078 return do_command(gspca_dev
, CPIA_COMMAND_WriteMCPort
, 2, 0,
1082 static int set_flicker(struct gspca_dev
*gspca_dev
, int on
, int apply
)
1084 /* Everything in here is from the Windows driver */
1085 /* define for compgain calculation */
1087 #define COMPGAIN(base, curexp, newexp) \
1088 (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
1089 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1090 (u16)((float)curexp * (float)(u8)(curcomp + 128) / \
1091 (float)(u8)(basecomp - 128))
1093 /* equivalent functions without floating point math */
1094 #define COMPGAIN(base, curexp, newexp) \
1095 (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2 * newexp)))
1096 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1097 (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
1100 struct sd
*sd
= (struct sd
*) gspca_dev
;
1101 int currentexp
= sd
->params
.exposure
.coarseExpLo
+
1102 sd
->params
.exposure
.coarseExpHi
* 256;
1106 int cj
= sd
->params
.flickerControl
.coarseJump
;
1107 sd
->params
.flickerControl
.flickerMode
= 1;
1108 sd
->params
.flickerControl
.disabled
= 0;
1109 if (sd
->params
.exposure
.expMode
!= 2) {
1110 sd
->params
.exposure
.expMode
= 2;
1111 sd
->exposure_status
= EXPOSURE_NORMAL
;
1113 currentexp
= currentexp
<< sd
->params
.exposure
.gain
;
1114 sd
->params
.exposure
.gain
= 0;
1115 /* round down current exposure to nearest value */
1116 startexp
= (currentexp
+ ROUND_UP_EXP_FOR_FLICKER
) / cj
;
1119 startexp
= (startexp
* cj
) - 1;
1120 if (FIRMWARE_VERSION(1, 2))
1121 while (startexp
> MAX_EXP_102
)
1124 while (startexp
> MAX_EXP
)
1126 sd
->params
.exposure
.coarseExpLo
= startexp
& 0xff;
1127 sd
->params
.exposure
.coarseExpHi
= startexp
>> 8;
1128 if (currentexp
> startexp
) {
1129 if (currentexp
> (2 * startexp
))
1130 currentexp
= 2 * startexp
;
1131 sd
->params
.exposure
.redComp
=
1132 COMPGAIN(COMP_RED
, currentexp
, startexp
);
1133 sd
->params
.exposure
.green1Comp
=
1134 COMPGAIN(COMP_GREEN1
, currentexp
, startexp
);
1135 sd
->params
.exposure
.green2Comp
=
1136 COMPGAIN(COMP_GREEN2
, currentexp
, startexp
);
1137 sd
->params
.exposure
.blueComp
=
1138 COMPGAIN(COMP_BLUE
, currentexp
, startexp
);
1140 sd
->params
.exposure
.redComp
= COMP_RED
;
1141 sd
->params
.exposure
.green1Comp
= COMP_GREEN1
;
1142 sd
->params
.exposure
.green2Comp
= COMP_GREEN2
;
1143 sd
->params
.exposure
.blueComp
= COMP_BLUE
;
1145 if (FIRMWARE_VERSION(1, 2))
1146 sd
->params
.exposure
.compMode
= 0;
1148 sd
->params
.exposure
.compMode
= 1;
1150 sd
->params
.apcor
.gain1
= 0x18;
1151 sd
->params
.apcor
.gain2
= 0x18;
1152 sd
->params
.apcor
.gain4
= 0x16;
1153 sd
->params
.apcor
.gain8
= 0x14;
1155 sd
->params
.flickerControl
.flickerMode
= 0;
1156 sd
->params
.flickerControl
.disabled
= 1;
1157 /* Average equivalent coarse for each comp channel */
1158 startexp
= EXP_FROM_COMP(COMP_RED
,
1159 sd
->params
.exposure
.redComp
, currentexp
);
1160 startexp
+= EXP_FROM_COMP(COMP_GREEN1
,
1161 sd
->params
.exposure
.green1Comp
, currentexp
);
1162 startexp
+= EXP_FROM_COMP(COMP_GREEN2
,
1163 sd
->params
.exposure
.green2Comp
, currentexp
);
1164 startexp
+= EXP_FROM_COMP(COMP_BLUE
,
1165 sd
->params
.exposure
.blueComp
, currentexp
);
1166 startexp
= startexp
>> 2;
1167 while (startexp
> MAX_EXP
&& sd
->params
.exposure
.gain
<
1168 sd
->params
.exposure
.gainMode
- 1) {
1169 startexp
= startexp
>> 1;
1170 ++sd
->params
.exposure
.gain
;
1172 if (FIRMWARE_VERSION(1, 2) && startexp
> MAX_EXP_102
)
1173 startexp
= MAX_EXP_102
;
1174 if (startexp
> MAX_EXP
)
1176 sd
->params
.exposure
.coarseExpLo
= startexp
& 0xff;
1177 sd
->params
.exposure
.coarseExpHi
= startexp
>> 8;
1178 sd
->params
.exposure
.redComp
= COMP_RED
;
1179 sd
->params
.exposure
.green1Comp
= COMP_GREEN1
;
1180 sd
->params
.exposure
.green2Comp
= COMP_GREEN2
;
1181 sd
->params
.exposure
.blueComp
= COMP_BLUE
;
1182 sd
->params
.exposure
.compMode
= 1;
1183 sd
->params
.apcor
.gain1
= 0x18;
1184 sd
->params
.apcor
.gain2
= 0x16;
1185 sd
->params
.apcor
.gain4
= 0x24;
1186 sd
->params
.apcor
.gain8
= 0x34;
1188 sd
->params
.vlOffset
.gain1
= 20;
1189 sd
->params
.vlOffset
.gain2
= 24;
1190 sd
->params
.vlOffset
.gain4
= 26;
1191 sd
->params
.vlOffset
.gain8
= 26;
1194 ret
= command_setexposure(gspca_dev
);
1198 ret
= command_setapcor(gspca_dev
);
1202 ret
= command_setvloffset(gspca_dev
);
1206 ret
= command_setflickerctrl(gspca_dev
);
1212 #undef EXP_FROM_COMP
1216 /* monitor the exposure and adjust the sensor frame rate if needed */
1217 static void monitor_exposure(struct gspca_dev
*gspca_dev
)
1219 struct sd
*sd
= (struct sd
*) gspca_dev
;
1220 u8 exp_acc
, bcomp
, gain
, coarseL
, cmd
[8];
1221 int ret
, light_exp
, dark_exp
, very_dark_exp
;
1222 int old_exposure
, new_exposure
, framerate
;
1223 int setfps
= 0, setexp
= 0, setflicker
= 0;
1225 /* get necessary stats and register settings from camera */
1226 /* do_command can't handle this, so do it ourselves */
1227 cmd
[0] = CPIA_COMMAND_ReadVPRegs
>> 8;
1228 cmd
[1] = CPIA_COMMAND_ReadVPRegs
& 0xff;
1235 ret
= cpia_usb_transferCmd(gspca_dev
, cmd
);
1237 PDEBUG(D_ERR
, "ReadVPRegs(30,4,9,8) - failed: %d", ret
);
1240 exp_acc
= gspca_dev
->usb_buf
[0];
1241 bcomp
= gspca_dev
->usb_buf
[1];
1242 gain
= gspca_dev
->usb_buf
[2];
1243 coarseL
= gspca_dev
->usb_buf
[3];
1245 light_exp
= sd
->params
.colourParams
.brightness
+
1246 TC
- 50 + EXP_ACC_LIGHT
;
1247 if (light_exp
> 255)
1249 dark_exp
= sd
->params
.colourParams
.brightness
+
1250 TC
- 50 - EXP_ACC_DARK
;
1253 very_dark_exp
= dark_exp
/ 2;
1255 old_exposure
= sd
->params
.exposure
.coarseExpHi
* 256 +
1256 sd
->params
.exposure
.coarseExpLo
;
1258 if (!sd
->params
.flickerControl
.disabled
) {
1259 /* Flicker control on */
1260 int max_comp
= FIRMWARE_VERSION(1, 2) ? MAX_COMP
:
1262 bcomp
+= 128; /* decode */
1263 if (bcomp
>= max_comp
&& exp_acc
< dark_exp
) {
1265 if (exp_acc
< very_dark_exp
) {
1267 if (sd
->exposure_status
== EXPOSURE_VERY_DARK
)
1268 ++sd
->exposure_count
;
1270 sd
->exposure_status
=
1272 sd
->exposure_count
= 1;
1276 if (sd
->exposure_status
== EXPOSURE_DARK
)
1277 ++sd
->exposure_count
;
1279 sd
->exposure_status
= EXPOSURE_DARK
;
1280 sd
->exposure_count
= 1;
1283 } else if (old_exposure
<= LOW_EXP
|| exp_acc
> light_exp
) {
1285 if (old_exposure
<= VERY_LOW_EXP
) {
1287 if (sd
->exposure_status
== EXPOSURE_VERY_LIGHT
)
1288 ++sd
->exposure_count
;
1290 sd
->exposure_status
=
1291 EXPOSURE_VERY_LIGHT
;
1292 sd
->exposure_count
= 1;
1296 if (sd
->exposure_status
== EXPOSURE_LIGHT
)
1297 ++sd
->exposure_count
;
1299 sd
->exposure_status
= EXPOSURE_LIGHT
;
1300 sd
->exposure_count
= 1;
1304 /* not dark or light */
1305 sd
->exposure_status
= EXPOSURE_NORMAL
;
1308 /* Flicker control off */
1309 if (old_exposure
>= MAX_EXP
&& exp_acc
< dark_exp
) {
1311 if (exp_acc
< very_dark_exp
) {
1313 if (sd
->exposure_status
== EXPOSURE_VERY_DARK
)
1314 ++sd
->exposure_count
;
1316 sd
->exposure_status
=
1318 sd
->exposure_count
= 1;
1322 if (sd
->exposure_status
== EXPOSURE_DARK
)
1323 ++sd
->exposure_count
;
1325 sd
->exposure_status
= EXPOSURE_DARK
;
1326 sd
->exposure_count
= 1;
1329 } else if (old_exposure
<= LOW_EXP
|| exp_acc
> light_exp
) {
1331 if (old_exposure
<= VERY_LOW_EXP
) {
1333 if (sd
->exposure_status
== EXPOSURE_VERY_LIGHT
)
1334 ++sd
->exposure_count
;
1336 sd
->exposure_status
=
1337 EXPOSURE_VERY_LIGHT
;
1338 sd
->exposure_count
= 1;
1342 if (sd
->exposure_status
== EXPOSURE_LIGHT
)
1343 ++sd
->exposure_count
;
1345 sd
->exposure_status
= EXPOSURE_LIGHT
;
1346 sd
->exposure_count
= 1;
1350 /* not dark or light */
1351 sd
->exposure_status
= EXPOSURE_NORMAL
;
1355 framerate
= atomic_read(&sd
->fps
);
1356 if (framerate
> 30 || framerate
< 1)
1359 if (!sd
->params
.flickerControl
.disabled
) {
1360 /* Flicker control on */
1361 if ((sd
->exposure_status
== EXPOSURE_VERY_DARK
||
1362 sd
->exposure_status
== EXPOSURE_DARK
) &&
1363 sd
->exposure_count
>= DARK_TIME
* framerate
&&
1364 sd
->params
.sensorFps
.divisor
< 3) {
1366 /* dark for too long */
1367 ++sd
->params
.sensorFps
.divisor
;
1370 sd
->params
.flickerControl
.coarseJump
=
1371 flicker_jumps
[sd
->mainsFreq
]
1372 [sd
->params
.sensorFps
.baserate
]
1373 [sd
->params
.sensorFps
.divisor
];
1376 new_exposure
= sd
->params
.flickerControl
.coarseJump
-1;
1377 while (new_exposure
< old_exposure
/ 2)
1379 sd
->params
.flickerControl
.coarseJump
;
1380 sd
->params
.exposure
.coarseExpLo
= new_exposure
& 0xff;
1381 sd
->params
.exposure
.coarseExpHi
= new_exposure
>> 8;
1383 sd
->exposure_status
= EXPOSURE_NORMAL
;
1384 PDEBUG(D_CONF
, "Automatically decreasing sensor_fps");
1386 } else if ((sd
->exposure_status
== EXPOSURE_VERY_LIGHT
||
1387 sd
->exposure_status
== EXPOSURE_LIGHT
) &&
1388 sd
->exposure_count
>= LIGHT_TIME
* framerate
&&
1389 sd
->params
.sensorFps
.divisor
> 0) {
1391 /* light for too long */
1392 int max_exp
= FIRMWARE_VERSION(1, 2) ? MAX_EXP_102
:
1394 --sd
->params
.sensorFps
.divisor
;
1397 sd
->params
.flickerControl
.coarseJump
=
1398 flicker_jumps
[sd
->mainsFreq
]
1399 [sd
->params
.sensorFps
.baserate
]
1400 [sd
->params
.sensorFps
.divisor
];
1403 new_exposure
= sd
->params
.flickerControl
.coarseJump
-1;
1404 while (new_exposure
< 2 * old_exposure
&&
1406 sd
->params
.flickerControl
.coarseJump
< max_exp
)
1408 sd
->params
.flickerControl
.coarseJump
;
1409 sd
->params
.exposure
.coarseExpLo
= new_exposure
& 0xff;
1410 sd
->params
.exposure
.coarseExpHi
= new_exposure
>> 8;
1412 sd
->exposure_status
= EXPOSURE_NORMAL
;
1413 PDEBUG(D_CONF
, "Automatically increasing sensor_fps");
1416 /* Flicker control off */
1417 if ((sd
->exposure_status
== EXPOSURE_VERY_DARK
||
1418 sd
->exposure_status
== EXPOSURE_DARK
) &&
1419 sd
->exposure_count
>= DARK_TIME
* framerate
&&
1420 sd
->params
.sensorFps
.divisor
< 3) {
1422 /* dark for too long */
1423 ++sd
->params
.sensorFps
.divisor
;
1426 if (sd
->params
.exposure
.gain
> 0) {
1427 --sd
->params
.exposure
.gain
;
1430 sd
->exposure_status
= EXPOSURE_NORMAL
;
1431 PDEBUG(D_CONF
, "Automatically decreasing sensor_fps");
1433 } else if ((sd
->exposure_status
== EXPOSURE_VERY_LIGHT
||
1434 sd
->exposure_status
== EXPOSURE_LIGHT
) &&
1435 sd
->exposure_count
>= LIGHT_TIME
* framerate
&&
1436 sd
->params
.sensorFps
.divisor
> 0) {
1438 /* light for too long */
1439 --sd
->params
.sensorFps
.divisor
;
1442 if (sd
->params
.exposure
.gain
<
1443 sd
->params
.exposure
.gainMode
- 1) {
1444 ++sd
->params
.exposure
.gain
;
1447 sd
->exposure_status
= EXPOSURE_NORMAL
;
1448 PDEBUG(D_CONF
, "Automatically increasing sensor_fps");
1453 command_setexposure(gspca_dev
);
1456 command_setsensorfps(gspca_dev
);
1459 command_setflickerctrl(gspca_dev
);
1462 /*-----------------------------------------------------------------*/
1463 /* if flicker is switched off, this function switches it back on.It checks,
1464 however, that conditions are suitable before restarting it.
1465 This should only be called for firmware version 1.2.
1467 It also adjust the colour balance when an exposure step is detected - as
1468 long as flicker is running
1470 static void restart_flicker(struct gspca_dev
*gspca_dev
)
1472 struct sd
*sd
= (struct sd
*) gspca_dev
;
1473 int cam_exposure
, old_exp
;
1475 if (!FIRMWARE_VERSION(1, 2))
1478 cam_exposure
= atomic_read(&sd
->cam_exposure
);
1480 if (sd
->params
.flickerControl
.flickerMode
== 0 ||
1484 old_exp
= sd
->params
.exposure
.coarseExpLo
+
1485 sd
->params
.exposure
.coarseExpHi
*256;
1487 see how far away camera exposure is from a valid
1488 flicker exposure value
1490 cam_exposure
%= sd
->params
.flickerControl
.coarseJump
;
1491 if (!sd
->params
.flickerControl
.disabled
&&
1492 cam_exposure
<= sd
->params
.flickerControl
.coarseJump
- 3) {
1493 /* Flicker control auto-disabled */
1494 sd
->params
.flickerControl
.disabled
= 1;
1497 if (sd
->params
.flickerControl
.disabled
&&
1498 old_exp
> sd
->params
.flickerControl
.coarseJump
+
1499 ROUND_UP_EXP_FOR_FLICKER
) {
1500 /* exposure is now high enough to switch
1501 flicker control back on */
1502 set_flicker(gspca_dev
, 1, 1);
1506 /* this function is called at probe time */
1507 static int sd_config(struct gspca_dev
*gspca_dev
,
1508 const struct usb_device_id
*id
)
1512 reset_camera_params(gspca_dev
);
1514 PDEBUG(D_PROBE
, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)",
1515 id
->idVendor
, id
->idProduct
);
1517 cam
= &gspca_dev
->cam
;
1518 cam
->cam_mode
= mode
;
1519 cam
->nmodes
= ARRAY_SIZE(mode
);
1521 sd_setfreq(gspca_dev
, FREQ_DEF
);
1526 /* -- start the camera -- */
1527 static int sd_start(struct gspca_dev
*gspca_dev
)
1529 struct sd
*sd
= (struct sd
*) gspca_dev
;
1532 /* Start the camera in low power mode */
1533 if (goto_low_power(gspca_dev
)) {
1534 if (sd
->params
.status
.systemState
!= WARM_BOOT_STATE
) {
1535 PDEBUG(D_ERR
, "unexpected systemstate: %02x",
1536 sd
->params
.status
.systemState
);
1537 printstatus(&sd
->params
);
1541 /* FIXME: this is just dirty trial and error */
1542 ret
= goto_high_power(gspca_dev
);
1546 ret
= do_command(gspca_dev
, CPIA_COMMAND_DiscardFrame
,
1551 ret
= goto_low_power(gspca_dev
);
1556 /* procedure described in developer's guide p3-28 */
1558 /* Check the firmware version. */
1559 sd
->params
.version
.firmwareVersion
= 0;
1560 get_version_information(gspca_dev
);
1561 if (sd
->params
.version
.firmwareVersion
!= 1) {
1562 PDEBUG(D_ERR
, "only firmware version 1 is supported (got: %d)",
1563 sd
->params
.version
.firmwareVersion
);
1567 /* A bug in firmware 1-02 limits gainMode to 2 */
1568 if (sd
->params
.version
.firmwareRevision
<= 2 &&
1569 sd
->params
.exposure
.gainMode
> 2) {
1570 sd
->params
.exposure
.gainMode
= 2;
1573 /* set QX3 detected flag */
1574 sd
->params
.qx3
.qx3_detected
= (sd
->params
.pnpID
.vendor
== 0x0813 &&
1575 sd
->params
.pnpID
.product
== 0x0001);
1577 /* The fatal error checking should be done after
1578 * the camera powers up (developer's guide p 3-38) */
1580 /* Set streamState before transition to high power to avoid bug
1581 * in firmware 1-02 */
1582 ret
= do_command(gspca_dev
, CPIA_COMMAND_ModifyCameraStatus
,
1583 STREAMSTATE
, 0, STREAM_NOT_READY
, 0);
1588 ret
= goto_high_power(gspca_dev
);
1592 /* Check the camera status */
1593 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
1597 if (sd
->params
.status
.fatalError
) {
1598 PDEBUG(D_ERR
, "fatal_error: %04x, vp_status: %04x",
1599 sd
->params
.status
.fatalError
,
1600 sd
->params
.status
.vpStatus
);
1604 /* VPVersion can't be retrieved before the camera is in HiPower,
1605 * so get it here instead of in get_version_information. */
1606 ret
= do_command(gspca_dev
, CPIA_COMMAND_GetVPVersion
, 0, 0, 0, 0);
1610 /* Determine video mode settings */
1611 sd
->params
.streamStartLine
= 120;
1613 priv
= gspca_dev
->cam
.cam_mode
[gspca_dev
->curr_mode
].priv
;
1614 if (priv
& 0x01) { /* crop */
1615 sd
->params
.roi
.colStart
= 2;
1616 sd
->params
.roi
.rowStart
= 6;
1618 sd
->params
.roi
.colStart
= 0;
1619 sd
->params
.roi
.rowStart
= 0;
1622 if (priv
& 0x02) { /* quarter */
1623 sd
->params
.format
.videoSize
= VIDEOSIZE_QCIF
;
1624 sd
->params
.roi
.colStart
/= 2;
1625 sd
->params
.roi
.rowStart
/= 2;
1626 sd
->params
.streamStartLine
/= 2;
1628 sd
->params
.format
.videoSize
= VIDEOSIZE_CIF
;
1630 sd
->params
.roi
.colEnd
= sd
->params
.roi
.colStart
+
1631 (gspca_dev
->width
>> 3);
1632 sd
->params
.roi
.rowEnd
= sd
->params
.roi
.rowStart
+
1633 (gspca_dev
->height
>> 2);
1635 /* And now set the camera to a known state */
1636 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetGrabMode
,
1637 CPIA_GRAB_CONTINEOUS
, 0, 0, 0);
1640 /* We start with compression disabled, as we need one uncompressed
1641 frame to handle later compressed frames */
1642 ret
= do_command(gspca_dev
, CPIA_COMMAND_SetCompression
,
1643 CPIA_COMPRESSION_NONE
,
1644 NO_DECIMATION
, 0, 0);
1647 ret
= command_setcompressiontarget(gspca_dev
);
1650 ret
= command_setcolourparams(gspca_dev
);
1653 ret
= command_setformat(gspca_dev
);
1656 ret
= command_setyuvtresh(gspca_dev
);
1659 ret
= command_setecptiming(gspca_dev
);
1662 ret
= command_setcompressionparams(gspca_dev
);
1665 ret
= command_setexposure(gspca_dev
);
1668 ret
= command_setcolourbalance(gspca_dev
);
1671 ret
= command_setsensorfps(gspca_dev
);
1674 ret
= command_setapcor(gspca_dev
);
1677 ret
= command_setflickerctrl(gspca_dev
);
1680 ret
= command_setvloffset(gspca_dev
);
1685 ret
= command_resume(gspca_dev
);
1689 /* Wait 6 frames before turning compression on for the sensor to get
1690 all settings and AEC/ACB to settle */
1691 sd
->first_frame
= 6;
1692 sd
->exposure_status
= EXPOSURE_NORMAL
;
1693 sd
->exposure_count
= 0;
1694 atomic_set(&sd
->cam_exposure
, 0);
1695 atomic_set(&sd
->fps
, 0);
1700 static void sd_stopN(struct gspca_dev
*gspca_dev
)
1702 command_pause(gspca_dev
);
1704 /* save camera state for later open (developers guide ch 3.5.3) */
1705 save_camera_state(gspca_dev
);
1708 goto_low_power(gspca_dev
);
1710 /* Update the camera status */
1711 do_command(gspca_dev
, CPIA_COMMAND_GetCameraStatus
, 0, 0, 0, 0);
1714 /* this function is called at probe and resume time */
1715 static int sd_init(struct gspca_dev
*gspca_dev
)
1717 struct sd
*sd
= (struct sd
*) gspca_dev
;
1720 /* Start / Stop the camera to make sure we are talking to
1721 a supported camera, and to get some information from it
1723 ret
= sd_start(gspca_dev
);
1727 sd_stopN(gspca_dev
);
1729 PDEBUG(D_PROBE
, "CPIA Version: %d.%02d (%d.%d)",
1730 sd
->params
.version
.firmwareVersion
,
1731 sd
->params
.version
.firmwareRevision
,
1732 sd
->params
.version
.vcVersion
,
1733 sd
->params
.version
.vcRevision
);
1734 PDEBUG(D_PROBE
, "CPIA PnP-ID: %04x:%04x:%04x",
1735 sd
->params
.pnpID
.vendor
, sd
->params
.pnpID
.product
,
1736 sd
->params
.pnpID
.deviceRevision
);
1737 PDEBUG(D_PROBE
, "VP-Version: %d.%d %04x",
1738 sd
->params
.vpVersion
.vpVersion
,
1739 sd
->params
.vpVersion
.vpRevision
,
1740 sd
->params
.vpVersion
.cameraHeadID
);
1745 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
1749 struct sd
*sd
= (struct sd
*) gspca_dev
;
1753 data
[0] == MAGIC_0
&& data
[1] == MAGIC_1
&&
1754 data
[16] == sd
->params
.format
.videoSize
&&
1755 data
[17] == sd
->params
.format
.subSample
&&
1756 data
[18] == sd
->params
.format
.yuvOrder
&&
1757 data
[24] == sd
->params
.roi
.colStart
&&
1758 data
[25] == sd
->params
.roi
.colEnd
&&
1759 data
[26] == sd
->params
.roi
.rowStart
&&
1760 data
[27] == sd
->params
.roi
.rowEnd
) {
1761 struct gspca_frame
*frame
= gspca_get_i_frame(gspca_dev
);
1763 atomic_set(&sd
->cam_exposure
, data
[39] * 2);
1764 atomic_set(&sd
->fps
, data
[41]);
1766 if (frame
== NULL
) {
1767 gspca_dev
->last_packet_type
= DISCARD_PACKET
;
1771 /* Check for proper EOF for last frame */
1772 if ((frame
->data_end
- frame
->data
) > 4 &&
1773 frame
->data_end
[-4] == 0xff &&
1774 frame
->data_end
[-3] == 0xff &&
1775 frame
->data_end
[-2] == 0xff &&
1776 frame
->data_end
[-1] == 0xff)
1777 gspca_frame_add(gspca_dev
, LAST_PACKET
,
1780 gspca_frame_add(gspca_dev
, FIRST_PACKET
, data
, len
);
1784 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
1787 static void sd_dq_callback(struct gspca_dev
*gspca_dev
)
1789 struct sd
*sd
= (struct sd
*) gspca_dev
;
1791 /* Set the normal compression settings once we have captured a
1792 few uncompressed frames (and AEC has hopefully settled) */
1793 if (sd
->first_frame
) {
1795 if (sd
->first_frame
== 0)
1796 command_setcompression(gspca_dev
);
1799 /* Switch flicker control back on if it got turned off */
1800 restart_flicker(gspca_dev
);
1802 /* If AEC is enabled, monitor the exposure and
1803 adjust the sensor frame rate if needed */
1804 if (sd
->params
.exposure
.expMode
== 2)
1805 monitor_exposure(gspca_dev
);
1807 /* Update our knowledge of the camera state */
1808 do_command(gspca_dev
, CPIA_COMMAND_GetExposure
, 0, 0, 0, 0);
1809 if (sd
->params
.qx3
.qx3_detected
)
1810 do_command(gspca_dev
, CPIA_COMMAND_ReadMCPorts
, 0, 0, 0, 0);
1813 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
)
1815 struct sd
*sd
= (struct sd
*) gspca_dev
;
1818 sd
->params
.colourParams
.brightness
= val
;
1819 sd
->params
.flickerControl
.allowableOverExposure
=
1820 find_over_exposure(sd
->params
.colourParams
.brightness
);
1821 if (gspca_dev
->streaming
) {
1822 ret
= command_setcolourparams(gspca_dev
);
1825 return command_setflickerctrl(gspca_dev
);
1830 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
)
1832 struct sd
*sd
= (struct sd
*) gspca_dev
;
1834 *val
= sd
->params
.colourParams
.brightness
;
1838 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
)
1840 struct sd
*sd
= (struct sd
*) gspca_dev
;
1842 sd
->params
.colourParams
.contrast
= val
;
1843 if (gspca_dev
->streaming
)
1844 return command_setcolourparams(gspca_dev
);
1849 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
)
1851 struct sd
*sd
= (struct sd
*) gspca_dev
;
1853 *val
= sd
->params
.colourParams
.contrast
;
1857 static int sd_setsaturation(struct gspca_dev
*gspca_dev
, __s32 val
)
1859 struct sd
*sd
= (struct sd
*) gspca_dev
;
1861 sd
->params
.colourParams
.saturation
= val
;
1862 if (gspca_dev
->streaming
)
1863 return command_setcolourparams(gspca_dev
);
1868 static int sd_getsaturation(struct gspca_dev
*gspca_dev
, __s32
*val
)
1870 struct sd
*sd
= (struct sd
*) gspca_dev
;
1872 *val
= sd
->params
.colourParams
.saturation
;
1876 static int sd_setfreq(struct gspca_dev
*gspca_dev
, __s32 val
)
1878 struct sd
*sd
= (struct sd
*) gspca_dev
;
1882 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1885 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1889 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1898 sd
->params
.flickerControl
.coarseJump
=
1899 flicker_jumps
[sd
->mainsFreq
]
1900 [sd
->params
.sensorFps
.baserate
]
1901 [sd
->params
.sensorFps
.divisor
];
1903 return set_flicker(gspca_dev
, on
, gspca_dev
->streaming
);
1906 static int sd_getfreq(struct gspca_dev
*gspca_dev
, __s32
*val
)
1908 struct sd
*sd
= (struct sd
*) gspca_dev
;
1914 static int sd_setcomptarget(struct gspca_dev
*gspca_dev
, __s32 val
)
1916 struct sd
*sd
= (struct sd
*) gspca_dev
;
1918 sd
->params
.compressionTarget
.frTargeting
= val
;
1919 if (gspca_dev
->streaming
)
1920 return command_setcompressiontarget(gspca_dev
);
1925 static int sd_getcomptarget(struct gspca_dev
*gspca_dev
, __s32
*val
)
1927 struct sd
*sd
= (struct sd
*) gspca_dev
;
1929 *val
= sd
->params
.compressionTarget
.frTargeting
;
1933 static int sd_querymenu(struct gspca_dev
*gspca_dev
,
1934 struct v4l2_querymenu
*menu
)
1937 case V4L2_CID_POWER_LINE_FREQUENCY
:
1938 switch (menu
->index
) {
1939 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1940 strcpy((char *) menu
->name
, "NoFliker");
1942 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1943 strcpy((char *) menu
->name
, "50 Hz");
1945 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1946 strcpy((char *) menu
->name
, "60 Hz");
1950 case V4L2_CID_COMP_TARGET
:
1951 switch (menu
->index
) {
1952 case CPIA_COMPRESSION_TARGET_QUALITY
:
1953 strcpy((char *) menu
->name
, "Quality");
1955 case CPIA_COMPRESSION_TARGET_FRAMERATE
:
1956 strcpy((char *) menu
->name
, "Framerate");
1964 /* sub-driver description */
1965 static const struct sd_desc sd_desc
= {
1966 .name
= MODULE_NAME
,
1968 .nctrls
= ARRAY_SIZE(sd_ctrls
),
1969 .config
= sd_config
,
1973 .dq_callback
= sd_dq_callback
,
1974 .pkt_scan
= sd_pkt_scan
,
1975 .querymenu
= sd_querymenu
,
1978 /* -- module initialisation -- */
1979 static const __devinitdata
struct usb_device_id device_table
[] = {
1980 {USB_DEVICE(0x0553, 0x0002)},
1981 {USB_DEVICE(0x0813, 0x0001)},
1984 MODULE_DEVICE_TABLE(usb
, device_table
);
1986 /* -- device connect -- */
1987 static int sd_probe(struct usb_interface
*intf
,
1988 const struct usb_device_id
*id
)
1990 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
1994 static struct usb_driver sd_driver
= {
1995 .name
= MODULE_NAME
,
1996 .id_table
= device_table
,
1998 .disconnect
= gspca_disconnect
,
2000 .suspend
= gspca_suspend
,
2001 .resume
= gspca_resume
,
2005 /* -- module insert / remove -- */
2006 static int __init
sd_mod_init(void)
2009 ret
= usb_register(&sd_driver
);
2012 PDEBUG(D_PROBE
, "registered");
2015 static void __exit
sd_mod_exit(void)
2017 usb_deregister(&sd_driver
);
2018 PDEBUG(D_PROBE
, "deregistered");
2021 module_init(sd_mod_init
);
2022 module_exit(sd_mod_exit
);