PM / sleep: Asynchronous threads for suspend_noirq
[linux/fpc-iii.git] / drivers / media / usb / gspca / cpia1.c
blobf23df4a9d8c56e460840082bfd5bb9ebcafce511
1 /*
2 * cpia CPiA (1) gspca driver
4 * Copyright (C) 2010-2011 Hans de Goede <hdegoede@redhat.com>
6 * This module is adapted from the in kernel v4l1 cpia driver which is :
8 * (C) Copyright 1999-2000 Peter Pregler
9 * (C) Copyright 1999-2000 Scott J. Bertin
10 * (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.com>
11 * (C) Copyright 2000 STMicroelectronics
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31 #define MODULE_NAME "cpia1"
33 #include <linux/input.h>
34 #include "gspca.h"
36 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
37 MODULE_DESCRIPTION("Vision CPiA");
38 MODULE_LICENSE("GPL");
40 /* constant value's */
41 #define MAGIC_0 0x19
42 #define MAGIC_1 0x68
43 #define DATA_IN 0xc0
44 #define DATA_OUT 0x40
45 #define VIDEOSIZE_QCIF 0 /* 176x144 */
46 #define VIDEOSIZE_CIF 1 /* 352x288 */
47 #define SUBSAMPLE_420 0
48 #define SUBSAMPLE_422 1
49 #define YUVORDER_YUYV 0
50 #define YUVORDER_UYVY 1
51 #define NOT_COMPRESSED 0
52 #define COMPRESSED 1
53 #define NO_DECIMATION 0
54 #define DECIMATION_ENAB 1
55 #define EOI 0xff /* End Of Image */
56 #define EOL 0xfd /* End Of Line */
57 #define FRAME_HEADER_SIZE 64
59 /* Image grab modes */
60 #define CPIA_GRAB_SINGLE 0
61 #define CPIA_GRAB_CONTINEOUS 1
63 /* Compression parameters */
64 #define CPIA_COMPRESSION_NONE 0
65 #define CPIA_COMPRESSION_AUTO 1
66 #define CPIA_COMPRESSION_MANUAL 2
67 #define CPIA_COMPRESSION_TARGET_QUALITY 0
68 #define CPIA_COMPRESSION_TARGET_FRAMERATE 1
70 /* Return offsets for GetCameraState */
71 #define SYSTEMSTATE 0
72 #define GRABSTATE 1
73 #define STREAMSTATE 2
74 #define FATALERROR 3
75 #define CMDERROR 4
76 #define DEBUGFLAGS 5
77 #define VPSTATUS 6
78 #define ERRORCODE 7
80 /* SystemState */
81 #define UNINITIALISED_STATE 0
82 #define PASS_THROUGH_STATE 1
83 #define LO_POWER_STATE 2
84 #define HI_POWER_STATE 3
85 #define WARM_BOOT_STATE 4
87 /* GrabState */
88 #define GRAB_IDLE 0
89 #define GRAB_ACTIVE 1
90 #define GRAB_DONE 2
92 /* StreamState */
93 #define STREAM_NOT_READY 0
94 #define STREAM_READY 1
95 #define STREAM_OPEN 2
96 #define STREAM_PAUSED 3
97 #define STREAM_FINISHED 4
99 /* Fatal Error, CmdError, and DebugFlags */
100 #define CPIA_FLAG 1
101 #define SYSTEM_FLAG 2
102 #define INT_CTRL_FLAG 4
103 #define PROCESS_FLAG 8
104 #define COM_FLAG 16
105 #define VP_CTRL_FLAG 32
106 #define CAPTURE_FLAG 64
107 #define DEBUG_FLAG 128
109 /* VPStatus */
110 #define VP_STATE_OK 0x00
112 #define VP_STATE_FAILED_VIDEOINIT 0x01
113 #define VP_STATE_FAILED_AECACBINIT 0x02
114 #define VP_STATE_AEC_MAX 0x04
115 #define VP_STATE_ACB_BMAX 0x08
117 #define VP_STATE_ACB_RMIN 0x10
118 #define VP_STATE_ACB_GMIN 0x20
119 #define VP_STATE_ACB_RMAX 0x40
120 #define VP_STATE_ACB_GMAX 0x80
122 /* default (minimum) compensation values */
123 #define COMP_RED 220
124 #define COMP_GREEN1 214
125 #define COMP_GREEN2 COMP_GREEN1
126 #define COMP_BLUE 230
128 /* exposure status */
129 #define EXPOSURE_VERY_LIGHT 0
130 #define EXPOSURE_LIGHT 1
131 #define EXPOSURE_NORMAL 2
132 #define EXPOSURE_DARK 3
133 #define EXPOSURE_VERY_DARK 4
135 #define CPIA_MODULE_CPIA (0 << 5)
136 #define CPIA_MODULE_SYSTEM (1 << 5)
137 #define CPIA_MODULE_VP_CTRL (5 << 5)
138 #define CPIA_MODULE_CAPTURE (6 << 5)
139 #define CPIA_MODULE_DEBUG (7 << 5)
141 #define INPUT (DATA_IN << 8)
142 #define OUTPUT (DATA_OUT << 8)
144 #define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)
145 #define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)
146 #define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)
147 #define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)
148 #define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)
149 #define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)
150 #define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)
151 #define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)
153 #define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)
154 #define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)
155 #define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)
156 #define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)
157 #define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)
158 #define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)
159 #define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)
160 #define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)
161 #define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)
162 #define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)
163 #define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)
164 #define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)
165 #define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
167 #define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
168 #define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)
169 #define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
170 #define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
171 #define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
172 #define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)
173 #define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)
174 #define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)
175 #define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)
176 #define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)
177 #define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)
178 #define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)
179 #define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)
180 #define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)
181 #define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)
182 #define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)
183 #define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)
185 #define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)
186 #define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)
187 #define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)
188 #define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)
189 #define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)
190 #define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)
191 #define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)
192 #define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)
193 #define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)
194 #define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)
195 #define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
196 #define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
197 #define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
198 #define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
199 #define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)
201 #define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
202 #define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
203 #define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)
204 #define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)
205 #define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
206 #define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
207 #define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
208 #define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)
210 #define ROUND_UP_EXP_FOR_FLICKER 15
212 /* Constants for automatic frame rate adjustment */
213 #define MAX_EXP 302
214 #define MAX_EXP_102 255
215 #define LOW_EXP 140
216 #define VERY_LOW_EXP 70
217 #define TC 94
218 #define EXP_ACC_DARK 50
219 #define EXP_ACC_LIGHT 90
220 #define HIGH_COMP_102 160
221 #define MAX_COMP 239
222 #define DARK_TIME 3
223 #define LIGHT_TIME 3
225 #define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \
226 sd->params.version.firmwareRevision == (y))
228 #define CPIA1_CID_COMP_TARGET (V4L2_CTRL_CLASS_USER + 0x1000)
229 #define BRIGHTNESS_DEF 50
230 #define CONTRAST_DEF 48
231 #define SATURATION_DEF 50
232 #define FREQ_DEF V4L2_CID_POWER_LINE_FREQUENCY_50HZ
233 #define ILLUMINATORS_1_DEF 0
234 #define ILLUMINATORS_2_DEF 0
235 #define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY
237 /* Developer's Guide Table 5 p 3-34
238 * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
239 static u8 flicker_jumps[2][2][4] =
240 { { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
241 { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
244 struct cam_params {
245 struct {
246 u8 firmwareVersion;
247 u8 firmwareRevision;
248 u8 vcVersion;
249 u8 vcRevision;
250 } version;
251 struct {
252 u16 vendor;
253 u16 product;
254 u16 deviceRevision;
255 } pnpID;
256 struct {
257 u8 vpVersion;
258 u8 vpRevision;
259 u16 cameraHeadID;
260 } vpVersion;
261 struct {
262 u8 systemState;
263 u8 grabState;
264 u8 streamState;
265 u8 fatalError;
266 u8 cmdError;
267 u8 debugFlags;
268 u8 vpStatus;
269 u8 errorCode;
270 } status;
271 struct {
272 u8 brightness;
273 u8 contrast;
274 u8 saturation;
275 } colourParams;
276 struct {
277 u8 gainMode;
278 u8 expMode;
279 u8 compMode;
280 u8 centreWeight;
281 u8 gain;
282 u8 fineExp;
283 u8 coarseExpLo;
284 u8 coarseExpHi;
285 u8 redComp;
286 u8 green1Comp;
287 u8 green2Comp;
288 u8 blueComp;
289 } exposure;
290 struct {
291 u8 balanceMode;
292 u8 redGain;
293 u8 greenGain;
294 u8 blueGain;
295 } colourBalance;
296 struct {
297 u8 divisor;
298 u8 baserate;
299 } sensorFps;
300 struct {
301 u8 gain1;
302 u8 gain2;
303 u8 gain4;
304 u8 gain8;
305 } apcor;
306 struct {
307 u8 disabled;
308 u8 flickerMode;
309 u8 coarseJump;
310 u8 allowableOverExposure;
311 } flickerControl;
312 struct {
313 u8 gain1;
314 u8 gain2;
315 u8 gain4;
316 u8 gain8;
317 } vlOffset;
318 struct {
319 u8 mode;
320 u8 decimation;
321 } compression;
322 struct {
323 u8 frTargeting;
324 u8 targetFR;
325 u8 targetQ;
326 } compressionTarget;
327 struct {
328 u8 yThreshold;
329 u8 uvThreshold;
330 } yuvThreshold;
331 struct {
332 u8 hysteresis;
333 u8 threshMax;
334 u8 smallStep;
335 u8 largeStep;
336 u8 decimationHysteresis;
337 u8 frDiffStepThresh;
338 u8 qDiffStepThresh;
339 u8 decimationThreshMod;
340 } compressionParams;
341 struct {
342 u8 videoSize; /* CIF/QCIF */
343 u8 subSample;
344 u8 yuvOrder;
345 } format;
346 struct { /* Intel QX3 specific data */
347 u8 qx3_detected; /* a QX3 is present */
348 u8 toplight; /* top light lit , R/W */
349 u8 bottomlight; /* bottom light lit, R/W */
350 u8 button; /* snapshot button pressed (R/O) */
351 u8 cradled; /* microscope is in cradle (R/O) */
352 } qx3;
353 struct {
354 u8 colStart; /* skip first 8*colStart pixels */
355 u8 colEnd; /* finish at 8*colEnd pixels */
356 u8 rowStart; /* skip first 4*rowStart lines */
357 u8 rowEnd; /* finish at 4*rowEnd lines */
358 } roi;
359 u8 ecpTiming;
360 u8 streamStartLine;
363 /* specific webcam descriptor */
364 struct sd {
365 struct gspca_dev gspca_dev; /* !! must be the first item */
366 struct cam_params params; /* camera settings */
368 atomic_t cam_exposure;
369 atomic_t fps;
370 int exposure_count;
371 u8 exposure_status;
372 struct v4l2_ctrl *freq;
373 u8 mainsFreq; /* 0 = 50hz, 1 = 60hz */
374 u8 first_frame;
377 static const struct v4l2_pix_format mode[] = {
378 {160, 120, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
379 /* The sizeimage is trial and error, as with low framerates
380 the camera will pad out usb frames, making the image
381 data larger then strictly necessary */
382 .bytesperline = 160,
383 .sizeimage = 65536,
384 .colorspace = V4L2_COLORSPACE_SRGB,
385 .priv = 3},
386 {176, 144, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
387 .bytesperline = 172,
388 .sizeimage = 65536,
389 .colorspace = V4L2_COLORSPACE_SRGB,
390 .priv = 2},
391 {320, 240, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
392 .bytesperline = 320,
393 .sizeimage = 262144,
394 .colorspace = V4L2_COLORSPACE_SRGB,
395 .priv = 1},
396 {352, 288, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
397 .bytesperline = 352,
398 .sizeimage = 262144,
399 .colorspace = V4L2_COLORSPACE_SRGB,
400 .priv = 0},
403 /**********************************************************************
405 * General functions
407 **********************************************************************/
409 static int cpia_usb_transferCmd(struct gspca_dev *gspca_dev, u8 *command)
411 u8 requesttype;
412 unsigned int pipe;
413 int ret, databytes = command[6] | (command[7] << 8);
414 /* Sometimes we see spurious EPIPE errors */
415 int retries = 3;
417 if (command[0] == DATA_IN) {
418 pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
419 requesttype = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
420 } else if (command[0] == DATA_OUT) {
421 pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
422 requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE;
423 } else {
424 PERR("Unexpected first byte of command: %x", command[0]);
425 return -EINVAL;
428 retry:
429 ret = usb_control_msg(gspca_dev->dev, pipe,
430 command[1],
431 requesttype,
432 command[2] | (command[3] << 8),
433 command[4] | (command[5] << 8),
434 gspca_dev->usb_buf, databytes, 1000);
436 if (ret < 0)
437 pr_err("usb_control_msg %02x, error %d\n", command[1], ret);
439 if (ret == -EPIPE && retries > 0) {
440 retries--;
441 goto retry;
444 return (ret < 0) ? ret : 0;
447 /* send an arbitrary command to the camera */
448 static int do_command(struct gspca_dev *gspca_dev, u16 command,
449 u8 a, u8 b, u8 c, u8 d)
451 struct sd *sd = (struct sd *) gspca_dev;
452 int ret, datasize;
453 u8 cmd[8];
455 switch (command) {
456 case CPIA_COMMAND_GetCPIAVersion:
457 case CPIA_COMMAND_GetPnPID:
458 case CPIA_COMMAND_GetCameraStatus:
459 case CPIA_COMMAND_GetVPVersion:
460 case CPIA_COMMAND_GetColourParams:
461 case CPIA_COMMAND_GetColourBalance:
462 case CPIA_COMMAND_GetExposure:
463 datasize = 8;
464 break;
465 case CPIA_COMMAND_ReadMCPorts:
466 case CPIA_COMMAND_ReadVCRegs:
467 datasize = 4;
468 break;
469 default:
470 datasize = 0;
471 break;
474 cmd[0] = command >> 8;
475 cmd[1] = command & 0xff;
476 cmd[2] = a;
477 cmd[3] = b;
478 cmd[4] = c;
479 cmd[5] = d;
480 cmd[6] = datasize;
481 cmd[7] = 0;
483 ret = cpia_usb_transferCmd(gspca_dev, cmd);
484 if (ret)
485 return ret;
487 switch (command) {
488 case CPIA_COMMAND_GetCPIAVersion:
489 sd->params.version.firmwareVersion = gspca_dev->usb_buf[0];
490 sd->params.version.firmwareRevision = gspca_dev->usb_buf[1];
491 sd->params.version.vcVersion = gspca_dev->usb_buf[2];
492 sd->params.version.vcRevision = gspca_dev->usb_buf[3];
493 break;
494 case CPIA_COMMAND_GetPnPID:
495 sd->params.pnpID.vendor =
496 gspca_dev->usb_buf[0] | (gspca_dev->usb_buf[1] << 8);
497 sd->params.pnpID.product =
498 gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
499 sd->params.pnpID.deviceRevision =
500 gspca_dev->usb_buf[4] | (gspca_dev->usb_buf[5] << 8);
501 break;
502 case CPIA_COMMAND_GetCameraStatus:
503 sd->params.status.systemState = gspca_dev->usb_buf[0];
504 sd->params.status.grabState = gspca_dev->usb_buf[1];
505 sd->params.status.streamState = gspca_dev->usb_buf[2];
506 sd->params.status.fatalError = gspca_dev->usb_buf[3];
507 sd->params.status.cmdError = gspca_dev->usb_buf[4];
508 sd->params.status.debugFlags = gspca_dev->usb_buf[5];
509 sd->params.status.vpStatus = gspca_dev->usb_buf[6];
510 sd->params.status.errorCode = gspca_dev->usb_buf[7];
511 break;
512 case CPIA_COMMAND_GetVPVersion:
513 sd->params.vpVersion.vpVersion = gspca_dev->usb_buf[0];
514 sd->params.vpVersion.vpRevision = gspca_dev->usb_buf[1];
515 sd->params.vpVersion.cameraHeadID =
516 gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
517 break;
518 case CPIA_COMMAND_GetColourParams:
519 sd->params.colourParams.brightness = gspca_dev->usb_buf[0];
520 sd->params.colourParams.contrast = gspca_dev->usb_buf[1];
521 sd->params.colourParams.saturation = gspca_dev->usb_buf[2];
522 break;
523 case CPIA_COMMAND_GetColourBalance:
524 sd->params.colourBalance.redGain = gspca_dev->usb_buf[0];
525 sd->params.colourBalance.greenGain = gspca_dev->usb_buf[1];
526 sd->params.colourBalance.blueGain = gspca_dev->usb_buf[2];
527 break;
528 case CPIA_COMMAND_GetExposure:
529 sd->params.exposure.gain = gspca_dev->usb_buf[0];
530 sd->params.exposure.fineExp = gspca_dev->usb_buf[1];
531 sd->params.exposure.coarseExpLo = gspca_dev->usb_buf[2];
532 sd->params.exposure.coarseExpHi = gspca_dev->usb_buf[3];
533 sd->params.exposure.redComp = gspca_dev->usb_buf[4];
534 sd->params.exposure.green1Comp = gspca_dev->usb_buf[5];
535 sd->params.exposure.green2Comp = gspca_dev->usb_buf[6];
536 sd->params.exposure.blueComp = gspca_dev->usb_buf[7];
537 break;
539 case CPIA_COMMAND_ReadMCPorts:
540 /* test button press */
541 a = ((gspca_dev->usb_buf[1] & 0x02) == 0);
542 if (a != sd->params.qx3.button) {
543 #if IS_ENABLED(CONFIG_INPUT)
544 input_report_key(gspca_dev->input_dev, KEY_CAMERA, a);
545 input_sync(gspca_dev->input_dev);
546 #endif
547 sd->params.qx3.button = a;
549 if (sd->params.qx3.button) {
550 /* button pressed - unlock the latch */
551 do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
552 3, 0xdf, 0xdf, 0);
553 do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
554 3, 0xff, 0xff, 0);
557 /* test whether microscope is cradled */
558 sd->params.qx3.cradled = ((gspca_dev->usb_buf[2] & 0x40) == 0);
559 break;
562 return 0;
565 /* send a command to the camera with an additional data transaction */
566 static int do_command_extended(struct gspca_dev *gspca_dev, u16 command,
567 u8 a, u8 b, u8 c, u8 d,
568 u8 e, u8 f, u8 g, u8 h,
569 u8 i, u8 j, u8 k, u8 l)
571 u8 cmd[8];
573 cmd[0] = command >> 8;
574 cmd[1] = command & 0xff;
575 cmd[2] = a;
576 cmd[3] = b;
577 cmd[4] = c;
578 cmd[5] = d;
579 cmd[6] = 8;
580 cmd[7] = 0;
581 gspca_dev->usb_buf[0] = e;
582 gspca_dev->usb_buf[1] = f;
583 gspca_dev->usb_buf[2] = g;
584 gspca_dev->usb_buf[3] = h;
585 gspca_dev->usb_buf[4] = i;
586 gspca_dev->usb_buf[5] = j;
587 gspca_dev->usb_buf[6] = k;
588 gspca_dev->usb_buf[7] = l;
590 return cpia_usb_transferCmd(gspca_dev, cmd);
593 /* find_over_exposure
594 * Finds a suitable value of OverExposure for use with SetFlickerCtrl
595 * Some calculation is required because this value changes with the brightness
596 * set with SetColourParameters
598 * Parameters: Brightness - last brightness value set with SetColourParameters
600 * Returns: OverExposure value to use with SetFlickerCtrl
602 #define FLICKER_MAX_EXPOSURE 250
603 #define FLICKER_ALLOWABLE_OVER_EXPOSURE 146
604 #define FLICKER_BRIGHTNESS_CONSTANT 59
605 static int find_over_exposure(int brightness)
607 int MaxAllowableOverExposure, OverExposure;
609 MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness -
610 FLICKER_BRIGHTNESS_CONSTANT;
612 if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE)
613 OverExposure = MaxAllowableOverExposure;
614 else
615 OverExposure = FLICKER_ALLOWABLE_OVER_EXPOSURE;
617 return OverExposure;
619 #undef FLICKER_MAX_EXPOSURE
620 #undef FLICKER_ALLOWABLE_OVER_EXPOSURE
621 #undef FLICKER_BRIGHTNESS_CONSTANT
623 /* initialise cam_data structure */
624 static void reset_camera_params(struct gspca_dev *gspca_dev)
626 struct sd *sd = (struct sd *) gspca_dev;
627 struct cam_params *params = &sd->params;
629 /* The following parameter values are the defaults from
630 * "Software Developer's Guide for CPiA Cameras". Any changes
631 * to the defaults are noted in comments. */
632 params->colourParams.brightness = BRIGHTNESS_DEF;
633 params->colourParams.contrast = CONTRAST_DEF;
634 params->colourParams.saturation = SATURATION_DEF;
635 params->exposure.gainMode = 4;
636 params->exposure.expMode = 2; /* AEC */
637 params->exposure.compMode = 1;
638 params->exposure.centreWeight = 1;
639 params->exposure.gain = 0;
640 params->exposure.fineExp = 0;
641 params->exposure.coarseExpLo = 185;
642 params->exposure.coarseExpHi = 0;
643 params->exposure.redComp = COMP_RED;
644 params->exposure.green1Comp = COMP_GREEN1;
645 params->exposure.green2Comp = COMP_GREEN2;
646 params->exposure.blueComp = COMP_BLUE;
647 params->colourBalance.balanceMode = 2; /* ACB */
648 params->colourBalance.redGain = 32;
649 params->colourBalance.greenGain = 6;
650 params->colourBalance.blueGain = 92;
651 params->apcor.gain1 = 0x18;
652 params->apcor.gain2 = 0x16;
653 params->apcor.gain4 = 0x24;
654 params->apcor.gain8 = 0x34;
655 params->vlOffset.gain1 = 20;
656 params->vlOffset.gain2 = 24;
657 params->vlOffset.gain4 = 26;
658 params->vlOffset.gain8 = 26;
659 params->compressionParams.hysteresis = 3;
660 params->compressionParams.threshMax = 11;
661 params->compressionParams.smallStep = 1;
662 params->compressionParams.largeStep = 3;
663 params->compressionParams.decimationHysteresis = 2;
664 params->compressionParams.frDiffStepThresh = 5;
665 params->compressionParams.qDiffStepThresh = 3;
666 params->compressionParams.decimationThreshMod = 2;
667 /* End of default values from Software Developer's Guide */
669 /* Set Sensor FPS to 15fps. This seems better than 30fps
670 * for indoor lighting. */
671 params->sensorFps.divisor = 1;
672 params->sensorFps.baserate = 1;
674 params->flickerControl.flickerMode = 0;
675 params->flickerControl.disabled = 1;
676 params->flickerControl.coarseJump =
677 flicker_jumps[sd->mainsFreq]
678 [params->sensorFps.baserate]
679 [params->sensorFps.divisor];
680 params->flickerControl.allowableOverExposure =
681 find_over_exposure(params->colourParams.brightness);
683 params->yuvThreshold.yThreshold = 6; /* From windows driver */
684 params->yuvThreshold.uvThreshold = 6; /* From windows driver */
686 params->format.subSample = SUBSAMPLE_420;
687 params->format.yuvOrder = YUVORDER_YUYV;
689 params->compression.mode = CPIA_COMPRESSION_AUTO;
690 params->compression.decimation = NO_DECIMATION;
692 params->compressionTarget.frTargeting = COMP_TARGET_DEF;
693 params->compressionTarget.targetFR = 15; /* From windows driver */
694 params->compressionTarget.targetQ = 5; /* From windows driver */
696 params->qx3.qx3_detected = 0;
697 params->qx3.toplight = 0;
698 params->qx3.bottomlight = 0;
699 params->qx3.button = 0;
700 params->qx3.cradled = 0;
703 static void printstatus(struct gspca_dev *gspca_dev, struct cam_params *params)
705 PDEBUG(D_PROBE, "status: %02x %02x %02x %02x %02x %02x %02x %02x",
706 params->status.systemState, params->status.grabState,
707 params->status.streamState, params->status.fatalError,
708 params->status.cmdError, params->status.debugFlags,
709 params->status.vpStatus, params->status.errorCode);
712 static int goto_low_power(struct gspca_dev *gspca_dev)
714 struct sd *sd = (struct sd *) gspca_dev;
715 int ret;
717 ret = do_command(gspca_dev, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0);
718 if (ret)
719 return ret;
721 ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
722 if (ret)
723 return ret;
725 if (sd->params.status.systemState != LO_POWER_STATE) {
726 if (sd->params.status.systemState != WARM_BOOT_STATE) {
727 PERR("unexpected state after lo power cmd: %02x",
728 sd->params.status.systemState);
729 printstatus(gspca_dev, &sd->params);
731 return -EIO;
734 PDEBUG(D_CONF, "camera now in LOW power state");
735 return 0;
738 static int goto_high_power(struct gspca_dev *gspca_dev)
740 struct sd *sd = (struct sd *) gspca_dev;
741 int ret;
743 ret = do_command(gspca_dev, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0);
744 if (ret)
745 return ret;
747 msleep_interruptible(40); /* windows driver does it too */
749 if (signal_pending(current))
750 return -EINTR;
752 ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
753 if (ret)
754 return ret;
756 if (sd->params.status.systemState != HI_POWER_STATE) {
757 PERR("unexpected state after hi power cmd: %02x",
758 sd->params.status.systemState);
759 printstatus(gspca_dev, &sd->params);
760 return -EIO;
763 PDEBUG(D_CONF, "camera now in HIGH power state");
764 return 0;
767 static int get_version_information(struct gspca_dev *gspca_dev)
769 int ret;
771 /* GetCPIAVersion */
772 ret = do_command(gspca_dev, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0);
773 if (ret)
774 return ret;
776 /* GetPnPID */
777 return do_command(gspca_dev, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0);
780 static int save_camera_state(struct gspca_dev *gspca_dev)
782 int ret;
784 ret = do_command(gspca_dev, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
785 if (ret)
786 return ret;
788 return do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
791 static int command_setformat(struct gspca_dev *gspca_dev)
793 struct sd *sd = (struct sd *) gspca_dev;
794 int ret;
796 ret = do_command(gspca_dev, CPIA_COMMAND_SetFormat,
797 sd->params.format.videoSize,
798 sd->params.format.subSample,
799 sd->params.format.yuvOrder, 0);
800 if (ret)
801 return ret;
803 return do_command(gspca_dev, CPIA_COMMAND_SetROI,
804 sd->params.roi.colStart, sd->params.roi.colEnd,
805 sd->params.roi.rowStart, sd->params.roi.rowEnd);
808 static int command_setcolourparams(struct gspca_dev *gspca_dev)
810 struct sd *sd = (struct sd *) gspca_dev;
811 return do_command(gspca_dev, CPIA_COMMAND_SetColourParams,
812 sd->params.colourParams.brightness,
813 sd->params.colourParams.contrast,
814 sd->params.colourParams.saturation, 0);
817 static int command_setapcor(struct gspca_dev *gspca_dev)
819 struct sd *sd = (struct sd *) gspca_dev;
820 return do_command(gspca_dev, CPIA_COMMAND_SetApcor,
821 sd->params.apcor.gain1,
822 sd->params.apcor.gain2,
823 sd->params.apcor.gain4,
824 sd->params.apcor.gain8);
827 static int command_setvloffset(struct gspca_dev *gspca_dev)
829 struct sd *sd = (struct sd *) gspca_dev;
830 return do_command(gspca_dev, CPIA_COMMAND_SetVLOffset,
831 sd->params.vlOffset.gain1,
832 sd->params.vlOffset.gain2,
833 sd->params.vlOffset.gain4,
834 sd->params.vlOffset.gain8);
837 static int command_setexposure(struct gspca_dev *gspca_dev)
839 struct sd *sd = (struct sd *) gspca_dev;
840 int ret;
842 ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
843 sd->params.exposure.gainMode,
845 sd->params.exposure.compMode,
846 sd->params.exposure.centreWeight,
847 sd->params.exposure.gain,
848 sd->params.exposure.fineExp,
849 sd->params.exposure.coarseExpLo,
850 sd->params.exposure.coarseExpHi,
851 sd->params.exposure.redComp,
852 sd->params.exposure.green1Comp,
853 sd->params.exposure.green2Comp,
854 sd->params.exposure.blueComp);
855 if (ret)
856 return ret;
858 if (sd->params.exposure.expMode != 1) {
859 ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
861 sd->params.exposure.expMode,
862 0, 0,
863 sd->params.exposure.gain,
864 sd->params.exposure.fineExp,
865 sd->params.exposure.coarseExpLo,
866 sd->params.exposure.coarseExpHi,
867 0, 0, 0, 0);
870 return ret;
873 static int command_setcolourbalance(struct gspca_dev *gspca_dev)
875 struct sd *sd = (struct sd *) gspca_dev;
877 if (sd->params.colourBalance.balanceMode == 1) {
878 int ret;
880 ret = do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
882 sd->params.colourBalance.redGain,
883 sd->params.colourBalance.greenGain,
884 sd->params.colourBalance.blueGain);
885 if (ret)
886 return ret;
888 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
889 3, 0, 0, 0);
891 if (sd->params.colourBalance.balanceMode == 2) {
892 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
893 2, 0, 0, 0);
895 if (sd->params.colourBalance.balanceMode == 3) {
896 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
897 3, 0, 0, 0);
900 return -EINVAL;
903 static int command_setcompressiontarget(struct gspca_dev *gspca_dev)
905 struct sd *sd = (struct sd *) gspca_dev;
907 return do_command(gspca_dev, CPIA_COMMAND_SetCompressionTarget,
908 sd->params.compressionTarget.frTargeting,
909 sd->params.compressionTarget.targetFR,
910 sd->params.compressionTarget.targetQ, 0);
913 static int command_setyuvtresh(struct gspca_dev *gspca_dev)
915 struct sd *sd = (struct sd *) gspca_dev;
917 return do_command(gspca_dev, CPIA_COMMAND_SetYUVThresh,
918 sd->params.yuvThreshold.yThreshold,
919 sd->params.yuvThreshold.uvThreshold, 0, 0);
922 static int command_setcompressionparams(struct gspca_dev *gspca_dev)
924 struct sd *sd = (struct sd *) gspca_dev;
926 return do_command_extended(gspca_dev,
927 CPIA_COMMAND_SetCompressionParams,
928 0, 0, 0, 0,
929 sd->params.compressionParams.hysteresis,
930 sd->params.compressionParams.threshMax,
931 sd->params.compressionParams.smallStep,
932 sd->params.compressionParams.largeStep,
933 sd->params.compressionParams.decimationHysteresis,
934 sd->params.compressionParams.frDiffStepThresh,
935 sd->params.compressionParams.qDiffStepThresh,
936 sd->params.compressionParams.decimationThreshMod);
939 static int command_setcompression(struct gspca_dev *gspca_dev)
941 struct sd *sd = (struct sd *) gspca_dev;
943 return do_command(gspca_dev, CPIA_COMMAND_SetCompression,
944 sd->params.compression.mode,
945 sd->params.compression.decimation, 0, 0);
948 static int command_setsensorfps(struct gspca_dev *gspca_dev)
950 struct sd *sd = (struct sd *) gspca_dev;
952 return do_command(gspca_dev, CPIA_COMMAND_SetSensorFPS,
953 sd->params.sensorFps.divisor,
954 sd->params.sensorFps.baserate, 0, 0);
957 static int command_setflickerctrl(struct gspca_dev *gspca_dev)
959 struct sd *sd = (struct sd *) gspca_dev;
961 return do_command(gspca_dev, CPIA_COMMAND_SetFlickerCtrl,
962 sd->params.flickerControl.flickerMode,
963 sd->params.flickerControl.coarseJump,
964 sd->params.flickerControl.allowableOverExposure,
968 static int command_setecptiming(struct gspca_dev *gspca_dev)
970 struct sd *sd = (struct sd *) gspca_dev;
972 return do_command(gspca_dev, CPIA_COMMAND_SetECPTiming,
973 sd->params.ecpTiming, 0, 0, 0);
976 static int command_pause(struct gspca_dev *gspca_dev)
978 return do_command(gspca_dev, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
981 static int command_resume(struct gspca_dev *gspca_dev)
983 struct sd *sd = (struct sd *) gspca_dev;
985 return do_command(gspca_dev, CPIA_COMMAND_InitStreamCap,
986 0, sd->params.streamStartLine, 0, 0);
989 static int command_setlights(struct gspca_dev *gspca_dev)
991 struct sd *sd = (struct sd *) gspca_dev;
992 int ret, p1, p2;
994 p1 = (sd->params.qx3.bottomlight == 0) << 1;
995 p2 = (sd->params.qx3.toplight == 0) << 3;
997 ret = do_command(gspca_dev, CPIA_COMMAND_WriteVCReg,
998 0x90, 0x8f, 0x50, 0);
999 if (ret)
1000 return ret;
1002 return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0,
1003 p1 | p2 | 0xe0, 0);
1006 static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply)
1008 /* Everything in here is from the Windows driver */
1009 /* define for compgain calculation */
1010 #if 0
1011 #define COMPGAIN(base, curexp, newexp) \
1012 (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
1013 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1014 (u16)((float)curexp * (float)(u8)(curcomp + 128) / \
1015 (float)(u8)(basecomp - 128))
1016 #else
1017 /* equivalent functions without floating point math */
1018 #define COMPGAIN(base, curexp, newexp) \
1019 (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2 * newexp)))
1020 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1021 (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
1022 #endif
1024 struct sd *sd = (struct sd *) gspca_dev;
1025 int currentexp = sd->params.exposure.coarseExpLo +
1026 sd->params.exposure.coarseExpHi * 256;
1027 int ret, startexp;
1029 if (on) {
1030 int cj = sd->params.flickerControl.coarseJump;
1031 sd->params.flickerControl.flickerMode = 1;
1032 sd->params.flickerControl.disabled = 0;
1033 if (sd->params.exposure.expMode != 2) {
1034 sd->params.exposure.expMode = 2;
1035 sd->exposure_status = EXPOSURE_NORMAL;
1037 currentexp = currentexp << sd->params.exposure.gain;
1038 sd->params.exposure.gain = 0;
1039 /* round down current exposure to nearest value */
1040 startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj;
1041 if (startexp < 1)
1042 startexp = 1;
1043 startexp = (startexp * cj) - 1;
1044 if (FIRMWARE_VERSION(1, 2))
1045 while (startexp > MAX_EXP_102)
1046 startexp -= cj;
1047 else
1048 while (startexp > MAX_EXP)
1049 startexp -= cj;
1050 sd->params.exposure.coarseExpLo = startexp & 0xff;
1051 sd->params.exposure.coarseExpHi = startexp >> 8;
1052 if (currentexp > startexp) {
1053 if (currentexp > (2 * startexp))
1054 currentexp = 2 * startexp;
1055 sd->params.exposure.redComp =
1056 COMPGAIN(COMP_RED, currentexp, startexp);
1057 sd->params.exposure.green1Comp =
1058 COMPGAIN(COMP_GREEN1, currentexp, startexp);
1059 sd->params.exposure.green2Comp =
1060 COMPGAIN(COMP_GREEN2, currentexp, startexp);
1061 sd->params.exposure.blueComp =
1062 COMPGAIN(COMP_BLUE, currentexp, startexp);
1063 } else {
1064 sd->params.exposure.redComp = COMP_RED;
1065 sd->params.exposure.green1Comp = COMP_GREEN1;
1066 sd->params.exposure.green2Comp = COMP_GREEN2;
1067 sd->params.exposure.blueComp = COMP_BLUE;
1069 if (FIRMWARE_VERSION(1, 2))
1070 sd->params.exposure.compMode = 0;
1071 else
1072 sd->params.exposure.compMode = 1;
1074 sd->params.apcor.gain1 = 0x18;
1075 sd->params.apcor.gain2 = 0x18;
1076 sd->params.apcor.gain4 = 0x16;
1077 sd->params.apcor.gain8 = 0x14;
1078 } else {
1079 sd->params.flickerControl.flickerMode = 0;
1080 sd->params.flickerControl.disabled = 1;
1081 /* Average equivalent coarse for each comp channel */
1082 startexp = EXP_FROM_COMP(COMP_RED,
1083 sd->params.exposure.redComp, currentexp);
1084 startexp += EXP_FROM_COMP(COMP_GREEN1,
1085 sd->params.exposure.green1Comp, currentexp);
1086 startexp += EXP_FROM_COMP(COMP_GREEN2,
1087 sd->params.exposure.green2Comp, currentexp);
1088 startexp += EXP_FROM_COMP(COMP_BLUE,
1089 sd->params.exposure.blueComp, currentexp);
1090 startexp = startexp >> 2;
1091 while (startexp > MAX_EXP && sd->params.exposure.gain <
1092 sd->params.exposure.gainMode - 1) {
1093 startexp = startexp >> 1;
1094 ++sd->params.exposure.gain;
1096 if (FIRMWARE_VERSION(1, 2) && startexp > MAX_EXP_102)
1097 startexp = MAX_EXP_102;
1098 if (startexp > MAX_EXP)
1099 startexp = MAX_EXP;
1100 sd->params.exposure.coarseExpLo = startexp & 0xff;
1101 sd->params.exposure.coarseExpHi = startexp >> 8;
1102 sd->params.exposure.redComp = COMP_RED;
1103 sd->params.exposure.green1Comp = COMP_GREEN1;
1104 sd->params.exposure.green2Comp = COMP_GREEN2;
1105 sd->params.exposure.blueComp = COMP_BLUE;
1106 sd->params.exposure.compMode = 1;
1107 sd->params.apcor.gain1 = 0x18;
1108 sd->params.apcor.gain2 = 0x16;
1109 sd->params.apcor.gain4 = 0x24;
1110 sd->params.apcor.gain8 = 0x34;
1112 sd->params.vlOffset.gain1 = 20;
1113 sd->params.vlOffset.gain2 = 24;
1114 sd->params.vlOffset.gain4 = 26;
1115 sd->params.vlOffset.gain8 = 26;
1117 if (apply) {
1118 ret = command_setexposure(gspca_dev);
1119 if (ret)
1120 return ret;
1122 ret = command_setapcor(gspca_dev);
1123 if (ret)
1124 return ret;
1126 ret = command_setvloffset(gspca_dev);
1127 if (ret)
1128 return ret;
1130 ret = command_setflickerctrl(gspca_dev);
1131 if (ret)
1132 return ret;
1135 return 0;
1136 #undef EXP_FROM_COMP
1137 #undef COMPGAIN
1140 /* monitor the exposure and adjust the sensor frame rate if needed */
1141 static void monitor_exposure(struct gspca_dev *gspca_dev)
1143 struct sd *sd = (struct sd *) gspca_dev;
1144 u8 exp_acc, bcomp, cmd[8];
1145 int ret, light_exp, dark_exp, very_dark_exp;
1146 int old_exposure, new_exposure, framerate;
1147 int setfps = 0, setexp = 0, setflicker = 0;
1149 /* get necessary stats and register settings from camera */
1150 /* do_command can't handle this, so do it ourselves */
1151 cmd[0] = CPIA_COMMAND_ReadVPRegs >> 8;
1152 cmd[1] = CPIA_COMMAND_ReadVPRegs & 0xff;
1153 cmd[2] = 30;
1154 cmd[3] = 4;
1155 cmd[4] = 9;
1156 cmd[5] = 8;
1157 cmd[6] = 8;
1158 cmd[7] = 0;
1159 ret = cpia_usb_transferCmd(gspca_dev, cmd);
1160 if (ret) {
1161 pr_err("ReadVPRegs(30,4,9,8) - failed: %d\n", ret);
1162 return;
1164 exp_acc = gspca_dev->usb_buf[0];
1165 bcomp = gspca_dev->usb_buf[1];
1167 light_exp = sd->params.colourParams.brightness +
1168 TC - 50 + EXP_ACC_LIGHT;
1169 if (light_exp > 255)
1170 light_exp = 255;
1171 dark_exp = sd->params.colourParams.brightness +
1172 TC - 50 - EXP_ACC_DARK;
1173 if (dark_exp < 0)
1174 dark_exp = 0;
1175 very_dark_exp = dark_exp / 2;
1177 old_exposure = sd->params.exposure.coarseExpHi * 256 +
1178 sd->params.exposure.coarseExpLo;
1180 if (!sd->params.flickerControl.disabled) {
1181 /* Flicker control on */
1182 int max_comp = FIRMWARE_VERSION(1, 2) ? MAX_COMP :
1183 HIGH_COMP_102;
1184 bcomp += 128; /* decode */
1185 if (bcomp >= max_comp && exp_acc < dark_exp) {
1186 /* dark */
1187 if (exp_acc < very_dark_exp) {
1188 /* very dark */
1189 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1190 ++sd->exposure_count;
1191 else {
1192 sd->exposure_status =
1193 EXPOSURE_VERY_DARK;
1194 sd->exposure_count = 1;
1196 } else {
1197 /* just dark */
1198 if (sd->exposure_status == EXPOSURE_DARK)
1199 ++sd->exposure_count;
1200 else {
1201 sd->exposure_status = EXPOSURE_DARK;
1202 sd->exposure_count = 1;
1205 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1206 /* light */
1207 if (old_exposure <= VERY_LOW_EXP) {
1208 /* very light */
1209 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1210 ++sd->exposure_count;
1211 else {
1212 sd->exposure_status =
1213 EXPOSURE_VERY_LIGHT;
1214 sd->exposure_count = 1;
1216 } else {
1217 /* just light */
1218 if (sd->exposure_status == EXPOSURE_LIGHT)
1219 ++sd->exposure_count;
1220 else {
1221 sd->exposure_status = EXPOSURE_LIGHT;
1222 sd->exposure_count = 1;
1225 } else {
1226 /* not dark or light */
1227 sd->exposure_status = EXPOSURE_NORMAL;
1229 } else {
1230 /* Flicker control off */
1231 if (old_exposure >= MAX_EXP && exp_acc < dark_exp) {
1232 /* dark */
1233 if (exp_acc < very_dark_exp) {
1234 /* very dark */
1235 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1236 ++sd->exposure_count;
1237 else {
1238 sd->exposure_status =
1239 EXPOSURE_VERY_DARK;
1240 sd->exposure_count = 1;
1242 } else {
1243 /* just dark */
1244 if (sd->exposure_status == EXPOSURE_DARK)
1245 ++sd->exposure_count;
1246 else {
1247 sd->exposure_status = EXPOSURE_DARK;
1248 sd->exposure_count = 1;
1251 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1252 /* light */
1253 if (old_exposure <= VERY_LOW_EXP) {
1254 /* very light */
1255 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1256 ++sd->exposure_count;
1257 else {
1258 sd->exposure_status =
1259 EXPOSURE_VERY_LIGHT;
1260 sd->exposure_count = 1;
1262 } else {
1263 /* just light */
1264 if (sd->exposure_status == EXPOSURE_LIGHT)
1265 ++sd->exposure_count;
1266 else {
1267 sd->exposure_status = EXPOSURE_LIGHT;
1268 sd->exposure_count = 1;
1271 } else {
1272 /* not dark or light */
1273 sd->exposure_status = EXPOSURE_NORMAL;
1277 framerate = atomic_read(&sd->fps);
1278 if (framerate > 30 || framerate < 1)
1279 framerate = 1;
1281 if (!sd->params.flickerControl.disabled) {
1282 /* Flicker control on */
1283 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1284 sd->exposure_status == EXPOSURE_DARK) &&
1285 sd->exposure_count >= DARK_TIME * framerate &&
1286 sd->params.sensorFps.divisor < 2) {
1288 /* dark for too long */
1289 ++sd->params.sensorFps.divisor;
1290 setfps = 1;
1292 sd->params.flickerControl.coarseJump =
1293 flicker_jumps[sd->mainsFreq]
1294 [sd->params.sensorFps.baserate]
1295 [sd->params.sensorFps.divisor];
1296 setflicker = 1;
1298 new_exposure = sd->params.flickerControl.coarseJump-1;
1299 while (new_exposure < old_exposure / 2)
1300 new_exposure +=
1301 sd->params.flickerControl.coarseJump;
1302 sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1303 sd->params.exposure.coarseExpHi = new_exposure >> 8;
1304 setexp = 1;
1305 sd->exposure_status = EXPOSURE_NORMAL;
1306 PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
1308 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1309 sd->exposure_status == EXPOSURE_LIGHT) &&
1310 sd->exposure_count >= LIGHT_TIME * framerate &&
1311 sd->params.sensorFps.divisor > 0) {
1313 /* light for too long */
1314 int max_exp = FIRMWARE_VERSION(1, 2) ? MAX_EXP_102 :
1315 MAX_EXP;
1316 --sd->params.sensorFps.divisor;
1317 setfps = 1;
1319 sd->params.flickerControl.coarseJump =
1320 flicker_jumps[sd->mainsFreq]
1321 [sd->params.sensorFps.baserate]
1322 [sd->params.sensorFps.divisor];
1323 setflicker = 1;
1325 new_exposure = sd->params.flickerControl.coarseJump-1;
1326 while (new_exposure < 2 * old_exposure &&
1327 new_exposure +
1328 sd->params.flickerControl.coarseJump < max_exp)
1329 new_exposure +=
1330 sd->params.flickerControl.coarseJump;
1331 sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1332 sd->params.exposure.coarseExpHi = new_exposure >> 8;
1333 setexp = 1;
1334 sd->exposure_status = EXPOSURE_NORMAL;
1335 PDEBUG(D_CONF, "Automatically increasing sensor_fps");
1337 } else {
1338 /* Flicker control off */
1339 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1340 sd->exposure_status == EXPOSURE_DARK) &&
1341 sd->exposure_count >= DARK_TIME * framerate &&
1342 sd->params.sensorFps.divisor < 2) {
1344 /* dark for too long */
1345 ++sd->params.sensorFps.divisor;
1346 setfps = 1;
1348 if (sd->params.exposure.gain > 0) {
1349 --sd->params.exposure.gain;
1350 setexp = 1;
1352 sd->exposure_status = EXPOSURE_NORMAL;
1353 PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
1355 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1356 sd->exposure_status == EXPOSURE_LIGHT) &&
1357 sd->exposure_count >= LIGHT_TIME * framerate &&
1358 sd->params.sensorFps.divisor > 0) {
1360 /* light for too long */
1361 --sd->params.sensorFps.divisor;
1362 setfps = 1;
1364 if (sd->params.exposure.gain <
1365 sd->params.exposure.gainMode - 1) {
1366 ++sd->params.exposure.gain;
1367 setexp = 1;
1369 sd->exposure_status = EXPOSURE_NORMAL;
1370 PDEBUG(D_CONF, "Automatically increasing sensor_fps");
1374 if (setexp)
1375 command_setexposure(gspca_dev);
1377 if (setfps)
1378 command_setsensorfps(gspca_dev);
1380 if (setflicker)
1381 command_setflickerctrl(gspca_dev);
1384 /*-----------------------------------------------------------------*/
1385 /* if flicker is switched off, this function switches it back on.It checks,
1386 however, that conditions are suitable before restarting it.
1387 This should only be called for firmware version 1.2.
1389 It also adjust the colour balance when an exposure step is detected - as
1390 long as flicker is running
1392 static void restart_flicker(struct gspca_dev *gspca_dev)
1394 struct sd *sd = (struct sd *) gspca_dev;
1395 int cam_exposure, old_exp;
1397 if (!FIRMWARE_VERSION(1, 2))
1398 return;
1400 cam_exposure = atomic_read(&sd->cam_exposure);
1402 if (sd->params.flickerControl.flickerMode == 0 ||
1403 cam_exposure == 0)
1404 return;
1406 old_exp = sd->params.exposure.coarseExpLo +
1407 sd->params.exposure.coarseExpHi*256;
1409 see how far away camera exposure is from a valid
1410 flicker exposure value
1412 cam_exposure %= sd->params.flickerControl.coarseJump;
1413 if (!sd->params.flickerControl.disabled &&
1414 cam_exposure <= sd->params.flickerControl.coarseJump - 3) {
1415 /* Flicker control auto-disabled */
1416 sd->params.flickerControl.disabled = 1;
1419 if (sd->params.flickerControl.disabled &&
1420 old_exp > sd->params.flickerControl.coarseJump +
1421 ROUND_UP_EXP_FOR_FLICKER) {
1422 /* exposure is now high enough to switch
1423 flicker control back on */
1424 set_flicker(gspca_dev, 1, 1);
1428 /* this function is called at probe time */
1429 static int sd_config(struct gspca_dev *gspca_dev,
1430 const struct usb_device_id *id)
1432 struct sd *sd = (struct sd *) gspca_dev;
1433 struct cam *cam;
1435 sd->mainsFreq = FREQ_DEF == V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
1436 reset_camera_params(gspca_dev);
1438 PDEBUG(D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)",
1439 id->idVendor, id->idProduct);
1441 cam = &gspca_dev->cam;
1442 cam->cam_mode = mode;
1443 cam->nmodes = ARRAY_SIZE(mode);
1445 goto_low_power(gspca_dev);
1446 /* Check the firmware version. */
1447 sd->params.version.firmwareVersion = 0;
1448 get_version_information(gspca_dev);
1449 if (sd->params.version.firmwareVersion != 1) {
1450 PERR("only firmware version 1 is supported (got: %d)",
1451 sd->params.version.firmwareVersion);
1452 return -ENODEV;
1455 /* A bug in firmware 1-02 limits gainMode to 2 */
1456 if (sd->params.version.firmwareRevision <= 2 &&
1457 sd->params.exposure.gainMode > 2) {
1458 sd->params.exposure.gainMode = 2;
1461 /* set QX3 detected flag */
1462 sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 &&
1463 sd->params.pnpID.product == 0x0001);
1464 return 0;
1467 /* -- start the camera -- */
1468 static int sd_start(struct gspca_dev *gspca_dev)
1470 struct sd *sd = (struct sd *) gspca_dev;
1471 int priv, ret;
1473 /* Start the camera in low power mode */
1474 if (goto_low_power(gspca_dev)) {
1475 if (sd->params.status.systemState != WARM_BOOT_STATE) {
1476 PERR("unexpected systemstate: %02x",
1477 sd->params.status.systemState);
1478 printstatus(gspca_dev, &sd->params);
1479 return -ENODEV;
1482 /* FIXME: this is just dirty trial and error */
1483 ret = goto_high_power(gspca_dev);
1484 if (ret)
1485 return ret;
1487 ret = do_command(gspca_dev, CPIA_COMMAND_DiscardFrame,
1488 0, 0, 0, 0);
1489 if (ret)
1490 return ret;
1492 ret = goto_low_power(gspca_dev);
1493 if (ret)
1494 return ret;
1497 /* procedure described in developer's guide p3-28 */
1499 /* Check the firmware version. */
1500 sd->params.version.firmwareVersion = 0;
1501 get_version_information(gspca_dev);
1503 /* The fatal error checking should be done after
1504 * the camera powers up (developer's guide p 3-38) */
1506 /* Set streamState before transition to high power to avoid bug
1507 * in firmware 1-02 */
1508 ret = do_command(gspca_dev, CPIA_COMMAND_ModifyCameraStatus,
1509 STREAMSTATE, 0, STREAM_NOT_READY, 0);
1510 if (ret)
1511 return ret;
1513 /* GotoHiPower */
1514 ret = goto_high_power(gspca_dev);
1515 if (ret)
1516 return ret;
1518 /* Check the camera status */
1519 ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1520 if (ret)
1521 return ret;
1523 if (sd->params.status.fatalError) {
1524 PERR("fatal_error: %04x, vp_status: %04x",
1525 sd->params.status.fatalError, sd->params.status.vpStatus);
1526 return -EIO;
1529 /* VPVersion can't be retrieved before the camera is in HiPower,
1530 * so get it here instead of in get_version_information. */
1531 ret = do_command(gspca_dev, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0);
1532 if (ret)
1533 return ret;
1535 /* Determine video mode settings */
1536 sd->params.streamStartLine = 120;
1538 priv = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1539 if (priv & 0x01) { /* crop */
1540 sd->params.roi.colStart = 2;
1541 sd->params.roi.rowStart = 6;
1542 } else {
1543 sd->params.roi.colStart = 0;
1544 sd->params.roi.rowStart = 0;
1547 if (priv & 0x02) { /* quarter */
1548 sd->params.format.videoSize = VIDEOSIZE_QCIF;
1549 sd->params.roi.colStart /= 2;
1550 sd->params.roi.rowStart /= 2;
1551 sd->params.streamStartLine /= 2;
1552 } else
1553 sd->params.format.videoSize = VIDEOSIZE_CIF;
1555 sd->params.roi.colEnd = sd->params.roi.colStart +
1556 (gspca_dev->pixfmt.width >> 3);
1557 sd->params.roi.rowEnd = sd->params.roi.rowStart +
1558 (gspca_dev->pixfmt.height >> 2);
1560 /* And now set the camera to a known state */
1561 ret = do_command(gspca_dev, CPIA_COMMAND_SetGrabMode,
1562 CPIA_GRAB_CONTINEOUS, 0, 0, 0);
1563 if (ret)
1564 return ret;
1565 /* We start with compression disabled, as we need one uncompressed
1566 frame to handle later compressed frames */
1567 ret = do_command(gspca_dev, CPIA_COMMAND_SetCompression,
1568 CPIA_COMPRESSION_NONE,
1569 NO_DECIMATION, 0, 0);
1570 if (ret)
1571 return ret;
1572 ret = command_setcompressiontarget(gspca_dev);
1573 if (ret)
1574 return ret;
1575 ret = command_setcolourparams(gspca_dev);
1576 if (ret)
1577 return ret;
1578 ret = command_setformat(gspca_dev);
1579 if (ret)
1580 return ret;
1581 ret = command_setyuvtresh(gspca_dev);
1582 if (ret)
1583 return ret;
1584 ret = command_setecptiming(gspca_dev);
1585 if (ret)
1586 return ret;
1587 ret = command_setcompressionparams(gspca_dev);
1588 if (ret)
1589 return ret;
1590 ret = command_setexposure(gspca_dev);
1591 if (ret)
1592 return ret;
1593 ret = command_setcolourbalance(gspca_dev);
1594 if (ret)
1595 return ret;
1596 ret = command_setsensorfps(gspca_dev);
1597 if (ret)
1598 return ret;
1599 ret = command_setapcor(gspca_dev);
1600 if (ret)
1601 return ret;
1602 ret = command_setflickerctrl(gspca_dev);
1603 if (ret)
1604 return ret;
1605 ret = command_setvloffset(gspca_dev);
1606 if (ret)
1607 return ret;
1609 /* Start stream */
1610 ret = command_resume(gspca_dev);
1611 if (ret)
1612 return ret;
1614 /* Wait 6 frames before turning compression on for the sensor to get
1615 all settings and AEC/ACB to settle */
1616 sd->first_frame = 6;
1617 sd->exposure_status = EXPOSURE_NORMAL;
1618 sd->exposure_count = 0;
1619 atomic_set(&sd->cam_exposure, 0);
1620 atomic_set(&sd->fps, 0);
1622 return 0;
1625 static void sd_stopN(struct gspca_dev *gspca_dev)
1627 struct sd *sd = (struct sd *) gspca_dev;
1629 command_pause(gspca_dev);
1631 /* save camera state for later open (developers guide ch 3.5.3) */
1632 save_camera_state(gspca_dev);
1634 /* GotoLoPower */
1635 goto_low_power(gspca_dev);
1637 /* Update the camera status */
1638 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1640 #if IS_ENABLED(CONFIG_INPUT)
1641 /* If the last button state is pressed, release it now! */
1642 if (sd->params.qx3.button) {
1643 /* The camera latch will hold the pressed state until we reset
1644 the latch, so we do not reset sd->params.qx3.button now, to
1645 avoid a false keypress being reported the next sd_start */
1646 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1647 input_sync(gspca_dev->input_dev);
1649 #endif
1652 /* this function is called at probe and resume time */
1653 static int sd_init(struct gspca_dev *gspca_dev)
1655 struct sd *sd = (struct sd *) gspca_dev;
1656 int ret;
1658 /* Start / Stop the camera to make sure we are talking to
1659 a supported camera, and to get some information from it
1660 to print. */
1661 ret = sd_start(gspca_dev);
1662 if (ret)
1663 return ret;
1665 /* Ensure the QX3 illuminators' states are restored upon resume,
1666 or disable the illuminator controls, if this isn't a QX3 */
1667 if (sd->params.qx3.qx3_detected)
1668 command_setlights(gspca_dev);
1670 sd_stopN(gspca_dev);
1672 PDEBUG(D_PROBE, "CPIA Version: %d.%02d (%d.%d)",
1673 sd->params.version.firmwareVersion,
1674 sd->params.version.firmwareRevision,
1675 sd->params.version.vcVersion,
1676 sd->params.version.vcRevision);
1677 PDEBUG(D_PROBE, "CPIA PnP-ID: %04x:%04x:%04x",
1678 sd->params.pnpID.vendor, sd->params.pnpID.product,
1679 sd->params.pnpID.deviceRevision);
1680 PDEBUG(D_PROBE, "VP-Version: %d.%d %04x",
1681 sd->params.vpVersion.vpVersion,
1682 sd->params.vpVersion.vpRevision,
1683 sd->params.vpVersion.cameraHeadID);
1685 return 0;
1688 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1689 u8 *data,
1690 int len)
1692 struct sd *sd = (struct sd *) gspca_dev;
1694 /* Check for SOF */
1695 if (len >= 64 &&
1696 data[0] == MAGIC_0 && data[1] == MAGIC_1 &&
1697 data[16] == sd->params.format.videoSize &&
1698 data[17] == sd->params.format.subSample &&
1699 data[18] == sd->params.format.yuvOrder &&
1700 data[24] == sd->params.roi.colStart &&
1701 data[25] == sd->params.roi.colEnd &&
1702 data[26] == sd->params.roi.rowStart &&
1703 data[27] == sd->params.roi.rowEnd) {
1704 u8 *image;
1706 atomic_set(&sd->cam_exposure, data[39] * 2);
1707 atomic_set(&sd->fps, data[41]);
1709 /* Check for proper EOF for last frame */
1710 image = gspca_dev->image;
1711 if (image != NULL &&
1712 gspca_dev->image_len > 4 &&
1713 image[gspca_dev->image_len - 4] == 0xff &&
1714 image[gspca_dev->image_len - 3] == 0xff &&
1715 image[gspca_dev->image_len - 2] == 0xff &&
1716 image[gspca_dev->image_len - 1] == 0xff)
1717 gspca_frame_add(gspca_dev, LAST_PACKET,
1718 NULL, 0);
1720 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
1721 return;
1724 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1727 static void sd_dq_callback(struct gspca_dev *gspca_dev)
1729 struct sd *sd = (struct sd *) gspca_dev;
1731 /* Set the normal compression settings once we have captured a
1732 few uncompressed frames (and AEC has hopefully settled) */
1733 if (sd->first_frame) {
1734 sd->first_frame--;
1735 if (sd->first_frame == 0)
1736 command_setcompression(gspca_dev);
1739 /* Switch flicker control back on if it got turned off */
1740 restart_flicker(gspca_dev);
1742 /* If AEC is enabled, monitor the exposure and
1743 adjust the sensor frame rate if needed */
1744 if (sd->params.exposure.expMode == 2)
1745 monitor_exposure(gspca_dev);
1747 /* Update our knowledge of the camera state */
1748 do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
1749 do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
1752 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1754 struct gspca_dev *gspca_dev =
1755 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1756 struct sd *sd = (struct sd *)gspca_dev;
1758 gspca_dev->usb_err = 0;
1760 if (!gspca_dev->streaming && ctrl->id != V4L2_CID_POWER_LINE_FREQUENCY)
1761 return 0;
1763 switch (ctrl->id) {
1764 case V4L2_CID_BRIGHTNESS:
1765 sd->params.colourParams.brightness = ctrl->val;
1766 sd->params.flickerControl.allowableOverExposure =
1767 find_over_exposure(sd->params.colourParams.brightness);
1768 gspca_dev->usb_err = command_setcolourparams(gspca_dev);
1769 if (!gspca_dev->usb_err)
1770 gspca_dev->usb_err = command_setflickerctrl(gspca_dev);
1771 break;
1772 case V4L2_CID_CONTRAST:
1773 sd->params.colourParams.contrast = ctrl->val;
1774 gspca_dev->usb_err = command_setcolourparams(gspca_dev);
1775 break;
1776 case V4L2_CID_SATURATION:
1777 sd->params.colourParams.saturation = ctrl->val;
1778 gspca_dev->usb_err = command_setcolourparams(gspca_dev);
1779 break;
1780 case V4L2_CID_POWER_LINE_FREQUENCY:
1781 sd->mainsFreq = ctrl->val == V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
1782 sd->params.flickerControl.coarseJump =
1783 flicker_jumps[sd->mainsFreq]
1784 [sd->params.sensorFps.baserate]
1785 [sd->params.sensorFps.divisor];
1787 gspca_dev->usb_err = set_flicker(gspca_dev,
1788 ctrl->val != V4L2_CID_POWER_LINE_FREQUENCY_DISABLED,
1789 gspca_dev->streaming);
1790 break;
1791 case V4L2_CID_ILLUMINATORS_1:
1792 sd->params.qx3.bottomlight = ctrl->val;
1793 gspca_dev->usb_err = command_setlights(gspca_dev);
1794 break;
1795 case V4L2_CID_ILLUMINATORS_2:
1796 sd->params.qx3.toplight = ctrl->val;
1797 gspca_dev->usb_err = command_setlights(gspca_dev);
1798 break;
1799 case CPIA1_CID_COMP_TARGET:
1800 sd->params.compressionTarget.frTargeting = ctrl->val;
1801 gspca_dev->usb_err = command_setcompressiontarget(gspca_dev);
1802 break;
1804 return gspca_dev->usb_err;
1807 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1808 .s_ctrl = sd_s_ctrl,
1811 static int sd_init_controls(struct gspca_dev *gspca_dev)
1813 struct sd *sd = (struct sd *)gspca_dev;
1814 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1815 static const char * const comp_target_menu[] = {
1816 "Quality",
1817 "Framerate",
1818 NULL
1820 static const struct v4l2_ctrl_config comp_target = {
1821 .ops = &sd_ctrl_ops,
1822 .id = CPIA1_CID_COMP_TARGET,
1823 .type = V4L2_CTRL_TYPE_MENU,
1824 .name = "Compression Target",
1825 .qmenu = comp_target_menu,
1826 .max = 1,
1827 .def = COMP_TARGET_DEF,
1830 gspca_dev->vdev.ctrl_handler = hdl;
1831 v4l2_ctrl_handler_init(hdl, 7);
1832 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1833 V4L2_CID_BRIGHTNESS, 0, 100, 1, BRIGHTNESS_DEF);
1834 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1835 V4L2_CID_CONTRAST, 0, 96, 8, CONTRAST_DEF);
1836 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1837 V4L2_CID_SATURATION, 0, 100, 1, SATURATION_DEF);
1838 sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
1839 V4L2_CID_POWER_LINE_FREQUENCY,
1840 V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
1841 FREQ_DEF);
1842 if (sd->params.qx3.qx3_detected) {
1843 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1844 V4L2_CID_ILLUMINATORS_1, 0, 1, 1,
1845 ILLUMINATORS_1_DEF);
1846 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1847 V4L2_CID_ILLUMINATORS_2, 0, 1, 1,
1848 ILLUMINATORS_2_DEF);
1850 v4l2_ctrl_new_custom(hdl, &comp_target, NULL);
1852 if (hdl->error) {
1853 pr_err("Could not initialize controls\n");
1854 return hdl->error;
1856 return 0;
1859 /* sub-driver description */
1860 static const struct sd_desc sd_desc = {
1861 .name = MODULE_NAME,
1862 .config = sd_config,
1863 .init = sd_init,
1864 .init_controls = sd_init_controls,
1865 .start = sd_start,
1866 .stopN = sd_stopN,
1867 .dq_callback = sd_dq_callback,
1868 .pkt_scan = sd_pkt_scan,
1869 #if IS_ENABLED(CONFIG_INPUT)
1870 .other_input = 1,
1871 #endif
1874 /* -- module initialisation -- */
1875 static const struct usb_device_id device_table[] = {
1876 {USB_DEVICE(0x0553, 0x0002)},
1877 {USB_DEVICE(0x0813, 0x0001)},
1880 MODULE_DEVICE_TABLE(usb, device_table);
1882 /* -- device connect -- */
1883 static int sd_probe(struct usb_interface *intf,
1884 const struct usb_device_id *id)
1886 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1887 THIS_MODULE);
1890 static struct usb_driver sd_driver = {
1891 .name = MODULE_NAME,
1892 .id_table = device_table,
1893 .probe = sd_probe,
1894 .disconnect = gspca_disconnect,
1895 #ifdef CONFIG_PM
1896 .suspend = gspca_suspend,
1897 .resume = gspca_resume,
1898 .reset_resume = gspca_resume,
1899 #endif
1902 module_usb_driver(sd_driver);