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