Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/video/gspca/sonixb.c
17602 views
1
/*
2
* sonix sn9c102 (bayer) library
3
*
4
* Copyright (C) 2009-2011 Jean-François Moine <http://moinejf.free.fr>
5
* Copyright (C) 2003 2004 Michel Xhaard [email protected]
6
* Add Pas106 Stefano Mozzi (C) 2004
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
/* Some documentation on known sonixb registers:
24
25
Reg Use
26
sn9c101 / sn9c102:
27
0x10 high nibble red gain low nibble blue gain
28
0x11 low nibble green gain
29
sn9c103:
30
0x05 red gain 0-127
31
0x06 blue gain 0-127
32
0x07 green gain 0-127
33
all:
34
0x08-0x0f i2c / 3wire registers
35
0x12 hstart
36
0x13 vstart
37
0x15 hsize (hsize = register-value * 16)
38
0x16 vsize (vsize = register-value * 16)
39
0x17 bit 0 toggle compression quality (according to sn9c102 driver)
40
0x18 bit 7 enables compression, bit 4-5 set image down scaling:
41
00 scale 1, 01 scale 1/2, 10, scale 1/4
42
0x19 high-nibble is sensor clock divider, changes exposure on sensors which
43
use a clock generated by the bridge. Some sensors have their own clock.
44
0x1c auto_exposure area (for avg_lum) startx (startx = register-value * 32)
45
0x1d auto_exposure area (for avg_lum) starty (starty = register-value * 32)
46
0x1e auto_exposure area (for avg_lum) stopx (hsize = (0x1e - 0x1c) * 32)
47
0x1f auto_exposure area (for avg_lum) stopy (vsize = (0x1f - 0x1d) * 32)
48
*/
49
50
#define MODULE_NAME "sonixb"
51
52
#include <linux/input.h>
53
#include "gspca.h"
54
55
MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
56
MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
57
MODULE_LICENSE("GPL");
58
59
/* controls */
60
enum e_ctrl {
61
BRIGHTNESS,
62
GAIN,
63
EXPOSURE,
64
AUTOGAIN,
65
FREQ,
66
NCTRLS /* number of controls */
67
};
68
69
/* specific webcam descriptor */
70
struct sd {
71
struct gspca_dev gspca_dev; /* !! must be the first item */
72
73
struct gspca_ctrl ctrls[NCTRLS];
74
75
atomic_t avg_lum;
76
int prev_avg_lum;
77
int exp_too_low_cnt;
78
int exp_too_high_cnt;
79
int header_read;
80
u8 header[12]; /* Header without sof marker */
81
82
unsigned char autogain_ignore_frames;
83
unsigned char frames_to_drop;
84
85
__u8 bridge; /* Type of bridge */
86
#define BRIDGE_101 0
87
#define BRIDGE_102 0 /* We make no difference between 101 and 102 */
88
#define BRIDGE_103 1
89
90
__u8 sensor; /* Type of image sensor chip */
91
#define SENSOR_HV7131D 0
92
#define SENSOR_HV7131R 1
93
#define SENSOR_OV6650 2
94
#define SENSOR_OV7630 3
95
#define SENSOR_PAS106 4
96
#define SENSOR_PAS202 5
97
#define SENSOR_TAS5110C 6
98
#define SENSOR_TAS5110D 7
99
#define SENSOR_TAS5130CXX 8
100
__u8 reg11;
101
};
102
103
typedef const __u8 sensor_init_t[8];
104
105
struct sensor_data {
106
const __u8 *bridge_init;
107
sensor_init_t *sensor_init;
108
int sensor_init_size;
109
int flags;
110
unsigned ctrl_dis;
111
__u8 sensor_addr;
112
};
113
114
/* sensor_data flags */
115
#define F_GAIN 0x01 /* has gain */
116
#define F_SIF 0x02 /* sif or vga */
117
#define F_COARSE_EXPO 0x04 /* exposure control is coarse */
118
119
/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
120
#define MODE_RAW 0x10 /* raw bayer mode */
121
#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */
122
123
/* ctrl_dis helper macros */
124
#define NO_EXPO ((1 << EXPOSURE) | (1 << AUTOGAIN))
125
#define NO_FREQ (1 << FREQ)
126
#define NO_BRIGHTNESS (1 << BRIGHTNESS)
127
128
#define COMP 0xc7 /* 0x87 //0x07 */
129
#define COMP1 0xc9 /* 0x89 //0x09 */
130
131
#define MCK_INIT 0x63
132
#define MCK_INIT1 0x20 /*fixme: Bayer - 0x50 for JPEG ??*/
133
134
#define SYS_CLK 0x04
135
136
#define SENS(bridge, sensor, _flags, _ctrl_dis, _sensor_addr) \
137
{ \
138
.bridge_init = bridge, \
139
.sensor_init = sensor, \
140
.sensor_init_size = sizeof(sensor), \
141
.flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \
142
}
143
144
/* We calculate the autogain at the end of the transfer of a frame, at this
145
moment a frame with the old settings is being captured and transmitted. So
146
if we adjust the gain or exposure we must ignore atleast the next frame for
147
the new settings to come into effect before doing any other adjustments. */
148
#define AUTOGAIN_IGNORE_FRAMES 1
149
150
/* V4L2 controls supported by the driver */
151
static void setbrightness(struct gspca_dev *gspca_dev);
152
static void setgain(struct gspca_dev *gspca_dev);
153
static void setexposure(struct gspca_dev *gspca_dev);
154
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
155
static void setfreq(struct gspca_dev *gspca_dev);
156
157
static const struct ctrl sd_ctrls[NCTRLS] = {
158
[BRIGHTNESS] = {
159
{
160
.id = V4L2_CID_BRIGHTNESS,
161
.type = V4L2_CTRL_TYPE_INTEGER,
162
.name = "Brightness",
163
.minimum = 0,
164
.maximum = 255,
165
.step = 1,
166
.default_value = 127,
167
},
168
.set_control = setbrightness
169
},
170
[GAIN] = {
171
{
172
.id = V4L2_CID_GAIN,
173
.type = V4L2_CTRL_TYPE_INTEGER,
174
.name = "Gain",
175
.minimum = 0,
176
.maximum = 255,
177
.step = 1,
178
#define GAIN_KNEE 230
179
.default_value = 127,
180
},
181
.set_control = setgain
182
},
183
[EXPOSURE] = {
184
{
185
.id = V4L2_CID_EXPOSURE,
186
.type = V4L2_CTRL_TYPE_INTEGER,
187
.name = "Exposure",
188
.minimum = 0,
189
.maximum = 1023,
190
.step = 1,
191
.default_value = 66,
192
/* 33 ms / 30 fps (except on PASXXX) */
193
#define EXPOSURE_KNEE 200 /* 100 ms / 10 fps (except on PASXXX) */
194
.flags = 0,
195
},
196
.set_control = setexposure
197
},
198
/* for coarse exposure */
199
#define COARSE_EXPOSURE_MIN 2
200
#define COARSE_EXPOSURE_MAX 15
201
#define COARSE_EXPOSURE_DEF 2 /* 30 fps */
202
[AUTOGAIN] = {
203
{
204
.id = V4L2_CID_AUTOGAIN,
205
.type = V4L2_CTRL_TYPE_BOOLEAN,
206
.name = "Automatic Gain (and Exposure)",
207
.minimum = 0,
208
.maximum = 1,
209
.step = 1,
210
#define AUTOGAIN_DEF 1
211
.default_value = AUTOGAIN_DEF,
212
.flags = V4L2_CTRL_FLAG_UPDATE
213
},
214
.set = sd_setautogain,
215
},
216
[FREQ] = {
217
{
218
.id = V4L2_CID_POWER_LINE_FREQUENCY,
219
.type = V4L2_CTRL_TYPE_MENU,
220
.name = "Light frequency filter",
221
.minimum = 0,
222
.maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
223
.step = 1,
224
#define FREQ_DEF 0
225
.default_value = FREQ_DEF,
226
},
227
.set_control = setfreq
228
},
229
};
230
231
static const struct v4l2_pix_format vga_mode[] = {
232
{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
233
.bytesperline = 160,
234
.sizeimage = 160 * 120,
235
.colorspace = V4L2_COLORSPACE_SRGB,
236
.priv = 2 | MODE_RAW},
237
{160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
238
.bytesperline = 160,
239
.sizeimage = 160 * 120 * 5 / 4,
240
.colorspace = V4L2_COLORSPACE_SRGB,
241
.priv = 2},
242
{320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
243
.bytesperline = 320,
244
.sizeimage = 320 * 240 * 5 / 4,
245
.colorspace = V4L2_COLORSPACE_SRGB,
246
.priv = 1},
247
{640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
248
.bytesperline = 640,
249
.sizeimage = 640 * 480 * 5 / 4,
250
.colorspace = V4L2_COLORSPACE_SRGB,
251
.priv = 0},
252
};
253
static const struct v4l2_pix_format sif_mode[] = {
254
{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
255
.bytesperline = 160,
256
.sizeimage = 160 * 120,
257
.colorspace = V4L2_COLORSPACE_SRGB,
258
.priv = 1 | MODE_RAW | MODE_REDUCED_SIF},
259
{160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
260
.bytesperline = 160,
261
.sizeimage = 160 * 120 * 5 / 4,
262
.colorspace = V4L2_COLORSPACE_SRGB,
263
.priv = 1 | MODE_REDUCED_SIF},
264
{176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
265
.bytesperline = 176,
266
.sizeimage = 176 * 144,
267
.colorspace = V4L2_COLORSPACE_SRGB,
268
.priv = 1 | MODE_RAW},
269
{176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
270
.bytesperline = 176,
271
.sizeimage = 176 * 144 * 5 / 4,
272
.colorspace = V4L2_COLORSPACE_SRGB,
273
.priv = 1},
274
{320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
275
.bytesperline = 320,
276
.sizeimage = 320 * 240 * 5 / 4,
277
.colorspace = V4L2_COLORSPACE_SRGB,
278
.priv = 0 | MODE_REDUCED_SIF},
279
{352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
280
.bytesperline = 352,
281
.sizeimage = 352 * 288 * 5 / 4,
282
.colorspace = V4L2_COLORSPACE_SRGB,
283
.priv = 0},
284
};
285
286
static const __u8 initHv7131d[] = {
287
0x04, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
288
0x00, 0x00,
289
0x00, 0x00, 0x00, 0x02, 0x02, 0x00,
290
0x28, 0x1e, 0x60, 0x8e, 0x42,
291
};
292
static const __u8 hv7131d_sensor_init[][8] = {
293
{0xa0, 0x11, 0x01, 0x04, 0x00, 0x00, 0x00, 0x17},
294
{0xa0, 0x11, 0x02, 0x00, 0x00, 0x00, 0x00, 0x17},
295
{0xa0, 0x11, 0x28, 0x00, 0x00, 0x00, 0x00, 0x17},
296
{0xa0, 0x11, 0x30, 0x30, 0x00, 0x00, 0x00, 0x17}, /* reset level */
297
{0xa0, 0x11, 0x34, 0x02, 0x00, 0x00, 0x00, 0x17}, /* pixel bias volt */
298
};
299
300
static const __u8 initHv7131r[] = {
301
0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
302
0x00, 0x00,
303
0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
304
0x28, 0x1e, 0x60, 0x8a, 0x20,
305
};
306
static const __u8 hv7131r_sensor_init[][8] = {
307
{0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
308
{0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
309
{0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
310
{0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
311
{0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
312
};
313
static const __u8 initOv6650[] = {
314
0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
315
0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
316
0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
317
0x10,
318
};
319
static const __u8 ov6650_sensor_init[][8] = {
320
/* Bright, contrast, etc are set through SCBB interface.
321
* AVCAP on win2 do not send any data on this controls. */
322
/* Anyway, some registers appears to alter bright and constrat */
323
324
/* Reset sensor */
325
{0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
326
/* Set clock register 0x11 low nibble is clock divider */
327
{0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
328
/* Next some unknown stuff */
329
{0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
330
/* {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10},
331
* THIS SET GREEN SCREEN
332
* (pixels could be innverted in decode kind of "brg",
333
* but blue wont be there. Avoid this data ... */
334
{0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
335
{0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
336
{0xa0, 0x60, 0x30, 0x3d, 0x0a, 0xd8, 0xa4, 0x10},
337
/* Enable rgb brightness control */
338
{0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10},
339
/* HDG: Note windows uses the line below, which sets both register 0x60
340
and 0x61 I believe these registers of the ov6650 are identical as
341
those of the ov7630, because if this is true the windows settings
342
add a bit additional red gain and a lot additional blue gain, which
343
matches my findings that the windows settings make blue much too
344
blue and red a little too red.
345
{0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, */
346
/* Some more unknown stuff */
347
{0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
348
{0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
349
};
350
351
static const __u8 initOv7630[] = {
352
0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
353
0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
354
0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */
355
0x28, 0x1e, /* H & V sizes r15 .. r16 */
356
0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */
357
};
358
static const __u8 ov7630_sensor_init[][8] = {
359
{0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
360
{0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
361
/* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */
362
{0xd0, 0x21, 0x12, 0x5c, 0x00, 0x80, 0x34, 0x10}, /* jfm */
363
{0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
364
{0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
365
{0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
366
{0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
367
{0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
368
{0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
369
{0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
370
{0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
371
/* {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, * jfm */
372
{0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
373
{0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
374
{0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
375
{0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
376
{0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
377
{0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
378
};
379
380
static const __u8 initPas106[] = {
381
0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
382
0x00, 0x00,
383
0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
384
0x16, 0x12, 0x24, COMP1, MCK_INIT1,
385
};
386
/* compression 0x86 mckinit1 0x2b */
387
388
/* "Known" PAS106B registers:
389
0x02 clock divider
390
0x03 Variable framerate bits 4-11
391
0x04 Var framerate bits 0-3, one must leave the 4 msb's at 0 !!
392
The variable framerate control must never be set lower then 300,
393
which sets the framerate at 90 / reg02, otherwise vsync is lost.
394
0x05 Shutter Time Line Offset, this can be used as an exposure control:
395
0 = use full frame time, 255 = no exposure at all
396
Note this may never be larger then "var-framerate control" / 2 - 2.
397
When var-framerate control is < 514, no exposure is reached at the max
398
allowed value for the framerate control value, rather then at 255.
399
0x06 Shutter Time Pixel Offset, like reg05 this influences exposure, but
400
only a very little bit, leave at 0xcd
401
0x07 offset sign bit (bit0 1 > negative offset)
402
0x08 offset
403
0x09 Blue Gain
404
0x0a Green1 Gain
405
0x0b Green2 Gain
406
0x0c Red Gain
407
0x0e Global gain
408
0x13 Write 1 to commit settings to sensor
409
*/
410
411
static const __u8 pas106_sensor_init[][8] = {
412
/* Pixel Clock Divider 6 */
413
{ 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 },
414
/* Frame Time MSB (also seen as 0x12) */
415
{ 0xa1, 0x40, 0x03, 0x13, 0x00, 0x00, 0x00, 0x14 },
416
/* Frame Time LSB (also seen as 0x05) */
417
{ 0xa1, 0x40, 0x04, 0x06, 0x00, 0x00, 0x00, 0x14 },
418
/* Shutter Time Line Offset (also seen as 0x6d) */
419
{ 0xa1, 0x40, 0x05, 0x65, 0x00, 0x00, 0x00, 0x14 },
420
/* Shutter Time Pixel Offset (also seen as 0xb1) */
421
{ 0xa1, 0x40, 0x06, 0xcd, 0x00, 0x00, 0x00, 0x14 },
422
/* Black Level Subtract Sign (also seen 0x00) */
423
{ 0xa1, 0x40, 0x07, 0xc1, 0x00, 0x00, 0x00, 0x14 },
424
/* Black Level Subtract Level (also seen 0x01) */
425
{ 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
426
{ 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
427
/* Color Gain B Pixel 5 a */
428
{ 0xa1, 0x40, 0x09, 0x05, 0x00, 0x00, 0x00, 0x14 },
429
/* Color Gain G1 Pixel 1 5 */
430
{ 0xa1, 0x40, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x14 },
431
/* Color Gain G2 Pixel 1 0 5 */
432
{ 0xa1, 0x40, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x14 },
433
/* Color Gain R Pixel 3 1 */
434
{ 0xa1, 0x40, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x14 },
435
/* Color GainH Pixel */
436
{ 0xa1, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x14 },
437
/* Global Gain */
438
{ 0xa1, 0x40, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x14 },
439
/* Contrast */
440
{ 0xa1, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x14 },
441
/* H&V synchro polarity */
442
{ 0xa1, 0x40, 0x10, 0x06, 0x00, 0x00, 0x00, 0x14 },
443
/* ?default */
444
{ 0xa1, 0x40, 0x11, 0x06, 0x00, 0x00, 0x00, 0x14 },
445
/* DAC scale */
446
{ 0xa1, 0x40, 0x12, 0x06, 0x00, 0x00, 0x00, 0x14 },
447
/* ?default */
448
{ 0xa1, 0x40, 0x14, 0x02, 0x00, 0x00, 0x00, 0x14 },
449
/* Validate Settings */
450
{ 0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14 },
451
};
452
453
static const __u8 initPas202[] = {
454
0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
455
0x00, 0x00,
456
0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
457
0x28, 0x1e, 0x20, 0x89, 0x20,
458
};
459
460
/* "Known" PAS202BCB registers:
461
0x02 clock divider
462
0x04 Variable framerate bits 6-11 (*)
463
0x05 Var framerate bits 0-5, one must leave the 2 msb's at 0 !!
464
0x07 Blue Gain
465
0x08 Green Gain
466
0x09 Red Gain
467
0x0b offset sign bit (bit0 1 > negative offset)
468
0x0c offset
469
0x0e Unknown image is slightly brighter when bit 0 is 0, if reg0f is 0 too,
470
leave at 1 otherwise we get a jump in our exposure control
471
0x0f Exposure 0-255, 0 = use full frame time, 255 = no exposure at all
472
0x10 Master gain 0 - 31
473
0x11 write 1 to apply changes
474
(*) The variable framerate control must never be set lower then 500
475
which sets the framerate at 30 / reg02, otherwise vsync is lost.
476
*/
477
static const __u8 pas202_sensor_init[][8] = {
478
/* Set the clock divider to 4 -> 30 / 4 = 7.5 fps, we would like
479
to set it lower, but for some reason the bridge starts missing
480
vsync's then */
481
{0xa0, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x10},
482
{0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
483
{0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
484
{0xd0, 0x40, 0x0c, 0x00, 0x0c, 0x01, 0x32, 0x10},
485
{0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
486
{0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
487
{0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
488
{0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
489
{0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
490
{0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
491
};
492
493
static const __u8 initTas5110c[] = {
494
0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
495
0x00, 0x00,
496
0x00, 0x00, 0x00, 0x45, 0x09, 0x0a,
497
0x16, 0x12, 0x60, 0x86, 0x2b,
498
};
499
/* Same as above, except a different hstart */
500
static const __u8 initTas5110d[] = {
501
0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
502
0x00, 0x00,
503
0x00, 0x00, 0x00, 0x41, 0x09, 0x0a,
504
0x16, 0x12, 0x60, 0x86, 0x2b,
505
};
506
/* tas5110c is 3 wire, tas5110d is 2 wire (regular i2c) */
507
static const __u8 tas5110c_sensor_init[][8] = {
508
{0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
509
{0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
510
};
511
/* Known TAS5110D registers
512
* reg02: gain, bit order reversed!! 0 == max gain, 255 == min gain
513
* reg03: bit3: vflip, bit4: ~hflip, bit7: ~gainboost (~ == inverted)
514
* Note: writing reg03 seems to only work when written together with 02
515
*/
516
static const __u8 tas5110d_sensor_init[][8] = {
517
{0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17}, /* reset */
518
};
519
520
static const __u8 initTas5130[] = {
521
0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
522
0x00, 0x00,
523
0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a,
524
0x28, 0x1e, 0x60, COMP, MCK_INIT,
525
};
526
static const __u8 tas5130_sensor_init[][8] = {
527
/* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
528
* shutter 0x47 short exposure? */
529
{0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
530
/* shutter 0x01 long exposure */
531
{0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
532
};
533
534
static const struct sensor_data sensor_data[] = {
535
SENS(initHv7131d, hv7131d_sensor_init, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0),
536
SENS(initHv7131r, hv7131r_sensor_init, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0),
537
SENS(initOv6650, ov6650_sensor_init, F_GAIN|F_SIF, 0, 0x60),
538
SENS(initOv7630, ov7630_sensor_init, F_GAIN, 0, 0x21),
539
SENS(initPas106, pas106_sensor_init, F_GAIN|F_SIF, NO_FREQ, 0),
540
SENS(initPas202, pas202_sensor_init, F_GAIN, NO_FREQ, 0),
541
SENS(initTas5110c, tas5110c_sensor_init, F_GAIN|F_SIF|F_COARSE_EXPO,
542
NO_BRIGHTNESS|NO_FREQ, 0),
543
SENS(initTas5110d, tas5110d_sensor_init, F_GAIN|F_SIF|F_COARSE_EXPO,
544
NO_BRIGHTNESS|NO_FREQ, 0),
545
SENS(initTas5130, tas5130_sensor_init, F_GAIN,
546
NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0),
547
};
548
549
/* get one byte in gspca_dev->usb_buf */
550
static void reg_r(struct gspca_dev *gspca_dev,
551
__u16 value)
552
{
553
usb_control_msg(gspca_dev->dev,
554
usb_rcvctrlpipe(gspca_dev->dev, 0),
555
0, /* request */
556
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
557
value,
558
0, /* index */
559
gspca_dev->usb_buf, 1,
560
500);
561
}
562
563
static void reg_w(struct gspca_dev *gspca_dev,
564
__u16 value,
565
const __u8 *buffer,
566
int len)
567
{
568
#ifdef GSPCA_DEBUG
569
if (len > USB_BUF_SZ) {
570
PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
571
return;
572
}
573
#endif
574
memcpy(gspca_dev->usb_buf, buffer, len);
575
usb_control_msg(gspca_dev->dev,
576
usb_sndctrlpipe(gspca_dev->dev, 0),
577
0x08, /* request */
578
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
579
value,
580
0, /* index */
581
gspca_dev->usb_buf, len,
582
500);
583
}
584
585
static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
586
{
587
int retry = 60;
588
589
/* is i2c ready */
590
reg_w(gspca_dev, 0x08, buffer, 8);
591
while (retry--) {
592
msleep(10);
593
reg_r(gspca_dev, 0x08);
594
if (gspca_dev->usb_buf[0] & 0x04) {
595
if (gspca_dev->usb_buf[0] & 0x08)
596
return -1;
597
return 0;
598
}
599
}
600
return -1;
601
}
602
603
static void i2c_w_vector(struct gspca_dev *gspca_dev,
604
const __u8 buffer[][8], int len)
605
{
606
for (;;) {
607
reg_w(gspca_dev, 0x08, *buffer, 8);
608
len -= 8;
609
if (len <= 0)
610
break;
611
buffer++;
612
}
613
}
614
615
static void setbrightness(struct gspca_dev *gspca_dev)
616
{
617
struct sd *sd = (struct sd *) gspca_dev;
618
619
switch (sd->sensor) {
620
case SENSOR_OV6650:
621
case SENSOR_OV7630: {
622
__u8 i2cOV[] =
623
{0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
624
625
/* change reg 0x06 */
626
i2cOV[1] = sensor_data[sd->sensor].sensor_addr;
627
i2cOV[3] = sd->ctrls[BRIGHTNESS].val;
628
if (i2c_w(gspca_dev, i2cOV) < 0)
629
goto err;
630
break;
631
}
632
case SENSOR_PAS106:
633
case SENSOR_PAS202: {
634
__u8 i2cpbright[] =
635
{0xb0, 0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x16};
636
__u8 i2cpdoit[] =
637
{0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
638
639
/* PAS106 uses reg 7 and 8 instead of b and c */
640
if (sd->sensor == SENSOR_PAS106) {
641
i2cpbright[2] = 7;
642
i2cpdoit[2] = 0x13;
643
}
644
645
if (sd->ctrls[BRIGHTNESS].val < 127) {
646
/* change reg 0x0b, signreg */
647
i2cpbright[3] = 0x01;
648
/* set reg 0x0c, offset */
649
i2cpbright[4] = 127 - sd->ctrls[BRIGHTNESS].val;
650
} else
651
i2cpbright[4] = sd->ctrls[BRIGHTNESS].val - 127;
652
653
if (i2c_w(gspca_dev, i2cpbright) < 0)
654
goto err;
655
if (i2c_w(gspca_dev, i2cpdoit) < 0)
656
goto err;
657
break;
658
}
659
}
660
return;
661
err:
662
PDEBUG(D_ERR, "i2c error brightness");
663
}
664
665
static void setsensorgain(struct gspca_dev *gspca_dev)
666
{
667
struct sd *sd = (struct sd *) gspca_dev;
668
u8 gain = sd->ctrls[GAIN].val;
669
670
switch (sd->sensor) {
671
case SENSOR_HV7131D: {
672
__u8 i2c[] =
673
{0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17};
674
675
i2c[3] = 0x3f - (gain / 4);
676
i2c[4] = 0x3f - (gain / 4);
677
i2c[5] = 0x3f - (gain / 4);
678
679
if (i2c_w(gspca_dev, i2c) < 0)
680
goto err;
681
break;
682
}
683
case SENSOR_TAS5110C:
684
case SENSOR_TAS5130CXX: {
685
__u8 i2c[] =
686
{0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
687
688
i2c[4] = 255 - gain;
689
if (i2c_w(gspca_dev, i2c) < 0)
690
goto err;
691
break;
692
}
693
case SENSOR_TAS5110D: {
694
__u8 i2c[] = {
695
0xb0, 0x61, 0x02, 0x00, 0x10, 0x00, 0x00, 0x17 };
696
gain = 255 - gain;
697
/* The bits in the register are the wrong way around!! */
698
i2c[3] |= (gain & 0x80) >> 7;
699
i2c[3] |= (gain & 0x40) >> 5;
700
i2c[3] |= (gain & 0x20) >> 3;
701
i2c[3] |= (gain & 0x10) >> 1;
702
i2c[3] |= (gain & 0x08) << 1;
703
i2c[3] |= (gain & 0x04) << 3;
704
i2c[3] |= (gain & 0x02) << 5;
705
i2c[3] |= (gain & 0x01) << 7;
706
if (i2c_w(gspca_dev, i2c) < 0)
707
goto err;
708
break;
709
}
710
711
case SENSOR_OV6650:
712
gain >>= 1;
713
/* fall thru */
714
case SENSOR_OV7630: {
715
__u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
716
717
i2c[1] = sensor_data[sd->sensor].sensor_addr;
718
i2c[3] = gain >> 2;
719
if (i2c_w(gspca_dev, i2c) < 0)
720
goto err;
721
break;
722
}
723
case SENSOR_PAS106:
724
case SENSOR_PAS202: {
725
__u8 i2cpgain[] =
726
{0xa0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x15};
727
__u8 i2cpcolorgain[] =
728
{0xc0, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x15};
729
__u8 i2cpdoit[] =
730
{0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
731
732
/* PAS106 uses different regs (and has split green gains) */
733
if (sd->sensor == SENSOR_PAS106) {
734
i2cpgain[2] = 0x0e;
735
i2cpcolorgain[0] = 0xd0;
736
i2cpcolorgain[2] = 0x09;
737
i2cpdoit[2] = 0x13;
738
}
739
740
i2cpgain[3] = gain >> 3;
741
i2cpcolorgain[3] = gain >> 4;
742
i2cpcolorgain[4] = gain >> 4;
743
i2cpcolorgain[5] = gain >> 4;
744
i2cpcolorgain[6] = gain >> 4;
745
746
if (i2c_w(gspca_dev, i2cpgain) < 0)
747
goto err;
748
if (i2c_w(gspca_dev, i2cpcolorgain) < 0)
749
goto err;
750
if (i2c_w(gspca_dev, i2cpdoit) < 0)
751
goto err;
752
break;
753
}
754
}
755
return;
756
err:
757
PDEBUG(D_ERR, "i2c error gain");
758
}
759
760
static void setgain(struct gspca_dev *gspca_dev)
761
{
762
struct sd *sd = (struct sd *) gspca_dev;
763
__u8 gain;
764
__u8 buf[3] = { 0, 0, 0 };
765
766
if (sensor_data[sd->sensor].flags & F_GAIN) {
767
/* Use the sensor gain to do the actual gain */
768
setsensorgain(gspca_dev);
769
return;
770
}
771
772
if (sd->bridge == BRIDGE_103) {
773
gain = sd->ctrls[GAIN].val >> 1;
774
buf[0] = gain; /* Red */
775
buf[1] = gain; /* Green */
776
buf[2] = gain; /* Blue */
777
reg_w(gspca_dev, 0x05, buf, 3);
778
} else {
779
gain = sd->ctrls[GAIN].val >> 4;
780
buf[0] = gain << 4 | gain; /* Red and blue */
781
buf[1] = gain; /* Green */
782
reg_w(gspca_dev, 0x10, buf, 2);
783
}
784
}
785
786
static void setexposure(struct gspca_dev *gspca_dev)
787
{
788
struct sd *sd = (struct sd *) gspca_dev;
789
790
switch (sd->sensor) {
791
case SENSOR_HV7131D: {
792
/* Note the datasheet wrongly says line mode exposure uses reg
793
0x26 and 0x27, testing has shown 0x25 + 0x26 */
794
__u8 i2c[] = {0xc0, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x17};
795
/* The HV7131D's exposure goes from 0 - 65535, we scale our
796
exposure of 0-1023 to 0-6138. There are 2 reasons for this:
797
1) This puts our exposure knee of 200 at approx the point
798
where the framerate starts dropping
799
2) At 6138 the framerate has already dropped to 2 fps,
800
going any lower makes little sense */
801
u16 reg = sd->ctrls[EXPOSURE].val * 6;
802
803
i2c[3] = reg >> 8;
804
i2c[4] = reg & 0xff;
805
if (i2c_w(gspca_dev, i2c) != 0)
806
goto err;
807
break;
808
}
809
case SENSOR_TAS5110C:
810
case SENSOR_TAS5110D: {
811
/* register 19's high nibble contains the sn9c10x clock divider
812
The high nibble configures the no fps according to the
813
formula: 60 / high_nibble. With a maximum of 30 fps */
814
u8 reg = sd->ctrls[EXPOSURE].val;
815
816
reg = (reg << 4) | 0x0b;
817
reg_w(gspca_dev, 0x19, &reg, 1);
818
break;
819
}
820
case SENSOR_OV6650:
821
case SENSOR_OV7630: {
822
/* The ov6650 / ov7630 have 2 registers which both influence
823
exposure, register 11, whose low nibble sets the nr off fps
824
according to: fps = 30 / (low_nibble + 1)
825
826
The fps configures the maximum exposure setting, but it is
827
possible to use less exposure then what the fps maximum
828
allows by setting register 10. register 10 configures the
829
actual exposure as quotient of the full exposure, with 0
830
being no exposure at all (not very useful) and reg10_max
831
being max exposure possible at that framerate.
832
833
The code maps our 0 - 510 ms exposure ctrl to these 2
834
registers, trying to keep fps as high as possible.
835
*/
836
__u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
837
int reg10, reg11, reg10_max;
838
839
/* ov6645 datasheet says reg10_max is 9a, but that uses
840
tline * 2 * reg10 as formula for calculating texpo, the
841
ov6650 probably uses the same formula as the 7730 which uses
842
tline * 4 * reg10, which explains why the reg10max we've
843
found experimentally for the ov6650 is exactly half that of
844
the ov6645. The ov7630 datasheet says the max is 0x41. */
845
if (sd->sensor == SENSOR_OV6650) {
846
reg10_max = 0x4d;
847
i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */
848
} else
849
reg10_max = 0x41;
850
851
reg11 = (15 * sd->ctrls[EXPOSURE].val + 999) / 1000;
852
if (reg11 < 1)
853
reg11 = 1;
854
else if (reg11 > 16)
855
reg11 = 16;
856
857
/* In 640x480, if the reg11 has less than 4, the image is
858
unstable (the bridge goes into a higher compression mode
859
which we have not reverse engineered yet). */
860
if (gspca_dev->width == 640 && reg11 < 4)
861
reg11 = 4;
862
863
/* frame exposure time in ms = 1000 * reg11 / 30 ->
864
reg10 = (sd->ctrls[EXPOSURE].val / 2) * reg10_max
865
/ (1000 * reg11 / 30) */
866
reg10 = (sd->ctrls[EXPOSURE].val * 15 * reg10_max)
867
/ (1000 * reg11);
868
869
/* Don't allow this to get below 10 when using autogain, the
870
steps become very large (relatively) when below 10 causing
871
the image to oscilate from much too dark, to much too bright
872
and back again. */
873
if (sd->ctrls[AUTOGAIN].val && reg10 < 10)
874
reg10 = 10;
875
else if (reg10 > reg10_max)
876
reg10 = reg10_max;
877
878
/* Write reg 10 and reg11 low nibble */
879
i2c[1] = sensor_data[sd->sensor].sensor_addr;
880
i2c[3] = reg10;
881
i2c[4] |= reg11 - 1;
882
883
/* If register 11 didn't change, don't change it */
884
if (sd->reg11 == reg11)
885
i2c[0] = 0xa0;
886
887
if (i2c_w(gspca_dev, i2c) == 0)
888
sd->reg11 = reg11;
889
else
890
goto err;
891
break;
892
}
893
case SENSOR_PAS202: {
894
__u8 i2cpframerate[] =
895
{0xb0, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x16};
896
__u8 i2cpexpo[] =
897
{0xa0, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x16};
898
const __u8 i2cpdoit[] =
899
{0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
900
int framerate_ctrl;
901
902
/* The exposure knee for the autogain algorithm is 200
903
(100 ms / 10 fps on other sensors), for values below this
904
use the control for setting the partial frame expose time,
905
above that use variable framerate. This way we run at max
906
framerate ([email protected] fps, 320x240@10fps) until the knee
907
is reached. Using the variable framerate control above 200
908
is better then playing around with both clockdiv + partial
909
frame exposure times (like we are doing with the ov chips),
910
as that sometimes leads to jumps in the exposure control,
911
which are bad for auto exposure. */
912
if (sd->ctrls[EXPOSURE].val < 200) {
913
i2cpexpo[3] = 255 - (sd->ctrls[EXPOSURE].val * 255)
914
/ 200;
915
framerate_ctrl = 500;
916
} else {
917
/* The PAS202's exposure control goes from 0 - 4095,
918
but anything below 500 causes vsync issues, so scale
919
our 200-1023 to 500-4095 */
920
framerate_ctrl = (sd->ctrls[EXPOSURE].val - 200)
921
* 1000 / 229 + 500;
922
}
923
924
i2cpframerate[3] = framerate_ctrl >> 6;
925
i2cpframerate[4] = framerate_ctrl & 0x3f;
926
if (i2c_w(gspca_dev, i2cpframerate) < 0)
927
goto err;
928
if (i2c_w(gspca_dev, i2cpexpo) < 0)
929
goto err;
930
if (i2c_w(gspca_dev, i2cpdoit) < 0)
931
goto err;
932
break;
933
}
934
case SENSOR_PAS106: {
935
__u8 i2cpframerate[] =
936
{0xb1, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x14};
937
__u8 i2cpexpo[] =
938
{0xa1, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x14};
939
const __u8 i2cpdoit[] =
940
{0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14};
941
int framerate_ctrl;
942
943
/* For values below 150 use partial frame exposure, above
944
that use framerate ctrl */
945
if (sd->ctrls[EXPOSURE].val < 150) {
946
i2cpexpo[3] = 150 - sd->ctrls[EXPOSURE].val;
947
framerate_ctrl = 300;
948
} else {
949
/* The PAS106's exposure control goes from 0 - 4095,
950
but anything below 300 causes vsync issues, so scale
951
our 150-1023 to 300-4095 */
952
framerate_ctrl = (sd->ctrls[EXPOSURE].val - 150)
953
* 1000 / 230 + 300;
954
}
955
956
i2cpframerate[3] = framerate_ctrl >> 4;
957
i2cpframerate[4] = framerate_ctrl & 0x0f;
958
if (i2c_w(gspca_dev, i2cpframerate) < 0)
959
goto err;
960
if (i2c_w(gspca_dev, i2cpexpo) < 0)
961
goto err;
962
if (i2c_w(gspca_dev, i2cpdoit) < 0)
963
goto err;
964
break;
965
}
966
}
967
return;
968
err:
969
PDEBUG(D_ERR, "i2c error exposure");
970
}
971
972
static void setfreq(struct gspca_dev *gspca_dev)
973
{
974
struct sd *sd = (struct sd *) gspca_dev;
975
976
switch (sd->sensor) {
977
case SENSOR_OV6650:
978
case SENSOR_OV7630: {
979
/* Framerate adjust register for artificial light 50 hz flicker
980
compensation, for the ov6650 this is identical to ov6630
981
0x2b register, see ov6630 datasheet.
982
0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
983
__u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
984
switch (sd->ctrls[FREQ].val) {
985
default:
986
/* case 0: * no filter*/
987
/* case 2: * 60 hz */
988
i2c[3] = 0;
989
break;
990
case 1: /* 50 hz */
991
i2c[3] = (sd->sensor == SENSOR_OV6650)
992
? 0x4f : 0x8a;
993
break;
994
}
995
i2c[1] = sensor_data[sd->sensor].sensor_addr;
996
if (i2c_w(gspca_dev, i2c) < 0)
997
PDEBUG(D_ERR, "i2c error setfreq");
998
break;
999
}
1000
}
1001
}
1002
1003
#include "autogain_functions.h"
1004
1005
static void do_autogain(struct gspca_dev *gspca_dev)
1006
{
1007
int deadzone, desired_avg_lum, result;
1008
struct sd *sd = (struct sd *) gspca_dev;
1009
int avg_lum = atomic_read(&sd->avg_lum);
1010
1011
if ((gspca_dev->ctrl_dis & (1 << AUTOGAIN)) ||
1012
avg_lum == -1 || !sd->ctrls[AUTOGAIN].val)
1013
return;
1014
1015
if (sd->autogain_ignore_frames > 0) {
1016
sd->autogain_ignore_frames--;
1017
return;
1018
}
1019
1020
/* SIF / VGA sensors have a different autoexposure area and thus
1021
different avg_lum values for the same picture brightness */
1022
if (sensor_data[sd->sensor].flags & F_SIF) {
1023
deadzone = 500;
1024
/* SIF sensors tend to overexpose, so keep this small */
1025
desired_avg_lum = 5000;
1026
} else {
1027
deadzone = 1500;
1028
desired_avg_lum = 13000;
1029
}
1030
1031
if (sensor_data[sd->sensor].flags & F_COARSE_EXPO)
1032
result = coarse_grained_expo_autogain(gspca_dev, avg_lum,
1033
sd->ctrls[BRIGHTNESS].val
1034
* desired_avg_lum / 127,
1035
deadzone);
1036
else
1037
result = auto_gain_n_exposure(gspca_dev, avg_lum,
1038
sd->ctrls[BRIGHTNESS].val
1039
* desired_avg_lum / 127,
1040
deadzone, GAIN_KNEE, EXPOSURE_KNEE);
1041
1042
if (result) {
1043
PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d",
1044
(int) sd->ctrls[GAIN].val,
1045
(int) sd->ctrls[EXPOSURE].val);
1046
sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1047
}
1048
}
1049
1050
/* this function is called at probe time */
1051
static int sd_config(struct gspca_dev *gspca_dev,
1052
const struct usb_device_id *id)
1053
{
1054
struct sd *sd = (struct sd *) gspca_dev;
1055
struct cam *cam;
1056
1057
reg_r(gspca_dev, 0x00);
1058
if (gspca_dev->usb_buf[0] != 0x10)
1059
return -ENODEV;
1060
1061
/* copy the webcam info from the device id */
1062
sd->sensor = id->driver_info >> 8;
1063
sd->bridge = id->driver_info & 0xff;
1064
1065
gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
1066
#if AUTOGAIN_DEF
1067
if (!(gspca_dev->ctrl_dis & (1 << AUTOGAIN)))
1068
gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE);
1069
#endif
1070
1071
cam = &gspca_dev->cam;
1072
cam->ctrls = sd->ctrls;
1073
if (!(sensor_data[sd->sensor].flags & F_SIF)) {
1074
cam->cam_mode = vga_mode;
1075
cam->nmodes = ARRAY_SIZE(vga_mode);
1076
} else {
1077
cam->cam_mode = sif_mode;
1078
cam->nmodes = ARRAY_SIZE(sif_mode);
1079
}
1080
cam->npkt = 36; /* 36 packets per ISOC message */
1081
1082
if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) {
1083
sd->ctrls[EXPOSURE].min = COARSE_EXPOSURE_MIN;
1084
sd->ctrls[EXPOSURE].max = COARSE_EXPOSURE_MAX;
1085
sd->ctrls[EXPOSURE].def = COARSE_EXPOSURE_DEF;
1086
}
1087
1088
return 0;
1089
}
1090
1091
/* this function is called at probe and resume time */
1092
static int sd_init(struct gspca_dev *gspca_dev)
1093
{
1094
const __u8 stop = 0x09; /* Disable stream turn of LED */
1095
1096
reg_w(gspca_dev, 0x01, &stop, 1);
1097
1098
return 0;
1099
}
1100
1101
/* -- start the camera -- */
1102
static int sd_start(struct gspca_dev *gspca_dev)
1103
{
1104
struct sd *sd = (struct sd *) gspca_dev;
1105
struct cam *cam = &gspca_dev->cam;
1106
int i, mode;
1107
__u8 regs[0x31];
1108
1109
mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07;
1110
/* Copy registers 0x01 - 0x19 from the template */
1111
memcpy(&regs[0x01], sensor_data[sd->sensor].bridge_init, 0x19);
1112
/* Set the mode */
1113
regs[0x18] |= mode << 4;
1114
1115
/* Set bridge gain to 1.0 */
1116
if (sd->bridge == BRIDGE_103) {
1117
regs[0x05] = 0x20; /* Red */
1118
regs[0x06] = 0x20; /* Green */
1119
regs[0x07] = 0x20; /* Blue */
1120
} else {
1121
regs[0x10] = 0x00; /* Red and blue */
1122
regs[0x11] = 0x00; /* Green */
1123
}
1124
1125
/* Setup pixel numbers and auto exposure window */
1126
if (sensor_data[sd->sensor].flags & F_SIF) {
1127
regs[0x1a] = 0x14; /* HO_SIZE 640, makes no sense */
1128
regs[0x1b] = 0x0a; /* VO_SIZE 320, makes no sense */
1129
regs[0x1c] = 0x02; /* AE H-start 64 */
1130
regs[0x1d] = 0x02; /* AE V-start 64 */
1131
regs[0x1e] = 0x09; /* AE H-end 288 */
1132
regs[0x1f] = 0x07; /* AE V-end 224 */
1133
} else {
1134
regs[0x1a] = 0x1d; /* HO_SIZE 960, makes no sense */
1135
regs[0x1b] = 0x10; /* VO_SIZE 512, makes no sense */
1136
regs[0x1c] = 0x05; /* AE H-start 160 */
1137
regs[0x1d] = 0x03; /* AE V-start 96 */
1138
regs[0x1e] = 0x0f; /* AE H-end 480 */
1139
regs[0x1f] = 0x0c; /* AE V-end 384 */
1140
}
1141
1142
/* Setup the gamma table (only used with the sn9c103 bridge) */
1143
for (i = 0; i < 16; i++)
1144
regs[0x20 + i] = i * 16;
1145
regs[0x20 + i] = 255;
1146
1147
/* Special cases where some regs depend on mode or bridge */
1148
switch (sd->sensor) {
1149
case SENSOR_TAS5130CXX:
1150
/* FIXME / TESTME
1151
probably not mode specific at all most likely the upper
1152
nibble of 0x19 is exposure (clock divider) just as with
1153
the tas5110, we need someone to test this. */
1154
regs[0x19] = mode ? 0x23 : 0x43;
1155
break;
1156
case SENSOR_OV7630:
1157
/* FIXME / TESTME for some reason with the 101/102 bridge the
1158
clock is set to 12 Mhz (reg1 == 0x04), rather then 24.
1159
Also the hstart needs to go from 1 to 2 when using a 103,
1160
which is likely related. This does not seem right. */
1161
if (sd->bridge == BRIDGE_103) {
1162
regs[0x01] = 0x44; /* Select 24 Mhz clock */
1163
regs[0x12] = 0x02; /* Set hstart to 2 */
1164
}
1165
}
1166
/* Disable compression when the raw bayer format has been selected */
1167
if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
1168
regs[0x18] &= ~0x80;
1169
1170
/* Vga mode emulation on SIF sensor? */
1171
if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) {
1172
regs[0x12] += 16; /* hstart adjust */
1173
regs[0x13] += 24; /* vstart adjust */
1174
regs[0x15] = 320 / 16; /* hsize */
1175
regs[0x16] = 240 / 16; /* vsize */
1176
}
1177
1178
/* reg 0x01 bit 2 video transfert on */
1179
reg_w(gspca_dev, 0x01, &regs[0x01], 1);
1180
/* reg 0x17 SensorClk enable inv Clk 0x60 */
1181
reg_w(gspca_dev, 0x17, &regs[0x17], 1);
1182
/* Set the registers from the template */
1183
reg_w(gspca_dev, 0x01, &regs[0x01],
1184
(sd->bridge == BRIDGE_103) ? 0x30 : 0x1f);
1185
1186
/* Init the sensor */
1187
i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init,
1188
sensor_data[sd->sensor].sensor_init_size);
1189
1190
/* Mode / bridge specific sensor setup */
1191
switch (sd->sensor) {
1192
case SENSOR_PAS202: {
1193
const __u8 i2cpclockdiv[] =
1194
{0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10};
1195
/* clockdiv from 4 to 3 (7.5 -> 10 fps) when in low res mode */
1196
if (mode)
1197
i2c_w(gspca_dev, i2cpclockdiv);
1198
break;
1199
}
1200
case SENSOR_OV7630:
1201
/* FIXME / TESTME We should be able to handle this identical
1202
for the 101/102 and the 103 case */
1203
if (sd->bridge == BRIDGE_103) {
1204
const __u8 i2c[] = { 0xa0, 0x21, 0x13,
1205
0x80, 0x00, 0x00, 0x00, 0x10 };
1206
i2c_w(gspca_dev, i2c);
1207
}
1208
break;
1209
}
1210
/* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
1211
reg_w(gspca_dev, 0x15, &regs[0x15], 2);
1212
/* compression register */
1213
reg_w(gspca_dev, 0x18, &regs[0x18], 1);
1214
/* H_start */
1215
reg_w(gspca_dev, 0x12, &regs[0x12], 1);
1216
/* V_START */
1217
reg_w(gspca_dev, 0x13, &regs[0x13], 1);
1218
/* reset 0x17 SensorClk enable inv Clk 0x60 */
1219
/*fixme: ov7630 [17]=68 8f (+20 if 102)*/
1220
reg_w(gspca_dev, 0x17, &regs[0x17], 1);
1221
/*MCKSIZE ->3 */ /*fixme: not ov7630*/
1222
reg_w(gspca_dev, 0x19, &regs[0x19], 1);
1223
/* AE_STRX AE_STRY AE_ENDX AE_ENDY */
1224
reg_w(gspca_dev, 0x1c, &regs[0x1c], 4);
1225
/* Enable video transfert */
1226
reg_w(gspca_dev, 0x01, &regs[0x01], 1);
1227
/* Compression */
1228
reg_w(gspca_dev, 0x18, &regs[0x18], 2);
1229
msleep(20);
1230
1231
sd->reg11 = -1;
1232
1233
setgain(gspca_dev);
1234
setbrightness(gspca_dev);
1235
setexposure(gspca_dev);
1236
setfreq(gspca_dev);
1237
1238
sd->frames_to_drop = 0;
1239
sd->autogain_ignore_frames = 0;
1240
sd->exp_too_high_cnt = 0;
1241
sd->exp_too_low_cnt = 0;
1242
atomic_set(&sd->avg_lum, -1);
1243
return 0;
1244
}
1245
1246
static void sd_stopN(struct gspca_dev *gspca_dev)
1247
{
1248
sd_init(gspca_dev);
1249
}
1250
1251
static u8* find_sof(struct gspca_dev *gspca_dev, u8 *data, int len)
1252
{
1253
struct sd *sd = (struct sd *) gspca_dev;
1254
int i, header_size = (sd->bridge == BRIDGE_103) ? 18 : 12;
1255
1256
/* frames start with:
1257
* ff ff 00 c4 c4 96 synchro
1258
* 00 (unknown)
1259
* xx (frame sequence / size / compression)
1260
* (xx) (idem - extra byte for sn9c103)
1261
* ll mm brightness sum inside auto exposure
1262
* ll mm brightness sum outside auto exposure
1263
* (xx xx xx xx xx) audio values for snc103
1264
*/
1265
for (i = 0; i < len; i++) {
1266
switch (sd->header_read) {
1267
case 0:
1268
if (data[i] == 0xff)
1269
sd->header_read++;
1270
break;
1271
case 1:
1272
if (data[i] == 0xff)
1273
sd->header_read++;
1274
else
1275
sd->header_read = 0;
1276
break;
1277
case 2:
1278
if (data[i] == 0x00)
1279
sd->header_read++;
1280
else if (data[i] != 0xff)
1281
sd->header_read = 0;
1282
break;
1283
case 3:
1284
if (data[i] == 0xc4)
1285
sd->header_read++;
1286
else if (data[i] == 0xff)
1287
sd->header_read = 1;
1288
else
1289
sd->header_read = 0;
1290
break;
1291
case 4:
1292
if (data[i] == 0xc4)
1293
sd->header_read++;
1294
else if (data[i] == 0xff)
1295
sd->header_read = 1;
1296
else
1297
sd->header_read = 0;
1298
break;
1299
case 5:
1300
if (data[i] == 0x96)
1301
sd->header_read++;
1302
else if (data[i] == 0xff)
1303
sd->header_read = 1;
1304
else
1305
sd->header_read = 0;
1306
break;
1307
default:
1308
sd->header[sd->header_read - 6] = data[i];
1309
sd->header_read++;
1310
if (sd->header_read == header_size) {
1311
sd->header_read = 0;
1312
return data + i + 1;
1313
}
1314
}
1315
}
1316
return NULL;
1317
}
1318
1319
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1320
u8 *data, /* isoc packet */
1321
int len) /* iso packet length */
1322
{
1323
int fr_h_sz = 0, lum_offset = 0, len_after_sof = 0;
1324
struct sd *sd = (struct sd *) gspca_dev;
1325
struct cam *cam = &gspca_dev->cam;
1326
u8 *sof;
1327
1328
sof = find_sof(gspca_dev, data, len);
1329
if (sof) {
1330
if (sd->bridge == BRIDGE_103) {
1331
fr_h_sz = 18;
1332
lum_offset = 3;
1333
} else {
1334
fr_h_sz = 12;
1335
lum_offset = 2;
1336
}
1337
1338
len_after_sof = len - (sof - data);
1339
len = (sof - data) - fr_h_sz;
1340
if (len < 0)
1341
len = 0;
1342
}
1343
1344
if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
1345
/* In raw mode we sometimes get some garbage after the frame
1346
ignore this */
1347
int used;
1348
int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
1349
1350
used = gspca_dev->image_len;
1351
if (used + len > size)
1352
len = size - used;
1353
}
1354
1355
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1356
1357
if (sof) {
1358
int lum = sd->header[lum_offset] +
1359
(sd->header[lum_offset + 1] << 8);
1360
1361
/* When exposure changes midway a frame we
1362
get a lum of 0 in this case drop 2 frames
1363
as the frames directly after an exposure
1364
change have an unstable image. Sometimes lum
1365
*really* is 0 (cam used in low light with
1366
low exposure setting), so do not drop frames
1367
if the previous lum was 0 too. */
1368
if (lum == 0 && sd->prev_avg_lum != 0) {
1369
lum = -1;
1370
sd->frames_to_drop = 2;
1371
sd->prev_avg_lum = 0;
1372
} else
1373
sd->prev_avg_lum = lum;
1374
atomic_set(&sd->avg_lum, lum);
1375
1376
if (sd->frames_to_drop)
1377
sd->frames_to_drop--;
1378
else
1379
gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
1380
1381
gspca_frame_add(gspca_dev, FIRST_PACKET, sof, len_after_sof);
1382
}
1383
}
1384
1385
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1386
{
1387
struct sd *sd = (struct sd *) gspca_dev;
1388
1389
sd->ctrls[AUTOGAIN].val = val;
1390
sd->exp_too_high_cnt = 0;
1391
sd->exp_too_low_cnt = 0;
1392
1393
/* when switching to autogain set defaults to make sure
1394
we are on a valid point of the autogain gain /
1395
exposure knee graph, and give this change time to
1396
take effect before doing autogain. */
1397
if (sd->ctrls[AUTOGAIN].val
1398
&& !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) {
1399
sd->ctrls[EXPOSURE].val = sd->ctrls[EXPOSURE].def;
1400
sd->ctrls[GAIN].val = sd->ctrls[GAIN].def;
1401
if (gspca_dev->streaming) {
1402
sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1403
setexposure(gspca_dev);
1404
setgain(gspca_dev);
1405
}
1406
}
1407
1408
if (sd->ctrls[AUTOGAIN].val)
1409
gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE);
1410
else
1411
gspca_dev->ctrl_inac = 0;
1412
1413
return 0;
1414
}
1415
1416
static int sd_querymenu(struct gspca_dev *gspca_dev,
1417
struct v4l2_querymenu *menu)
1418
{
1419
switch (menu->id) {
1420
case V4L2_CID_POWER_LINE_FREQUENCY:
1421
switch (menu->index) {
1422
case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1423
strcpy((char *) menu->name, "NoFliker");
1424
return 0;
1425
case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1426
strcpy((char *) menu->name, "50 Hz");
1427
return 0;
1428
case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1429
strcpy((char *) menu->name, "60 Hz");
1430
return 0;
1431
}
1432
break;
1433
}
1434
return -EINVAL;
1435
}
1436
1437
#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1438
static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
1439
u8 *data, /* interrupt packet data */
1440
int len) /* interrupt packet length */
1441
{
1442
int ret = -EINVAL;
1443
1444
if (len == 1 && data[0] == 1) {
1445
input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
1446
input_sync(gspca_dev->input_dev);
1447
input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1448
input_sync(gspca_dev->input_dev);
1449
ret = 0;
1450
}
1451
1452
return ret;
1453
}
1454
#endif
1455
1456
/* sub-driver description */
1457
static const struct sd_desc sd_desc = {
1458
.name = MODULE_NAME,
1459
.ctrls = sd_ctrls,
1460
.nctrls = ARRAY_SIZE(sd_ctrls),
1461
.config = sd_config,
1462
.init = sd_init,
1463
.start = sd_start,
1464
.stopN = sd_stopN,
1465
.pkt_scan = sd_pkt_scan,
1466
.querymenu = sd_querymenu,
1467
.dq_callback = do_autogain,
1468
#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1469
.int_pkt_scan = sd_int_pkt_scan,
1470
#endif
1471
};
1472
1473
/* -- module initialisation -- */
1474
#define SB(sensor, bridge) \
1475
.driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
1476
1477
1478
static const struct usb_device_id device_table[] = {
1479
{USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */
1480
{USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */
1481
{USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */
1482
{USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
1483
{USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
1484
{USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
1485
{USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
1486
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1487
{USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
1488
{USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
1489
#endif
1490
{USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
1491
{USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
1492
{USB_DEVICE(0x0c45, 0x602a), SB(HV7131D, 102)},
1493
/* {USB_DEVICE(0x0c45, 0x602b), SB(MI0343, 102)}, */
1494
{USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1495
{USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
1496
{USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
1497
/* {USB_DEVICE(0x0c45, 0x6030), SB(MI03XX, 102)}, */ /* MI0343 MI0360 MI0330 */
1498
/* {USB_DEVICE(0x0c45, 0x6082), SB(MI03XX, 103)}, */ /* MI0343 MI0360 */
1499
{USB_DEVICE(0x0c45, 0x6083), SB(HV7131D, 103)},
1500
{USB_DEVICE(0x0c45, 0x608c), SB(HV7131R, 103)},
1501
/* {USB_DEVICE(0x0c45, 0x608e), SB(CISVF10, 103)}, */
1502
{USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
1503
{USB_DEVICE(0x0c45, 0x60a8), SB(PAS106, 103)},
1504
{USB_DEVICE(0x0c45, 0x60aa), SB(TAS5130CXX, 103)},
1505
{USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
1506
{USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)},
1507
{}
1508
};
1509
MODULE_DEVICE_TABLE(usb, device_table);
1510
1511
/* -- device connect -- */
1512
static int sd_probe(struct usb_interface *intf,
1513
const struct usb_device_id *id)
1514
{
1515
return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1516
THIS_MODULE);
1517
}
1518
1519
static struct usb_driver sd_driver = {
1520
.name = MODULE_NAME,
1521
.id_table = device_table,
1522
.probe = sd_probe,
1523
.disconnect = gspca_disconnect,
1524
#ifdef CONFIG_PM
1525
.suspend = gspca_suspend,
1526
.resume = gspca_resume,
1527
#endif
1528
};
1529
1530
/* -- module insert / remove -- */
1531
static int __init sd_mod_init(void)
1532
{
1533
return usb_register(&sd_driver);
1534
}
1535
static void __exit sd_mod_exit(void)
1536
{
1537
usb_deregister(&sd_driver);
1538
}
1539
1540
module_init(sd_mod_init);
1541
module_exit(sd_mod_exit);
1542
1543