This source file includes following definitions.
- cpia_usb_transferCmd
- do_command
- do_command_extended
- find_over_exposure
- reset_camera_params
- printstatus
- goto_low_power
- goto_high_power
- get_version_information
- save_camera_state
- command_setformat
- command_setcolourparams
- command_setapcor
- command_setvloffset
- command_setexposure
- command_setcolourbalance
- command_setcompressiontarget
- command_setyuvtresh
- command_setcompressionparams
- command_setcompression
- command_setsensorfps
- command_setflickerctrl
- command_setecptiming
- command_pause
- command_resume
- command_setlights
- set_flicker
- monitor_exposure
- restart_flicker
- sd_config
- sd_start
- sd_stopN
- sd_init
- sd_pkt_scan
- sd_dq_callback
- sd_s_ctrl
- sd_init_controls
- sd_probe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16
17 #define MODULE_NAME "cpia1"
18
19 #include <linux/input.h>
20 #include <linux/sched/signal.h>
21
22 #include "gspca.h"
23
24 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
25 MODULE_DESCRIPTION("Vision CPiA");
26 MODULE_LICENSE("GPL");
27
28
29 #define MAGIC_0 0x19
30 #define MAGIC_1 0x68
31 #define DATA_IN 0xc0
32 #define DATA_OUT 0x40
33 #define VIDEOSIZE_QCIF 0
34 #define VIDEOSIZE_CIF 1
35 #define SUBSAMPLE_420 0
36 #define SUBSAMPLE_422 1
37 #define YUVORDER_YUYV 0
38 #define YUVORDER_UYVY 1
39 #define NOT_COMPRESSED 0
40 #define COMPRESSED 1
41 #define NO_DECIMATION 0
42 #define DECIMATION_ENAB 1
43 #define EOI 0xff
44 #define EOL 0xfd
45 #define FRAME_HEADER_SIZE 64
46
47
48 #define CPIA_GRAB_SINGLE 0
49 #define CPIA_GRAB_CONTINEOUS 1
50
51
52 #define CPIA_COMPRESSION_NONE 0
53 #define CPIA_COMPRESSION_AUTO 1
54 #define CPIA_COMPRESSION_MANUAL 2
55 #define CPIA_COMPRESSION_TARGET_QUALITY 0
56 #define CPIA_COMPRESSION_TARGET_FRAMERATE 1
57
58
59 #define SYSTEMSTATE 0
60 #define GRABSTATE 1
61 #define STREAMSTATE 2
62 #define FATALERROR 3
63 #define CMDERROR 4
64 #define DEBUGFLAGS 5
65 #define VPSTATUS 6
66 #define ERRORCODE 7
67
68
69 #define UNINITIALISED_STATE 0
70 #define PASS_THROUGH_STATE 1
71 #define LO_POWER_STATE 2
72 #define HI_POWER_STATE 3
73 #define WARM_BOOT_STATE 4
74
75
76 #define GRAB_IDLE 0
77 #define GRAB_ACTIVE 1
78 #define GRAB_DONE 2
79
80
81 #define STREAM_NOT_READY 0
82 #define STREAM_READY 1
83 #define STREAM_OPEN 2
84 #define STREAM_PAUSED 3
85 #define STREAM_FINISHED 4
86
87
88 #define CPIA_FLAG 1
89 #define SYSTEM_FLAG 2
90 #define INT_CTRL_FLAG 4
91 #define PROCESS_FLAG 8
92 #define COM_FLAG 16
93 #define VP_CTRL_FLAG 32
94 #define CAPTURE_FLAG 64
95 #define DEBUG_FLAG 128
96
97
98 #define VP_STATE_OK 0x00
99
100 #define VP_STATE_FAILED_VIDEOINIT 0x01
101 #define VP_STATE_FAILED_AECACBINIT 0x02
102 #define VP_STATE_AEC_MAX 0x04
103 #define VP_STATE_ACB_BMAX 0x08
104
105 #define VP_STATE_ACB_RMIN 0x10
106 #define VP_STATE_ACB_GMIN 0x20
107 #define VP_STATE_ACB_RMAX 0x40
108 #define VP_STATE_ACB_GMAX 0x80
109
110
111 #define COMP_RED 220
112 #define COMP_GREEN1 214
113 #define COMP_GREEN2 COMP_GREEN1
114 #define COMP_BLUE 230
115
116
117 #define EXPOSURE_VERY_LIGHT 0
118 #define EXPOSURE_LIGHT 1
119 #define EXPOSURE_NORMAL 2
120 #define EXPOSURE_DARK 3
121 #define EXPOSURE_VERY_DARK 4
122
123 #define CPIA_MODULE_CPIA (0 << 5)
124 #define CPIA_MODULE_SYSTEM (1 << 5)
125 #define CPIA_MODULE_VP_CTRL (5 << 5)
126 #define CPIA_MODULE_CAPTURE (6 << 5)
127 #define CPIA_MODULE_DEBUG (7 << 5)
128
129 #define INPUT (DATA_IN << 8)
130 #define OUTPUT (DATA_OUT << 8)
131
132 #define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)
133 #define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)
134 #define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)
135 #define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)
136 #define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)
137 #define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)
138 #define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)
139 #define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)
140
141 #define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)
142 #define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)
143 #define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)
144 #define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)
145 #define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)
146 #define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)
147 #define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)
148 #define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)
149 #define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)
150 #define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)
151 #define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)
152 #define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)
153 #define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
154
155 #define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
156 #define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)
157 #define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
158 #define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
159 #define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
160 #define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)
161 #define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)
162 #define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)
163 #define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)
164 #define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)
165 #define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)
166 #define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)
167 #define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)
168 #define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)
169 #define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)
170 #define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)
171 #define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)
172
173 #define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)
174 #define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)
175 #define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)
176 #define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)
177 #define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)
178 #define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)
179 #define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)
180 #define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)
181 #define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)
182 #define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)
183 #define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
184 #define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
185 #define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
186 #define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
187 #define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)
188
189 #define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
190 #define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
191 #define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)
192 #define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)
193 #define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
194 #define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
195 #define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
196 #define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)
197
198 #define ROUND_UP_EXP_FOR_FLICKER 15
199
200
201 #define MAX_EXP 302
202 #define MAX_EXP_102 255
203 #define LOW_EXP 140
204 #define VERY_LOW_EXP 70
205 #define TC 94
206 #define EXP_ACC_DARK 50
207 #define EXP_ACC_LIGHT 90
208 #define HIGH_COMP_102 160
209 #define MAX_COMP 239
210 #define DARK_TIME 3
211 #define LIGHT_TIME 3
212
213 #define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \
214 sd->params.version.firmwareRevision == (y))
215
216 #define CPIA1_CID_COMP_TARGET (V4L2_CTRL_CLASS_USER + 0x1000)
217 #define BRIGHTNESS_DEF 50
218 #define CONTRAST_DEF 48
219 #define SATURATION_DEF 50
220 #define FREQ_DEF V4L2_CID_POWER_LINE_FREQUENCY_50HZ
221 #define ILLUMINATORS_1_DEF 0
222 #define ILLUMINATORS_2_DEF 0
223 #define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY
224
225
226
227 static u8 flicker_jumps[2][2][4] =
228 { { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
229 { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
230 };
231
232 struct cam_params {
233 struct {
234 u8 firmwareVersion;
235 u8 firmwareRevision;
236 u8 vcVersion;
237 u8 vcRevision;
238 } version;
239 struct {
240 u16 vendor;
241 u16 product;
242 u16 deviceRevision;
243 } pnpID;
244 struct {
245 u8 vpVersion;
246 u8 vpRevision;
247 u16 cameraHeadID;
248 } vpVersion;
249 struct {
250 u8 systemState;
251 u8 grabState;
252 u8 streamState;
253 u8 fatalError;
254 u8 cmdError;
255 u8 debugFlags;
256 u8 vpStatus;
257 u8 errorCode;
258 } status;
259 struct {
260 u8 brightness;
261 u8 contrast;
262 u8 saturation;
263 } colourParams;
264 struct {
265 u8 gainMode;
266 u8 expMode;
267 u8 compMode;
268 u8 centreWeight;
269 u8 gain;
270 u8 fineExp;
271 u8 coarseExpLo;
272 u8 coarseExpHi;
273 u8 redComp;
274 u8 green1Comp;
275 u8 green2Comp;
276 u8 blueComp;
277 } exposure;
278 struct {
279 u8 balanceMode;
280 u8 redGain;
281 u8 greenGain;
282 u8 blueGain;
283 } colourBalance;
284 struct {
285 u8 divisor;
286 u8 baserate;
287 } sensorFps;
288 struct {
289 u8 gain1;
290 u8 gain2;
291 u8 gain4;
292 u8 gain8;
293 } apcor;
294 struct {
295 u8 disabled;
296 u8 flickerMode;
297 u8 coarseJump;
298 u8 allowableOverExposure;
299 } flickerControl;
300 struct {
301 u8 gain1;
302 u8 gain2;
303 u8 gain4;
304 u8 gain8;
305 } vlOffset;
306 struct {
307 u8 mode;
308 u8 decimation;
309 } compression;
310 struct {
311 u8 frTargeting;
312 u8 targetFR;
313 u8 targetQ;
314 } compressionTarget;
315 struct {
316 u8 yThreshold;
317 u8 uvThreshold;
318 } yuvThreshold;
319 struct {
320 u8 hysteresis;
321 u8 threshMax;
322 u8 smallStep;
323 u8 largeStep;
324 u8 decimationHysteresis;
325 u8 frDiffStepThresh;
326 u8 qDiffStepThresh;
327 u8 decimationThreshMod;
328 } compressionParams;
329 struct {
330 u8 videoSize;
331 u8 subSample;
332 u8 yuvOrder;
333 } format;
334 struct {
335 u8 qx3_detected;
336 u8 toplight;
337 u8 bottomlight;
338 u8 button;
339 u8 cradled;
340 } qx3;
341 struct {
342 u8 colStart;
343 u8 colEnd;
344 u8 rowStart;
345 u8 rowEnd;
346 } roi;
347 u8 ecpTiming;
348 u8 streamStartLine;
349 };
350
351
352 struct sd {
353 struct gspca_dev gspca_dev;
354 struct cam_params params;
355
356 atomic_t cam_exposure;
357 atomic_t fps;
358 int exposure_count;
359 u8 exposure_status;
360 struct v4l2_ctrl *freq;
361 u8 mainsFreq;
362 u8 first_frame;
363 };
364
365 static const struct v4l2_pix_format mode[] = {
366 {160, 120, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
367
368
369
370 .bytesperline = 160,
371 .sizeimage = 65536,
372 .colorspace = V4L2_COLORSPACE_SRGB,
373 .priv = 3},
374 {176, 144, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
375 .bytesperline = 172,
376 .sizeimage = 65536,
377 .colorspace = V4L2_COLORSPACE_SRGB,
378 .priv = 2},
379 {320, 240, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
380 .bytesperline = 320,
381 .sizeimage = 262144,
382 .colorspace = V4L2_COLORSPACE_SRGB,
383 .priv = 1},
384 {352, 288, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
385 .bytesperline = 352,
386 .sizeimage = 262144,
387 .colorspace = V4L2_COLORSPACE_SRGB,
388 .priv = 0},
389 };
390
391
392
393
394
395
396
397 static int cpia_usb_transferCmd(struct gspca_dev *gspca_dev, u8 *command)
398 {
399 u8 requesttype;
400 unsigned int pipe;
401 int ret, databytes = command[6] | (command[7] << 8);
402
403 int retries = 3;
404
405 if (command[0] == DATA_IN) {
406 pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
407 requesttype = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
408 } else if (command[0] == DATA_OUT) {
409 pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
410 requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE;
411 } else {
412 gspca_err(gspca_dev, "Unexpected first byte of command: %x\n",
413 command[0]);
414 return -EINVAL;
415 }
416
417 retry:
418 ret = usb_control_msg(gspca_dev->dev, pipe,
419 command[1],
420 requesttype,
421 command[2] | (command[3] << 8),
422 command[4] | (command[5] << 8),
423 gspca_dev->usb_buf, databytes, 1000);
424
425 if (ret < 0)
426 pr_err("usb_control_msg %02x, error %d\n", command[1], ret);
427
428 if (ret == -EPIPE && retries > 0) {
429 retries--;
430 goto retry;
431 }
432
433 return (ret < 0) ? ret : 0;
434 }
435
436
437 static int do_command(struct gspca_dev *gspca_dev, u16 command,
438 u8 a, u8 b, u8 c, u8 d)
439 {
440 struct sd *sd = (struct sd *) gspca_dev;
441 int ret, datasize;
442 u8 cmd[8];
443
444 switch (command) {
445 case CPIA_COMMAND_GetCPIAVersion:
446 case CPIA_COMMAND_GetPnPID:
447 case CPIA_COMMAND_GetCameraStatus:
448 case CPIA_COMMAND_GetVPVersion:
449 case CPIA_COMMAND_GetColourParams:
450 case CPIA_COMMAND_GetColourBalance:
451 case CPIA_COMMAND_GetExposure:
452 datasize = 8;
453 break;
454 case CPIA_COMMAND_ReadMCPorts:
455 case CPIA_COMMAND_ReadVCRegs:
456 datasize = 4;
457 break;
458 default:
459 datasize = 0;
460 break;
461 }
462
463 cmd[0] = command >> 8;
464 cmd[1] = command & 0xff;
465 cmd[2] = a;
466 cmd[3] = b;
467 cmd[4] = c;
468 cmd[5] = d;
469 cmd[6] = datasize;
470 cmd[7] = 0;
471
472 ret = cpia_usb_transferCmd(gspca_dev, cmd);
473 if (ret)
474 return ret;
475
476 switch (command) {
477 case CPIA_COMMAND_GetCPIAVersion:
478 sd->params.version.firmwareVersion = gspca_dev->usb_buf[0];
479 sd->params.version.firmwareRevision = gspca_dev->usb_buf[1];
480 sd->params.version.vcVersion = gspca_dev->usb_buf[2];
481 sd->params.version.vcRevision = gspca_dev->usb_buf[3];
482 break;
483 case CPIA_COMMAND_GetPnPID:
484 sd->params.pnpID.vendor =
485 gspca_dev->usb_buf[0] | (gspca_dev->usb_buf[1] << 8);
486 sd->params.pnpID.product =
487 gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
488 sd->params.pnpID.deviceRevision =
489 gspca_dev->usb_buf[4] | (gspca_dev->usb_buf[5] << 8);
490 break;
491 case CPIA_COMMAND_GetCameraStatus:
492 sd->params.status.systemState = gspca_dev->usb_buf[0];
493 sd->params.status.grabState = gspca_dev->usb_buf[1];
494 sd->params.status.streamState = gspca_dev->usb_buf[2];
495 sd->params.status.fatalError = gspca_dev->usb_buf[3];
496 sd->params.status.cmdError = gspca_dev->usb_buf[4];
497 sd->params.status.debugFlags = gspca_dev->usb_buf[5];
498 sd->params.status.vpStatus = gspca_dev->usb_buf[6];
499 sd->params.status.errorCode = gspca_dev->usb_buf[7];
500 break;
501 case CPIA_COMMAND_GetVPVersion:
502 sd->params.vpVersion.vpVersion = gspca_dev->usb_buf[0];
503 sd->params.vpVersion.vpRevision = gspca_dev->usb_buf[1];
504 sd->params.vpVersion.cameraHeadID =
505 gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
506 break;
507 case CPIA_COMMAND_GetColourParams:
508 sd->params.colourParams.brightness = gspca_dev->usb_buf[0];
509 sd->params.colourParams.contrast = gspca_dev->usb_buf[1];
510 sd->params.colourParams.saturation = gspca_dev->usb_buf[2];
511 break;
512 case CPIA_COMMAND_GetColourBalance:
513 sd->params.colourBalance.redGain = gspca_dev->usb_buf[0];
514 sd->params.colourBalance.greenGain = gspca_dev->usb_buf[1];
515 sd->params.colourBalance.blueGain = gspca_dev->usb_buf[2];
516 break;
517 case CPIA_COMMAND_GetExposure:
518 sd->params.exposure.gain = gspca_dev->usb_buf[0];
519 sd->params.exposure.fineExp = gspca_dev->usb_buf[1];
520 sd->params.exposure.coarseExpLo = gspca_dev->usb_buf[2];
521 sd->params.exposure.coarseExpHi = gspca_dev->usb_buf[3];
522 sd->params.exposure.redComp = gspca_dev->usb_buf[4];
523 sd->params.exposure.green1Comp = gspca_dev->usb_buf[5];
524 sd->params.exposure.green2Comp = gspca_dev->usb_buf[6];
525 sd->params.exposure.blueComp = gspca_dev->usb_buf[7];
526 break;
527
528 case CPIA_COMMAND_ReadMCPorts:
529
530 a = ((gspca_dev->usb_buf[1] & 0x02) == 0);
531 if (a != sd->params.qx3.button) {
532 #if IS_ENABLED(CONFIG_INPUT)
533 input_report_key(gspca_dev->input_dev, KEY_CAMERA, a);
534 input_sync(gspca_dev->input_dev);
535 #endif
536 sd->params.qx3.button = a;
537 }
538 if (sd->params.qx3.button) {
539
540 ret = do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
541 3, 0xdf, 0xdf, 0);
542 if (ret)
543 return ret;
544 ret = do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
545 3, 0xff, 0xff, 0);
546 if (ret)
547 return ret;
548 }
549
550
551 sd->params.qx3.cradled = ((gspca_dev->usb_buf[2] & 0x40) == 0);
552 break;
553 }
554
555 return 0;
556 }
557
558
559 static int do_command_extended(struct gspca_dev *gspca_dev, u16 command,
560 u8 a, u8 b, u8 c, u8 d,
561 u8 e, u8 f, u8 g, u8 h,
562 u8 i, u8 j, u8 k, u8 l)
563 {
564 u8 cmd[8];
565
566 cmd[0] = command >> 8;
567 cmd[1] = command & 0xff;
568 cmd[2] = a;
569 cmd[3] = b;
570 cmd[4] = c;
571 cmd[5] = d;
572 cmd[6] = 8;
573 cmd[7] = 0;
574 gspca_dev->usb_buf[0] = e;
575 gspca_dev->usb_buf[1] = f;
576 gspca_dev->usb_buf[2] = g;
577 gspca_dev->usb_buf[3] = h;
578 gspca_dev->usb_buf[4] = i;
579 gspca_dev->usb_buf[5] = j;
580 gspca_dev->usb_buf[6] = k;
581 gspca_dev->usb_buf[7] = l;
582
583 return cpia_usb_transferCmd(gspca_dev, cmd);
584 }
585
586
587
588
589
590
591
592
593
594
595 #define FLICKER_MAX_EXPOSURE 250
596 #define FLICKER_ALLOWABLE_OVER_EXPOSURE 146
597 #define FLICKER_BRIGHTNESS_CONSTANT 59
598 static int find_over_exposure(int brightness)
599 {
600 int MaxAllowableOverExposure, OverExposure;
601
602 MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness -
603 FLICKER_BRIGHTNESS_CONSTANT;
604
605 if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE)
606 OverExposure = MaxAllowableOverExposure;
607 else
608 OverExposure = FLICKER_ALLOWABLE_OVER_EXPOSURE;
609
610 return OverExposure;
611 }
612 #undef FLICKER_MAX_EXPOSURE
613 #undef FLICKER_ALLOWABLE_OVER_EXPOSURE
614 #undef FLICKER_BRIGHTNESS_CONSTANT
615
616
617 static void reset_camera_params(struct gspca_dev *gspca_dev)
618 {
619 struct sd *sd = (struct sd *) gspca_dev;
620 struct cam_params *params = &sd->params;
621
622
623
624
625 params->colourParams.brightness = BRIGHTNESS_DEF;
626 params->colourParams.contrast = CONTRAST_DEF;
627 params->colourParams.saturation = SATURATION_DEF;
628 params->exposure.gainMode = 4;
629 params->exposure.expMode = 2;
630 params->exposure.compMode = 1;
631 params->exposure.centreWeight = 1;
632 params->exposure.gain = 0;
633 params->exposure.fineExp = 0;
634 params->exposure.coarseExpLo = 185;
635 params->exposure.coarseExpHi = 0;
636 params->exposure.redComp = COMP_RED;
637 params->exposure.green1Comp = COMP_GREEN1;
638 params->exposure.green2Comp = COMP_GREEN2;
639 params->exposure.blueComp = COMP_BLUE;
640 params->colourBalance.balanceMode = 2;
641 params->colourBalance.redGain = 32;
642 params->colourBalance.greenGain = 6;
643 params->colourBalance.blueGain = 92;
644 params->apcor.gain1 = 0x18;
645 params->apcor.gain2 = 0x16;
646 params->apcor.gain4 = 0x24;
647 params->apcor.gain8 = 0x34;
648 params->vlOffset.gain1 = 20;
649 params->vlOffset.gain2 = 24;
650 params->vlOffset.gain4 = 26;
651 params->vlOffset.gain8 = 26;
652 params->compressionParams.hysteresis = 3;
653 params->compressionParams.threshMax = 11;
654 params->compressionParams.smallStep = 1;
655 params->compressionParams.largeStep = 3;
656 params->compressionParams.decimationHysteresis = 2;
657 params->compressionParams.frDiffStepThresh = 5;
658 params->compressionParams.qDiffStepThresh = 3;
659 params->compressionParams.decimationThreshMod = 2;
660
661
662
663
664 params->sensorFps.divisor = 1;
665 params->sensorFps.baserate = 1;
666
667 params->flickerControl.flickerMode = 0;
668 params->flickerControl.disabled = 1;
669 params->flickerControl.coarseJump =
670 flicker_jumps[sd->mainsFreq]
671 [params->sensorFps.baserate]
672 [params->sensorFps.divisor];
673 params->flickerControl.allowableOverExposure =
674 find_over_exposure(params->colourParams.brightness);
675
676 params->yuvThreshold.yThreshold = 6;
677 params->yuvThreshold.uvThreshold = 6;
678
679 params->format.subSample = SUBSAMPLE_420;
680 params->format.yuvOrder = YUVORDER_YUYV;
681
682 params->compression.mode = CPIA_COMPRESSION_AUTO;
683 params->compression.decimation = NO_DECIMATION;
684
685 params->compressionTarget.frTargeting = COMP_TARGET_DEF;
686 params->compressionTarget.targetFR = 15;
687 params->compressionTarget.targetQ = 5;
688
689 params->qx3.qx3_detected = 0;
690 params->qx3.toplight = 0;
691 params->qx3.bottomlight = 0;
692 params->qx3.button = 0;
693 params->qx3.cradled = 0;
694 }
695
696 static void printstatus(struct gspca_dev *gspca_dev, struct cam_params *params)
697 {
698 gspca_dbg(gspca_dev, D_PROBE, "status: %02x %02x %02x %02x %02x %02x %02x %02x\n",
699 params->status.systemState, params->status.grabState,
700 params->status.streamState, params->status.fatalError,
701 params->status.cmdError, params->status.debugFlags,
702 params->status.vpStatus, params->status.errorCode);
703 }
704
705 static int goto_low_power(struct gspca_dev *gspca_dev)
706 {
707 struct sd *sd = (struct sd *) gspca_dev;
708 int ret;
709
710 ret = do_command(gspca_dev, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0);
711 if (ret)
712 return ret;
713
714 ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
715 if (ret)
716 return ret;
717
718 if (sd->params.status.systemState != LO_POWER_STATE) {
719 if (sd->params.status.systemState != WARM_BOOT_STATE) {
720 gspca_err(gspca_dev, "unexpected state after lo power cmd: %02x\n",
721 sd->params.status.systemState);
722 printstatus(gspca_dev, &sd->params);
723 }
724 return -EIO;
725 }
726
727 gspca_dbg(gspca_dev, D_CONF, "camera now in LOW power state\n");
728 return 0;
729 }
730
731 static int goto_high_power(struct gspca_dev *gspca_dev)
732 {
733 struct sd *sd = (struct sd *) gspca_dev;
734 int ret;
735
736 ret = do_command(gspca_dev, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0);
737 if (ret)
738 return ret;
739
740 msleep_interruptible(40);
741
742 if (signal_pending(current))
743 return -EINTR;
744
745 ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
746 if (ret)
747 return ret;
748
749 if (sd->params.status.systemState != HI_POWER_STATE) {
750 gspca_err(gspca_dev, "unexpected state after hi power cmd: %02x\n",
751 sd->params.status.systemState);
752 printstatus(gspca_dev, &sd->params);
753 return -EIO;
754 }
755
756 gspca_dbg(gspca_dev, D_CONF, "camera now in HIGH power state\n");
757 return 0;
758 }
759
760 static int get_version_information(struct gspca_dev *gspca_dev)
761 {
762 int ret;
763
764
765 ret = do_command(gspca_dev, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0);
766 if (ret)
767 return ret;
768
769
770 return do_command(gspca_dev, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0);
771 }
772
773 static int save_camera_state(struct gspca_dev *gspca_dev)
774 {
775 int ret;
776
777 ret = do_command(gspca_dev, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
778 if (ret)
779 return ret;
780
781 return do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
782 }
783
784 static int command_setformat(struct gspca_dev *gspca_dev)
785 {
786 struct sd *sd = (struct sd *) gspca_dev;
787 int ret;
788
789 ret = do_command(gspca_dev, CPIA_COMMAND_SetFormat,
790 sd->params.format.videoSize,
791 sd->params.format.subSample,
792 sd->params.format.yuvOrder, 0);
793 if (ret)
794 return ret;
795
796 return do_command(gspca_dev, CPIA_COMMAND_SetROI,
797 sd->params.roi.colStart, sd->params.roi.colEnd,
798 sd->params.roi.rowStart, sd->params.roi.rowEnd);
799 }
800
801 static int command_setcolourparams(struct gspca_dev *gspca_dev)
802 {
803 struct sd *sd = (struct sd *) gspca_dev;
804 return do_command(gspca_dev, CPIA_COMMAND_SetColourParams,
805 sd->params.colourParams.brightness,
806 sd->params.colourParams.contrast,
807 sd->params.colourParams.saturation, 0);
808 }
809
810 static int command_setapcor(struct gspca_dev *gspca_dev)
811 {
812 struct sd *sd = (struct sd *) gspca_dev;
813 return do_command(gspca_dev, CPIA_COMMAND_SetApcor,
814 sd->params.apcor.gain1,
815 sd->params.apcor.gain2,
816 sd->params.apcor.gain4,
817 sd->params.apcor.gain8);
818 }
819
820 static int command_setvloffset(struct gspca_dev *gspca_dev)
821 {
822 struct sd *sd = (struct sd *) gspca_dev;
823 return do_command(gspca_dev, CPIA_COMMAND_SetVLOffset,
824 sd->params.vlOffset.gain1,
825 sd->params.vlOffset.gain2,
826 sd->params.vlOffset.gain4,
827 sd->params.vlOffset.gain8);
828 }
829
830 static int command_setexposure(struct gspca_dev *gspca_dev)
831 {
832 struct sd *sd = (struct sd *) gspca_dev;
833 int ret;
834
835 ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
836 sd->params.exposure.gainMode,
837 1,
838 sd->params.exposure.compMode,
839 sd->params.exposure.centreWeight,
840 sd->params.exposure.gain,
841 sd->params.exposure.fineExp,
842 sd->params.exposure.coarseExpLo,
843 sd->params.exposure.coarseExpHi,
844 sd->params.exposure.redComp,
845 sd->params.exposure.green1Comp,
846 sd->params.exposure.green2Comp,
847 sd->params.exposure.blueComp);
848 if (ret)
849 return ret;
850
851 if (sd->params.exposure.expMode != 1) {
852 ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
853 0,
854 sd->params.exposure.expMode,
855 0, 0,
856 sd->params.exposure.gain,
857 sd->params.exposure.fineExp,
858 sd->params.exposure.coarseExpLo,
859 sd->params.exposure.coarseExpHi,
860 0, 0, 0, 0);
861 }
862
863 return ret;
864 }
865
866 static int command_setcolourbalance(struct gspca_dev *gspca_dev)
867 {
868 struct sd *sd = (struct sd *) gspca_dev;
869
870 if (sd->params.colourBalance.balanceMode == 1) {
871 int ret;
872
873 ret = do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
874 1,
875 sd->params.colourBalance.redGain,
876 sd->params.colourBalance.greenGain,
877 sd->params.colourBalance.blueGain);
878 if (ret)
879 return ret;
880
881 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
882 3, 0, 0, 0);
883 }
884 if (sd->params.colourBalance.balanceMode == 2) {
885 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
886 2, 0, 0, 0);
887 }
888 if (sd->params.colourBalance.balanceMode == 3) {
889 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
890 3, 0, 0, 0);
891 }
892
893 return -EINVAL;
894 }
895
896 static int command_setcompressiontarget(struct gspca_dev *gspca_dev)
897 {
898 struct sd *sd = (struct sd *) gspca_dev;
899
900 return do_command(gspca_dev, CPIA_COMMAND_SetCompressionTarget,
901 sd->params.compressionTarget.frTargeting,
902 sd->params.compressionTarget.targetFR,
903 sd->params.compressionTarget.targetQ, 0);
904 }
905
906 static int command_setyuvtresh(struct gspca_dev *gspca_dev)
907 {
908 struct sd *sd = (struct sd *) gspca_dev;
909
910 return do_command(gspca_dev, CPIA_COMMAND_SetYUVThresh,
911 sd->params.yuvThreshold.yThreshold,
912 sd->params.yuvThreshold.uvThreshold, 0, 0);
913 }
914
915 static int command_setcompressionparams(struct gspca_dev *gspca_dev)
916 {
917 struct sd *sd = (struct sd *) gspca_dev;
918
919 return do_command_extended(gspca_dev,
920 CPIA_COMMAND_SetCompressionParams,
921 0, 0, 0, 0,
922 sd->params.compressionParams.hysteresis,
923 sd->params.compressionParams.threshMax,
924 sd->params.compressionParams.smallStep,
925 sd->params.compressionParams.largeStep,
926 sd->params.compressionParams.decimationHysteresis,
927 sd->params.compressionParams.frDiffStepThresh,
928 sd->params.compressionParams.qDiffStepThresh,
929 sd->params.compressionParams.decimationThreshMod);
930 }
931
932 static int command_setcompression(struct gspca_dev *gspca_dev)
933 {
934 struct sd *sd = (struct sd *) gspca_dev;
935
936 return do_command(gspca_dev, CPIA_COMMAND_SetCompression,
937 sd->params.compression.mode,
938 sd->params.compression.decimation, 0, 0);
939 }
940
941 static int command_setsensorfps(struct gspca_dev *gspca_dev)
942 {
943 struct sd *sd = (struct sd *) gspca_dev;
944
945 return do_command(gspca_dev, CPIA_COMMAND_SetSensorFPS,
946 sd->params.sensorFps.divisor,
947 sd->params.sensorFps.baserate, 0, 0);
948 }
949
950 static int command_setflickerctrl(struct gspca_dev *gspca_dev)
951 {
952 struct sd *sd = (struct sd *) gspca_dev;
953
954 return do_command(gspca_dev, CPIA_COMMAND_SetFlickerCtrl,
955 sd->params.flickerControl.flickerMode,
956 sd->params.flickerControl.coarseJump,
957 sd->params.flickerControl.allowableOverExposure,
958 0);
959 }
960
961 static int command_setecptiming(struct gspca_dev *gspca_dev)
962 {
963 struct sd *sd = (struct sd *) gspca_dev;
964
965 return do_command(gspca_dev, CPIA_COMMAND_SetECPTiming,
966 sd->params.ecpTiming, 0, 0, 0);
967 }
968
969 static int command_pause(struct gspca_dev *gspca_dev)
970 {
971 return do_command(gspca_dev, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
972 }
973
974 static int command_resume(struct gspca_dev *gspca_dev)
975 {
976 struct sd *sd = (struct sd *) gspca_dev;
977
978 return do_command(gspca_dev, CPIA_COMMAND_InitStreamCap,
979 0, sd->params.streamStartLine, 0, 0);
980 }
981
982 static int command_setlights(struct gspca_dev *gspca_dev)
983 {
984 struct sd *sd = (struct sd *) gspca_dev;
985 int ret, p1, p2;
986
987 p1 = (sd->params.qx3.bottomlight == 0) << 1;
988 p2 = (sd->params.qx3.toplight == 0) << 3;
989
990 ret = do_command(gspca_dev, CPIA_COMMAND_WriteVCReg,
991 0x90, 0x8f, 0x50, 0);
992 if (ret)
993 return ret;
994
995 return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0,
996 p1 | p2 | 0xe0, 0);
997 }
998
999 static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply)
1000 {
1001
1002
1003 #if 0
1004 #define COMPGAIN(base, curexp, newexp) \
1005 (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
1006 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1007 (u16)((float)curexp * (float)(u8)(curcomp + 128) / \
1008 (float)(u8)(basecomp - 128))
1009 #else
1010
1011 #define COMPGAIN(base, curexp, newexp) \
1012 (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2 * newexp)))
1013 #define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1014 (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
1015 #endif
1016
1017 struct sd *sd = (struct sd *) gspca_dev;
1018 int currentexp = sd->params.exposure.coarseExpLo +
1019 sd->params.exposure.coarseExpHi * 256;
1020 int ret, startexp;
1021
1022 if (on) {
1023 int cj = sd->params.flickerControl.coarseJump;
1024 sd->params.flickerControl.flickerMode = 1;
1025 sd->params.flickerControl.disabled = 0;
1026 if (sd->params.exposure.expMode != 2) {
1027 sd->params.exposure.expMode = 2;
1028 sd->exposure_status = EXPOSURE_NORMAL;
1029 }
1030 currentexp = currentexp << sd->params.exposure.gain;
1031 sd->params.exposure.gain = 0;
1032
1033 startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj;
1034 if (startexp < 1)
1035 startexp = 1;
1036 startexp = (startexp * cj) - 1;
1037 if (FIRMWARE_VERSION(1, 2))
1038 while (startexp > MAX_EXP_102)
1039 startexp -= cj;
1040 else
1041 while (startexp > MAX_EXP)
1042 startexp -= cj;
1043 sd->params.exposure.coarseExpLo = startexp & 0xff;
1044 sd->params.exposure.coarseExpHi = startexp >> 8;
1045 if (currentexp > startexp) {
1046 if (currentexp > (2 * startexp))
1047 currentexp = 2 * startexp;
1048 sd->params.exposure.redComp =
1049 COMPGAIN(COMP_RED, currentexp, startexp);
1050 sd->params.exposure.green1Comp =
1051 COMPGAIN(COMP_GREEN1, currentexp, startexp);
1052 sd->params.exposure.green2Comp =
1053 COMPGAIN(COMP_GREEN2, currentexp, startexp);
1054 sd->params.exposure.blueComp =
1055 COMPGAIN(COMP_BLUE, currentexp, startexp);
1056 } else {
1057 sd->params.exposure.redComp = COMP_RED;
1058 sd->params.exposure.green1Comp = COMP_GREEN1;
1059 sd->params.exposure.green2Comp = COMP_GREEN2;
1060 sd->params.exposure.blueComp = COMP_BLUE;
1061 }
1062 if (FIRMWARE_VERSION(1, 2))
1063 sd->params.exposure.compMode = 0;
1064 else
1065 sd->params.exposure.compMode = 1;
1066
1067 sd->params.apcor.gain1 = 0x18;
1068 sd->params.apcor.gain2 = 0x18;
1069 sd->params.apcor.gain4 = 0x16;
1070 sd->params.apcor.gain8 = 0x14;
1071 } else {
1072 sd->params.flickerControl.flickerMode = 0;
1073 sd->params.flickerControl.disabled = 1;
1074
1075 startexp = EXP_FROM_COMP(COMP_RED,
1076 sd->params.exposure.redComp, currentexp);
1077 startexp += EXP_FROM_COMP(COMP_GREEN1,
1078 sd->params.exposure.green1Comp, currentexp);
1079 startexp += EXP_FROM_COMP(COMP_GREEN2,
1080 sd->params.exposure.green2Comp, currentexp);
1081 startexp += EXP_FROM_COMP(COMP_BLUE,
1082 sd->params.exposure.blueComp, currentexp);
1083 startexp = startexp >> 2;
1084 while (startexp > MAX_EXP && sd->params.exposure.gain <
1085 sd->params.exposure.gainMode - 1) {
1086 startexp = startexp >> 1;
1087 ++sd->params.exposure.gain;
1088 }
1089 if (FIRMWARE_VERSION(1, 2) && startexp > MAX_EXP_102)
1090 startexp = MAX_EXP_102;
1091 if (startexp > MAX_EXP)
1092 startexp = MAX_EXP;
1093 sd->params.exposure.coarseExpLo = startexp & 0xff;
1094 sd->params.exposure.coarseExpHi = startexp >> 8;
1095 sd->params.exposure.redComp = COMP_RED;
1096 sd->params.exposure.green1Comp = COMP_GREEN1;
1097 sd->params.exposure.green2Comp = COMP_GREEN2;
1098 sd->params.exposure.blueComp = COMP_BLUE;
1099 sd->params.exposure.compMode = 1;
1100 sd->params.apcor.gain1 = 0x18;
1101 sd->params.apcor.gain2 = 0x16;
1102 sd->params.apcor.gain4 = 0x24;
1103 sd->params.apcor.gain8 = 0x34;
1104 }
1105 sd->params.vlOffset.gain1 = 20;
1106 sd->params.vlOffset.gain2 = 24;
1107 sd->params.vlOffset.gain4 = 26;
1108 sd->params.vlOffset.gain8 = 26;
1109
1110 if (apply) {
1111 ret = command_setexposure(gspca_dev);
1112 if (ret)
1113 return ret;
1114
1115 ret = command_setapcor(gspca_dev);
1116 if (ret)
1117 return ret;
1118
1119 ret = command_setvloffset(gspca_dev);
1120 if (ret)
1121 return ret;
1122
1123 ret = command_setflickerctrl(gspca_dev);
1124 if (ret)
1125 return ret;
1126 }
1127
1128 return 0;
1129 #undef EXP_FROM_COMP
1130 #undef COMPGAIN
1131 }
1132
1133
1134 static void monitor_exposure(struct gspca_dev *gspca_dev)
1135 {
1136 struct sd *sd = (struct sd *) gspca_dev;
1137 u8 exp_acc, bcomp, cmd[8];
1138 int ret, light_exp, dark_exp, very_dark_exp;
1139 int old_exposure, new_exposure, framerate;
1140 int setfps = 0, setexp = 0, setflicker = 0;
1141
1142
1143
1144 cmd[0] = CPIA_COMMAND_ReadVPRegs >> 8;
1145 cmd[1] = CPIA_COMMAND_ReadVPRegs & 0xff;
1146 cmd[2] = 30;
1147 cmd[3] = 4;
1148 cmd[4] = 9;
1149 cmd[5] = 8;
1150 cmd[6] = 8;
1151 cmd[7] = 0;
1152 ret = cpia_usb_transferCmd(gspca_dev, cmd);
1153 if (ret) {
1154 pr_err("ReadVPRegs(30,4,9,8) - failed: %d\n", ret);
1155 return;
1156 }
1157 exp_acc = gspca_dev->usb_buf[0];
1158 bcomp = gspca_dev->usb_buf[1];
1159
1160 light_exp = sd->params.colourParams.brightness +
1161 TC - 50 + EXP_ACC_LIGHT;
1162 if (light_exp > 255)
1163 light_exp = 255;
1164 dark_exp = sd->params.colourParams.brightness +
1165 TC - 50 - EXP_ACC_DARK;
1166 if (dark_exp < 0)
1167 dark_exp = 0;
1168 very_dark_exp = dark_exp / 2;
1169
1170 old_exposure = sd->params.exposure.coarseExpHi * 256 +
1171 sd->params.exposure.coarseExpLo;
1172
1173 if (!sd->params.flickerControl.disabled) {
1174
1175 int max_comp = FIRMWARE_VERSION(1, 2) ? MAX_COMP :
1176 HIGH_COMP_102;
1177 bcomp += 128;
1178 if (bcomp >= max_comp && exp_acc < dark_exp) {
1179
1180 if (exp_acc < very_dark_exp) {
1181
1182 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1183 ++sd->exposure_count;
1184 else {
1185 sd->exposure_status =
1186 EXPOSURE_VERY_DARK;
1187 sd->exposure_count = 1;
1188 }
1189 } else {
1190
1191 if (sd->exposure_status == EXPOSURE_DARK)
1192 ++sd->exposure_count;
1193 else {
1194 sd->exposure_status = EXPOSURE_DARK;
1195 sd->exposure_count = 1;
1196 }
1197 }
1198 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1199
1200 if (old_exposure <= VERY_LOW_EXP) {
1201
1202 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1203 ++sd->exposure_count;
1204 else {
1205 sd->exposure_status =
1206 EXPOSURE_VERY_LIGHT;
1207 sd->exposure_count = 1;
1208 }
1209 } else {
1210
1211 if (sd->exposure_status == EXPOSURE_LIGHT)
1212 ++sd->exposure_count;
1213 else {
1214 sd->exposure_status = EXPOSURE_LIGHT;
1215 sd->exposure_count = 1;
1216 }
1217 }
1218 } else {
1219
1220 sd->exposure_status = EXPOSURE_NORMAL;
1221 }
1222 } else {
1223
1224 if (old_exposure >= MAX_EXP && exp_acc < dark_exp) {
1225
1226 if (exp_acc < very_dark_exp) {
1227
1228 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1229 ++sd->exposure_count;
1230 else {
1231 sd->exposure_status =
1232 EXPOSURE_VERY_DARK;
1233 sd->exposure_count = 1;
1234 }
1235 } else {
1236
1237 if (sd->exposure_status == EXPOSURE_DARK)
1238 ++sd->exposure_count;
1239 else {
1240 sd->exposure_status = EXPOSURE_DARK;
1241 sd->exposure_count = 1;
1242 }
1243 }
1244 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1245
1246 if (old_exposure <= VERY_LOW_EXP) {
1247
1248 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1249 ++sd->exposure_count;
1250 else {
1251 sd->exposure_status =
1252 EXPOSURE_VERY_LIGHT;
1253 sd->exposure_count = 1;
1254 }
1255 } else {
1256
1257 if (sd->exposure_status == EXPOSURE_LIGHT)
1258 ++sd->exposure_count;
1259 else {
1260 sd->exposure_status = EXPOSURE_LIGHT;
1261 sd->exposure_count = 1;
1262 }
1263 }
1264 } else {
1265
1266 sd->exposure_status = EXPOSURE_NORMAL;
1267 }
1268 }
1269
1270 framerate = atomic_read(&sd->fps);
1271 if (framerate > 30 || framerate < 1)
1272 framerate = 1;
1273
1274 if (!sd->params.flickerControl.disabled) {
1275
1276 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1277 sd->exposure_status == EXPOSURE_DARK) &&
1278 sd->exposure_count >= DARK_TIME * framerate &&
1279 sd->params.sensorFps.divisor < 2) {
1280
1281
1282 ++sd->params.sensorFps.divisor;
1283 setfps = 1;
1284
1285 sd->params.flickerControl.coarseJump =
1286 flicker_jumps[sd->mainsFreq]
1287 [sd->params.sensorFps.baserate]
1288 [sd->params.sensorFps.divisor];
1289 setflicker = 1;
1290
1291 new_exposure = sd->params.flickerControl.coarseJump-1;
1292 while (new_exposure < old_exposure / 2)
1293 new_exposure +=
1294 sd->params.flickerControl.coarseJump;
1295 sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1296 sd->params.exposure.coarseExpHi = new_exposure >> 8;
1297 setexp = 1;
1298 sd->exposure_status = EXPOSURE_NORMAL;
1299 gspca_dbg(gspca_dev, D_CONF, "Automatically decreasing sensor_fps\n");
1300
1301 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1302 sd->exposure_status == EXPOSURE_LIGHT) &&
1303 sd->exposure_count >= LIGHT_TIME * framerate &&
1304 sd->params.sensorFps.divisor > 0) {
1305
1306
1307 int max_exp = FIRMWARE_VERSION(1, 2) ? MAX_EXP_102 :
1308 MAX_EXP;
1309 --sd->params.sensorFps.divisor;
1310 setfps = 1;
1311
1312 sd->params.flickerControl.coarseJump =
1313 flicker_jumps[sd->mainsFreq]
1314 [sd->params.sensorFps.baserate]
1315 [sd->params.sensorFps.divisor];
1316 setflicker = 1;
1317
1318 new_exposure = sd->params.flickerControl.coarseJump-1;
1319 while (new_exposure < 2 * old_exposure &&
1320 new_exposure +
1321 sd->params.flickerControl.coarseJump < max_exp)
1322 new_exposure +=
1323 sd->params.flickerControl.coarseJump;
1324 sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1325 sd->params.exposure.coarseExpHi = new_exposure >> 8;
1326 setexp = 1;
1327 sd->exposure_status = EXPOSURE_NORMAL;
1328 gspca_dbg(gspca_dev, D_CONF, "Automatically increasing sensor_fps\n");
1329 }
1330 } else {
1331
1332 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1333 sd->exposure_status == EXPOSURE_DARK) &&
1334 sd->exposure_count >= DARK_TIME * framerate &&
1335 sd->params.sensorFps.divisor < 2) {
1336
1337
1338 ++sd->params.sensorFps.divisor;
1339 setfps = 1;
1340
1341 if (sd->params.exposure.gain > 0) {
1342 --sd->params.exposure.gain;
1343 setexp = 1;
1344 }
1345 sd->exposure_status = EXPOSURE_NORMAL;
1346 gspca_dbg(gspca_dev, D_CONF, "Automatically decreasing sensor_fps\n");
1347
1348 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1349 sd->exposure_status == EXPOSURE_LIGHT) &&
1350 sd->exposure_count >= LIGHT_TIME * framerate &&
1351 sd->params.sensorFps.divisor > 0) {
1352
1353
1354 --sd->params.sensorFps.divisor;
1355 setfps = 1;
1356
1357 if (sd->params.exposure.gain <
1358 sd->params.exposure.gainMode - 1) {
1359 ++sd->params.exposure.gain;
1360 setexp = 1;
1361 }
1362 sd->exposure_status = EXPOSURE_NORMAL;
1363 gspca_dbg(gspca_dev, D_CONF, "Automatically increasing sensor_fps\n");
1364 }
1365 }
1366
1367 if (setexp)
1368 command_setexposure(gspca_dev);
1369
1370 if (setfps)
1371 command_setsensorfps(gspca_dev);
1372
1373 if (setflicker)
1374 command_setflickerctrl(gspca_dev);
1375 }
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385 static void restart_flicker(struct gspca_dev *gspca_dev)
1386 {
1387 struct sd *sd = (struct sd *) gspca_dev;
1388 int cam_exposure, old_exp;
1389
1390 if (!FIRMWARE_VERSION(1, 2))
1391 return;
1392
1393 cam_exposure = atomic_read(&sd->cam_exposure);
1394
1395 if (sd->params.flickerControl.flickerMode == 0 ||
1396 cam_exposure == 0)
1397 return;
1398
1399 old_exp = sd->params.exposure.coarseExpLo +
1400 sd->params.exposure.coarseExpHi*256;
1401
1402
1403
1404
1405 cam_exposure %= sd->params.flickerControl.coarseJump;
1406 if (!sd->params.flickerControl.disabled &&
1407 cam_exposure <= sd->params.flickerControl.coarseJump - 3) {
1408
1409 sd->params.flickerControl.disabled = 1;
1410 }
1411
1412 if (sd->params.flickerControl.disabled &&
1413 old_exp > sd->params.flickerControl.coarseJump +
1414 ROUND_UP_EXP_FOR_FLICKER) {
1415
1416
1417 set_flicker(gspca_dev, 1, 1);
1418 }
1419 }
1420
1421
1422 static int sd_config(struct gspca_dev *gspca_dev,
1423 const struct usb_device_id *id)
1424 {
1425 struct sd *sd = (struct sd *) gspca_dev;
1426 struct cam *cam;
1427 int ret;
1428
1429 sd->mainsFreq = FREQ_DEF == V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
1430 reset_camera_params(gspca_dev);
1431
1432 gspca_dbg(gspca_dev, D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)\n",
1433 id->idVendor, id->idProduct);
1434
1435 cam = &gspca_dev->cam;
1436 cam->cam_mode = mode;
1437 cam->nmodes = ARRAY_SIZE(mode);
1438
1439 ret = goto_low_power(gspca_dev);
1440 if (ret)
1441 gspca_err(gspca_dev, "Cannot go to low power mode: %d\n",
1442 ret);
1443
1444 sd->params.version.firmwareVersion = 0;
1445 get_version_information(gspca_dev);
1446 if (sd->params.version.firmwareVersion != 1) {
1447 gspca_err(gspca_dev, "only firmware version 1 is supported (got: %d)\n",
1448 sd->params.version.firmwareVersion);
1449 return -ENODEV;
1450 }
1451
1452
1453 if (sd->params.version.firmwareRevision <= 2 &&
1454 sd->params.exposure.gainMode > 2) {
1455 sd->params.exposure.gainMode = 2;
1456 }
1457
1458
1459 sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 &&
1460 sd->params.pnpID.product == 0x0001);
1461 return 0;
1462 }
1463
1464
1465 static int sd_start(struct gspca_dev *gspca_dev)
1466 {
1467 struct sd *sd = (struct sd *) gspca_dev;
1468 int priv, ret;
1469
1470
1471 if (goto_low_power(gspca_dev)) {
1472 if (sd->params.status.systemState != WARM_BOOT_STATE) {
1473 gspca_err(gspca_dev, "unexpected systemstate: %02x\n",
1474 sd->params.status.systemState);
1475 printstatus(gspca_dev, &sd->params);
1476 return -ENODEV;
1477 }
1478
1479
1480 ret = goto_high_power(gspca_dev);
1481 if (ret)
1482 return ret;
1483
1484 ret = do_command(gspca_dev, CPIA_COMMAND_DiscardFrame,
1485 0, 0, 0, 0);
1486 if (ret)
1487 return ret;
1488
1489 ret = goto_low_power(gspca_dev);
1490 if (ret)
1491 return ret;
1492 }
1493
1494
1495
1496
1497 sd->params.version.firmwareVersion = 0;
1498 get_version_information(gspca_dev);
1499
1500
1501
1502
1503
1504
1505 ret = do_command(gspca_dev, CPIA_COMMAND_ModifyCameraStatus,
1506 STREAMSTATE, 0, STREAM_NOT_READY, 0);
1507 if (ret)
1508 return ret;
1509
1510
1511 ret = goto_high_power(gspca_dev);
1512 if (ret)
1513 return ret;
1514
1515
1516 ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1517 if (ret)
1518 return ret;
1519
1520 if (sd->params.status.fatalError) {
1521 gspca_err(gspca_dev, "fatal_error: %04x, vp_status: %04x\n",
1522 sd->params.status.fatalError,
1523 sd->params.status.vpStatus);
1524 return -EIO;
1525 }
1526
1527
1528
1529 ret = do_command(gspca_dev, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0);
1530 if (ret)
1531 return ret;
1532
1533
1534 sd->params.streamStartLine = 120;
1535
1536 priv = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1537 if (priv & 0x01) {
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) {
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
1559 ret = do_command(gspca_dev, CPIA_COMMAND_SetGrabMode,
1560 CPIA_GRAB_CONTINEOUS, 0, 0, 0);
1561 if (ret)
1562 return ret;
1563
1564
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
1608 ret = command_resume(gspca_dev);
1609 if (ret)
1610 return ret;
1611
1612
1613
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
1630 save_camera_state(gspca_dev);
1631
1632
1633 goto_low_power(gspca_dev);
1634
1635
1636 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1637
1638 #if IS_ENABLED(CONFIG_INPUT)
1639
1640 if (sd->params.qx3.button) {
1641
1642
1643
1644 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1645 input_sync(gspca_dev->input_dev);
1646 }
1647 #endif
1648 }
1649
1650
1651 static int sd_init(struct gspca_dev *gspca_dev)
1652 {
1653 struct sd *sd = (struct sd *) gspca_dev;
1654 int ret;
1655
1656
1657
1658
1659 ret = sd_start(gspca_dev);
1660 if (ret)
1661 return ret;
1662
1663
1664
1665 if (sd->params.qx3.qx3_detected)
1666 command_setlights(gspca_dev);
1667
1668 sd_stopN(gspca_dev);
1669
1670 gspca_dbg(gspca_dev, D_PROBE, "CPIA Version: %d.%02d (%d.%d)\n",
1671 sd->params.version.firmwareVersion,
1672 sd->params.version.firmwareRevision,
1673 sd->params.version.vcVersion,
1674 sd->params.version.vcRevision);
1675 gspca_dbg(gspca_dev, D_PROBE, "CPIA PnP-ID: %04x:%04x:%04x",
1676 sd->params.pnpID.vendor, sd->params.pnpID.product,
1677 sd->params.pnpID.deviceRevision);
1678 gspca_dbg(gspca_dev, 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
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
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
1730
1731 if (sd->first_frame) {
1732 sd->first_frame--;
1733 if (sd->first_frame == 0)
1734 command_setcompression(gspca_dev);
1735 }
1736
1737
1738 restart_flicker(gspca_dev);
1739
1740
1741
1742 if (sd->params.exposure.expMode == 2)
1743 monitor_exposure(gspca_dev);
1744
1745
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
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
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
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);