Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/video/gspca/ov534_9.c
17705 views
1
/*
2
* ov534-ov965x gspca driver
3
*
4
* Copyright (C) 2009-2010 Jean-Francois Moine http://moinejf.free.fr
5
* Copyright (C) 2008 Antonio Ospite <[email protected]>
6
* Copyright (C) 2008 Jim Paris <[email protected]>
7
*
8
* Based on a prototype written by Mark Ferrell <[email protected]>
9
* USB protocol reverse engineered by Jim Paris <[email protected]>
10
* https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
11
*
12
* This program is free software; you can redistribute it and/or modify
13
* it under the terms of the GNU General Public License as published by
14
* the Free Software Foundation; either version 2 of the License, or
15
* any later version.
16
*
17
* This program is distributed in the hope that it will be useful,
18
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
* GNU General Public License for more details.
21
*
22
* You should have received a copy of the GNU General Public License
23
* along with this program; if not, write to the Free Software
24
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
*/
26
27
#define MODULE_NAME "ov534_9"
28
29
#include "gspca.h"
30
31
#define OV534_REG_ADDRESS 0xf1 /* sensor address */
32
#define OV534_REG_SUBADDR 0xf2
33
#define OV534_REG_WRITE 0xf3
34
#define OV534_REG_READ 0xf4
35
#define OV534_REG_OPERATION 0xf5
36
#define OV534_REG_STATUS 0xf6
37
38
#define OV534_OP_WRITE_3 0x37
39
#define OV534_OP_WRITE_2 0x33
40
#define OV534_OP_READ_2 0xf9
41
42
#define CTRL_TIMEOUT 500
43
44
MODULE_AUTHOR("Jean-Francois Moine <[email protected]>");
45
MODULE_DESCRIPTION("GSPCA/OV534_9 USB Camera Driver");
46
MODULE_LICENSE("GPL");
47
48
/* specific webcam descriptor */
49
struct sd {
50
struct gspca_dev gspca_dev; /* !! must be the first item */
51
__u32 last_pts;
52
u8 last_fid;
53
54
u8 brightness;
55
u8 contrast;
56
u8 autogain;
57
u8 exposure;
58
s8 sharpness;
59
u8 satur;
60
u8 freq;
61
};
62
63
/* V4L2 controls supported by the driver */
64
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
65
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
66
static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
67
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
68
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
69
static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
70
static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
71
static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
72
static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
73
static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
74
static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val);
75
static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val);
76
static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
77
static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
78
79
static const struct ctrl sd_ctrls[] = {
80
{ /* 0 */
81
{
82
.id = V4L2_CID_BRIGHTNESS,
83
.type = V4L2_CTRL_TYPE_INTEGER,
84
.name = "Brightness",
85
.minimum = 0,
86
.maximum = 15,
87
.step = 1,
88
#define BRIGHTNESS_DEF 7
89
.default_value = BRIGHTNESS_DEF,
90
},
91
.set = sd_setbrightness,
92
.get = sd_getbrightness,
93
},
94
{ /* 1 */
95
{
96
.id = V4L2_CID_CONTRAST,
97
.type = V4L2_CTRL_TYPE_INTEGER,
98
.name = "Contrast",
99
.minimum = 0,
100
.maximum = 15,
101
.step = 1,
102
#define CONTRAST_DEF 3
103
.default_value = CONTRAST_DEF,
104
},
105
.set = sd_setcontrast,
106
.get = sd_getcontrast,
107
},
108
{ /* 2 */
109
{
110
.id = V4L2_CID_AUTOGAIN,
111
.type = V4L2_CTRL_TYPE_BOOLEAN,
112
.name = "Autogain",
113
.minimum = 0,
114
.maximum = 1,
115
.step = 1,
116
#define AUTOGAIN_DEF 1
117
.default_value = AUTOGAIN_DEF,
118
},
119
.set = sd_setautogain,
120
.get = sd_getautogain,
121
},
122
#define EXPO_IDX 3
123
{ /* 3 */
124
{
125
.id = V4L2_CID_EXPOSURE,
126
.type = V4L2_CTRL_TYPE_INTEGER,
127
.name = "Exposure",
128
.minimum = 0,
129
.maximum = 3,
130
.step = 1,
131
#define EXPO_DEF 0
132
.default_value = EXPO_DEF,
133
},
134
.set = sd_setexposure,
135
.get = sd_getexposure,
136
},
137
{ /* 4 */
138
{
139
.id = V4L2_CID_SHARPNESS,
140
.type = V4L2_CTRL_TYPE_INTEGER,
141
.name = "Sharpness",
142
.minimum = -1, /* -1 = auto */
143
.maximum = 4,
144
.step = 1,
145
#define SHARPNESS_DEF -1
146
.default_value = SHARPNESS_DEF,
147
},
148
.set = sd_setsharpness,
149
.get = sd_getsharpness,
150
},
151
{ /* 5 */
152
{
153
.id = V4L2_CID_SATURATION,
154
.type = V4L2_CTRL_TYPE_INTEGER,
155
.name = "Saturation",
156
.minimum = 0,
157
.maximum = 4,
158
.step = 1,
159
#define SATUR_DEF 2
160
.default_value = SATUR_DEF,
161
},
162
.set = sd_setsatur,
163
.get = sd_getsatur,
164
},
165
{
166
{
167
.id = V4L2_CID_POWER_LINE_FREQUENCY,
168
.type = V4L2_CTRL_TYPE_MENU,
169
.name = "Light frequency filter",
170
.minimum = 0,
171
.maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
172
.step = 1,
173
#define FREQ_DEF 0
174
.default_value = FREQ_DEF,
175
},
176
.set = sd_setfreq,
177
.get = sd_getfreq,
178
},
179
};
180
181
static const struct v4l2_pix_format ov965x_mode[] = {
182
#define QVGA_MODE 0
183
{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
184
.bytesperline = 320,
185
.sizeimage = 320 * 240 * 3 / 8 + 590,
186
.colorspace = V4L2_COLORSPACE_JPEG},
187
#define VGA_MODE 1
188
{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
189
.bytesperline = 640,
190
.sizeimage = 640 * 480 * 3 / 8 + 590,
191
.colorspace = V4L2_COLORSPACE_JPEG},
192
#define SVGA_MODE 2
193
{800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
194
.bytesperline = 800,
195
.sizeimage = 800 * 600 * 3 / 8 + 590,
196
.colorspace = V4L2_COLORSPACE_JPEG},
197
#define XGA_MODE 3
198
{1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
199
.bytesperline = 1024,
200
.sizeimage = 1024 * 768 * 3 / 8 + 590,
201
.colorspace = V4L2_COLORSPACE_JPEG},
202
#define SXGA_MODE 4
203
{1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
204
.bytesperline = 1280,
205
.sizeimage = 1280 * 1024 * 3 / 8 + 590,
206
.colorspace = V4L2_COLORSPACE_JPEG},
207
};
208
209
static const u8 bridge_init[][2] = {
210
{0x88, 0xf8},
211
{0x89, 0xff},
212
{0x76, 0x03},
213
{0x92, 0x03},
214
{0x95, 0x10},
215
{0xe2, 0x00},
216
{0xe7, 0x3e},
217
{0x8d, 0x1c},
218
{0x8e, 0x00},
219
{0x8f, 0x00},
220
{0x1f, 0x00},
221
{0xc3, 0xf9},
222
{0x89, 0xff},
223
{0x88, 0xf8},
224
{0x76, 0x03},
225
{0x92, 0x01},
226
{0x93, 0x18},
227
{0x1c, 0x0a},
228
{0x1d, 0x48},
229
{0xc0, 0x50},
230
{0xc1, 0x3c},
231
{0x34, 0x05},
232
{0xc2, 0x0c},
233
{0xc3, 0xf9},
234
{0x34, 0x05},
235
{0xe7, 0x2e},
236
{0x31, 0xf9},
237
{0x35, 0x02},
238
{0xd9, 0x10},
239
{0x25, 0x42},
240
{0x94, 0x11},
241
};
242
243
static const u8 sensor_init[][2] = {
244
{0x12, 0x80}, /* com7 - SSCB reset */
245
{0x00, 0x00}, /* gain */
246
{0x01, 0x80}, /* blue */
247
{0x02, 0x80}, /* red */
248
{0x03, 0x1b}, /* vref */
249
{0x04, 0x03}, /* com1 - exposure low bits */
250
{0x0b, 0x57}, /* ver */
251
{0x0e, 0x61}, /* com5 */
252
{0x0f, 0x42}, /* com6 */
253
{0x11, 0x00}, /* clkrc */
254
{0x12, 0x02}, /* com7 - 15fps VGA YUYV */
255
{0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
256
{0x14, 0x28}, /* com9 */
257
{0x16, 0x24}, /* reg16 */
258
{0x17, 0x1d}, /* hstart*/
259
{0x18, 0xbd}, /* hstop */
260
{0x19, 0x01}, /* vstrt */
261
{0x1a, 0x81}, /* vstop*/
262
{0x1e, 0x04}, /* mvfp */
263
{0x24, 0x3c}, /* aew */
264
{0x25, 0x36}, /* aeb */
265
{0x26, 0x71}, /* vpt */
266
{0x27, 0x08}, /* bbias */
267
{0x28, 0x08}, /* gbbias */
268
{0x29, 0x15}, /* gr com */
269
{0x2a, 0x00}, /* exhch */
270
{0x2b, 0x00}, /* exhcl */
271
{0x2c, 0x08}, /* rbias */
272
{0x32, 0xff}, /* href */
273
{0x33, 0x00}, /* chlf */
274
{0x34, 0x3f}, /* aref1 */
275
{0x35, 0x00}, /* aref2 */
276
{0x36, 0xf8}, /* aref3 */
277
{0x38, 0x72}, /* adc2 */
278
{0x39, 0x57}, /* aref4 */
279
{0x3a, 0x80}, /* tslb - yuyv */
280
{0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
281
{0x3d, 0x99}, /* com13 */
282
{0x3f, 0xc1}, /* edge */
283
{0x40, 0xc0}, /* com15 */
284
{0x41, 0x40}, /* com16 */
285
{0x42, 0xc0}, /* com17 */
286
{0x43, 0x0a}, /* rsvd */
287
{0x44, 0xf0},
288
{0x45, 0x46},
289
{0x46, 0x62},
290
{0x47, 0x2a},
291
{0x48, 0x3c},
292
{0x4a, 0xfc},
293
{0x4b, 0xfc},
294
{0x4c, 0x7f},
295
{0x4d, 0x7f},
296
{0x4e, 0x7f},
297
{0x4f, 0x98}, /* matrix */
298
{0x50, 0x98},
299
{0x51, 0x00},
300
{0x52, 0x28},
301
{0x53, 0x70},
302
{0x54, 0x98},
303
{0x58, 0x1a}, /* matrix coef sign */
304
{0x59, 0x85}, /* AWB control */
305
{0x5a, 0xa9},
306
{0x5b, 0x64},
307
{0x5c, 0x84},
308
{0x5d, 0x53},
309
{0x5e, 0x0e},
310
{0x5f, 0xf0}, /* AWB blue limit */
311
{0x60, 0xf0}, /* AWB red limit */
312
{0x61, 0xf0}, /* AWB green limit */
313
{0x62, 0x00}, /* lcc1 */
314
{0x63, 0x00}, /* lcc2 */
315
{0x64, 0x02}, /* lcc3 */
316
{0x65, 0x16}, /* lcc4 */
317
{0x66, 0x01}, /* lcc5 */
318
{0x69, 0x02}, /* hv */
319
{0x6b, 0x5a}, /* dbvl */
320
{0x6c, 0x04},
321
{0x6d, 0x55},
322
{0x6e, 0x00},
323
{0x6f, 0x9d},
324
{0x70, 0x21}, /* dnsth */
325
{0x71, 0x78},
326
{0x72, 0x00}, /* poidx */
327
{0x73, 0x01}, /* pckdv */
328
{0x74, 0x3a}, /* xindx */
329
{0x75, 0x35}, /* yindx */
330
{0x76, 0x01},
331
{0x77, 0x02},
332
{0x7a, 0x12}, /* gamma curve */
333
{0x7b, 0x08},
334
{0x7c, 0x16},
335
{0x7d, 0x30},
336
{0x7e, 0x5e},
337
{0x7f, 0x72},
338
{0x80, 0x82},
339
{0x81, 0x8e},
340
{0x82, 0x9a},
341
{0x83, 0xa4},
342
{0x84, 0xac},
343
{0x85, 0xb8},
344
{0x86, 0xc3},
345
{0x87, 0xd6},
346
{0x88, 0xe6},
347
{0x89, 0xf2},
348
{0x8a, 0x03},
349
{0x8c, 0x89}, /* com19 */
350
{0x14, 0x28}, /* com9 */
351
{0x90, 0x7d},
352
{0x91, 0x7b},
353
{0x9d, 0x03}, /* lcc6 */
354
{0x9e, 0x04}, /* lcc7 */
355
{0x9f, 0x7a},
356
{0xa0, 0x79},
357
{0xa1, 0x40}, /* aechm */
358
{0xa4, 0x50}, /* com21 */
359
{0xa5, 0x68}, /* com26 */
360
{0xa6, 0x4a}, /* AWB green */
361
{0xa8, 0xc1}, /* refa8 */
362
{0xa9, 0xef}, /* refa9 */
363
{0xaa, 0x92},
364
{0xab, 0x04},
365
{0xac, 0x80}, /* black level control */
366
{0xad, 0x80},
367
{0xae, 0x80},
368
{0xaf, 0x80},
369
{0xb2, 0xf2},
370
{0xb3, 0x20},
371
{0xb4, 0x20}, /* ctrlb4 */
372
{0xb5, 0x00},
373
{0xb6, 0xaf},
374
{0xbb, 0xae},
375
{0xbc, 0x7f}, /* ADC channel offsets */
376
{0xdb, 0x7f},
377
{0xbe, 0x7f},
378
{0xbf, 0x7f},
379
{0xc0, 0xe2},
380
{0xc1, 0xc0},
381
{0xc2, 0x01},
382
{0xc3, 0x4e},
383
{0xc6, 0x85},
384
{0xc7, 0x80}, /* com24 */
385
{0xc9, 0xe0},
386
{0xca, 0xe8},
387
{0xcb, 0xf0},
388
{0xcc, 0xd8},
389
{0xcd, 0xf1},
390
{0x4f, 0x98}, /* matrix */
391
{0x50, 0x98},
392
{0x51, 0x00},
393
{0x52, 0x28},
394
{0x53, 0x70},
395
{0x54, 0x98},
396
{0x58, 0x1a},
397
{0xff, 0x41}, /* read 41, write ff 00 */
398
{0x41, 0x40}, /* com16 */
399
400
{0xc5, 0x03}, /* 60 Hz banding filter */
401
{0x6a, 0x02}, /* 50 Hz banding filter */
402
403
{0x12, 0x62}, /* com7 - 30fps VGA YUV */
404
{0x36, 0xfa}, /* aref3 */
405
{0x69, 0x0a}, /* hv */
406
{0x8c, 0x89}, /* com22 */
407
{0x14, 0x28}, /* com9 */
408
{0x3e, 0x0c},
409
{0x41, 0x40}, /* com16 */
410
{0x72, 0x00},
411
{0x73, 0x00},
412
{0x74, 0x3a},
413
{0x75, 0x35},
414
{0x76, 0x01},
415
{0xc7, 0x80},
416
{0x03, 0x12}, /* vref */
417
{0x17, 0x16}, /* hstart */
418
{0x18, 0x02}, /* hstop */
419
{0x19, 0x01}, /* vstrt */
420
{0x1a, 0x3d}, /* vstop */
421
{0x32, 0xff}, /* href */
422
{0xc0, 0xaa},
423
};
424
425
static const u8 bridge_init_2[][2] = {
426
{0x94, 0xaa},
427
{0xf1, 0x60},
428
{0xe5, 0x04},
429
{0xc0, 0x50},
430
{0xc1, 0x3c},
431
{0x8c, 0x00},
432
{0x8d, 0x1c},
433
{0x34, 0x05},
434
435
{0xc2, 0x0c},
436
{0xc3, 0xf9},
437
{0xda, 0x01},
438
{0x50, 0x00},
439
{0x51, 0xa0},
440
{0x52, 0x3c},
441
{0x53, 0x00},
442
{0x54, 0x00},
443
{0x55, 0x00},
444
{0x57, 0x00},
445
{0x5c, 0x00},
446
{0x5a, 0xa0},
447
{0x5b, 0x78},
448
{0x35, 0x02},
449
{0xd9, 0x10},
450
{0x94, 0x11},
451
};
452
453
static const u8 sensor_init_2[][2] = {
454
{0x3b, 0xc4},
455
{0x1e, 0x04}, /* mvfp */
456
{0x13, 0xe0}, /* com8 */
457
{0x00, 0x00}, /* gain */
458
{0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
459
{0x11, 0x03}, /* clkrc */
460
{0x6b, 0x5a}, /* dblv */
461
{0x6a, 0x05},
462
{0xc5, 0x07},
463
{0xa2, 0x4b},
464
{0xa3, 0x3e},
465
{0x2d, 0x00},
466
{0xff, 0x42}, /* read 42, write ff 00 */
467
{0x42, 0xc0}, /* com17 */
468
{0x2d, 0x00},
469
{0xff, 0x42}, /* read 42, write ff 00 */
470
{0x42, 0xc1}, /* com17 */
471
/* sharpness */
472
{0x3f, 0x01},
473
{0xff, 0x42}, /* read 42, write ff 00 */
474
{0x42, 0xc1}, /* com17 */
475
/* saturation */
476
{0x4f, 0x98}, /* matrix */
477
{0x50, 0x98},
478
{0x51, 0x00},
479
{0x52, 0x28},
480
{0x53, 0x70},
481
{0x54, 0x98},
482
{0x58, 0x1a},
483
{0xff, 0x41}, /* read 41, write ff 00 */
484
{0x41, 0x40}, /* com16 */
485
/* contrast */
486
{0x56, 0x40},
487
/* brightness */
488
{0x55, 0x8f},
489
/* expo */
490
{0x10, 0x25}, /* aech - exposure high bits */
491
{0xff, 0x13}, /* read 13, write ff 00 */
492
{0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
493
};
494
495
static const u8 sensor_start_1_vga[][2] = { /* same for qvga */
496
{0x12, 0x62}, /* com7 - 30fps VGA YUV */
497
{0x36, 0xfa}, /* aref3 */
498
{0x69, 0x0a}, /* hv */
499
{0x8c, 0x89}, /* com22 */
500
{0x14, 0x28}, /* com9 */
501
{0x3e, 0x0c}, /* com14 */
502
{0x41, 0x40}, /* com16 */
503
{0x72, 0x00},
504
{0x73, 0x00},
505
{0x74, 0x3a},
506
{0x75, 0x35},
507
{0x76, 0x01},
508
{0xc7, 0x80}, /* com24 */
509
{0x03, 0x12}, /* vref */
510
{0x17, 0x16}, /* hstart */
511
{0x18, 0x02}, /* hstop */
512
{0x19, 0x01}, /* vstrt */
513
{0x1a, 0x3d}, /* vstop */
514
{0x32, 0xff}, /* href */
515
{0xc0, 0xaa},
516
};
517
518
static const u8 sensor_start_1_svga[][2] = {
519
{0x12, 0x02}, /* com7 - YUYV - VGA 15 full resolution */
520
{0x36, 0xf8}, /* aref3 */
521
{0x69, 0x02}, /* hv */
522
{0x8c, 0x0d}, /* com22 */
523
{0x3e, 0x0c}, /* com14 */
524
{0x41, 0x40}, /* com16 */
525
{0x72, 0x00},
526
{0x73, 0x01},
527
{0x74, 0x3a},
528
{0x75, 0x35},
529
{0x76, 0x01},
530
{0xc7, 0x80}, /* com24 */
531
{0x03, 0x1b}, /* vref */
532
{0x17, 0x1d}, /* hstart */
533
{0x18, 0xbd}, /* hstop */
534
{0x19, 0x01}, /* vstrt */
535
{0x1a, 0x81}, /* vstop */
536
{0x32, 0xff}, /* href */
537
{0xc0, 0xe2},
538
};
539
540
static const u8 sensor_start_1_xga[][2] = {
541
{0x12, 0x02}, /* com7 */
542
{0x36, 0xf8}, /* aref3 */
543
{0x69, 0x02}, /* hv */
544
{0x8c, 0x89}, /* com22 */
545
{0x14, 0x28}, /* com9 */
546
{0x3e, 0x0c}, /* com14 */
547
{0x41, 0x40}, /* com16 */
548
{0x72, 0x00},
549
{0x73, 0x01},
550
{0x74, 0x3a},
551
{0x75, 0x35},
552
{0x76, 0x01},
553
{0xc7, 0x80}, /* com24 */
554
{0x03, 0x1b}, /* vref */
555
{0x17, 0x1d}, /* hstart */
556
{0x18, 0xbd}, /* hstop */
557
{0x19, 0x01}, /* vstrt */
558
{0x1a, 0x81}, /* vstop */
559
{0x32, 0xff}, /* href */
560
{0xc0, 0xe2},
561
};
562
563
static const u8 sensor_start_1_sxga[][2] = {
564
{0x12, 0x02}, /* com7 */
565
{0x36, 0xf8}, /* aref3 */
566
{0x69, 0x02}, /* hv */
567
{0x8c, 0x89}, /* com22 */
568
{0x14, 0x28}, /* com9 */
569
{0x3e, 0x0c}, /* com14 */
570
{0x41, 0x40}, /* com16 */
571
{0x72, 0x00},
572
{0x73, 0x01},
573
{0x74, 0x3a},
574
{0x75, 0x35},
575
{0x76, 0x01},
576
{0xc7, 0x80}, /* com24 */
577
{0x03, 0x1b}, /* vref */
578
{0x17, 0x1d}, /* hstart */
579
{0x18, 0x02}, /* hstop */
580
{0x19, 0x01}, /* vstrt */
581
{0x1a, 0x81}, /* vstop */
582
{0x32, 0xff}, /* href */
583
{0xc0, 0xe2},
584
};
585
586
static const u8 bridge_start_qvga[][2] = {
587
{0x94, 0xaa},
588
{0xf1, 0x60},
589
{0xe5, 0x04},
590
{0xc0, 0x50},
591
{0xc1, 0x3c},
592
{0x8c, 0x00},
593
{0x8d, 0x1c},
594
{0x34, 0x05},
595
596
{0xc2, 0x4c},
597
{0xc3, 0xf9},
598
{0xda, 0x00},
599
{0x50, 0x00},
600
{0x51, 0xa0},
601
{0x52, 0x78},
602
{0x53, 0x00},
603
{0x54, 0x00},
604
{0x55, 0x00},
605
{0x57, 0x00},
606
{0x5c, 0x00},
607
{0x5a, 0x50},
608
{0x5b, 0x3c},
609
{0x35, 0x02},
610
{0xd9, 0x10},
611
{0x94, 0x11},
612
};
613
614
static const u8 bridge_start_vga[][2] = {
615
{0x94, 0xaa},
616
{0xf1, 0x60},
617
{0xe5, 0x04},
618
{0xc0, 0x50},
619
{0xc1, 0x3c},
620
{0x8c, 0x00},
621
{0x8d, 0x1c},
622
{0x34, 0x05},
623
{0xc2, 0x0c},
624
{0xc3, 0xf9},
625
{0xda, 0x01},
626
{0x50, 0x00},
627
{0x51, 0xa0},
628
{0x52, 0x3c},
629
{0x53, 0x00},
630
{0x54, 0x00},
631
{0x55, 0x00},
632
{0x57, 0x00},
633
{0x5c, 0x00},
634
{0x5a, 0xa0},
635
{0x5b, 0x78},
636
{0x35, 0x02},
637
{0xd9, 0x10},
638
{0x94, 0x11},
639
};
640
641
static const u8 bridge_start_svga[][2] = {
642
{0x94, 0xaa},
643
{0xf1, 0x60},
644
{0xe5, 0x04},
645
{0xc0, 0xa0},
646
{0xc1, 0x80},
647
{0x8c, 0x00},
648
{0x8d, 0x1c},
649
{0x34, 0x05},
650
{0xc2, 0x4c},
651
{0xc3, 0xf9},
652
{0x50, 0x00},
653
{0x51, 0x40},
654
{0x52, 0x00},
655
{0x53, 0x00},
656
{0x54, 0x00},
657
{0x55, 0x88},
658
{0x57, 0x00},
659
{0x5c, 0x00},
660
{0x5a, 0xc8},
661
{0x5b, 0x96},
662
{0x35, 0x02},
663
{0xd9, 0x10},
664
{0xda, 0x00},
665
{0x94, 0x11},
666
};
667
668
static const u8 bridge_start_xga[][2] = {
669
{0x94, 0xaa},
670
{0xf1, 0x60},
671
{0xe5, 0x04},
672
{0xc0, 0xa0},
673
{0xc1, 0x80},
674
{0x8c, 0x00},
675
{0x8d, 0x1c},
676
{0x34, 0x05},
677
{0xc2, 0x4c},
678
{0xc3, 0xf9},
679
{0x50, 0x00},
680
{0x51, 0x40},
681
{0x52, 0x00},
682
{0x53, 0x00},
683
{0x54, 0x00},
684
{0x55, 0x88},
685
{0x57, 0x00},
686
{0x5c, 0x01},
687
{0x5a, 0x00},
688
{0x5b, 0xc0},
689
{0x35, 0x02},
690
{0xd9, 0x10},
691
{0xda, 0x01},
692
{0x94, 0x11},
693
};
694
695
static const u8 bridge_start_sxga[][2] = {
696
{0x94, 0xaa},
697
{0xf1, 0x60},
698
{0xe5, 0x04},
699
{0xc0, 0xa0},
700
{0xc1, 0x80},
701
{0x8c, 0x00},
702
{0x8d, 0x1c},
703
{0x34, 0x05},
704
{0xc2, 0x0c},
705
{0xc3, 0xf9},
706
{0xda, 0x00},
707
{0x35, 0x02},
708
{0xd9, 0x10},
709
{0x94, 0x11},
710
};
711
712
static const u8 sensor_start_2_qvga[][2] = {
713
{0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */
714
{0x1e, 0x04}, /* mvfp */
715
{0x13, 0xe0}, /* com8 */
716
{0x00, 0x00},
717
{0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
718
{0x11, 0x01}, /* clkrc */
719
{0x6b, 0x5a}, /* dblv */
720
{0x6a, 0x02}, /* 50 Hz banding filter */
721
{0xc5, 0x03}, /* 60 Hz banding filter */
722
{0xa2, 0x96}, /* bd50 */
723
{0xa3, 0x7d}, /* bd60 */
724
725
{0xff, 0x13}, /* read 13, write ff 00 */
726
{0x13, 0xe7},
727
{0x3a, 0x80}, /* tslb - yuyv */
728
};
729
730
static const u8 sensor_start_2_vga[][2] = {
731
{0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
732
{0x1e, 0x04}, /* mvfp */
733
{0x13, 0xe0}, /* com8 */
734
{0x00, 0x00},
735
{0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
736
{0x11, 0x03}, /* clkrc */
737
{0x6b, 0x5a}, /* dblv */
738
{0x6a, 0x05}, /* 50 Hz banding filter */
739
{0xc5, 0x07}, /* 60 Hz banding filter */
740
{0xa2, 0x4b}, /* bd50 */
741
{0xa3, 0x3e}, /* bd60 */
742
743
{0x2d, 0x00}, /* advfl */
744
};
745
746
static const u8 sensor_start_2_svga[][2] = { /* same for xga */
747
{0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
748
{0x1e, 0x04}, /* mvfp */
749
{0x13, 0xe0}, /* com8 */
750
{0x00, 0x00},
751
{0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
752
{0x11, 0x01}, /* clkrc */
753
{0x6b, 0x5a}, /* dblv */
754
{0x6a, 0x0c}, /* 50 Hz banding filter */
755
{0xc5, 0x0f}, /* 60 Hz banding filter */
756
{0xa2, 0x4e}, /* bd50 */
757
{0xa3, 0x41}, /* bd60 */
758
};
759
760
static const u8 sensor_start_2_sxga[][2] = {
761
{0x13, 0xe0}, /* com8 */
762
{0x00, 0x00},
763
{0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
764
{0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
765
{0x1e, 0x04}, /* mvfp */
766
{0x11, 0x01}, /* clkrc */
767
{0x6b, 0x5a}, /* dblv */
768
{0x6a, 0x0c}, /* 50 Hz banding filter */
769
{0xc5, 0x0f}, /* 60 Hz banding filter */
770
{0xa2, 0x4e}, /* bd50 */
771
{0xa3, 0x41}, /* bd60 */
772
};
773
774
static void reg_w_i(struct gspca_dev *gspca_dev, u16 reg, u8 val)
775
{
776
struct usb_device *udev = gspca_dev->dev;
777
int ret;
778
779
if (gspca_dev->usb_err < 0)
780
return;
781
gspca_dev->usb_buf[0] = val;
782
ret = usb_control_msg(udev,
783
usb_sndctrlpipe(udev, 0),
784
0x01,
785
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
786
0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
787
if (ret < 0) {
788
err("reg_w failed %d", ret);
789
gspca_dev->usb_err = ret;
790
}
791
}
792
793
static void reg_w(struct gspca_dev *gspca_dev, u16 reg, u8 val)
794
{
795
PDEBUG(D_USBO, "reg_w [%04x] = %02x", reg, val);
796
reg_w_i(gspca_dev, reg, val);
797
}
798
799
static u8 reg_r(struct gspca_dev *gspca_dev, u16 reg)
800
{
801
struct usb_device *udev = gspca_dev->dev;
802
int ret;
803
804
if (gspca_dev->usb_err < 0)
805
return 0;
806
ret = usb_control_msg(udev,
807
usb_rcvctrlpipe(udev, 0),
808
0x01,
809
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
810
0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
811
PDEBUG(D_USBI, "reg_r [%04x] -> %02x", reg, gspca_dev->usb_buf[0]);
812
if (ret < 0) {
813
err("reg_r err %d", ret);
814
gspca_dev->usb_err = ret;
815
}
816
return gspca_dev->usb_buf[0];
817
}
818
819
static int sccb_check_status(struct gspca_dev *gspca_dev)
820
{
821
u8 data;
822
int i;
823
824
for (i = 0; i < 5; i++) {
825
data = reg_r(gspca_dev, OV534_REG_STATUS);
826
827
switch (data) {
828
case 0x00:
829
return 1;
830
case 0x04:
831
return 0;
832
case 0x03:
833
break;
834
default:
835
PDEBUG(D_USBI|D_USBO,
836
"sccb status 0x%02x, attempt %d/5",
837
data, i + 1);
838
}
839
}
840
return 0;
841
}
842
843
static void sccb_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
844
{
845
PDEBUG(D_USBO, "sccb_write [%02x] = %02x", reg, val);
846
reg_w_i(gspca_dev, OV534_REG_SUBADDR, reg);
847
reg_w_i(gspca_dev, OV534_REG_WRITE, val);
848
reg_w_i(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
849
850
if (!sccb_check_status(gspca_dev))
851
err("sccb_write failed");
852
}
853
854
static u8 sccb_read(struct gspca_dev *gspca_dev, u16 reg)
855
{
856
reg_w(gspca_dev, OV534_REG_SUBADDR, reg);
857
reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
858
if (!sccb_check_status(gspca_dev))
859
err("sccb_read failed 1");
860
861
reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
862
if (!sccb_check_status(gspca_dev))
863
err("sccb_read failed 2");
864
865
return reg_r(gspca_dev, OV534_REG_READ);
866
}
867
868
/* output a bridge sequence (reg - val) */
869
static void reg_w_array(struct gspca_dev *gspca_dev,
870
const u8 (*data)[2], int len)
871
{
872
while (--len >= 0) {
873
reg_w(gspca_dev, (*data)[0], (*data)[1]);
874
data++;
875
}
876
}
877
878
/* output a sensor sequence (reg - val) */
879
static void sccb_w_array(struct gspca_dev *gspca_dev,
880
const u8 (*data)[2], int len)
881
{
882
while (--len >= 0) {
883
if ((*data)[0] != 0xff) {
884
sccb_write(gspca_dev, (*data)[0], (*data)[1]);
885
} else {
886
sccb_read(gspca_dev, (*data)[1]);
887
sccb_write(gspca_dev, 0xff, 0x00);
888
}
889
data++;
890
}
891
}
892
893
/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
894
* (direction and output)? */
895
static void set_led(struct gspca_dev *gspca_dev, int status)
896
{
897
u8 data;
898
899
PDEBUG(D_CONF, "led status: %d", status);
900
901
data = reg_r(gspca_dev, 0x21);
902
data |= 0x80;
903
reg_w(gspca_dev, 0x21, data);
904
905
data = reg_r(gspca_dev, 0x23);
906
if (status)
907
data |= 0x80;
908
else
909
data &= ~0x80;
910
911
reg_w(gspca_dev, 0x23, data);
912
913
if (!status) {
914
data = reg_r(gspca_dev, 0x21);
915
data &= ~0x80;
916
reg_w(gspca_dev, 0x21, data);
917
}
918
}
919
920
static void setbrightness(struct gspca_dev *gspca_dev)
921
{
922
struct sd *sd = (struct sd *) gspca_dev;
923
u8 val;
924
925
val = sd->brightness;
926
if (val < 8)
927
val = 15 - val; /* f .. 8 */
928
else
929
val = val - 8; /* 0 .. 7 */
930
sccb_write(gspca_dev, 0x55, /* brtn - brightness adjustment */
931
0x0f | (val << 4));
932
}
933
934
static void setcontrast(struct gspca_dev *gspca_dev)
935
{
936
struct sd *sd = (struct sd *) gspca_dev;
937
938
sccb_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */
939
sd->contrast << 4);
940
}
941
942
static void setautogain(struct gspca_dev *gspca_dev)
943
{
944
struct sd *sd = (struct sd *) gspca_dev;
945
u8 val;
946
947
/*fixme: should adjust agc/awb/aec by different controls */
948
val = sccb_read(gspca_dev, 0x13); /* com8 */
949
sccb_write(gspca_dev, 0xff, 0x00);
950
if (sd->autogain)
951
val |= 0x05; /* agc & aec */
952
else
953
val &= 0xfa;
954
sccb_write(gspca_dev, 0x13, val);
955
}
956
957
static void setexposure(struct gspca_dev *gspca_dev)
958
{
959
struct sd *sd = (struct sd *) gspca_dev;
960
u8 val;
961
static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e};
962
963
sccb_write(gspca_dev, 0x10, /* aec[9:2] */
964
expo[sd->exposure]);
965
966
val = sccb_read(gspca_dev, 0x13); /* com8 */
967
sccb_write(gspca_dev, 0xff, 0x00);
968
sccb_write(gspca_dev, 0x13, val);
969
970
val = sccb_read(gspca_dev, 0xa1); /* aech */
971
sccb_write(gspca_dev, 0xff, 0x00);
972
sccb_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */
973
}
974
975
static void setsharpness(struct gspca_dev *gspca_dev)
976
{
977
struct sd *sd = (struct sd *) gspca_dev;
978
s8 val;
979
980
val = sd->sharpness;
981
if (val < 0) { /* auto */
982
val = sccb_read(gspca_dev, 0x42); /* com17 */
983
sccb_write(gspca_dev, 0xff, 0x00);
984
sccb_write(gspca_dev, 0x42, val | 0x40);
985
/* Edge enhancement strength auto adjust */
986
return;
987
}
988
if (val != 0)
989
val = 1 << (val - 1);
990
sccb_write(gspca_dev, 0x3f, /* edge - edge enhance. factor */
991
val);
992
val = sccb_read(gspca_dev, 0x42); /* com17 */
993
sccb_write(gspca_dev, 0xff, 0x00);
994
sccb_write(gspca_dev, 0x42, val & 0xbf);
995
}
996
997
static void setsatur(struct gspca_dev *gspca_dev)
998
{
999
struct sd *sd = (struct sd *) gspca_dev;
1000
u8 val1, val2, val3;
1001
static const u8 matrix[5][2] = {
1002
{0x14, 0x38},
1003
{0x1e, 0x54},
1004
{0x28, 0x70},
1005
{0x32, 0x8c},
1006
{0x48, 0x90}
1007
};
1008
1009
val1 = matrix[sd->satur][0];
1010
val2 = matrix[sd->satur][1];
1011
val3 = val1 + val2;
1012
sccb_write(gspca_dev, 0x4f, val3); /* matrix coeff */
1013
sccb_write(gspca_dev, 0x50, val3);
1014
sccb_write(gspca_dev, 0x51, 0x00);
1015
sccb_write(gspca_dev, 0x52, val1);
1016
sccb_write(gspca_dev, 0x53, val2);
1017
sccb_write(gspca_dev, 0x54, val3);
1018
sccb_write(gspca_dev, 0x58, 0x1a); /* mtxs - coeff signs */
1019
1020
val1 = sccb_read(gspca_dev, 0x41); /* com16 */
1021
sccb_write(gspca_dev, 0xff, 0x00);
1022
sccb_write(gspca_dev, 0x41, val1);
1023
}
1024
1025
static void setfreq(struct gspca_dev *gspca_dev)
1026
{
1027
struct sd *sd = (struct sd *) gspca_dev;
1028
u8 val;
1029
1030
val = sccb_read(gspca_dev, 0x13); /* com8 */
1031
sccb_write(gspca_dev, 0xff, 0x00);
1032
if (sd->freq == 0) {
1033
sccb_write(gspca_dev, 0x13, val & 0xdf);
1034
return;
1035
}
1036
sccb_write(gspca_dev, 0x13, val | 0x20);
1037
1038
val = sccb_read(gspca_dev, 0x42); /* com17 */
1039
sccb_write(gspca_dev, 0xff, 0x00);
1040
if (sd->freq == 1)
1041
val |= 0x01;
1042
else
1043
val &= 0xfe;
1044
sccb_write(gspca_dev, 0x42, val);
1045
}
1046
1047
/* this function is called at probe time */
1048
static int sd_config(struct gspca_dev *gspca_dev,
1049
const struct usb_device_id *id)
1050
{
1051
struct sd *sd = (struct sd *) gspca_dev;
1052
struct cam *cam;
1053
1054
cam = &gspca_dev->cam;
1055
1056
cam->cam_mode = ov965x_mode;
1057
cam->nmodes = ARRAY_SIZE(ov965x_mode);
1058
1059
sd->brightness = BRIGHTNESS_DEF;
1060
sd->contrast = CONTRAST_DEF;
1061
#if AUTOGAIN_DEF != 0
1062
sd->autogain = AUTOGAIN_DEF;
1063
gspca_dev->ctrl_inac |= (1 << EXPO_IDX);
1064
#endif
1065
#if EXPO_DEF != 0
1066
sd->exposure = EXPO_DEF;
1067
#endif
1068
#if SHARPNESS_DEF != 0
1069
sd->sharpness = SHARPNESS_DEF;
1070
#endif
1071
sd->satur = SATUR_DEF;
1072
sd->freq = FREQ_DEF;
1073
1074
return 0;
1075
}
1076
1077
/* this function is called at probe and resume time */
1078
static int sd_init(struct gspca_dev *gspca_dev)
1079
{
1080
u16 sensor_id;
1081
1082
/* reset bridge */
1083
reg_w(gspca_dev, 0xe7, 0x3a);
1084
reg_w(gspca_dev, 0xe0, 0x08);
1085
msleep(100);
1086
1087
/* initialize the sensor address */
1088
reg_w(gspca_dev, OV534_REG_ADDRESS, 0x60);
1089
1090
/* reset sensor */
1091
sccb_write(gspca_dev, 0x12, 0x80);
1092
msleep(10);
1093
1094
/* probe the sensor */
1095
sccb_read(gspca_dev, 0x0a);
1096
sensor_id = sccb_read(gspca_dev, 0x0a) << 8;
1097
sccb_read(gspca_dev, 0x0b);
1098
sensor_id |= sccb_read(gspca_dev, 0x0b);
1099
PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
1100
1101
/* initialize */
1102
reg_w_array(gspca_dev, bridge_init,
1103
ARRAY_SIZE(bridge_init));
1104
sccb_w_array(gspca_dev, sensor_init,
1105
ARRAY_SIZE(sensor_init));
1106
reg_w_array(gspca_dev, bridge_init_2,
1107
ARRAY_SIZE(bridge_init_2));
1108
sccb_w_array(gspca_dev, sensor_init_2,
1109
ARRAY_SIZE(sensor_init_2));
1110
reg_w(gspca_dev, 0xe0, 0x00);
1111
reg_w(gspca_dev, 0xe0, 0x01);
1112
set_led(gspca_dev, 0);
1113
reg_w(gspca_dev, 0xe0, 0x00);
1114
1115
return gspca_dev->usb_err;
1116
}
1117
1118
static int sd_start(struct gspca_dev *gspca_dev)
1119
{
1120
switch (gspca_dev->curr_mode) {
1121
case QVGA_MODE: /* 320x240 */
1122
sccb_w_array(gspca_dev, sensor_start_1_vga,
1123
ARRAY_SIZE(sensor_start_1_vga));
1124
reg_w_array(gspca_dev, bridge_start_qvga,
1125
ARRAY_SIZE(bridge_start_qvga));
1126
sccb_w_array(gspca_dev, sensor_start_2_qvga,
1127
ARRAY_SIZE(sensor_start_2_qvga));
1128
break;
1129
case VGA_MODE: /* 640x480 */
1130
sccb_w_array(gspca_dev, sensor_start_1_vga,
1131
ARRAY_SIZE(sensor_start_1_vga));
1132
reg_w_array(gspca_dev, bridge_start_vga,
1133
ARRAY_SIZE(bridge_start_vga));
1134
sccb_w_array(gspca_dev, sensor_start_2_vga,
1135
ARRAY_SIZE(sensor_start_2_vga));
1136
break;
1137
case SVGA_MODE: /* 800x600 */
1138
sccb_w_array(gspca_dev, sensor_start_1_svga,
1139
ARRAY_SIZE(sensor_start_1_svga));
1140
reg_w_array(gspca_dev, bridge_start_svga,
1141
ARRAY_SIZE(bridge_start_svga));
1142
sccb_w_array(gspca_dev, sensor_start_2_svga,
1143
ARRAY_SIZE(sensor_start_2_svga));
1144
break;
1145
case XGA_MODE: /* 1024x768 */
1146
sccb_w_array(gspca_dev, sensor_start_1_xga,
1147
ARRAY_SIZE(sensor_start_1_xga));
1148
reg_w_array(gspca_dev, bridge_start_xga,
1149
ARRAY_SIZE(bridge_start_xga));
1150
sccb_w_array(gspca_dev, sensor_start_2_svga,
1151
ARRAY_SIZE(sensor_start_2_svga));
1152
break;
1153
default:
1154
/* case SXGA_MODE: * 1280x1024 */
1155
sccb_w_array(gspca_dev, sensor_start_1_sxga,
1156
ARRAY_SIZE(sensor_start_1_sxga));
1157
reg_w_array(gspca_dev, bridge_start_sxga,
1158
ARRAY_SIZE(bridge_start_sxga));
1159
sccb_w_array(gspca_dev, sensor_start_2_sxga,
1160
ARRAY_SIZE(sensor_start_2_sxga));
1161
break;
1162
}
1163
setfreq(gspca_dev);
1164
setautogain(gspca_dev);
1165
setbrightness(gspca_dev);
1166
setcontrast(gspca_dev);
1167
setexposure(gspca_dev);
1168
setsharpness(gspca_dev);
1169
setsatur(gspca_dev);
1170
1171
reg_w(gspca_dev, 0xe0, 0x00);
1172
reg_w(gspca_dev, 0xe0, 0x00);
1173
set_led(gspca_dev, 1);
1174
return gspca_dev->usb_err;
1175
}
1176
1177
static void sd_stopN(struct gspca_dev *gspca_dev)
1178
{
1179
reg_w(gspca_dev, 0xe0, 0x01);
1180
set_led(gspca_dev, 0);
1181
reg_w(gspca_dev, 0xe0, 0x00);
1182
}
1183
1184
/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
1185
#define UVC_STREAM_EOH (1 << 7)
1186
#define UVC_STREAM_ERR (1 << 6)
1187
#define UVC_STREAM_STI (1 << 5)
1188
#define UVC_STREAM_RES (1 << 4)
1189
#define UVC_STREAM_SCR (1 << 3)
1190
#define UVC_STREAM_PTS (1 << 2)
1191
#define UVC_STREAM_EOF (1 << 1)
1192
#define UVC_STREAM_FID (1 << 0)
1193
1194
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1195
u8 *data, int len)
1196
{
1197
struct sd *sd = (struct sd *) gspca_dev;
1198
__u32 this_pts;
1199
u8 this_fid;
1200
int remaining_len = len;
1201
1202
do {
1203
len = min(remaining_len, 2040);
1204
1205
/* Payloads are prefixed with a UVC-style header. We
1206
consider a frame to start when the FID toggles, or the PTS
1207
changes. A frame ends when EOF is set, and we've received
1208
the correct number of bytes. */
1209
1210
/* Verify UVC header. Header length is always 12 */
1211
if (data[0] != 12 || len < 12) {
1212
PDEBUG(D_PACK, "bad header");
1213
goto discard;
1214
}
1215
1216
/* Check errors */
1217
if (data[1] & UVC_STREAM_ERR) {
1218
PDEBUG(D_PACK, "payload error");
1219
goto discard;
1220
}
1221
1222
/* Extract PTS and FID */
1223
if (!(data[1] & UVC_STREAM_PTS)) {
1224
PDEBUG(D_PACK, "PTS not present");
1225
goto discard;
1226
}
1227
this_pts = (data[5] << 24) | (data[4] << 16)
1228
| (data[3] << 8) | data[2];
1229
this_fid = data[1] & UVC_STREAM_FID;
1230
1231
/* If PTS or FID has changed, start a new frame. */
1232
if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
1233
if (gspca_dev->last_packet_type == INTER_PACKET)
1234
gspca_frame_add(gspca_dev, LAST_PACKET,
1235
NULL, 0);
1236
sd->last_pts = this_pts;
1237
sd->last_fid = this_fid;
1238
gspca_frame_add(gspca_dev, FIRST_PACKET,
1239
data + 12, len - 12);
1240
/* If this packet is marked as EOF, end the frame */
1241
} else if (data[1] & UVC_STREAM_EOF) {
1242
sd->last_pts = 0;
1243
gspca_frame_add(gspca_dev, LAST_PACKET,
1244
data + 12, len - 12);
1245
} else {
1246
1247
/* Add the data from this payload */
1248
gspca_frame_add(gspca_dev, INTER_PACKET,
1249
data + 12, len - 12);
1250
}
1251
1252
/* Done this payload */
1253
goto scan_next;
1254
1255
discard:
1256
/* Discard data until a new frame starts. */
1257
gspca_dev->last_packet_type = DISCARD_PACKET;
1258
1259
scan_next:
1260
remaining_len -= len;
1261
data += len;
1262
} while (remaining_len > 0);
1263
}
1264
1265
/* controls */
1266
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1267
{
1268
struct sd *sd = (struct sd *) gspca_dev;
1269
1270
sd->brightness = val;
1271
if (gspca_dev->streaming)
1272
setbrightness(gspca_dev);
1273
return gspca_dev->usb_err;
1274
}
1275
1276
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1277
{
1278
struct sd *sd = (struct sd *) gspca_dev;
1279
1280
*val = sd->brightness;
1281
return 0;
1282
}
1283
1284
static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1285
{
1286
struct sd *sd = (struct sd *) gspca_dev;
1287
1288
sd->contrast = val;
1289
if (gspca_dev->streaming)
1290
setcontrast(gspca_dev);
1291
return gspca_dev->usb_err;
1292
}
1293
1294
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1295
{
1296
struct sd *sd = (struct sd *) gspca_dev;
1297
1298
*val = sd->contrast;
1299
return 0;
1300
}
1301
1302
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1303
{
1304
struct sd *sd = (struct sd *) gspca_dev;
1305
1306
sd->autogain = val;
1307
1308
if (gspca_dev->streaming) {
1309
if (val)
1310
gspca_dev->ctrl_inac |= (1 << EXPO_IDX);
1311
else
1312
gspca_dev->ctrl_inac &= ~(1 << EXPO_IDX);
1313
setautogain(gspca_dev);
1314
}
1315
return gspca_dev->usb_err;
1316
}
1317
1318
static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1319
{
1320
struct sd *sd = (struct sd *) gspca_dev;
1321
1322
*val = sd->autogain;
1323
return 0;
1324
}
1325
1326
static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1327
{
1328
struct sd *sd = (struct sd *) gspca_dev;
1329
1330
sd->exposure = val;
1331
if (gspca_dev->streaming)
1332
setexposure(gspca_dev);
1333
return gspca_dev->usb_err;
1334
}
1335
1336
static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1337
{
1338
struct sd *sd = (struct sd *) gspca_dev;
1339
1340
*val = sd->exposure;
1341
return 0;
1342
}
1343
1344
static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
1345
{
1346
struct sd *sd = (struct sd *) gspca_dev;
1347
1348
sd->sharpness = val;
1349
if (gspca_dev->streaming)
1350
setsharpness(gspca_dev);
1351
return gspca_dev->usb_err;
1352
}
1353
1354
static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
1355
{
1356
struct sd *sd = (struct sd *) gspca_dev;
1357
1358
*val = sd->sharpness;
1359
return 0;
1360
}
1361
1362
static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val)
1363
{
1364
struct sd *sd = (struct sd *) gspca_dev;
1365
1366
sd->satur = val;
1367
if (gspca_dev->streaming)
1368
setsatur(gspca_dev);
1369
return gspca_dev->usb_err;
1370
}
1371
1372
static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val)
1373
{
1374
struct sd *sd = (struct sd *) gspca_dev;
1375
1376
*val = sd->satur;
1377
return 0;
1378
}
1379
static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1380
{
1381
struct sd *sd = (struct sd *) gspca_dev;
1382
1383
sd->freq = val;
1384
if (gspca_dev->streaming)
1385
setfreq(gspca_dev);
1386
return gspca_dev->usb_err;
1387
}
1388
1389
static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1390
{
1391
struct sd *sd = (struct sd *) gspca_dev;
1392
1393
*val = sd->freq;
1394
return 0;
1395
}
1396
1397
static int sd_querymenu(struct gspca_dev *gspca_dev,
1398
struct v4l2_querymenu *menu)
1399
{
1400
switch (menu->id) {
1401
case V4L2_CID_POWER_LINE_FREQUENCY:
1402
switch (menu->index) {
1403
case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1404
strcpy((char *) menu->name, "NoFliker");
1405
return 0;
1406
case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1407
strcpy((char *) menu->name, "50 Hz");
1408
return 0;
1409
case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1410
strcpy((char *) menu->name, "60 Hz");
1411
return 0;
1412
}
1413
break;
1414
}
1415
return -EINVAL;
1416
}
1417
1418
/* sub-driver description */
1419
static const struct sd_desc sd_desc = {
1420
.name = MODULE_NAME,
1421
.ctrls = sd_ctrls,
1422
.nctrls = ARRAY_SIZE(sd_ctrls),
1423
.config = sd_config,
1424
.init = sd_init,
1425
.start = sd_start,
1426
.stopN = sd_stopN,
1427
.pkt_scan = sd_pkt_scan,
1428
.querymenu = sd_querymenu,
1429
};
1430
1431
/* -- module initialisation -- */
1432
static const struct usb_device_id device_table[] = {
1433
{USB_DEVICE(0x06f8, 0x3003)},
1434
{}
1435
};
1436
1437
MODULE_DEVICE_TABLE(usb, device_table);
1438
1439
/* -- device connect -- */
1440
static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
1441
{
1442
return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1443
THIS_MODULE);
1444
}
1445
1446
static struct usb_driver sd_driver = {
1447
.name = MODULE_NAME,
1448
.id_table = device_table,
1449
.probe = sd_probe,
1450
.disconnect = gspca_disconnect,
1451
#ifdef CONFIG_PM
1452
.suspend = gspca_suspend,
1453
.resume = gspca_resume,
1454
#endif
1455
};
1456
1457
/* -- module insert / remove -- */
1458
static int __init sd_mod_init(void)
1459
{
1460
return usb_register(&sd_driver);
1461
}
1462
1463
static void __exit sd_mod_exit(void)
1464
{
1465
usb_deregister(&sd_driver);
1466
}
1467
1468
module_init(sd_mod_init);
1469
module_exit(sd_mod_exit);
1470
1471