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