Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/video/gspca/spca561.c
17705 views
1
/*
2
* Sunplus spca561 subdriver
3
*
4
* Copyright (C) 2004 Michel Xhaard [email protected]
5
*
6
* V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
7
*
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* any later version.
12
*
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
17
*
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
*/
22
23
#define MODULE_NAME "spca561"
24
25
#include <linux/input.h>
26
#include "gspca.h"
27
28
MODULE_AUTHOR("Michel Xhaard <[email protected]>");
29
MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver");
30
MODULE_LICENSE("GPL");
31
32
/* specific webcam descriptor */
33
struct sd {
34
struct gspca_dev gspca_dev; /* !! must be the first item */
35
36
__u16 exposure; /* rev12a only */
37
#define EXPOSURE_MIN 1
38
#define EXPOSURE_DEF 700 /* == 10 fps */
39
#define EXPOSURE_MAX (2047 + 325) /* see setexposure */
40
41
__u8 contrast; /* rev72a only */
42
#define CONTRAST_MIN 0x00
43
#define CONTRAST_DEF 0x20
44
#define CONTRAST_MAX 0x3f
45
46
__u8 brightness; /* rev72a only */
47
#define BRIGHTNESS_MIN 0
48
#define BRIGHTNESS_DEF 0x20
49
#define BRIGHTNESS_MAX 0x3f
50
51
__u8 white;
52
#define HUE_MIN 1
53
#define HUE_DEF 0x40
54
#define HUE_MAX 0x7f
55
56
__u8 autogain;
57
#define AUTOGAIN_MIN 0
58
#define AUTOGAIN_DEF 1
59
#define AUTOGAIN_MAX 1
60
61
__u8 gain; /* rev12a only */
62
#define GAIN_MIN 0
63
#define GAIN_DEF 63
64
#define GAIN_MAX 255
65
66
#define EXPO12A_DEF 3
67
__u8 expo12a; /* expo/gain? for rev 12a */
68
69
__u8 chip_revision;
70
#define Rev012A 0
71
#define Rev072A 1
72
73
signed char ag_cnt;
74
#define AG_CNT_START 13
75
};
76
77
static const struct v4l2_pix_format sif_012a_mode[] = {
78
{160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
79
.bytesperline = 160,
80
.sizeimage = 160 * 120,
81
.colorspace = V4L2_COLORSPACE_SRGB,
82
.priv = 3},
83
{176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
84
.bytesperline = 176,
85
.sizeimage = 176 * 144,
86
.colorspace = V4L2_COLORSPACE_SRGB,
87
.priv = 2},
88
{320, 240, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
89
.bytesperline = 320,
90
.sizeimage = 320 * 240 * 4 / 8,
91
.colorspace = V4L2_COLORSPACE_SRGB,
92
.priv = 1},
93
{352, 288, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
94
.bytesperline = 352,
95
.sizeimage = 352 * 288 * 4 / 8,
96
.colorspace = V4L2_COLORSPACE_SRGB,
97
.priv = 0},
98
};
99
100
static const struct v4l2_pix_format sif_072a_mode[] = {
101
{160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
102
.bytesperline = 160,
103
.sizeimage = 160 * 120,
104
.colorspace = V4L2_COLORSPACE_SRGB,
105
.priv = 3},
106
{176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
107
.bytesperline = 176,
108
.sizeimage = 176 * 144,
109
.colorspace = V4L2_COLORSPACE_SRGB,
110
.priv = 2},
111
{320, 240, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
112
.bytesperline = 320,
113
.sizeimage = 320 * 240,
114
.colorspace = V4L2_COLORSPACE_SRGB,
115
.priv = 1},
116
{352, 288, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
117
.bytesperline = 352,
118
.sizeimage = 352 * 288,
119
.colorspace = V4L2_COLORSPACE_SRGB,
120
.priv = 0},
121
};
122
123
/*
124
* Initialization data
125
* I'm not very sure how to split initialization from open data
126
* chunks. For now, we'll consider everything as initialization
127
*/
128
/* Frame packet header offsets for the spca561 */
129
#define SPCA561_OFFSET_SNAP 1
130
#define SPCA561_OFFSET_TYPE 2
131
#define SPCA561_OFFSET_COMPRESS 3
132
#define SPCA561_OFFSET_FRAMSEQ 4
133
#define SPCA561_OFFSET_GPIO 5
134
#define SPCA561_OFFSET_USBBUFF 6
135
#define SPCA561_OFFSET_WIN2GRAVE 7
136
#define SPCA561_OFFSET_WIN2RAVE 8
137
#define SPCA561_OFFSET_WIN2BAVE 9
138
#define SPCA561_OFFSET_WIN2GBAVE 10
139
#define SPCA561_OFFSET_WIN1GRAVE 11
140
#define SPCA561_OFFSET_WIN1RAVE 12
141
#define SPCA561_OFFSET_WIN1BAVE 13
142
#define SPCA561_OFFSET_WIN1GBAVE 14
143
#define SPCA561_OFFSET_FREQ 15
144
#define SPCA561_OFFSET_VSYNC 16
145
#define SPCA561_INDEX_I2C_BASE 0x8800
146
#define SPCA561_SNAPBIT 0x20
147
#define SPCA561_SNAPCTRL 0x40
148
149
static const u16 rev72a_reset[][2] = {
150
{0x0000, 0x8114}, /* Software GPIO output data */
151
{0x0001, 0x8114}, /* Software GPIO output data */
152
{0x0000, 0x8112}, /* Some kind of reset */
153
{}
154
};
155
static const __u16 rev72a_init_data1[][2] = {
156
{0x0003, 0x8701}, /* PCLK clock delay adjustment */
157
{0x0001, 0x8703}, /* HSYNC from cmos inverted */
158
{0x0011, 0x8118}, /* Enable and conf sensor */
159
{0x0001, 0x8118}, /* Conf sensor */
160
{0x0092, 0x8804}, /* I know nothing about these */
161
{0x0010, 0x8802}, /* 0x88xx registers, so I won't */
162
{}
163
};
164
static const u16 rev72a_init_sensor1[][2] = {
165
{0x0001, 0x000d},
166
{0x0002, 0x0018},
167
{0x0004, 0x0165},
168
{0x0005, 0x0021},
169
{0x0007, 0x00aa},
170
{0x0020, 0x1504},
171
{0x0039, 0x0002},
172
{0x0035, 0x0010},
173
{0x0009, 0x1049},
174
{0x0028, 0x000b},
175
{0x003b, 0x000f},
176
{0x003c, 0x0000},
177
{}
178
};
179
static const __u16 rev72a_init_data2[][2] = {
180
{0x0018, 0x8601}, /* Pixel/line selection for color separation */
181
{0x0000, 0x8602}, /* Optical black level for user setting */
182
{0x0060, 0x8604}, /* Optical black horizontal offset */
183
{0x0002, 0x8605}, /* Optical black vertical offset */
184
{0x0000, 0x8603}, /* Non-automatic optical black level */
185
{0x0002, 0x865b}, /* Horizontal offset for valid pixels */
186
{0x0000, 0x865f}, /* Vertical valid pixels window (x2) */
187
{0x00b0, 0x865d}, /* Horizontal valid pixels window (x2) */
188
{0x0090, 0x865e}, /* Vertical valid lines window (x2) */
189
{0x00e0, 0x8406}, /* Memory buffer threshold */
190
{0x0000, 0x8660}, /* Compensation memory stuff */
191
{0x0002, 0x8201}, /* Output address for r/w serial EEPROM */
192
{0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */
193
{0x0001, 0x8200}, /* OprMode to be executed by hardware */
194
/* from ms-win */
195
{0x0000, 0x8611}, /* R offset for white balance */
196
{0x00fd, 0x8612}, /* Gr offset for white balance */
197
{0x0003, 0x8613}, /* B offset for white balance */
198
{0x0000, 0x8614}, /* Gb offset for white balance */
199
/* from ms-win */
200
{0x0035, 0x8651}, /* R gain for white balance */
201
{0x0040, 0x8652}, /* Gr gain for white balance */
202
{0x005f, 0x8653}, /* B gain for white balance */
203
{0x0040, 0x8654}, /* Gb gain for white balance */
204
{0x0002, 0x8502}, /* Maximum average bit rate stuff */
205
{0x0011, 0x8802},
206
207
{0x0087, 0x8700}, /* Set master clock (96Mhz????) */
208
{0x0081, 0x8702}, /* Master clock output enable */
209
210
{0x0000, 0x8500}, /* Set image type (352x288 no compression) */
211
/* Originally was 0x0010 (352x288 compression) */
212
213
{0x0002, 0x865b}, /* Horizontal offset for valid pixels */
214
{0x0003, 0x865c}, /* Vertical offset for valid lines */
215
{}
216
};
217
static const u16 rev72a_init_sensor2[][2] = {
218
{0x0003, 0x0121},
219
{0x0004, 0x0165},
220
{0x0005, 0x002f}, /* blanking control column */
221
{0x0006, 0x0000}, /* blanking mode row*/
222
{0x000a, 0x0002},
223
{0x0009, 0x1061}, /* setexposure times && pixel clock
224
* 0001 0 | 000 0110 0001 */
225
{0x0035, 0x0014},
226
{}
227
};
228
229
/******************** QC Express etch2 stuff ********************/
230
static const __u16 Pb100_1map8300[][2] = {
231
/* reg, value */
232
{0x8320, 0x3304},
233
234
{0x8303, 0x0125}, /* image area */
235
{0x8304, 0x0169},
236
{0x8328, 0x000b},
237
{0x833c, 0x0001}, /*fixme: win:07*/
238
239
{0x832f, 0x1904}, /*fixme: was 0419*/
240
{0x8307, 0x00aa},
241
{0x8301, 0x0003},
242
{0x8302, 0x000e},
243
{}
244
};
245
static const __u16 Pb100_2map8300[][2] = {
246
/* reg, value */
247
{0x8339, 0x0000},
248
{0x8307, 0x00aa},
249
{}
250
};
251
252
static const __u16 spca561_161rev12A_data1[][2] = {
253
{0x29, 0x8118}, /* Control register (various enable bits) */
254
{0x08, 0x8114}, /* GPIO: Led off */
255
{0x0e, 0x8112}, /* 0x0e stream off 0x3e stream on */
256
{0x00, 0x8102}, /* white balance - new */
257
{0x92, 0x8804},
258
{0x04, 0x8802}, /* windows uses 08 */
259
{}
260
};
261
static const __u16 spca561_161rev12A_data2[][2] = {
262
{0x21, 0x8118},
263
{0x10, 0x8500},
264
{0x07, 0x8601},
265
{0x07, 0x8602},
266
{0x04, 0x8501},
267
268
{0x07, 0x8201}, /* windows uses 02 */
269
{0x08, 0x8200},
270
{0x01, 0x8200},
271
272
{0x90, 0x8604},
273
{0x00, 0x8605},
274
{0xb0, 0x8603},
275
276
/* sensor gains */
277
{0x07, 0x8601}, /* white balance - new */
278
{0x07, 0x8602}, /* white balance - new */
279
{0x00, 0x8610}, /* *red */
280
{0x00, 0x8611}, /* 3f *green */
281
{0x00, 0x8612}, /* green *blue */
282
{0x00, 0x8613}, /* blue *green */
283
{0x43, 0x8614}, /* green *red - white balance - was 0x35 */
284
{0x40, 0x8615}, /* 40 *green - white balance - was 0x35 */
285
{0x71, 0x8616}, /* 7a *blue - white balance - was 0x35 */
286
{0x40, 0x8617}, /* 40 *green - white balance - was 0x35 */
287
288
{0x0c, 0x8620}, /* 0c */
289
{0xc8, 0x8631}, /* c8 */
290
{0xc8, 0x8634}, /* c8 */
291
{0x23, 0x8635}, /* 23 */
292
{0x1f, 0x8636}, /* 1f */
293
{0xdd, 0x8637}, /* dd */
294
{0xe1, 0x8638}, /* e1 */
295
{0x1d, 0x8639}, /* 1d */
296
{0x21, 0x863a}, /* 21 */
297
{0xe3, 0x863b}, /* e3 */
298
{0xdf, 0x863c}, /* df */
299
{0xf0, 0x8505},
300
{0x32, 0x850a},
301
/* {0x99, 0x8700}, * - white balance - new (removed) */
302
/* HDG we used to do this in stop0, making the init state and the state
303
after a start / stop different, so do this here instead. */
304
{0x29, 0x8118},
305
{}
306
};
307
308
static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value)
309
{
310
int ret;
311
312
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
313
0, /* request */
314
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
315
value, index, NULL, 0, 500);
316
PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value);
317
if (ret < 0)
318
err("reg write: error %d", ret);
319
}
320
321
static void write_vector(struct gspca_dev *gspca_dev,
322
const __u16 data[][2])
323
{
324
struct usb_device *dev = gspca_dev->dev;
325
int i;
326
327
i = 0;
328
while (data[i][1] != 0) {
329
reg_w_val(dev, data[i][1], data[i][0]);
330
i++;
331
}
332
}
333
334
/* read 'len' bytes to gspca_dev->usb_buf */
335
static void reg_r(struct gspca_dev *gspca_dev,
336
__u16 index, __u16 length)
337
{
338
usb_control_msg(gspca_dev->dev,
339
usb_rcvctrlpipe(gspca_dev->dev, 0),
340
0, /* request */
341
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
342
0, /* value */
343
index, gspca_dev->usb_buf, length, 500);
344
}
345
346
/* write 'len' bytes from gspca_dev->usb_buf */
347
static void reg_w_buf(struct gspca_dev *gspca_dev,
348
__u16 index, __u16 len)
349
{
350
usb_control_msg(gspca_dev->dev,
351
usb_sndctrlpipe(gspca_dev->dev, 0),
352
0, /* request */
353
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
354
0, /* value */
355
index, gspca_dev->usb_buf, len, 500);
356
}
357
358
static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg)
359
{
360
int retry = 60;
361
362
reg_w_val(gspca_dev->dev, 0x8801, reg);
363
reg_w_val(gspca_dev->dev, 0x8805, value);
364
reg_w_val(gspca_dev->dev, 0x8800, value >> 8);
365
do {
366
reg_r(gspca_dev, 0x8803, 1);
367
if (!gspca_dev->usb_buf[0])
368
return;
369
msleep(10);
370
} while (--retry);
371
}
372
373
static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
374
{
375
int retry = 60;
376
__u8 value;
377
378
reg_w_val(gspca_dev->dev, 0x8804, 0x92);
379
reg_w_val(gspca_dev->dev, 0x8801, reg);
380
reg_w_val(gspca_dev->dev, 0x8802, mode | 0x01);
381
do {
382
reg_r(gspca_dev, 0x8803, 1);
383
if (!gspca_dev->usb_buf[0]) {
384
reg_r(gspca_dev, 0x8800, 1);
385
value = gspca_dev->usb_buf[0];
386
reg_r(gspca_dev, 0x8805, 1);
387
return ((int) value << 8) | gspca_dev->usb_buf[0];
388
}
389
msleep(10);
390
} while (--retry);
391
return -1;
392
}
393
394
static void sensor_mapwrite(struct gspca_dev *gspca_dev,
395
const __u16 (*sensormap)[2])
396
{
397
while ((*sensormap)[0]) {
398
gspca_dev->usb_buf[0] = (*sensormap)[1];
399
gspca_dev->usb_buf[1] = (*sensormap)[1] >> 8;
400
reg_w_buf(gspca_dev, (*sensormap)[0], 2);
401
sensormap++;
402
}
403
}
404
405
static void write_sensor_72a(struct gspca_dev *gspca_dev,
406
const __u16 (*sensor)[2])
407
{
408
while ((*sensor)[0]) {
409
i2c_write(gspca_dev, (*sensor)[1], (*sensor)[0]);
410
sensor++;
411
}
412
}
413
414
static void init_161rev12A(struct gspca_dev *gspca_dev)
415
{
416
write_vector(gspca_dev, spca561_161rev12A_data1);
417
sensor_mapwrite(gspca_dev, Pb100_1map8300);
418
/*fixme: should be in sd_start*/
419
write_vector(gspca_dev, spca561_161rev12A_data2);
420
sensor_mapwrite(gspca_dev, Pb100_2map8300);
421
}
422
423
/* this function is called at probe time */
424
static int sd_config(struct gspca_dev *gspca_dev,
425
const struct usb_device_id *id)
426
{
427
struct sd *sd = (struct sd *) gspca_dev;
428
struct cam *cam;
429
__u16 vendor, product;
430
__u8 data1, data2;
431
432
/* Read frm global register the USB product and vendor IDs, just to
433
* prove that we can communicate with the device. This works, which
434
* confirms at we are communicating properly and that the device
435
* is a 561. */
436
reg_r(gspca_dev, 0x8104, 1);
437
data1 = gspca_dev->usb_buf[0];
438
reg_r(gspca_dev, 0x8105, 1);
439
data2 = gspca_dev->usb_buf[0];
440
vendor = (data2 << 8) | data1;
441
reg_r(gspca_dev, 0x8106, 1);
442
data1 = gspca_dev->usb_buf[0];
443
reg_r(gspca_dev, 0x8107, 1);
444
data2 = gspca_dev->usb_buf[0];
445
product = (data2 << 8) | data1;
446
if (vendor != id->idVendor || product != id->idProduct) {
447
PDEBUG(D_PROBE, "Bad vendor / product from device");
448
return -EINVAL;
449
}
450
451
cam = &gspca_dev->cam;
452
gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */
453
454
sd->chip_revision = id->driver_info;
455
if (sd->chip_revision == Rev012A) {
456
cam->cam_mode = sif_012a_mode;
457
cam->nmodes = ARRAY_SIZE(sif_012a_mode);
458
} else {
459
cam->cam_mode = sif_072a_mode;
460
cam->nmodes = ARRAY_SIZE(sif_072a_mode);
461
}
462
sd->brightness = BRIGHTNESS_DEF;
463
sd->contrast = CONTRAST_DEF;
464
sd->white = HUE_DEF;
465
sd->exposure = EXPOSURE_DEF;
466
sd->autogain = AUTOGAIN_DEF;
467
sd->gain = GAIN_DEF;
468
sd->expo12a = EXPO12A_DEF;
469
return 0;
470
}
471
472
/* this function is called at probe and resume time */
473
static int sd_init_12a(struct gspca_dev *gspca_dev)
474
{
475
PDEBUG(D_STREAM, "Chip revision: 012a");
476
init_161rev12A(gspca_dev);
477
return 0;
478
}
479
static int sd_init_72a(struct gspca_dev *gspca_dev)
480
{
481
PDEBUG(D_STREAM, "Chip revision: 072a");
482
write_vector(gspca_dev, rev72a_reset);
483
msleep(200);
484
write_vector(gspca_dev, rev72a_init_data1);
485
write_sensor_72a(gspca_dev, rev72a_init_sensor1);
486
write_vector(gspca_dev, rev72a_init_data2);
487
write_sensor_72a(gspca_dev, rev72a_init_sensor2);
488
reg_w_val(gspca_dev->dev, 0x8112, 0x30);
489
return 0;
490
}
491
492
/* rev 72a only */
493
static void setbrightness(struct gspca_dev *gspca_dev)
494
{
495
struct sd *sd = (struct sd *) gspca_dev;
496
struct usb_device *dev = gspca_dev->dev;
497
__u8 value;
498
499
value = sd->brightness;
500
501
/* offsets for white balance */
502
reg_w_val(dev, 0x8611, value); /* R */
503
reg_w_val(dev, 0x8612, value); /* Gr */
504
reg_w_val(dev, 0x8613, value); /* B */
505
reg_w_val(dev, 0x8614, value); /* Gb */
506
}
507
508
static void setwhite(struct gspca_dev *gspca_dev)
509
{
510
struct sd *sd = (struct sd *) gspca_dev;
511
__u16 white;
512
__u8 blue, red;
513
__u16 reg;
514
515
/* try to emulate MS-win as possible */
516
white = sd->white;
517
red = 0x20 + white * 3 / 8;
518
blue = 0x90 - white * 5 / 8;
519
if (sd->chip_revision == Rev012A) {
520
reg = 0x8614;
521
} else {
522
reg = 0x8651;
523
red += sd->contrast - 0x20;
524
blue += sd->contrast - 0x20;
525
}
526
reg_w_val(gspca_dev->dev, reg, red);
527
reg_w_val(gspca_dev->dev, reg + 2, blue);
528
}
529
530
static void setcontrast(struct gspca_dev *gspca_dev)
531
{
532
struct sd *sd = (struct sd *) gspca_dev;
533
struct usb_device *dev = gspca_dev->dev;
534
__u8 value;
535
536
if (sd->chip_revision != Rev072A)
537
return;
538
value = sd->contrast + 0x20;
539
540
/* gains for white balance */
541
setwhite(gspca_dev);
542
/* reg_w_val(dev, 0x8651, value); * R - done by setwhite */
543
reg_w_val(dev, 0x8652, value); /* Gr */
544
/* reg_w_val(dev, 0x8653, value); * B - done by setwhite */
545
reg_w_val(dev, 0x8654, value); /* Gb */
546
}
547
548
/* rev 12a only */
549
static void setexposure(struct gspca_dev *gspca_dev)
550
{
551
struct sd *sd = (struct sd *) gspca_dev;
552
int i, expo = 0;
553
554
/* Register 0x8309 controls exposure for the spca561,
555
the basic exposure setting goes from 1-2047, where 1 is completely
556
dark and 2047 is very bright. It not only influences exposure but
557
also the framerate (to allow for longer exposure) from 1 - 300 it
558
only raises the exposure time then from 300 - 600 it halves the
559
framerate to be able to further raise the exposure time and for every
560
300 more it halves the framerate again. This allows for a maximum
561
exposure time of circa 0.2 - 0.25 seconds (30 / (2000/3000) fps).
562
Sometimes this is not enough, the 1-2047 uses bits 0-10, bits 11-12
563
configure a divider for the base framerate which us used at the
564
exposure setting of 1-300. These bits configure the base framerate
565
according to the following formula: fps = 60 / (value + 2) */
566
567
/* We choose to use the high bits setting the fixed framerate divisor
568
asap, as setting high basic exposure setting without the fixed
569
divider in combination with high gains makes the cam stop */
570
int table[] = { 0, 450, 550, 625, EXPOSURE_MAX };
571
572
for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
573
if (sd->exposure <= table[i + 1]) {
574
expo = sd->exposure - table[i];
575
if (i)
576
expo += 300;
577
expo |= i << 11;
578
break;
579
}
580
}
581
582
gspca_dev->usb_buf[0] = expo;
583
gspca_dev->usb_buf[1] = expo >> 8;
584
reg_w_buf(gspca_dev, 0x8309, 2);
585
}
586
587
/* rev 12a only */
588
static void setgain(struct gspca_dev *gspca_dev)
589
{
590
struct sd *sd = (struct sd *) gspca_dev;
591
592
/* gain reg low 6 bits 0-63 gain, bit 6 and 7, both double the
593
sensitivity when set, so 31 + one of them set == 63, and 15
594
with both of them set == 63 */
595
if (sd->gain < 64)
596
gspca_dev->usb_buf[0] = sd->gain;
597
else if (sd->gain < 128)
598
gspca_dev->usb_buf[0] = (sd->gain / 2) | 0x40;
599
else
600
gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xc0;
601
602
gspca_dev->usb_buf[1] = 0;
603
reg_w_buf(gspca_dev, 0x8335, 2);
604
}
605
606
static void setautogain(struct gspca_dev *gspca_dev)
607
{
608
struct sd *sd = (struct sd *) gspca_dev;
609
610
if (sd->autogain)
611
sd->ag_cnt = AG_CNT_START;
612
else
613
sd->ag_cnt = -1;
614
}
615
616
static int sd_start_12a(struct gspca_dev *gspca_dev)
617
{
618
struct usb_device *dev = gspca_dev->dev;
619
int mode;
620
static const __u8 Reg8391[8] =
621
{0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00};
622
623
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
624
if (mode <= 1) {
625
/* Use compression on 320x240 and above */
626
reg_w_val(dev, 0x8500, 0x10 | mode);
627
} else {
628
/* I couldn't get the compression to work below 320x240
629
* Fortunately at these resolutions the bandwidth
630
* is sufficient to push raw frames at ~20fps */
631
reg_w_val(dev, 0x8500, mode);
632
} /* -- [email protected] */
633
634
gspca_dev->usb_buf[0] = 0xaa;
635
gspca_dev->usb_buf[1] = 0x00;
636
reg_w_buf(gspca_dev, 0x8307, 2);
637
/* clock - lower 0x8X values lead to fps > 30 */
638
reg_w_val(gspca_dev->dev, 0x8700, 0x8a);
639
/* 0x8f 0x85 0x27 clock */
640
reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
641
reg_w_val(gspca_dev->dev, 0x850b, 0x03);
642
memcpy(gspca_dev->usb_buf, Reg8391, 8);
643
reg_w_buf(gspca_dev, 0x8391, 8);
644
reg_w_buf(gspca_dev, 0x8390, 8);
645
setwhite(gspca_dev);
646
setgain(gspca_dev);
647
setexposure(gspca_dev);
648
649
/* Led ON (bit 3 -> 0 */
650
reg_w_val(gspca_dev->dev, 0x8114, 0x00);
651
return 0;
652
}
653
static int sd_start_72a(struct gspca_dev *gspca_dev)
654
{
655
struct usb_device *dev = gspca_dev->dev;
656
int Clck;
657
int mode;
658
659
write_vector(gspca_dev, rev72a_reset);
660
msleep(200);
661
write_vector(gspca_dev, rev72a_init_data1);
662
write_sensor_72a(gspca_dev, rev72a_init_sensor1);
663
664
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
665
switch (mode) {
666
default:
667
case 0:
668
Clck = 0x27; /* ms-win 0x87 */
669
break;
670
case 1:
671
Clck = 0x25;
672
break;
673
case 2:
674
Clck = 0x22;
675
break;
676
case 3:
677
Clck = 0x21;
678
break;
679
}
680
reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */
681
reg_w_val(dev, 0x8702, 0x81);
682
reg_w_val(dev, 0x8500, mode); /* mode */
683
write_sensor_72a(gspca_dev, rev72a_init_sensor2);
684
setcontrast(gspca_dev);
685
/* setbrightness(gspca_dev); * fixme: bad values */
686
setautogain(gspca_dev);
687
reg_w_val(dev, 0x8112, 0x10 | 0x20);
688
return 0;
689
}
690
691
static void sd_stopN(struct gspca_dev *gspca_dev)
692
{
693
struct sd *sd = (struct sd *) gspca_dev;
694
695
if (sd->chip_revision == Rev012A) {
696
reg_w_val(gspca_dev->dev, 0x8112, 0x0e);
697
/* Led Off (bit 3 -> 1 */
698
reg_w_val(gspca_dev->dev, 0x8114, 0x08);
699
} else {
700
reg_w_val(gspca_dev->dev, 0x8112, 0x20);
701
/* reg_w_val(gspca_dev->dev, 0x8102, 0x00); ?? */
702
}
703
}
704
705
static void do_autogain(struct gspca_dev *gspca_dev)
706
{
707
struct sd *sd = (struct sd *) gspca_dev;
708
int expotimes;
709
int pixelclk;
710
int gainG;
711
__u8 R, Gr, Gb, B;
712
int y;
713
__u8 luma_mean = 110;
714
__u8 luma_delta = 20;
715
__u8 spring = 4;
716
717
if (sd->ag_cnt < 0)
718
return;
719
if (--sd->ag_cnt >= 0)
720
return;
721
sd->ag_cnt = AG_CNT_START;
722
723
switch (sd->chip_revision) {
724
case Rev072A:
725
reg_r(gspca_dev, 0x8621, 1);
726
Gr = gspca_dev->usb_buf[0];
727
reg_r(gspca_dev, 0x8622, 1);
728
R = gspca_dev->usb_buf[0];
729
reg_r(gspca_dev, 0x8623, 1);
730
B = gspca_dev->usb_buf[0];
731
reg_r(gspca_dev, 0x8624, 1);
732
Gb = gspca_dev->usb_buf[0];
733
y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8;
734
/* u= (128*B-(43*(Gr+Gb+R))) >> 8; */
735
/* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */
736
/* PDEBUG(D_CONF,"reading Y %d U %d V %d ",y,u,v); */
737
738
if (y < luma_mean - luma_delta ||
739
y > luma_mean + luma_delta) {
740
expotimes = i2c_read(gspca_dev, 0x09, 0x10);
741
pixelclk = 0x0800;
742
expotimes = expotimes & 0x07ff;
743
/* PDEBUG(D_PACK,
744
"Exposition Times 0x%03X Clock 0x%04X ",
745
expotimes,pixelclk); */
746
gainG = i2c_read(gspca_dev, 0x35, 0x10);
747
/* PDEBUG(D_PACK,
748
"reading Gain register %d", gainG); */
749
750
expotimes += (luma_mean - y) >> spring;
751
gainG += (luma_mean - y) / 50;
752
/* PDEBUG(D_PACK,
753
"compute expotimes %d gain %d",
754
expotimes,gainG); */
755
756
if (gainG > 0x3f)
757
gainG = 0x3f;
758
else if (gainG < 3)
759
gainG = 3;
760
i2c_write(gspca_dev, gainG, 0x35);
761
762
if (expotimes > 0x0256)
763
expotimes = 0x0256;
764
else if (expotimes < 3)
765
expotimes = 3;
766
i2c_write(gspca_dev, expotimes | pixelclk, 0x09);
767
}
768
break;
769
}
770
}
771
772
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
773
u8 *data, /* isoc packet */
774
int len) /* iso packet length */
775
{
776
struct sd *sd = (struct sd *) gspca_dev;
777
778
len--;
779
switch (*data++) { /* sequence number */
780
case 0: /* start of frame */
781
gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
782
783
/* This should never happen */
784
if (len < 2) {
785
PDEBUG(D_ERR, "Short SOF packet, ignoring");
786
gspca_dev->last_packet_type = DISCARD_PACKET;
787
return;
788
}
789
790
#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
791
if (data[0] & 0x20) {
792
input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
793
input_sync(gspca_dev->input_dev);
794
input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
795
input_sync(gspca_dev->input_dev);
796
}
797
#endif
798
799
if (data[1] & 0x10) {
800
/* compressed bayer */
801
gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
802
} else {
803
/* raw bayer (with a header, which we skip) */
804
if (sd->chip_revision == Rev012A) {
805
data += 20;
806
len -= 20;
807
} else {
808
data += 16;
809
len -= 16;
810
}
811
gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
812
}
813
return;
814
case 0xff: /* drop (empty mpackets) */
815
return;
816
}
817
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
818
}
819
820
/* rev 72a only */
821
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
822
{
823
struct sd *sd = (struct sd *) gspca_dev;
824
825
sd->brightness = val;
826
if (gspca_dev->streaming)
827
setbrightness(gspca_dev);
828
return 0;
829
}
830
831
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
832
{
833
struct sd *sd = (struct sd *) gspca_dev;
834
835
*val = sd->brightness;
836
return 0;
837
}
838
839
/* rev 72a only */
840
static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
841
{
842
struct sd *sd = (struct sd *) gspca_dev;
843
844
sd->contrast = val;
845
if (gspca_dev->streaming)
846
setcontrast(gspca_dev);
847
return 0;
848
}
849
850
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
851
{
852
struct sd *sd = (struct sd *) gspca_dev;
853
854
*val = sd->contrast;
855
return 0;
856
}
857
858
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
859
{
860
struct sd *sd = (struct sd *) gspca_dev;
861
862
sd->autogain = val;
863
if (gspca_dev->streaming)
864
setautogain(gspca_dev);
865
return 0;
866
}
867
868
static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
869
{
870
struct sd *sd = (struct sd *) gspca_dev;
871
872
*val = sd->autogain;
873
return 0;
874
}
875
876
static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val)
877
{
878
struct sd *sd = (struct sd *) gspca_dev;
879
880
sd->white = val;
881
if (gspca_dev->streaming)
882
setwhite(gspca_dev);
883
return 0;
884
}
885
886
static int sd_getwhite(struct gspca_dev *gspca_dev, __s32 *val)
887
{
888
struct sd *sd = (struct sd *) gspca_dev;
889
890
*val = sd->white;
891
return 0;
892
}
893
894
/* rev12a only */
895
static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
896
{
897
struct sd *sd = (struct sd *) gspca_dev;
898
899
sd->exposure = val;
900
if (gspca_dev->streaming)
901
setexposure(gspca_dev);
902
return 0;
903
}
904
905
static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
906
{
907
struct sd *sd = (struct sd *) gspca_dev;
908
909
*val = sd->exposure;
910
return 0;
911
}
912
913
/* rev12a only */
914
static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
915
{
916
struct sd *sd = (struct sd *) gspca_dev;
917
918
sd->gain = val;
919
if (gspca_dev->streaming)
920
setgain(gspca_dev);
921
return 0;
922
}
923
924
static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
925
{
926
struct sd *sd = (struct sd *) gspca_dev;
927
928
*val = sd->gain;
929
return 0;
930
}
931
932
/* control tables */
933
static const struct ctrl sd_ctrls_12a[] = {
934
{
935
{
936
.id = V4L2_CID_HUE,
937
.type = V4L2_CTRL_TYPE_INTEGER,
938
.name = "Hue",
939
.minimum = HUE_MIN,
940
.maximum = HUE_MAX,
941
.step = 1,
942
.default_value = HUE_DEF,
943
},
944
.set = sd_setwhite,
945
.get = sd_getwhite,
946
},
947
{
948
{
949
.id = V4L2_CID_EXPOSURE,
950
.type = V4L2_CTRL_TYPE_INTEGER,
951
.name = "Exposure",
952
.minimum = EXPOSURE_MIN,
953
.maximum = EXPOSURE_MAX,
954
.step = 1,
955
.default_value = EXPOSURE_DEF,
956
},
957
.set = sd_setexposure,
958
.get = sd_getexposure,
959
},
960
{
961
{
962
.id = V4L2_CID_GAIN,
963
.type = V4L2_CTRL_TYPE_INTEGER,
964
.name = "Gain",
965
.minimum = GAIN_MIN,
966
.maximum = GAIN_MAX,
967
.step = 1,
968
.default_value = GAIN_DEF,
969
},
970
.set = sd_setgain,
971
.get = sd_getgain,
972
},
973
};
974
975
static const struct ctrl sd_ctrls_72a[] = {
976
{
977
{
978
.id = V4L2_CID_HUE,
979
.type = V4L2_CTRL_TYPE_INTEGER,
980
.name = "Hue",
981
.minimum = HUE_MIN,
982
.maximum = HUE_MAX,
983
.step = 1,
984
.default_value = HUE_DEF,
985
},
986
.set = sd_setwhite,
987
.get = sd_getwhite,
988
},
989
{
990
{
991
.id = V4L2_CID_BRIGHTNESS,
992
.type = V4L2_CTRL_TYPE_INTEGER,
993
.name = "Brightness",
994
.minimum = BRIGHTNESS_MIN,
995
.maximum = BRIGHTNESS_MAX,
996
.step = 1,
997
.default_value = BRIGHTNESS_DEF,
998
},
999
.set = sd_setbrightness,
1000
.get = sd_getbrightness,
1001
},
1002
{
1003
{
1004
.id = V4L2_CID_CONTRAST,
1005
.type = V4L2_CTRL_TYPE_INTEGER,
1006
.name = "Contrast",
1007
.minimum = CONTRAST_MIN,
1008
.maximum = CONTRAST_MAX,
1009
.step = 1,
1010
.default_value = CONTRAST_DEF,
1011
},
1012
.set = sd_setcontrast,
1013
.get = sd_getcontrast,
1014
},
1015
{
1016
{
1017
.id = V4L2_CID_AUTOGAIN,
1018
.type = V4L2_CTRL_TYPE_BOOLEAN,
1019
.name = "Auto Gain",
1020
.minimum = AUTOGAIN_MIN,
1021
.maximum = AUTOGAIN_MAX,
1022
.step = 1,
1023
.default_value = AUTOGAIN_DEF,
1024
},
1025
.set = sd_setautogain,
1026
.get = sd_getautogain,
1027
},
1028
};
1029
1030
/* sub-driver description */
1031
static const struct sd_desc sd_desc_12a = {
1032
.name = MODULE_NAME,
1033
.ctrls = sd_ctrls_12a,
1034
.nctrls = ARRAY_SIZE(sd_ctrls_12a),
1035
.config = sd_config,
1036
.init = sd_init_12a,
1037
.start = sd_start_12a,
1038
.stopN = sd_stopN,
1039
.pkt_scan = sd_pkt_scan,
1040
#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1041
.other_input = 1,
1042
#endif
1043
};
1044
static const struct sd_desc sd_desc_72a = {
1045
.name = MODULE_NAME,
1046
.ctrls = sd_ctrls_72a,
1047
.nctrls = ARRAY_SIZE(sd_ctrls_72a),
1048
.config = sd_config,
1049
.init = sd_init_72a,
1050
.start = sd_start_72a,
1051
.stopN = sd_stopN,
1052
.pkt_scan = sd_pkt_scan,
1053
.dq_callback = do_autogain,
1054
#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1055
.other_input = 1,
1056
#endif
1057
};
1058
static const struct sd_desc *sd_desc[2] = {
1059
&sd_desc_12a,
1060
&sd_desc_72a
1061
};
1062
1063
/* -- module initialisation -- */
1064
static const struct usb_device_id device_table[] = {
1065
{USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},
1066
{USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},
1067
{USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},
1068
{USB_DEVICE(0x0461, 0x0815), .driver_info = Rev072A},
1069
{USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A},
1070
{USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A},
1071
{USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A},
1072
{USB_DEVICE(0x046d, 0x092b), .driver_info = Rev012A},
1073
{USB_DEVICE(0x046d, 0x092c), .driver_info = Rev012A},
1074
{USB_DEVICE(0x046d, 0x092d), .driver_info = Rev012A},
1075
{USB_DEVICE(0x046d, 0x092e), .driver_info = Rev012A},
1076
{USB_DEVICE(0x046d, 0x092f), .driver_info = Rev012A},
1077
{USB_DEVICE(0x04fc, 0x0561), .driver_info = Rev072A},
1078
{USB_DEVICE(0x060b, 0xa001), .driver_info = Rev072A},
1079
{USB_DEVICE(0x10fd, 0x7e50), .driver_info = Rev072A},
1080
{USB_DEVICE(0xabcd, 0xcdee), .driver_info = Rev072A},
1081
{}
1082
};
1083
1084
MODULE_DEVICE_TABLE(usb, device_table);
1085
1086
/* -- device connect -- */
1087
static int sd_probe(struct usb_interface *intf,
1088
const struct usb_device_id *id)
1089
{
1090
return gspca_dev_probe(intf, id,
1091
sd_desc[id->driver_info],
1092
sizeof(struct sd),
1093
THIS_MODULE);
1094
}
1095
1096
static struct usb_driver sd_driver = {
1097
.name = MODULE_NAME,
1098
.id_table = device_table,
1099
.probe = sd_probe,
1100
.disconnect = gspca_disconnect,
1101
#ifdef CONFIG_PM
1102
.suspend = gspca_suspend,
1103
.resume = gspca_resume,
1104
#endif
1105
};
1106
1107
/* -- module insert / remove -- */
1108
static int __init sd_mod_init(void)
1109
{
1110
return usb_register(&sd_driver);
1111
}
1112
static void __exit sd_mod_exit(void)
1113
{
1114
usb_deregister(&sd_driver);
1115
}
1116
1117
module_init(sd_mod_init);
1118
module_exit(sd_mod_exit);
1119
1120