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