1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
|
/*
* Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
* Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
* Copyright (c) 2002, 2003 Tuukka Toivonen
* Copyright (c) 2008 Erik Andrén
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* P/N 861037: Sensor HDCS1000 ASIC STV0600
* P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
* P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
* P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
* P/N 861075-0040: Sensor HDCS1000 ASIC
* P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
* P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
*/
#ifndef STV06XX_VV6410_H_
#define STV06XX_VV6410_H_
#include "stv06xx_sensor.h"
#define VV6410_COLS 416
#define VV6410_ROWS 320
/* Status registers */
/* Chip identification number including revision indicator */
#define VV6410_DEVICEH 0x00
#define VV6410_DEVICEL 0x01
/* User can determine whether timed I2C data
has been consumed by interrogating flag states */
#define VV6410_STATUS0 0x02
/* Current line counter value */
#define VV6410_LINECOUNTH 0x03
#define VV6410_LINECOUNTL 0x04
/* End x coordinate of image size */
#define VV6410_XENDH 0x05
#define VV6410_XENDL 0x06
/* End y coordinate of image size */
#define VV6410_YENDH 0x07
#define VV6410_YENDL 0x08
/* This is the average pixel value returned from the
dark line offset cancellation algorithm */
#define VV6410_DARKAVGH 0x09
#define VV6410_DARKAVGL 0x0a
/* This is the average pixel value returned from the
black line offset cancellation algorithm */
#define VV6410_BLACKAVGH 0x0b
#define VV6410_BLACKAVGL 0x0c
/* Flags to indicate whether the x or y image coordinates have been clipped */
#define VV6410_STATUS1 0x0d
/* Setup registers */
/* Low-power/sleep modes & video timing */
#define VV6410_SETUP0 0x10
/* Various parameters */
#define VV6410_SETUP1 0x11
/* Contains pixel counter reset value used by external sync */
#define VV6410_SYNCVALUE 0x12
/* Frame grabbing modes (FST, LST and QCK) */
#define VV6410_FGMODES 0x14
/* FST and QCK mapping modes. */
#define VV6410_PINMAPPING 0x15
/* Data resolution */
#define VV6410_DATAFORMAT 0x16
/* Output coding formats */
#define VV6410_OPFORMAT 0x17
/* Various mode select bits */
#define VV6410_MODESELECT 0x18
/* Exposure registers */
/* Fine exposure. */
#define VV6410_FINEH 0x20
#define VV6410_FINEL 0x21
/* Coarse exposure */
#define VV6410_COARSEH 0x22
#define VV6410_COARSEL 0x23
/* Analog gain setting */
#define VV6410_ANALOGGAIN 0x24
/* Clock division */
#define VV6410_CLKDIV 0x25
/* Dark line offset cancellation value */
#define VV6410_DARKOFFSETH 0x2c
#define VV6410_DARKOFFSETL 0x2d
/* Dark line offset cancellation enable */
#define VV6410_DARKOFFSETSETUP 0x2e
/* Video timing registers */
/* Line Length (Pixel Clocks) */
#define VV6410_LINELENGTHH 0x52
#define VV6410_LINELENGTHL 0x53
/* X-co-ordinate of top left corner of region of interest (x-offset) */
#define VV6410_XOFFSETH 0x57
#define VV6410_XOFFSETL 0x58
/* Y-coordinate of top left corner of region of interest (y-offset) */
#define VV6410_YOFFSETH 0x59
#define VV6410_YOFFSETL 0x5a
/* Field length (Lines) */
#define VV6410_FIELDLENGTHH 0x61
#define VV6410_FIELDLENGTHL 0x62
/* System registers */
/* Black offset cancellation default value */
#define VV6410_BLACKOFFSETH 0x70
#define VV6410_BLACKOFFSETL 0x71
/* Black offset cancellation setup */
#define VV6410_BLACKOFFSETSETUP 0x72
/* Analog Control Register 0 */
#define VV6410_CR0 0x75
/* Analog Control Register 1 */
#define VV6410_CR1 0x76
/* ADC Setup Register */
#define VV6410_AS0 0x77
/* Analog Test Register */
#define VV6410_AT0 0x78
/* Audio Amplifier Setup Register */
#define VV6410_AT1 0x79
#define VV6410_HFLIP (1 << 3)
#define VV6410_VFLIP (1 << 4)
#define VV6410_LOW_POWER_MODE (1 << 0)
#define VV6410_SOFT_RESET (1 << 2)
#define VV6410_PAL_25_FPS (0 << 3)
#define VV6410_CLK_DIV_2 (1 << 1)
#define VV6410_FINE_EXPOSURE 320
#define VV6410_COARSE_EXPOSURE 192
#define VV6410_DEFAULT_GAIN 5
#define VV6410_SUBSAMPLE 0x01
#define VV6410_CROP_TO_QVGA 0x02
static int vv6410_probe(struct sd *sd);
static int vv6410_start(struct sd *sd);
static int vv6410_init(struct sd *sd);
static int vv6410_stop(struct sd *sd);
static int vv6410_dump(struct sd *sd);
/* V4L2 controls supported by the driver */
static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val);
static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val);
const struct stv06xx_sensor stv06xx_sensor_vv6410 = {
.name = "ST VV6410",
.i2c_flush = 5,
.i2c_addr = 0x20,
.i2c_len = 1,
.init = vv6410_init,
.probe = vv6410_probe,
.start = vv6410_start,
.stop = vv6410_stop,
.dump = vv6410_dump,
.nctrls = 3,
.ctrls = {
{
{
.id = V4L2_CID_HFLIP,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "horizontal flip",
.minimum = 0,
.maximum = 1,
.step = 1,
.default_value = 0
},
.set = vv6410_set_hflip,
.get = vv6410_get_hflip
}, {
{
.id = V4L2_CID_VFLIP,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "vertical flip",
.minimum = 0,
.maximum = 1,
.step = 1,
.default_value = 0
},
.set = vv6410_set_vflip,
.get = vv6410_get_vflip
}, {
{
.id = V4L2_CID_GAIN,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "analog gain",
.minimum = 0,
.maximum = 15,
.step = 1,
.default_value = 0
},
.set = vv6410_set_analog_gain,
.get = vv6410_get_analog_gain
}
},
.nmodes = 1,
.modes = {
{
356,
292,
V4L2_PIX_FMT_SGRBG8,
V4L2_FIELD_NONE,
.sizeimage =
356 * 292,
.bytesperline = 356,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 0
}
}
};
/* If NULL, only single value to write, stored in len */
struct stv_init {
const u8 *data;
u16 start;
u8 len;
};
static const u8 x1500[] = { /* 0x1500 - 0x150f */
0x0b, 0xa7, 0xb7, 0x00, 0x00
};
static const u8 x1536[] = { /* 0x1536 - 0x153b */
0x02, 0x00, 0x60, 0x01, 0x20, 0x01
};
static const u8 x15c1[] = { /* 0x15c1 - 0x15c2 */
0xff, 0x03 /* Output word 0x03ff = 1023 (ISO size) */
};
static const struct stv_init stv_bridge_init[] = {
/* This reg is written twice. Some kind of reset? */
{NULL, 0x1620, 0x80},
{NULL, 0x1620, 0x00},
{NULL, 0x1423, 0x04},
{x1500, 0x1500, ARRAY_SIZE(x1500)},
{x1536, 0x1536, ARRAY_SIZE(x1536)},
{x15c1, 0x15c1, ARRAY_SIZE(x15c1)}
};
static const u8 vv6410_sensor_init[][2] = {
/* Setup registers */
{VV6410_SETUP0, VV6410_SOFT_RESET},
{VV6410_SETUP0, VV6410_LOW_POWER_MODE},
/* Use shuffled read-out mode */
{VV6410_SETUP1, BIT(6)},
/* All modes to 1 */
{VV6410_FGMODES, BIT(6) | BIT(4) | BIT(2) | BIT(0)},
{VV6410_PINMAPPING, 0x00},
/* Pre-clock generator divide off */
{VV6410_DATAFORMAT, BIT(7) | BIT(0)},
/* Exposure registers */
{VV6410_FINEH, VV6410_FINE_EXPOSURE >> 8},
{VV6410_FINEL, VV6410_FINE_EXPOSURE & 0xff},
{VV6410_COARSEH, VV6410_COARSE_EXPOSURE >> 8},
{VV6410_COARSEL, VV6410_COARSE_EXPOSURE & 0xff},
{VV6410_ANALOGGAIN, 0xf0 | VV6410_DEFAULT_GAIN},
{VV6410_CLKDIV, VV6410_CLK_DIV_2},
/* System registers */
/* Enable voltage doubler */
{VV6410_AS0, BIT(6) | BIT(4) | BIT(3) | BIT(2) | BIT(1)},
{VV6410_AT0, 0x00},
/* Power up audio, differential */
{VV6410_AT1, BIT(4)|BIT(0)},
};
#endif
|