Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/video/gspca/sn9c20x.c
17687 views
1
/*
2
* Sonix sn9c201 sn9c202 library
3
* Copyright (C) 2008-2009 microdia project <[email protected]>
4
* Copyright (C) 2009 Brian Johnson <[email protected]>
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* any later version.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
*/
20
21
#include <linux/input.h>
22
23
#include "gspca.h"
24
#include "jpeg.h"
25
26
#include <media/v4l2-chip-ident.h>
27
#include <linux/dmi.h>
28
29
MODULE_AUTHOR("Brian Johnson <[email protected]>, "
30
"microdia project <[email protected]>");
31
MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
32
MODULE_LICENSE("GPL");
33
34
#define MODULE_NAME "sn9c20x"
35
36
/*
37
* Pixel format private data
38
*/
39
#define SCALE_MASK 0x0f
40
#define SCALE_160x120 0
41
#define SCALE_320x240 1
42
#define SCALE_640x480 2
43
#define SCALE_1280x1024 3
44
#define MODE_RAW 0x10
45
#define MODE_JPEG 0x20
46
#define MODE_SXGA 0x80
47
48
#define SENSOR_OV9650 0
49
#define SENSOR_OV9655 1
50
#define SENSOR_SOI968 2
51
#define SENSOR_OV7660 3
52
#define SENSOR_OV7670 4
53
#define SENSOR_MT9V011 5
54
#define SENSOR_MT9V111 6
55
#define SENSOR_MT9V112 7
56
#define SENSOR_MT9M001 8
57
#define SENSOR_MT9M111 9
58
#define SENSOR_MT9M112 10
59
#define SENSOR_HV7131R 11
60
#define SENSOR_MT9VPRB 20
61
62
/* camera flags */
63
#define HAS_NO_BUTTON 0x1
64
#define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
65
#define FLIP_DETECT 0x4
66
67
/* specific webcam descriptor */
68
struct sd {
69
struct gspca_dev gspca_dev;
70
71
#define MIN_AVG_LUM 80
72
#define MAX_AVG_LUM 130
73
atomic_t avg_lum;
74
u8 old_step;
75
u8 older_step;
76
u8 exposure_step;
77
78
u8 brightness;
79
u8 contrast;
80
u8 saturation;
81
s16 hue;
82
u8 gamma;
83
u8 red;
84
u8 blue;
85
86
u8 hflip;
87
u8 vflip;
88
u8 gain;
89
u16 exposure;
90
u8 auto_exposure;
91
92
u8 i2c_addr;
93
u8 sensor;
94
u8 hstart;
95
u8 vstart;
96
97
u8 jpeg_hdr[JPEG_HDR_SZ];
98
u8 quality;
99
100
u8 flags;
101
};
102
103
struct i2c_reg_u8 {
104
u8 reg;
105
u8 val;
106
};
107
108
struct i2c_reg_u16 {
109
u8 reg;
110
u16 val;
111
};
112
113
static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val);
114
static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val);
115
static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val);
116
static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val);
117
static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val);
118
static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val);
119
static int sd_sethue(struct gspca_dev *gspca_dev, s32 val);
120
static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val);
121
static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val);
122
static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val);
123
static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val);
124
static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val);
125
static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val);
126
static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val);
127
static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val);
128
static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val);
129
static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val);
130
static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val);
131
static int sd_setgain(struct gspca_dev *gspca_dev, s32 val);
132
static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val);
133
static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val);
134
static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val);
135
static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val);
136
static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val);
137
138
static const struct dmi_system_id flip_dmi_table[] = {
139
{
140
.ident = "MSI MS-1034",
141
.matches = {
142
DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
143
DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"),
144
DMI_MATCH(DMI_PRODUCT_VERSION, "0341")
145
}
146
},
147
{
148
.ident = "MSI MS-1632",
149
.matches = {
150
DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
151
DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
152
}
153
},
154
{
155
.ident = "MSI MS-1633X",
156
.matches = {
157
DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
158
DMI_MATCH(DMI_BOARD_NAME, "MS-1633X")
159
}
160
},
161
{
162
.ident = "MSI MS-1635X",
163
.matches = {
164
DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
165
DMI_MATCH(DMI_BOARD_NAME, "MS-1635X")
166
}
167
},
168
{
169
.ident = "ASUSTeK W7J",
170
.matches = {
171
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
172
DMI_MATCH(DMI_BOARD_NAME, "W7J ")
173
}
174
},
175
{}
176
};
177
178
static const struct ctrl sd_ctrls[] = {
179
{
180
#define BRIGHTNESS_IDX 0
181
{
182
.id = V4L2_CID_BRIGHTNESS,
183
.type = V4L2_CTRL_TYPE_INTEGER,
184
.name = "Brightness",
185
.minimum = 0,
186
.maximum = 0xff,
187
.step = 1,
188
#define BRIGHTNESS_DEFAULT 0x7f
189
.default_value = BRIGHTNESS_DEFAULT,
190
},
191
.set = sd_setbrightness,
192
.get = sd_getbrightness,
193
},
194
{
195
#define CONTRAST_IDX 1
196
{
197
.id = V4L2_CID_CONTRAST,
198
.type = V4L2_CTRL_TYPE_INTEGER,
199
.name = "Contrast",
200
.minimum = 0,
201
.maximum = 0xff,
202
.step = 1,
203
#define CONTRAST_DEFAULT 0x7f
204
.default_value = CONTRAST_DEFAULT,
205
},
206
.set = sd_setcontrast,
207
.get = sd_getcontrast,
208
},
209
{
210
#define SATURATION_IDX 2
211
{
212
.id = V4L2_CID_SATURATION,
213
.type = V4L2_CTRL_TYPE_INTEGER,
214
.name = "Saturation",
215
.minimum = 0,
216
.maximum = 0xff,
217
.step = 1,
218
#define SATURATION_DEFAULT 0x7f
219
.default_value = SATURATION_DEFAULT,
220
},
221
.set = sd_setsaturation,
222
.get = sd_getsaturation,
223
},
224
{
225
#define HUE_IDX 3
226
{
227
.id = V4L2_CID_HUE,
228
.type = V4L2_CTRL_TYPE_INTEGER,
229
.name = "Hue",
230
.minimum = -180,
231
.maximum = 180,
232
.step = 1,
233
#define HUE_DEFAULT 0
234
.default_value = HUE_DEFAULT,
235
},
236
.set = sd_sethue,
237
.get = sd_gethue,
238
},
239
{
240
#define GAMMA_IDX 4
241
{
242
.id = V4L2_CID_GAMMA,
243
.type = V4L2_CTRL_TYPE_INTEGER,
244
.name = "Gamma",
245
.minimum = 0,
246
.maximum = 0xff,
247
.step = 1,
248
#define GAMMA_DEFAULT 0x10
249
.default_value = GAMMA_DEFAULT,
250
},
251
.set = sd_setgamma,
252
.get = sd_getgamma,
253
},
254
{
255
#define BLUE_IDX 5
256
{
257
.id = V4L2_CID_BLUE_BALANCE,
258
.type = V4L2_CTRL_TYPE_INTEGER,
259
.name = "Blue Balance",
260
.minimum = 0,
261
.maximum = 0x7f,
262
.step = 1,
263
#define BLUE_DEFAULT 0x28
264
.default_value = BLUE_DEFAULT,
265
},
266
.set = sd_setbluebalance,
267
.get = sd_getbluebalance,
268
},
269
{
270
#define RED_IDX 6
271
{
272
.id = V4L2_CID_RED_BALANCE,
273
.type = V4L2_CTRL_TYPE_INTEGER,
274
.name = "Red Balance",
275
.minimum = 0,
276
.maximum = 0x7f,
277
.step = 1,
278
#define RED_DEFAULT 0x28
279
.default_value = RED_DEFAULT,
280
},
281
.set = sd_setredbalance,
282
.get = sd_getredbalance,
283
},
284
{
285
#define HFLIP_IDX 7
286
{
287
.id = V4L2_CID_HFLIP,
288
.type = V4L2_CTRL_TYPE_BOOLEAN,
289
.name = "Horizontal Flip",
290
.minimum = 0,
291
.maximum = 1,
292
.step = 1,
293
#define HFLIP_DEFAULT 0
294
.default_value = HFLIP_DEFAULT,
295
},
296
.set = sd_sethflip,
297
.get = sd_gethflip,
298
},
299
{
300
#define VFLIP_IDX 8
301
{
302
.id = V4L2_CID_VFLIP,
303
.type = V4L2_CTRL_TYPE_BOOLEAN,
304
.name = "Vertical Flip",
305
.minimum = 0,
306
.maximum = 1,
307
.step = 1,
308
#define VFLIP_DEFAULT 0
309
.default_value = VFLIP_DEFAULT,
310
},
311
.set = sd_setvflip,
312
.get = sd_getvflip,
313
},
314
{
315
#define EXPOSURE_IDX 9
316
{
317
.id = V4L2_CID_EXPOSURE,
318
.type = V4L2_CTRL_TYPE_INTEGER,
319
.name = "Exposure",
320
.minimum = 0,
321
.maximum = 0x1780,
322
.step = 1,
323
#define EXPOSURE_DEFAULT 0x33
324
.default_value = EXPOSURE_DEFAULT,
325
},
326
.set = sd_setexposure,
327
.get = sd_getexposure,
328
},
329
{
330
#define GAIN_IDX 10
331
{
332
.id = V4L2_CID_GAIN,
333
.type = V4L2_CTRL_TYPE_INTEGER,
334
.name = "Gain",
335
.minimum = 0,
336
.maximum = 28,
337
.step = 1,
338
#define GAIN_DEFAULT 0x00
339
.default_value = GAIN_DEFAULT,
340
},
341
.set = sd_setgain,
342
.get = sd_getgain,
343
},
344
{
345
#define AUTOGAIN_IDX 11
346
{
347
.id = V4L2_CID_AUTOGAIN,
348
.type = V4L2_CTRL_TYPE_BOOLEAN,
349
.name = "Auto Exposure",
350
.minimum = 0,
351
.maximum = 1,
352
.step = 1,
353
#define AUTO_EXPOSURE_DEFAULT 1
354
.default_value = AUTO_EXPOSURE_DEFAULT,
355
},
356
.set = sd_setautoexposure,
357
.get = sd_getautoexposure,
358
},
359
};
360
361
static const struct v4l2_pix_format vga_mode[] = {
362
{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
363
.bytesperline = 160,
364
.sizeimage = 160 * 120 * 4 / 8 + 590,
365
.colorspace = V4L2_COLORSPACE_JPEG,
366
.priv = SCALE_160x120 | MODE_JPEG},
367
{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
368
.bytesperline = 160,
369
.sizeimage = 160 * 120,
370
.colorspace = V4L2_COLORSPACE_SRGB,
371
.priv = SCALE_160x120 | MODE_RAW},
372
{160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
373
.bytesperline = 160,
374
.sizeimage = 240 * 120,
375
.colorspace = V4L2_COLORSPACE_SRGB,
376
.priv = SCALE_160x120},
377
{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
378
.bytesperline = 320,
379
.sizeimage = 320 * 240 * 4 / 8 + 590,
380
.colorspace = V4L2_COLORSPACE_JPEG,
381
.priv = SCALE_320x240 | MODE_JPEG},
382
{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
383
.bytesperline = 320,
384
.sizeimage = 320 * 240 ,
385
.colorspace = V4L2_COLORSPACE_SRGB,
386
.priv = SCALE_320x240 | MODE_RAW},
387
{320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
388
.bytesperline = 320,
389
.sizeimage = 480 * 240 ,
390
.colorspace = V4L2_COLORSPACE_SRGB,
391
.priv = SCALE_320x240},
392
{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
393
.bytesperline = 640,
394
.sizeimage = 640 * 480 * 4 / 8 + 590,
395
.colorspace = V4L2_COLORSPACE_JPEG,
396
.priv = SCALE_640x480 | MODE_JPEG},
397
{640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
398
.bytesperline = 640,
399
.sizeimage = 640 * 480,
400
.colorspace = V4L2_COLORSPACE_SRGB,
401
.priv = SCALE_640x480 | MODE_RAW},
402
{640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
403
.bytesperline = 640,
404
.sizeimage = 960 * 480,
405
.colorspace = V4L2_COLORSPACE_SRGB,
406
.priv = SCALE_640x480},
407
};
408
409
static const struct v4l2_pix_format sxga_mode[] = {
410
{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
411
.bytesperline = 160,
412
.sizeimage = 160 * 120 * 4 / 8 + 590,
413
.colorspace = V4L2_COLORSPACE_JPEG,
414
.priv = SCALE_160x120 | MODE_JPEG},
415
{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
416
.bytesperline = 160,
417
.sizeimage = 160 * 120,
418
.colorspace = V4L2_COLORSPACE_SRGB,
419
.priv = SCALE_160x120 | MODE_RAW},
420
{160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
421
.bytesperline = 160,
422
.sizeimage = 240 * 120,
423
.colorspace = V4L2_COLORSPACE_SRGB,
424
.priv = SCALE_160x120},
425
{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
426
.bytesperline = 320,
427
.sizeimage = 320 * 240 * 4 / 8 + 590,
428
.colorspace = V4L2_COLORSPACE_JPEG,
429
.priv = SCALE_320x240 | MODE_JPEG},
430
{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
431
.bytesperline = 320,
432
.sizeimage = 320 * 240 ,
433
.colorspace = V4L2_COLORSPACE_SRGB,
434
.priv = SCALE_320x240 | MODE_RAW},
435
{320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
436
.bytesperline = 320,
437
.sizeimage = 480 * 240 ,
438
.colorspace = V4L2_COLORSPACE_SRGB,
439
.priv = SCALE_320x240},
440
{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
441
.bytesperline = 640,
442
.sizeimage = 640 * 480 * 4 / 8 + 590,
443
.colorspace = V4L2_COLORSPACE_JPEG,
444
.priv = SCALE_640x480 | MODE_JPEG},
445
{640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
446
.bytesperline = 640,
447
.sizeimage = 640 * 480,
448
.colorspace = V4L2_COLORSPACE_SRGB,
449
.priv = SCALE_640x480 | MODE_RAW},
450
{640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
451
.bytesperline = 640,
452
.sizeimage = 960 * 480,
453
.colorspace = V4L2_COLORSPACE_SRGB,
454
.priv = SCALE_640x480},
455
{1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
456
.bytesperline = 1280,
457
.sizeimage = 1280 * 1024,
458
.colorspace = V4L2_COLORSPACE_SRGB,
459
.priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
460
};
461
462
static const struct v4l2_pix_format mono_mode[] = {
463
{160, 120, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
464
.bytesperline = 160,
465
.sizeimage = 160 * 120,
466
.colorspace = V4L2_COLORSPACE_SRGB,
467
.priv = SCALE_160x120 | MODE_RAW},
468
{320, 240, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
469
.bytesperline = 320,
470
.sizeimage = 320 * 240 ,
471
.colorspace = V4L2_COLORSPACE_SRGB,
472
.priv = SCALE_320x240 | MODE_RAW},
473
{640, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
474
.bytesperline = 640,
475
.sizeimage = 640 * 480,
476
.colorspace = V4L2_COLORSPACE_SRGB,
477
.priv = SCALE_640x480 | MODE_RAW},
478
{1280, 1024, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
479
.bytesperline = 1280,
480
.sizeimage = 1280 * 1024,
481
.colorspace = V4L2_COLORSPACE_SRGB,
482
.priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
483
};
484
485
static const s16 hsv_red_x[] = {
486
41, 44, 46, 48, 50, 52, 54, 56,
487
58, 60, 62, 64, 66, 68, 70, 72,
488
74, 76, 78, 80, 81, 83, 85, 87,
489
88, 90, 92, 93, 95, 97, 98, 100,
490
101, 102, 104, 105, 107, 108, 109, 110,
491
112, 113, 114, 115, 116, 117, 118, 119,
492
120, 121, 122, 123, 123, 124, 125, 125,
493
126, 127, 127, 128, 128, 129, 129, 129,
494
130, 130, 130, 130, 131, 131, 131, 131,
495
131, 131, 131, 131, 130, 130, 130, 130,
496
129, 129, 129, 128, 128, 127, 127, 126,
497
125, 125, 124, 123, 122, 122, 121, 120,
498
119, 118, 117, 116, 115, 114, 112, 111,
499
110, 109, 107, 106, 105, 103, 102, 101,
500
99, 98, 96, 94, 93, 91, 90, 88,
501
86, 84, 83, 81, 79, 77, 75, 74,
502
72, 70, 68, 66, 64, 62, 60, 58,
503
56, 54, 52, 49, 47, 45, 43, 41,
504
39, 36, 34, 32, 30, 28, 25, 23,
505
21, 19, 16, 14, 12, 9, 7, 5,
506
3, 0, -1, -3, -6, -8, -10, -12,
507
-15, -17, -19, -22, -24, -26, -28, -30,
508
-33, -35, -37, -39, -41, -44, -46, -48,
509
-50, -52, -54, -56, -58, -60, -62, -64,
510
-66, -68, -70, -72, -74, -76, -78, -80,
511
-81, -83, -85, -87, -88, -90, -92, -93,
512
-95, -97, -98, -100, -101, -102, -104, -105,
513
-107, -108, -109, -110, -112, -113, -114, -115,
514
-116, -117, -118, -119, -120, -121, -122, -123,
515
-123, -124, -125, -125, -126, -127, -127, -128,
516
-128, -128, -128, -128, -128, -128, -128, -128,
517
-128, -128, -128, -128, -128, -128, -128, -128,
518
-128, -128, -128, -128, -128, -128, -128, -128,
519
-128, -127, -127, -126, -125, -125, -124, -123,
520
-122, -122, -121, -120, -119, -118, -117, -116,
521
-115, -114, -112, -111, -110, -109, -107, -106,
522
-105, -103, -102, -101, -99, -98, -96, -94,
523
-93, -91, -90, -88, -86, -84, -83, -81,
524
-79, -77, -75, -74, -72, -70, -68, -66,
525
-64, -62, -60, -58, -56, -54, -52, -49,
526
-47, -45, -43, -41, -39, -36, -34, -32,
527
-30, -28, -25, -23, -21, -19, -16, -14,
528
-12, -9, -7, -5, -3, 0, 1, 3,
529
6, 8, 10, 12, 15, 17, 19, 22,
530
24, 26, 28, 30, 33, 35, 37, 39, 41
531
};
532
533
static const s16 hsv_red_y[] = {
534
82, 80, 78, 76, 74, 73, 71, 69,
535
67, 65, 63, 61, 58, 56, 54, 52,
536
50, 48, 46, 44, 41, 39, 37, 35,
537
32, 30, 28, 26, 23, 21, 19, 16,
538
14, 12, 10, 7, 5, 3, 0, -1,
539
-3, -6, -8, -10, -13, -15, -17, -19,
540
-22, -24, -26, -29, -31, -33, -35, -38,
541
-40, -42, -44, -46, -48, -51, -53, -55,
542
-57, -59, -61, -63, -65, -67, -69, -71,
543
-73, -75, -77, -79, -81, -82, -84, -86,
544
-88, -89, -91, -93, -94, -96, -98, -99,
545
-101, -102, -104, -105, -106, -108, -109, -110,
546
-112, -113, -114, -115, -116, -117, -119, -120,
547
-120, -121, -122, -123, -124, -125, -126, -126,
548
-127, -128, -128, -128, -128, -128, -128, -128,
549
-128, -128, -128, -128, -128, -128, -128, -128,
550
-128, -128, -128, -128, -128, -128, -128, -128,
551
-128, -128, -128, -128, -128, -128, -128, -128,
552
-127, -127, -126, -125, -125, -124, -123, -122,
553
-121, -120, -119, -118, -117, -116, -115, -114,
554
-113, -111, -110, -109, -107, -106, -105, -103,
555
-102, -100, -99, -97, -96, -94, -92, -91,
556
-89, -87, -85, -84, -82, -80, -78, -76,
557
-74, -73, -71, -69, -67, -65, -63, -61,
558
-58, -56, -54, -52, -50, -48, -46, -44,
559
-41, -39, -37, -35, -32, -30, -28, -26,
560
-23, -21, -19, -16, -14, -12, -10, -7,
561
-5, -3, 0, 1, 3, 6, 8, 10,
562
13, 15, 17, 19, 22, 24, 26, 29,
563
31, 33, 35, 38, 40, 42, 44, 46,
564
48, 51, 53, 55, 57, 59, 61, 63,
565
65, 67, 69, 71, 73, 75, 77, 79,
566
81, 82, 84, 86, 88, 89, 91, 93,
567
94, 96, 98, 99, 101, 102, 104, 105,
568
106, 108, 109, 110, 112, 113, 114, 115,
569
116, 117, 119, 120, 120, 121, 122, 123,
570
124, 125, 126, 126, 127, 128, 128, 129,
571
129, 130, 130, 131, 131, 131, 131, 132,
572
132, 132, 132, 132, 132, 132, 132, 132,
573
132, 132, 132, 131, 131, 131, 130, 130,
574
130, 129, 129, 128, 127, 127, 126, 125,
575
125, 124, 123, 122, 121, 120, 119, 118,
576
117, 116, 115, 114, 113, 111, 110, 109,
577
107, 106, 105, 103, 102, 100, 99, 97,
578
96, 94, 92, 91, 89, 87, 85, 84, 82
579
};
580
581
static const s16 hsv_green_x[] = {
582
-124, -124, -125, -125, -125, -125, -125, -125,
583
-125, -126, -126, -125, -125, -125, -125, -125,
584
-125, -124, -124, -124, -123, -123, -122, -122,
585
-121, -121, -120, -120, -119, -118, -117, -117,
586
-116, -115, -114, -113, -112, -111, -110, -109,
587
-108, -107, -105, -104, -103, -102, -100, -99,
588
-98, -96, -95, -93, -92, -91, -89, -87,
589
-86, -84, -83, -81, -79, -77, -76, -74,
590
-72, -70, -69, -67, -65, -63, -61, -59,
591
-57, -55, -53, -51, -49, -47, -45, -43,
592
-41, -39, -37, -35, -33, -30, -28, -26,
593
-24, -22, -20, -18, -15, -13, -11, -9,
594
-7, -4, -2, 0, 1, 3, 6, 8,
595
10, 12, 14, 17, 19, 21, 23, 25,
596
27, 29, 32, 34, 36, 38, 40, 42,
597
44, 46, 48, 50, 52, 54, 56, 58,
598
60, 62, 64, 66, 68, 70, 71, 73,
599
75, 77, 78, 80, 82, 83, 85, 87,
600
88, 90, 91, 93, 94, 96, 97, 98,
601
100, 101, 102, 104, 105, 106, 107, 108,
602
109, 111, 112, 113, 113, 114, 115, 116,
603
117, 118, 118, 119, 120, 120, 121, 122,
604
122, 123, 123, 124, 124, 124, 125, 125,
605
125, 125, 125, 125, 125, 126, 126, 125,
606
125, 125, 125, 125, 125, 124, 124, 124,
607
123, 123, 122, 122, 121, 121, 120, 120,
608
119, 118, 117, 117, 116, 115, 114, 113,
609
112, 111, 110, 109, 108, 107, 105, 104,
610
103, 102, 100, 99, 98, 96, 95, 93,
611
92, 91, 89, 87, 86, 84, 83, 81,
612
79, 77, 76, 74, 72, 70, 69, 67,
613
65, 63, 61, 59, 57, 55, 53, 51,
614
49, 47, 45, 43, 41, 39, 37, 35,
615
33, 30, 28, 26, 24, 22, 20, 18,
616
15, 13, 11, 9, 7, 4, 2, 0,
617
-1, -3, -6, -8, -10, -12, -14, -17,
618
-19, -21, -23, -25, -27, -29, -32, -34,
619
-36, -38, -40, -42, -44, -46, -48, -50,
620
-52, -54, -56, -58, -60, -62, -64, -66,
621
-68, -70, -71, -73, -75, -77, -78, -80,
622
-82, -83, -85, -87, -88, -90, -91, -93,
623
-94, -96, -97, -98, -100, -101, -102, -104,
624
-105, -106, -107, -108, -109, -111, -112, -113,
625
-113, -114, -115, -116, -117, -118, -118, -119,
626
-120, -120, -121, -122, -122, -123, -123, -124, -124
627
};
628
629
static const s16 hsv_green_y[] = {
630
-100, -99, -98, -97, -95, -94, -93, -91,
631
-90, -89, -87, -86, -84, -83, -81, -80,
632
-78, -76, -75, -73, -71, -70, -68, -66,
633
-64, -63, -61, -59, -57, -55, -53, -51,
634
-49, -48, -46, -44, -42, -40, -38, -36,
635
-34, -32, -30, -27, -25, -23, -21, -19,
636
-17, -15, -13, -11, -9, -7, -4, -2,
637
0, 1, 3, 5, 7, 9, 11, 14,
638
16, 18, 20, 22, 24, 26, 28, 30,
639
32, 34, 36, 38, 40, 42, 44, 46,
640
48, 50, 52, 54, 56, 58, 59, 61,
641
63, 65, 67, 68, 70, 72, 74, 75,
642
77, 78, 80, 82, 83, 85, 86, 88,
643
89, 90, 92, 93, 95, 96, 97, 98,
644
100, 101, 102, 103, 104, 105, 106, 107,
645
108, 109, 110, 111, 112, 112, 113, 114,
646
115, 115, 116, 116, 117, 117, 118, 118,
647
119, 119, 119, 120, 120, 120, 120, 120,
648
121, 121, 121, 121, 121, 121, 120, 120,
649
120, 120, 120, 119, 119, 119, 118, 118,
650
117, 117, 116, 116, 115, 114, 114, 113,
651
112, 111, 111, 110, 109, 108, 107, 106,
652
105, 104, 103, 102, 100, 99, 98, 97,
653
95, 94, 93, 91, 90, 89, 87, 86,
654
84, 83, 81, 80, 78, 76, 75, 73,
655
71, 70, 68, 66, 64, 63, 61, 59,
656
57, 55, 53, 51, 49, 48, 46, 44,
657
42, 40, 38, 36, 34, 32, 30, 27,
658
25, 23, 21, 19, 17, 15, 13, 11,
659
9, 7, 4, 2, 0, -1, -3, -5,
660
-7, -9, -11, -14, -16, -18, -20, -22,
661
-24, -26, -28, -30, -32, -34, -36, -38,
662
-40, -42, -44, -46, -48, -50, -52, -54,
663
-56, -58, -59, -61, -63, -65, -67, -68,
664
-70, -72, -74, -75, -77, -78, -80, -82,
665
-83, -85, -86, -88, -89, -90, -92, -93,
666
-95, -96, -97, -98, -100, -101, -102, -103,
667
-104, -105, -106, -107, -108, -109, -110, -111,
668
-112, -112, -113, -114, -115, -115, -116, -116,
669
-117, -117, -118, -118, -119, -119, -119, -120,
670
-120, -120, -120, -120, -121, -121, -121, -121,
671
-121, -121, -120, -120, -120, -120, -120, -119,
672
-119, -119, -118, -118, -117, -117, -116, -116,
673
-115, -114, -114, -113, -112, -111, -111, -110,
674
-109, -108, -107, -106, -105, -104, -103, -102, -100
675
};
676
677
static const s16 hsv_blue_x[] = {
678
112, 113, 114, 114, 115, 116, 117, 117,
679
118, 118, 119, 119, 120, 120, 120, 121,
680
121, 121, 122, 122, 122, 122, 122, 122,
681
122, 122, 122, 122, 122, 122, 121, 121,
682
121, 120, 120, 120, 119, 119, 118, 118,
683
117, 116, 116, 115, 114, 113, 113, 112,
684
111, 110, 109, 108, 107, 106, 105, 104,
685
103, 102, 100, 99, 98, 97, 95, 94,
686
93, 91, 90, 88, 87, 85, 84, 82,
687
80, 79, 77, 76, 74, 72, 70, 69,
688
67, 65, 63, 61, 60, 58, 56, 54,
689
52, 50, 48, 46, 44, 42, 40, 38,
690
36, 34, 32, 30, 28, 26, 24, 22,
691
19, 17, 15, 13, 11, 9, 7, 5,
692
2, 0, -1, -3, -5, -7, -9, -12,
693
-14, -16, -18, -20, -22, -24, -26, -28,
694
-31, -33, -35, -37, -39, -41, -43, -45,
695
-47, -49, -51, -53, -54, -56, -58, -60,
696
-62, -64, -66, -67, -69, -71, -73, -74,
697
-76, -78, -79, -81, -83, -84, -86, -87,
698
-89, -90, -92, -93, -94, -96, -97, -98,
699
-99, -101, -102, -103, -104, -105, -106, -107,
700
-108, -109, -110, -111, -112, -113, -114, -114,
701
-115, -116, -117, -117, -118, -118, -119, -119,
702
-120, -120, -120, -121, -121, -121, -122, -122,
703
-122, -122, -122, -122, -122, -122, -122, -122,
704
-122, -122, -121, -121, -121, -120, -120, -120,
705
-119, -119, -118, -118, -117, -116, -116, -115,
706
-114, -113, -113, -112, -111, -110, -109, -108,
707
-107, -106, -105, -104, -103, -102, -100, -99,
708
-98, -97, -95, -94, -93, -91, -90, -88,
709
-87, -85, -84, -82, -80, -79, -77, -76,
710
-74, -72, -70, -69, -67, -65, -63, -61,
711
-60, -58, -56, -54, -52, -50, -48, -46,
712
-44, -42, -40, -38, -36, -34, -32, -30,
713
-28, -26, -24, -22, -19, -17, -15, -13,
714
-11, -9, -7, -5, -2, 0, 1, 3,
715
5, 7, 9, 12, 14, 16, 18, 20,
716
22, 24, 26, 28, 31, 33, 35, 37,
717
39, 41, 43, 45, 47, 49, 51, 53,
718
54, 56, 58, 60, 62, 64, 66, 67,
719
69, 71, 73, 74, 76, 78, 79, 81,
720
83, 84, 86, 87, 89, 90, 92, 93,
721
94, 96, 97, 98, 99, 101, 102, 103,
722
104, 105, 106, 107, 108, 109, 110, 111, 112
723
};
724
725
static const s16 hsv_blue_y[] = {
726
-11, -13, -15, -17, -19, -21, -23, -25,
727
-27, -29, -31, -33, -35, -37, -39, -41,
728
-43, -45, -46, -48, -50, -52, -54, -55,
729
-57, -59, -61, -62, -64, -66, -67, -69,
730
-71, -72, -74, -75, -77, -78, -80, -81,
731
-83, -84, -86, -87, -88, -90, -91, -92,
732
-93, -95, -96, -97, -98, -99, -100, -101,
733
-102, -103, -104, -105, -106, -106, -107, -108,
734
-109, -109, -110, -111, -111, -112, -112, -113,
735
-113, -114, -114, -114, -115, -115, -115, -115,
736
-116, -116, -116, -116, -116, -116, -116, -116,
737
-116, -115, -115, -115, -115, -114, -114, -114,
738
-113, -113, -112, -112, -111, -111, -110, -110,
739
-109, -108, -108, -107, -106, -105, -104, -103,
740
-102, -101, -100, -99, -98, -97, -96, -95,
741
-94, -93, -91, -90, -89, -88, -86, -85,
742
-84, -82, -81, -79, -78, -76, -75, -73,
743
-71, -70, -68, -67, -65, -63, -62, -60,
744
-58, -56, -55, -53, -51, -49, -47, -45,
745
-44, -42, -40, -38, -36, -34, -32, -30,
746
-28, -26, -24, -22, -20, -18, -16, -14,
747
-12, -10, -8, -6, -4, -2, 0, 1,
748
3, 5, 7, 9, 11, 13, 15, 17,
749
19, 21, 23, 25, 27, 29, 31, 33,
750
35, 37, 39, 41, 43, 45, 46, 48,
751
50, 52, 54, 55, 57, 59, 61, 62,
752
64, 66, 67, 69, 71, 72, 74, 75,
753
77, 78, 80, 81, 83, 84, 86, 87,
754
88, 90, 91, 92, 93, 95, 96, 97,
755
98, 99, 100, 101, 102, 103, 104, 105,
756
106, 106, 107, 108, 109, 109, 110, 111,
757
111, 112, 112, 113, 113, 114, 114, 114,
758
115, 115, 115, 115, 116, 116, 116, 116,
759
116, 116, 116, 116, 116, 115, 115, 115,
760
115, 114, 114, 114, 113, 113, 112, 112,
761
111, 111, 110, 110, 109, 108, 108, 107,
762
106, 105, 104, 103, 102, 101, 100, 99,
763
98, 97, 96, 95, 94, 93, 91, 90,
764
89, 88, 86, 85, 84, 82, 81, 79,
765
78, 76, 75, 73, 71, 70, 68, 67,
766
65, 63, 62, 60, 58, 56, 55, 53,
767
51, 49, 47, 45, 44, 42, 40, 38,
768
36, 34, 32, 30, 28, 26, 24, 22,
769
20, 18, 16, 14, 12, 10, 8, 6,
770
4, 2, 0, -1, -3, -5, -7, -9, -11
771
};
772
773
static u16 i2c_ident[] = {
774
V4L2_IDENT_OV9650,
775
V4L2_IDENT_OV9655,
776
V4L2_IDENT_SOI968,
777
V4L2_IDENT_OV7660,
778
V4L2_IDENT_OV7670,
779
V4L2_IDENT_MT9V011,
780
V4L2_IDENT_MT9V111,
781
V4L2_IDENT_MT9V112,
782
V4L2_IDENT_MT9M001C12ST,
783
V4L2_IDENT_MT9M111,
784
V4L2_IDENT_MT9M112,
785
V4L2_IDENT_HV7131R,
786
};
787
788
static u16 bridge_init[][2] = {
789
{0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
790
{0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
791
{0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
792
{0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
793
{0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
794
{0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
795
{0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
796
{0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
797
{0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
798
{0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
799
{0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
800
{0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
801
{0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
802
{0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
803
{0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
804
{0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
805
{0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
806
{0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
807
{0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
808
{0x1007, 0x00}
809
};
810
811
/* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
812
static u8 ov_gain[] = {
813
0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
814
0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
815
0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
816
0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
817
0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
818
0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
819
0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
820
0x70 /* 8x */
821
};
822
823
/* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
824
static u16 micron1_gain[] = {
825
/* 1x 1.25x 1.5x 1.75x */
826
0x0020, 0x0028, 0x0030, 0x0038,
827
/* 2x 2.25x 2.5x 2.75x */
828
0x00a0, 0x00a4, 0x00a8, 0x00ac,
829
/* 3x 3.25x 3.5x 3.75x */
830
0x00b0, 0x00b4, 0x00b8, 0x00bc,
831
/* 4x 4.25x 4.5x 4.75x */
832
0x00c0, 0x00c4, 0x00c8, 0x00cc,
833
/* 5x 5.25x 5.5x 5.75x */
834
0x00d0, 0x00d4, 0x00d8, 0x00dc,
835
/* 6x 6.25x 6.5x 6.75x */
836
0x00e0, 0x00e4, 0x00e8, 0x00ec,
837
/* 7x 7.25x 7.5x 7.75x */
838
0x00f0, 0x00f4, 0x00f8, 0x00fc,
839
/* 8x */
840
0x01c0
841
};
842
843
/* mt9m001 sensor uses a different gain formula then other micron sensors */
844
/* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
845
static u16 micron2_gain[] = {
846
/* 1x 1.25x 1.5x 1.75x */
847
0x0008, 0x000a, 0x000c, 0x000e,
848
/* 2x 2.25x 2.5x 2.75x */
849
0x0010, 0x0012, 0x0014, 0x0016,
850
/* 3x 3.25x 3.5x 3.75x */
851
0x0018, 0x001a, 0x001c, 0x001e,
852
/* 4x 4.25x 4.5x 4.75x */
853
0x0020, 0x0051, 0x0052, 0x0053,
854
/* 5x 5.25x 5.5x 5.75x */
855
0x0054, 0x0055, 0x0056, 0x0057,
856
/* 6x 6.25x 6.5x 6.75x */
857
0x0058, 0x0059, 0x005a, 0x005b,
858
/* 7x 7.25x 7.5x 7.75x */
859
0x005c, 0x005d, 0x005e, 0x005f,
860
/* 8x */
861
0x0060
862
};
863
864
/* Gain = .5 + bit[7:0] / 16 */
865
static u8 hv7131r_gain[] = {
866
0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
867
0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
868
0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
869
0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
870
0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
871
0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
872
0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
873
0x78 /* 8x */
874
};
875
876
static struct i2c_reg_u8 soi968_init[] = {
877
{0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f},
878
{0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
879
{0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
880
{0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
881
{0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
882
{0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
883
{0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
884
{0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
885
{0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
886
{0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
887
{0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
888
};
889
890
static struct i2c_reg_u8 ov7660_init[] = {
891
{0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
892
{0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
893
{0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
894
/* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
895
0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
896
{0x17, 0x10}, {0x18, 0x61},
897
{0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
898
{0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
899
{0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
900
};
901
902
static struct i2c_reg_u8 ov7670_init[] = {
903
{0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
904
{0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
905
{0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
906
{0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
907
{0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
908
{0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
909
{0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
910
{0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
911
{0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
912
{0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
913
{0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
914
{0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
915
{0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
916
{0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
917
{0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
918
{0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
919
{0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
920
{0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
921
{0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
922
{0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
923
{0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
924
{0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
925
{0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
926
{0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
927
{0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
928
{0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
929
{0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
930
{0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
931
{0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
932
{0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
933
{0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
934
{0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
935
{0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
936
{0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
937
{0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
938
{0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
939
{0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
940
{0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
941
{0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
942
{0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
943
{0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
944
{0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
945
{0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
946
{0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
947
{0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
948
{0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
949
{0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
950
{0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
951
{0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
952
{0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
953
{0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
954
{0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
955
{0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
956
{0x93, 0x00},
957
};
958
959
static struct i2c_reg_u8 ov9650_init[] = {
960
{0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78},
961
{0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
962
{0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
963
{0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
964
{0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
965
{0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
966
{0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
967
{0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
968
{0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
969
{0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
970
{0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
971
{0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
972
{0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
973
{0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
974
{0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
975
{0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
976
{0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
977
{0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
978
{0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
979
{0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
980
{0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
981
{0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
982
{0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
983
{0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
984
{0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
985
{0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
986
{0xaa, 0x92}, {0xab, 0x0a},
987
};
988
989
static struct i2c_reg_u8 ov9655_init[] = {
990
{0x12, 0x80}, {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
991
{0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
992
{0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
993
{0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
994
{0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
995
{0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
996
{0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
997
{0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
998
{0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
999
{0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
1000
{0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
1001
{0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
1002
{0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
1003
{0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
1004
{0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
1005
{0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
1006
{0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
1007
{0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
1008
{0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
1009
{0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
1010
{0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
1011
{0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
1012
{0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
1013
{0x04, 0x03}, {0x00, 0x13},
1014
};
1015
1016
static struct i2c_reg_u16 mt9v112_init[] = {
1017
{0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
1018
{0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
1019
{0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
1020
{0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
1021
{0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
1022
{0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
1023
{0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
1024
{0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
1025
{0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
1026
{0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
1027
{0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
1028
{0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1029
{0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
1030
{0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
1031
{0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
1032
{0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
1033
};
1034
1035
static struct i2c_reg_u16 mt9v111_init[] = {
1036
{0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
1037
{0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
1038
{0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
1039
{0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
1040
{0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
1041
{0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
1042
{0x0e, 0x0008}, {0x20, 0x0000}
1043
};
1044
1045
static struct i2c_reg_u16 mt9v011_init[] = {
1046
{0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
1047
{0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
1048
{0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
1049
{0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
1050
{0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
1051
{0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
1052
{0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
1053
{0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
1054
{0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
1055
{0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
1056
{0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
1057
{0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
1058
{0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
1059
{0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
1060
{0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
1061
{0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
1062
{0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
1063
{0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
1064
{0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
1065
{0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
1066
{0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
1067
{0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1068
{0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
1069
{0x06, 0x0029}, {0x05, 0x0009},
1070
};
1071
1072
static struct i2c_reg_u16 mt9m001_init[] = {
1073
{0x0d, 0x0001},
1074
{0x0d, 0x0000},
1075
{0x04, 0x0500}, /* hres = 1280 */
1076
{0x03, 0x0400}, /* vres = 1024 */
1077
{0x20, 0x1100},
1078
{0x06, 0x0010},
1079
{0x2b, 0x0024},
1080
{0x2e, 0x0024},
1081
{0x35, 0x0024},
1082
{0x2d, 0x0020},
1083
{0x2c, 0x0020},
1084
{0x09, 0x0ad4},
1085
{0x35, 0x0057},
1086
};
1087
1088
static struct i2c_reg_u16 mt9m111_init[] = {
1089
{0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1090
{0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1091
{0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1092
{0xf0, 0x0000},
1093
};
1094
1095
static struct i2c_reg_u16 mt9m112_init[] = {
1096
{0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1097
{0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1098
{0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1099
{0xf0, 0x0000},
1100
};
1101
1102
static struct i2c_reg_u8 hv7131r_init[] = {
1103
{0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1104
{0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1105
{0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
1106
{0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
1107
{0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
1108
{0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
1109
{0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
1110
{0x23, 0x09}, {0x01, 0x08},
1111
};
1112
1113
static int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
1114
{
1115
struct usb_device *dev = gspca_dev->dev;
1116
int result;
1117
result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
1118
0x00,
1119
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1120
reg,
1121
0x00,
1122
gspca_dev->usb_buf,
1123
length,
1124
500);
1125
if (unlikely(result < 0 || result != length)) {
1126
err("Read register failed 0x%02X", reg);
1127
return -EIO;
1128
}
1129
return 0;
1130
}
1131
1132
static int reg_w(struct gspca_dev *gspca_dev, u16 reg,
1133
const u8 *buffer, int length)
1134
{
1135
struct usb_device *dev = gspca_dev->dev;
1136
int result;
1137
memcpy(gspca_dev->usb_buf, buffer, length);
1138
result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1139
0x08,
1140
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1141
reg,
1142
0x00,
1143
gspca_dev->usb_buf,
1144
length,
1145
500);
1146
if (unlikely(result < 0 || result != length)) {
1147
err("Write register failed index 0x%02X", reg);
1148
return -EIO;
1149
}
1150
return 0;
1151
}
1152
1153
static int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
1154
{
1155
u8 data[1] = {value};
1156
return reg_w(gspca_dev, reg, data, 1);
1157
}
1158
1159
static int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
1160
{
1161
int i;
1162
reg_w(gspca_dev, 0x10c0, buffer, 8);
1163
for (i = 0; i < 5; i++) {
1164
reg_r(gspca_dev, 0x10c0, 1);
1165
if (gspca_dev->usb_buf[0] & 0x04) {
1166
if (gspca_dev->usb_buf[0] & 0x08)
1167
return -EIO;
1168
return 0;
1169
}
1170
msleep(1);
1171
}
1172
return -EIO;
1173
}
1174
1175
static int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1176
{
1177
struct sd *sd = (struct sd *) gspca_dev;
1178
1179
u8 row[8];
1180
1181
/*
1182
* from the point of view of the bridge, the length
1183
* includes the address
1184
*/
1185
row[0] = 0x81 | (2 << 4);
1186
row[1] = sd->i2c_addr;
1187
row[2] = reg;
1188
row[3] = val;
1189
row[4] = 0x00;
1190
row[5] = 0x00;
1191
row[6] = 0x00;
1192
row[7] = 0x10;
1193
1194
return i2c_w(gspca_dev, row);
1195
}
1196
1197
static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1198
{
1199
struct sd *sd = (struct sd *) gspca_dev;
1200
u8 row[8];
1201
1202
/*
1203
* from the point of view of the bridge, the length
1204
* includes the address
1205
*/
1206
row[0] = 0x81 | (3 << 4);
1207
row[1] = sd->i2c_addr;
1208
row[2] = reg;
1209
row[3] = (val >> 8) & 0xff;
1210
row[4] = val & 0xff;
1211
row[5] = 0x00;
1212
row[6] = 0x00;
1213
row[7] = 0x10;
1214
1215
return i2c_w(gspca_dev, row);
1216
}
1217
1218
static int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1219
{
1220
struct sd *sd = (struct sd *) gspca_dev;
1221
u8 row[8];
1222
1223
row[0] = 0x81 | (1 << 4);
1224
row[1] = sd->i2c_addr;
1225
row[2] = reg;
1226
row[3] = 0;
1227
row[4] = 0;
1228
row[5] = 0;
1229
row[6] = 0;
1230
row[7] = 0x10;
1231
if (i2c_w(gspca_dev, row) < 0)
1232
return -EIO;
1233
row[0] = 0x81 | (1 << 4) | 0x02;
1234
row[2] = 0;
1235
if (i2c_w(gspca_dev, row) < 0)
1236
return -EIO;
1237
if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1238
return -EIO;
1239
*val = gspca_dev->usb_buf[4];
1240
return 0;
1241
}
1242
1243
static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1244
{
1245
struct sd *sd = (struct sd *) gspca_dev;
1246
u8 row[8];
1247
1248
row[0] = 0x81 | (1 << 4);
1249
row[1] = sd->i2c_addr;
1250
row[2] = reg;
1251
row[3] = 0;
1252
row[4] = 0;
1253
row[5] = 0;
1254
row[6] = 0;
1255
row[7] = 0x10;
1256
if (i2c_w(gspca_dev, row) < 0)
1257
return -EIO;
1258
row[0] = 0x81 | (2 << 4) | 0x02;
1259
row[2] = 0;
1260
if (i2c_w(gspca_dev, row) < 0)
1261
return -EIO;
1262
if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1263
return -EIO;
1264
*val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1265
return 0;
1266
}
1267
1268
static int ov9650_init_sensor(struct gspca_dev *gspca_dev)
1269
{
1270
int i;
1271
u16 id;
1272
struct sd *sd = (struct sd *) gspca_dev;
1273
1274
if (i2c_r2(gspca_dev, 0x1c, &id) < 0)
1275
return -EINVAL;
1276
1277
if (id != 0x7fa2) {
1278
err("sensor id for ov9650 doesn't match (0x%04x)", id);
1279
return -ENODEV;
1280
}
1281
1282
for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) {
1283
if (i2c_w1(gspca_dev, ov9650_init[i].reg,
1284
ov9650_init[i].val) < 0) {
1285
err("OV9650 sensor initialization failed");
1286
return -ENODEV;
1287
}
1288
}
1289
sd->hstart = 1;
1290
sd->vstart = 7;
1291
return 0;
1292
}
1293
1294
static int ov9655_init_sensor(struct gspca_dev *gspca_dev)
1295
{
1296
int i;
1297
struct sd *sd = (struct sd *) gspca_dev;
1298
1299
for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) {
1300
if (i2c_w1(gspca_dev, ov9655_init[i].reg,
1301
ov9655_init[i].val) < 0) {
1302
err("OV9655 sensor initialization failed");
1303
return -ENODEV;
1304
}
1305
}
1306
/* disable hflip and vflip */
1307
gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1308
sd->hstart = 1;
1309
sd->vstart = 2;
1310
return 0;
1311
}
1312
1313
static int soi968_init_sensor(struct gspca_dev *gspca_dev)
1314
{
1315
int i;
1316
struct sd *sd = (struct sd *) gspca_dev;
1317
1318
for (i = 0; i < ARRAY_SIZE(soi968_init); i++) {
1319
if (i2c_w1(gspca_dev, soi968_init[i].reg,
1320
soi968_init[i].val) < 0) {
1321
err("SOI968 sensor initialization failed");
1322
return -ENODEV;
1323
}
1324
}
1325
/* disable hflip and vflip */
1326
gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX)
1327
| (1 << EXPOSURE_IDX);
1328
sd->hstart = 60;
1329
sd->vstart = 11;
1330
return 0;
1331
}
1332
1333
static int ov7660_init_sensor(struct gspca_dev *gspca_dev)
1334
{
1335
int i;
1336
struct sd *sd = (struct sd *) gspca_dev;
1337
1338
for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) {
1339
if (i2c_w1(gspca_dev, ov7660_init[i].reg,
1340
ov7660_init[i].val) < 0) {
1341
err("OV7660 sensor initialization failed");
1342
return -ENODEV;
1343
}
1344
}
1345
sd->hstart = 3;
1346
sd->vstart = 3;
1347
return 0;
1348
}
1349
1350
static int ov7670_init_sensor(struct gspca_dev *gspca_dev)
1351
{
1352
int i;
1353
struct sd *sd = (struct sd *) gspca_dev;
1354
1355
for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) {
1356
if (i2c_w1(gspca_dev, ov7670_init[i].reg,
1357
ov7670_init[i].val) < 0) {
1358
err("OV7670 sensor initialization failed");
1359
return -ENODEV;
1360
}
1361
}
1362
/* disable hflip and vflip */
1363
gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1364
sd->hstart = 0;
1365
sd->vstart = 1;
1366
return 0;
1367
}
1368
1369
static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
1370
{
1371
struct sd *sd = (struct sd *) gspca_dev;
1372
int i;
1373
u16 value;
1374
int ret;
1375
1376
sd->i2c_addr = 0x5d;
1377
ret = i2c_r2(gspca_dev, 0xff, &value);
1378
if ((ret == 0) && (value == 0x8243)) {
1379
for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) {
1380
if (i2c_w2(gspca_dev, mt9v011_init[i].reg,
1381
mt9v011_init[i].val) < 0) {
1382
err("MT9V011 sensor initialization failed");
1383
return -ENODEV;
1384
}
1385
}
1386
sd->hstart = 2;
1387
sd->vstart = 2;
1388
sd->sensor = SENSOR_MT9V011;
1389
info("MT9V011 sensor detected");
1390
return 0;
1391
}
1392
1393
sd->i2c_addr = 0x5c;
1394
i2c_w2(gspca_dev, 0x01, 0x0004);
1395
ret = i2c_r2(gspca_dev, 0xff, &value);
1396
if ((ret == 0) && (value == 0x823a)) {
1397
for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) {
1398
if (i2c_w2(gspca_dev, mt9v111_init[i].reg,
1399
mt9v111_init[i].val) < 0) {
1400
err("MT9V111 sensor initialization failed");
1401
return -ENODEV;
1402
}
1403
}
1404
gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX)
1405
| (1 << AUTOGAIN_IDX)
1406
| (1 << GAIN_IDX);
1407
sd->hstart = 2;
1408
sd->vstart = 2;
1409
sd->sensor = SENSOR_MT9V111;
1410
info("MT9V111 sensor detected");
1411
return 0;
1412
}
1413
1414
sd->i2c_addr = 0x5d;
1415
ret = i2c_w2(gspca_dev, 0xf0, 0x0000);
1416
if (ret < 0) {
1417
sd->i2c_addr = 0x48;
1418
i2c_w2(gspca_dev, 0xf0, 0x0000);
1419
}
1420
ret = i2c_r2(gspca_dev, 0x00, &value);
1421
if ((ret == 0) && (value == 0x1229)) {
1422
for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) {
1423
if (i2c_w2(gspca_dev, mt9v112_init[i].reg,
1424
mt9v112_init[i].val) < 0) {
1425
err("MT9V112 sensor initialization failed");
1426
return -ENODEV;
1427
}
1428
}
1429
sd->hstart = 6;
1430
sd->vstart = 2;
1431
sd->sensor = SENSOR_MT9V112;
1432
info("MT9V112 sensor detected");
1433
return 0;
1434
}
1435
1436
return -ENODEV;
1437
}
1438
1439
static int mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1440
{
1441
struct sd *sd = (struct sd *) gspca_dev;
1442
int i;
1443
for (i = 0; i < ARRAY_SIZE(mt9m112_init); i++) {
1444
if (i2c_w2(gspca_dev, mt9m112_init[i].reg,
1445
mt9m112_init[i].val) < 0) {
1446
err("MT9M112 sensor initialization failed");
1447
return -ENODEV;
1448
}
1449
}
1450
gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)
1451
| (1 << GAIN_IDX);
1452
sd->hstart = 0;
1453
sd->vstart = 2;
1454
return 0;
1455
}
1456
1457
static int mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1458
{
1459
struct sd *sd = (struct sd *) gspca_dev;
1460
int i;
1461
for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) {
1462
if (i2c_w2(gspca_dev, mt9m111_init[i].reg,
1463
mt9m111_init[i].val) < 0) {
1464
err("MT9M111 sensor initialization failed");
1465
return -ENODEV;
1466
}
1467
}
1468
gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)
1469
| (1 << GAIN_IDX);
1470
sd->hstart = 0;
1471
sd->vstart = 2;
1472
return 0;
1473
}
1474
1475
static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1476
{
1477
struct sd *sd = (struct sd *) gspca_dev;
1478
int i;
1479
u16 id;
1480
1481
if (i2c_r2(gspca_dev, 0x00, &id) < 0)
1482
return -EINVAL;
1483
1484
/* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1485
switch (id) {
1486
case 0x8411:
1487
case 0x8421:
1488
info("MT9M001 color sensor detected");
1489
break;
1490
case 0x8431:
1491
info("MT9M001 mono sensor detected");
1492
break;
1493
default:
1494
err("No MT9M001 chip detected, ID = %x\n", id);
1495
return -ENODEV;
1496
}
1497
1498
for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) {
1499
if (i2c_w2(gspca_dev, mt9m001_init[i].reg,
1500
mt9m001_init[i].val) < 0) {
1501
err("MT9M001 sensor initialization failed");
1502
return -ENODEV;
1503
}
1504
}
1505
/* disable hflip and vflip */
1506
gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1507
sd->hstart = 1;
1508
sd->vstart = 1;
1509
return 0;
1510
}
1511
1512
static int hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1513
{
1514
int i;
1515
struct sd *sd = (struct sd *) gspca_dev;
1516
1517
for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) {
1518
if (i2c_w1(gspca_dev, hv7131r_init[i].reg,
1519
hv7131r_init[i].val) < 0) {
1520
err("HV7131R Sensor initialization failed");
1521
return -ENODEV;
1522
}
1523
}
1524
sd->hstart = 0;
1525
sd->vstart = 1;
1526
return 0;
1527
}
1528
1529
static int set_cmatrix(struct gspca_dev *gspca_dev)
1530
{
1531
struct sd *sd = (struct sd *) gspca_dev;
1532
s32 hue_coord, hue_index = 180 + sd->hue;
1533
u8 cmatrix[21];
1534
1535
memset(cmatrix, 0, sizeof cmatrix);
1536
cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26;
1537
cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1538
cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1539
cmatrix[18] = sd->brightness - 0x80;
1540
1541
hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8;
1542
cmatrix[6] = hue_coord;
1543
cmatrix[7] = (hue_coord >> 8) & 0x0f;
1544
1545
hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8;
1546
cmatrix[8] = hue_coord;
1547
cmatrix[9] = (hue_coord >> 8) & 0x0f;
1548
1549
hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8;
1550
cmatrix[10] = hue_coord;
1551
cmatrix[11] = (hue_coord >> 8) & 0x0f;
1552
1553
hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8;
1554
cmatrix[12] = hue_coord;
1555
cmatrix[13] = (hue_coord >> 8) & 0x0f;
1556
1557
hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8;
1558
cmatrix[14] = hue_coord;
1559
cmatrix[15] = (hue_coord >> 8) & 0x0f;
1560
1561
hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8;
1562
cmatrix[16] = hue_coord;
1563
cmatrix[17] = (hue_coord >> 8) & 0x0f;
1564
1565
return reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1566
}
1567
1568
static int set_gamma(struct gspca_dev *gspca_dev)
1569
{
1570
struct sd *sd = (struct sd *) gspca_dev;
1571
u8 gamma[17];
1572
u8 gval = sd->gamma * 0xb8 / 0x100;
1573
1574
1575
gamma[0] = 0x0a;
1576
gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1577
gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1578
gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1579
gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1580
gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1581
gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1582
gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1583
gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1584
gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1585
gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1586
gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1587
gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1588
gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1589
gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1590
gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1591
gamma[16] = 0xf5;
1592
1593
return reg_w(gspca_dev, 0x1190, gamma, 17);
1594
}
1595
1596
static int set_redblue(struct gspca_dev *gspca_dev)
1597
{
1598
struct sd *sd = (struct sd *) gspca_dev;
1599
reg_w1(gspca_dev, 0x118c, sd->red);
1600
reg_w1(gspca_dev, 0x118f, sd->blue);
1601
return 0;
1602
}
1603
1604
static int set_hvflip(struct gspca_dev *gspca_dev)
1605
{
1606
u8 value, tslb, hflip, vflip;
1607
u16 value2;
1608
struct sd *sd = (struct sd *) gspca_dev;
1609
1610
if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1611
hflip = !sd->hflip;
1612
vflip = !sd->vflip;
1613
} else {
1614
hflip = sd->hflip;
1615
vflip = sd->vflip;
1616
}
1617
1618
switch (sd->sensor) {
1619
case SENSOR_OV7660:
1620
value = 0x01;
1621
if (hflip)
1622
value |= 0x20;
1623
if (vflip) {
1624
value |= 0x10;
1625
sd->vstart = 2;
1626
} else
1627
sd->vstart = 3;
1628
reg_w1(gspca_dev, 0x1182, sd->vstart);
1629
i2c_w1(gspca_dev, 0x1e, value);
1630
break;
1631
case SENSOR_OV9650:
1632
i2c_r1(gspca_dev, 0x1e, &value);
1633
value &= ~0x30;
1634
tslb = 0x01;
1635
if (hflip)
1636
value |= 0x20;
1637
if (vflip) {
1638
value |= 0x10;
1639
tslb = 0x49;
1640
}
1641
i2c_w1(gspca_dev, 0x1e, value);
1642
i2c_w1(gspca_dev, 0x3a, tslb);
1643
break;
1644
case SENSOR_MT9V111:
1645
case SENSOR_MT9V011:
1646
i2c_r2(gspca_dev, 0x20, &value2);
1647
value2 &= ~0xc0a0;
1648
if (hflip)
1649
value2 |= 0x8080;
1650
if (vflip)
1651
value2 |= 0x4020;
1652
i2c_w2(gspca_dev, 0x20, value2);
1653
break;
1654
case SENSOR_MT9M112:
1655
case SENSOR_MT9M111:
1656
case SENSOR_MT9V112:
1657
i2c_r2(gspca_dev, 0x20, &value2);
1658
value2 &= ~0x0003;
1659
if (hflip)
1660
value2 |= 0x0002;
1661
if (vflip)
1662
value2 |= 0x0001;
1663
i2c_w2(gspca_dev, 0x20, value2);
1664
break;
1665
case SENSOR_HV7131R:
1666
i2c_r1(gspca_dev, 0x01, &value);
1667
value &= ~0x03;
1668
if (vflip)
1669
value |= 0x01;
1670
if (hflip)
1671
value |= 0x02;
1672
i2c_w1(gspca_dev, 0x01, value);
1673
break;
1674
}
1675
return 0;
1676
}
1677
1678
static int set_exposure(struct gspca_dev *gspca_dev)
1679
{
1680
struct sd *sd = (struct sd *) gspca_dev;
1681
u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1682
switch (sd->sensor) {
1683
case SENSOR_OV7660:
1684
case SENSOR_OV7670:
1685
case SENSOR_OV9655:
1686
case SENSOR_OV9650:
1687
exp[0] |= (3 << 4);
1688
exp[2] = 0x2d;
1689
exp[3] = sd->exposure & 0xff;
1690
exp[4] = sd->exposure >> 8;
1691
break;
1692
case SENSOR_MT9M001:
1693
case SENSOR_MT9V112:
1694
case SENSOR_MT9V011:
1695
exp[0] |= (3 << 4);
1696
exp[2] = 0x09;
1697
exp[3] = sd->exposure >> 8;
1698
exp[4] = sd->exposure & 0xff;
1699
break;
1700
case SENSOR_HV7131R:
1701
exp[0] |= (4 << 4);
1702
exp[2] = 0x25;
1703
exp[3] = (sd->exposure >> 5) & 0xff;
1704
exp[4] = (sd->exposure << 3) & 0xff;
1705
exp[5] = 0;
1706
break;
1707
default:
1708
return 0;
1709
}
1710
i2c_w(gspca_dev, exp);
1711
return 0;
1712
}
1713
1714
static int set_gain(struct gspca_dev *gspca_dev)
1715
{
1716
struct sd *sd = (struct sd *) gspca_dev;
1717
u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1718
switch (sd->sensor) {
1719
case SENSOR_OV7660:
1720
case SENSOR_OV7670:
1721
case SENSOR_SOI968:
1722
case SENSOR_OV9655:
1723
case SENSOR_OV9650:
1724
gain[0] |= (2 << 4);
1725
gain[3] = ov_gain[sd->gain];
1726
break;
1727
case SENSOR_MT9V011:
1728
gain[0] |= (3 << 4);
1729
gain[2] = 0x35;
1730
gain[3] = micron1_gain[sd->gain] >> 8;
1731
gain[4] = micron1_gain[sd->gain] & 0xff;
1732
break;
1733
case SENSOR_MT9V112:
1734
gain[0] |= (3 << 4);
1735
gain[2] = 0x2f;
1736
gain[3] = micron1_gain[sd->gain] >> 8;
1737
gain[4] = micron1_gain[sd->gain] & 0xff;
1738
break;
1739
case SENSOR_MT9M001:
1740
gain[0] |= (3 << 4);
1741
gain[2] = 0x2f;
1742
gain[3] = micron2_gain[sd->gain] >> 8;
1743
gain[4] = micron2_gain[sd->gain] & 0xff;
1744
break;
1745
case SENSOR_HV7131R:
1746
gain[0] |= (2 << 4);
1747
gain[2] = 0x30;
1748
gain[3] = hv7131r_gain[sd->gain];
1749
break;
1750
default:
1751
return 0;
1752
}
1753
i2c_w(gspca_dev, gain);
1754
return 0;
1755
}
1756
1757
static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val)
1758
{
1759
struct sd *sd = (struct sd *) gspca_dev;
1760
1761
sd->brightness = val;
1762
if (gspca_dev->streaming)
1763
return set_cmatrix(gspca_dev);
1764
return 0;
1765
}
1766
1767
static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val)
1768
{
1769
struct sd *sd = (struct sd *) gspca_dev;
1770
*val = sd->brightness;
1771
return 0;
1772
}
1773
1774
1775
static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val)
1776
{
1777
struct sd *sd = (struct sd *) gspca_dev;
1778
1779
sd->contrast = val;
1780
if (gspca_dev->streaming)
1781
return set_cmatrix(gspca_dev);
1782
return 0;
1783
}
1784
1785
static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val)
1786
{
1787
struct sd *sd = (struct sd *) gspca_dev;
1788
*val = sd->contrast;
1789
return 0;
1790
}
1791
1792
static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val)
1793
{
1794
struct sd *sd = (struct sd *) gspca_dev;
1795
1796
sd->saturation = val;
1797
if (gspca_dev->streaming)
1798
return set_cmatrix(gspca_dev);
1799
return 0;
1800
}
1801
1802
static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val)
1803
{
1804
struct sd *sd = (struct sd *) gspca_dev;
1805
*val = sd->saturation;
1806
return 0;
1807
}
1808
1809
static int sd_sethue(struct gspca_dev *gspca_dev, s32 val)
1810
{
1811
struct sd *sd = (struct sd *) gspca_dev;
1812
1813
sd->hue = val;
1814
if (gspca_dev->streaming)
1815
return set_cmatrix(gspca_dev);
1816
return 0;
1817
}
1818
1819
static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val)
1820
{
1821
struct sd *sd = (struct sd *) gspca_dev;
1822
*val = sd->hue;
1823
return 0;
1824
}
1825
1826
static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val)
1827
{
1828
struct sd *sd = (struct sd *) gspca_dev;
1829
1830
sd->gamma = val;
1831
if (gspca_dev->streaming)
1832
return set_gamma(gspca_dev);
1833
return 0;
1834
}
1835
1836
static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val)
1837
{
1838
struct sd *sd = (struct sd *) gspca_dev;
1839
*val = sd->gamma;
1840
return 0;
1841
}
1842
1843
static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val)
1844
{
1845
struct sd *sd = (struct sd *) gspca_dev;
1846
1847
sd->red = val;
1848
if (gspca_dev->streaming)
1849
return set_redblue(gspca_dev);
1850
return 0;
1851
}
1852
1853
static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val)
1854
{
1855
struct sd *sd = (struct sd *) gspca_dev;
1856
*val = sd->red;
1857
return 0;
1858
}
1859
1860
static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val)
1861
{
1862
struct sd *sd = (struct sd *) gspca_dev;
1863
1864
sd->blue = val;
1865
if (gspca_dev->streaming)
1866
return set_redblue(gspca_dev);
1867
return 0;
1868
}
1869
1870
static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val)
1871
{
1872
struct sd *sd = (struct sd *) gspca_dev;
1873
*val = sd->blue;
1874
return 0;
1875
}
1876
1877
static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val)
1878
{
1879
struct sd *sd = (struct sd *) gspca_dev;
1880
1881
sd->hflip = val;
1882
if (gspca_dev->streaming)
1883
return set_hvflip(gspca_dev);
1884
return 0;
1885
}
1886
1887
static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val)
1888
{
1889
struct sd *sd = (struct sd *) gspca_dev;
1890
*val = sd->hflip;
1891
return 0;
1892
}
1893
1894
static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val)
1895
{
1896
struct sd *sd = (struct sd *) gspca_dev;
1897
1898
sd->vflip = val;
1899
if (gspca_dev->streaming)
1900
return set_hvflip(gspca_dev);
1901
return 0;
1902
}
1903
1904
static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val)
1905
{
1906
struct sd *sd = (struct sd *) gspca_dev;
1907
*val = sd->vflip;
1908
return 0;
1909
}
1910
1911
static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val)
1912
{
1913
struct sd *sd = (struct sd *) gspca_dev;
1914
1915
sd->exposure = val;
1916
if (gspca_dev->streaming)
1917
return set_exposure(gspca_dev);
1918
return 0;
1919
}
1920
1921
static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val)
1922
{
1923
struct sd *sd = (struct sd *) gspca_dev;
1924
*val = sd->exposure;
1925
return 0;
1926
}
1927
1928
static int sd_setgain(struct gspca_dev *gspca_dev, s32 val)
1929
{
1930
struct sd *sd = (struct sd *) gspca_dev;
1931
1932
sd->gain = val;
1933
if (gspca_dev->streaming)
1934
return set_gain(gspca_dev);
1935
return 0;
1936
}
1937
1938
static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val)
1939
{
1940
struct sd *sd = (struct sd *) gspca_dev;
1941
*val = sd->gain;
1942
return 0;
1943
}
1944
1945
static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val)
1946
{
1947
struct sd *sd = (struct sd *) gspca_dev;
1948
sd->auto_exposure = val;
1949
return 0;
1950
}
1951
1952
static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val)
1953
{
1954
struct sd *sd = (struct sd *) gspca_dev;
1955
*val = sd->auto_exposure;
1956
return 0;
1957
}
1958
1959
#ifdef CONFIG_VIDEO_ADV_DEBUG
1960
static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1961
struct v4l2_dbg_register *reg)
1962
{
1963
struct sd *sd = (struct sd *) gspca_dev;
1964
switch (reg->match.type) {
1965
case V4L2_CHIP_MATCH_HOST:
1966
if (reg->match.addr != 0)
1967
return -EINVAL;
1968
if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1969
return -EINVAL;
1970
if (reg_r(gspca_dev, reg->reg, 1) < 0)
1971
return -EINVAL;
1972
reg->val = gspca_dev->usb_buf[0];
1973
return 0;
1974
case V4L2_CHIP_MATCH_I2C_ADDR:
1975
if (reg->match.addr != sd->i2c_addr)
1976
return -EINVAL;
1977
if (sd->sensor >= SENSOR_MT9V011 &&
1978
sd->sensor <= SENSOR_MT9M112) {
1979
if (i2c_r2(gspca_dev, reg->reg, (u16 *)&reg->val) < 0)
1980
return -EINVAL;
1981
} else {
1982
if (i2c_r1(gspca_dev, reg->reg, (u8 *)&reg->val) < 0)
1983
return -EINVAL;
1984
}
1985
return 0;
1986
}
1987
return -EINVAL;
1988
}
1989
1990
static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1991
struct v4l2_dbg_register *reg)
1992
{
1993
struct sd *sd = (struct sd *) gspca_dev;
1994
switch (reg->match.type) {
1995
case V4L2_CHIP_MATCH_HOST:
1996
if (reg->match.addr != 0)
1997
return -EINVAL;
1998
if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1999
return -EINVAL;
2000
if (reg_w1(gspca_dev, reg->reg, reg->val) < 0)
2001
return -EINVAL;
2002
return 0;
2003
case V4L2_CHIP_MATCH_I2C_ADDR:
2004
if (reg->match.addr != sd->i2c_addr)
2005
return -EINVAL;
2006
if (sd->sensor >= SENSOR_MT9V011 &&
2007
sd->sensor <= SENSOR_MT9M112) {
2008
if (i2c_w2(gspca_dev, reg->reg, reg->val) < 0)
2009
return -EINVAL;
2010
} else {
2011
if (i2c_w1(gspca_dev, reg->reg, reg->val) < 0)
2012
return -EINVAL;
2013
}
2014
return 0;
2015
}
2016
return -EINVAL;
2017
}
2018
#endif
2019
2020
static int sd_chip_ident(struct gspca_dev *gspca_dev,
2021
struct v4l2_dbg_chip_ident *chip)
2022
{
2023
struct sd *sd = (struct sd *) gspca_dev;
2024
2025
switch (chip->match.type) {
2026
case V4L2_CHIP_MATCH_HOST:
2027
if (chip->match.addr != 0)
2028
return -EINVAL;
2029
chip->revision = 0;
2030
chip->ident = V4L2_IDENT_SN9C20X;
2031
return 0;
2032
case V4L2_CHIP_MATCH_I2C_ADDR:
2033
if (chip->match.addr != sd->i2c_addr)
2034
return -EINVAL;
2035
chip->revision = 0;
2036
chip->ident = i2c_ident[sd->sensor];
2037
return 0;
2038
}
2039
return -EINVAL;
2040
}
2041
2042
static int sd_config(struct gspca_dev *gspca_dev,
2043
const struct usb_device_id *id)
2044
{
2045
struct sd *sd = (struct sd *) gspca_dev;
2046
struct cam *cam;
2047
2048
cam = &gspca_dev->cam;
2049
2050
sd->sensor = (id->driver_info >> 8) & 0xff;
2051
sd->i2c_addr = id->driver_info & 0xff;
2052
sd->flags = (id->driver_info >> 16) & 0xff;
2053
2054
switch (sd->sensor) {
2055
case SENSOR_MT9M112:
2056
case SENSOR_MT9M111:
2057
case SENSOR_OV9650:
2058
case SENSOR_SOI968:
2059
cam->cam_mode = sxga_mode;
2060
cam->nmodes = ARRAY_SIZE(sxga_mode);
2061
break;
2062
case SENSOR_MT9M001:
2063
cam->cam_mode = mono_mode;
2064
cam->nmodes = ARRAY_SIZE(mono_mode);
2065
break;
2066
default:
2067
cam->cam_mode = vga_mode;
2068
cam->nmodes = ARRAY_SIZE(vga_mode);
2069
break;
2070
}
2071
2072
sd->old_step = 0;
2073
sd->older_step = 0;
2074
sd->exposure_step = 16;
2075
2076
sd->brightness = BRIGHTNESS_DEFAULT;
2077
sd->contrast = CONTRAST_DEFAULT;
2078
sd->saturation = SATURATION_DEFAULT;
2079
sd->hue = HUE_DEFAULT;
2080
sd->gamma = GAMMA_DEFAULT;
2081
sd->red = RED_DEFAULT;
2082
sd->blue = BLUE_DEFAULT;
2083
2084
sd->hflip = HFLIP_DEFAULT;
2085
sd->vflip = VFLIP_DEFAULT;
2086
sd->exposure = EXPOSURE_DEFAULT;
2087
sd->gain = GAIN_DEFAULT;
2088
sd->auto_exposure = AUTO_EXPOSURE_DEFAULT;
2089
2090
sd->quality = 95;
2091
2092
return 0;
2093
}
2094
2095
static int sd_init(struct gspca_dev *gspca_dev)
2096
{
2097
struct sd *sd = (struct sd *) gspca_dev;
2098
int i;
2099
u8 value;
2100
u8 i2c_init[9] =
2101
{0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
2102
2103
for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
2104
value = bridge_init[i][1];
2105
if (reg_w(gspca_dev, bridge_init[i][0], &value, 1) < 0) {
2106
err("Device initialization failed");
2107
return -ENODEV;
2108
}
2109
}
2110
2111
if (sd->flags & LED_REVERSE)
2112
reg_w1(gspca_dev, 0x1006, 0x00);
2113
else
2114
reg_w1(gspca_dev, 0x1006, 0x20);
2115
2116
if (reg_w(gspca_dev, 0x10c0, i2c_init, 9) < 0) {
2117
err("Device initialization failed");
2118
return -ENODEV;
2119
}
2120
2121
switch (sd->sensor) {
2122
case SENSOR_OV9650:
2123
if (ov9650_init_sensor(gspca_dev) < 0)
2124
return -ENODEV;
2125
info("OV9650 sensor detected");
2126
break;
2127
case SENSOR_OV9655:
2128
if (ov9655_init_sensor(gspca_dev) < 0)
2129
return -ENODEV;
2130
info("OV9655 sensor detected");
2131
break;
2132
case SENSOR_SOI968:
2133
if (soi968_init_sensor(gspca_dev) < 0)
2134
return -ENODEV;
2135
info("SOI968 sensor detected");
2136
break;
2137
case SENSOR_OV7660:
2138
if (ov7660_init_sensor(gspca_dev) < 0)
2139
return -ENODEV;
2140
info("OV7660 sensor detected");
2141
break;
2142
case SENSOR_OV7670:
2143
if (ov7670_init_sensor(gspca_dev) < 0)
2144
return -ENODEV;
2145
info("OV7670 sensor detected");
2146
break;
2147
case SENSOR_MT9VPRB:
2148
if (mt9v_init_sensor(gspca_dev) < 0)
2149
return -ENODEV;
2150
break;
2151
case SENSOR_MT9M111:
2152
if (mt9m111_init_sensor(gspca_dev) < 0)
2153
return -ENODEV;
2154
info("MT9M111 sensor detected");
2155
break;
2156
case SENSOR_MT9M112:
2157
if (mt9m112_init_sensor(gspca_dev) < 0)
2158
return -ENODEV;
2159
info("MT9M112 sensor detected");
2160
break;
2161
case SENSOR_MT9M001:
2162
if (mt9m001_init_sensor(gspca_dev) < 0)
2163
return -ENODEV;
2164
break;
2165
case SENSOR_HV7131R:
2166
if (hv7131r_init_sensor(gspca_dev) < 0)
2167
return -ENODEV;
2168
info("HV7131R sensor detected");
2169
break;
2170
default:
2171
info("Unsupported Sensor");
2172
return -ENODEV;
2173
}
2174
2175
return 0;
2176
}
2177
2178
static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
2179
{
2180
struct sd *sd = (struct sd *) gspca_dev;
2181
u8 value;
2182
switch (sd->sensor) {
2183
case SENSOR_SOI968:
2184
if (mode & MODE_SXGA) {
2185
i2c_w1(gspca_dev, 0x17, 0x1d);
2186
i2c_w1(gspca_dev, 0x18, 0xbd);
2187
i2c_w1(gspca_dev, 0x19, 0x01);
2188
i2c_w1(gspca_dev, 0x1a, 0x81);
2189
i2c_w1(gspca_dev, 0x12, 0x00);
2190
sd->hstart = 140;
2191
sd->vstart = 19;
2192
} else {
2193
i2c_w1(gspca_dev, 0x17, 0x13);
2194
i2c_w1(gspca_dev, 0x18, 0x63);
2195
i2c_w1(gspca_dev, 0x19, 0x01);
2196
i2c_w1(gspca_dev, 0x1a, 0x79);
2197
i2c_w1(gspca_dev, 0x12, 0x40);
2198
sd->hstart = 60;
2199
sd->vstart = 11;
2200
}
2201
break;
2202
case SENSOR_OV9650:
2203
if (mode & MODE_SXGA) {
2204
i2c_w1(gspca_dev, 0x17, 0x1b);
2205
i2c_w1(gspca_dev, 0x18, 0xbc);
2206
i2c_w1(gspca_dev, 0x19, 0x01);
2207
i2c_w1(gspca_dev, 0x1a, 0x82);
2208
i2c_r1(gspca_dev, 0x12, &value);
2209
i2c_w1(gspca_dev, 0x12, value & 0x07);
2210
} else {
2211
i2c_w1(gspca_dev, 0x17, 0x24);
2212
i2c_w1(gspca_dev, 0x18, 0xc5);
2213
i2c_w1(gspca_dev, 0x19, 0x00);
2214
i2c_w1(gspca_dev, 0x1a, 0x3c);
2215
i2c_r1(gspca_dev, 0x12, &value);
2216
i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
2217
}
2218
break;
2219
case SENSOR_MT9M112:
2220
case SENSOR_MT9M111:
2221
if (mode & MODE_SXGA) {
2222
i2c_w2(gspca_dev, 0xf0, 0x0002);
2223
i2c_w2(gspca_dev, 0xc8, 0x970b);
2224
i2c_w2(gspca_dev, 0xf0, 0x0000);
2225
} else {
2226
i2c_w2(gspca_dev, 0xf0, 0x0002);
2227
i2c_w2(gspca_dev, 0xc8, 0x8000);
2228
i2c_w2(gspca_dev, 0xf0, 0x0000);
2229
}
2230
break;
2231
}
2232
}
2233
2234
#define HW_WIN(mode, hstart, vstart) \
2235
((const u8 []){hstart, 0, vstart, 0, \
2236
(mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2237
(mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2238
2239
#define CLR_WIN(width, height) \
2240
((const u8 [])\
2241
{0, width >> 2, 0, height >> 1,\
2242
((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2243
2244
static int sd_start(struct gspca_dev *gspca_dev)
2245
{
2246
struct sd *sd = (struct sd *) gspca_dev;
2247
int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2248
int width = gspca_dev->width;
2249
int height = gspca_dev->height;
2250
u8 fmt, scale = 0;
2251
2252
jpeg_define(sd->jpeg_hdr, height, width,
2253
0x21);
2254
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2255
2256
if (mode & MODE_RAW)
2257
fmt = 0x2d;
2258
else if (mode & MODE_JPEG)
2259
fmt = 0x2c;
2260
else
2261
fmt = 0x2f; /* YUV 420 */
2262
2263
switch (mode & SCALE_MASK) {
2264
case SCALE_1280x1024:
2265
scale = 0xc0;
2266
info("Set 1280x1024");
2267
break;
2268
case SCALE_640x480:
2269
scale = 0x80;
2270
info("Set 640x480");
2271
break;
2272
case SCALE_320x240:
2273
scale = 0x90;
2274
info("Set 320x240");
2275
break;
2276
case SCALE_160x120:
2277
scale = 0xa0;
2278
info("Set 160x120");
2279
break;
2280
}
2281
2282
configure_sensor_output(gspca_dev, mode);
2283
reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2284
reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2285
reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2286
reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2287
reg_w1(gspca_dev, 0x1189, scale);
2288
reg_w1(gspca_dev, 0x10e0, fmt);
2289
2290
set_cmatrix(gspca_dev);
2291
set_gamma(gspca_dev);
2292
set_redblue(gspca_dev);
2293
set_gain(gspca_dev);
2294
set_exposure(gspca_dev);
2295
set_hvflip(gspca_dev);
2296
2297
reg_w1(gspca_dev, 0x1007, 0x20);
2298
2299
reg_r(gspca_dev, 0x1061, 1);
2300
reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] | 0x02);
2301
return 0;
2302
}
2303
2304
static void sd_stopN(struct gspca_dev *gspca_dev)
2305
{
2306
reg_w1(gspca_dev, 0x1007, 0x00);
2307
2308
reg_r(gspca_dev, 0x1061, 1);
2309
reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] & ~0x02);
2310
}
2311
2312
static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2313
{
2314
struct sd *sd = (struct sd *) gspca_dev;
2315
s16 new_exp;
2316
2317
/*
2318
* some hardcoded values are present
2319
* like those for maximal/minimal exposure
2320
* and exposure steps
2321
*/
2322
if (avg_lum < MIN_AVG_LUM) {
2323
if (sd->exposure > 0x1770)
2324
return;
2325
2326
new_exp = sd->exposure + sd->exposure_step;
2327
if (new_exp > 0x1770)
2328
new_exp = 0x1770;
2329
if (new_exp < 0x10)
2330
new_exp = 0x10;
2331
sd->exposure = new_exp;
2332
set_exposure(gspca_dev);
2333
2334
sd->older_step = sd->old_step;
2335
sd->old_step = 1;
2336
2337
if (sd->old_step ^ sd->older_step)
2338
sd->exposure_step /= 2;
2339
else
2340
sd->exposure_step += 2;
2341
}
2342
if (avg_lum > MAX_AVG_LUM) {
2343
if (sd->exposure < 0x10)
2344
return;
2345
new_exp = sd->exposure - sd->exposure_step;
2346
if (new_exp > 0x1700)
2347
new_exp = 0x1770;
2348
if (new_exp < 0x10)
2349
new_exp = 0x10;
2350
sd->exposure = new_exp;
2351
set_exposure(gspca_dev);
2352
sd->older_step = sd->old_step;
2353
sd->old_step = 0;
2354
2355
if (sd->old_step ^ sd->older_step)
2356
sd->exposure_step /= 2;
2357
else
2358
sd->exposure_step += 2;
2359
}
2360
}
2361
2362
static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2363
{
2364
struct sd *sd = (struct sd *) gspca_dev;
2365
2366
if (avg_lum < MIN_AVG_LUM) {
2367
if (sd->gain + 1 <= 28) {
2368
sd->gain++;
2369
set_gain(gspca_dev);
2370
}
2371
}
2372
if (avg_lum > MAX_AVG_LUM) {
2373
if (sd->gain > 0) {
2374
sd->gain--;
2375
set_gain(gspca_dev);
2376
}
2377
}
2378
}
2379
2380
static void sd_dqcallback(struct gspca_dev *gspca_dev)
2381
{
2382
struct sd *sd = (struct sd *) gspca_dev;
2383
int avg_lum;
2384
2385
if (!sd->auto_exposure)
2386
return;
2387
2388
avg_lum = atomic_read(&sd->avg_lum);
2389
if (sd->sensor == SENSOR_SOI968)
2390
do_autogain(gspca_dev, avg_lum);
2391
else
2392
do_autoexposure(gspca_dev, avg_lum);
2393
}
2394
2395
#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2396
static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2397
u8 *data, /* interrupt packet */
2398
int len) /* interrupt packet length */
2399
{
2400
struct sd *sd = (struct sd *) gspca_dev;
2401
int ret = -EINVAL;
2402
if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2403
input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2404
input_sync(gspca_dev->input_dev);
2405
input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2406
input_sync(gspca_dev->input_dev);
2407
ret = 0;
2408
}
2409
return ret;
2410
}
2411
#endif
2412
2413
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2414
u8 *data, /* isoc packet */
2415
int len) /* iso packet length */
2416
{
2417
struct sd *sd = (struct sd *) gspca_dev;
2418
int avg_lum;
2419
static u8 frame_header[] =
2420
{0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2421
if (len == 64 && memcmp(data, frame_header, 6) == 0) {
2422
avg_lum = ((data[35] >> 2) & 3) |
2423
(data[20] << 2) |
2424
(data[19] << 10);
2425
avg_lum += ((data[35] >> 4) & 3) |
2426
(data[22] << 2) |
2427
(data[21] << 10);
2428
avg_lum += ((data[35] >> 6) & 3) |
2429
(data[24] << 2) |
2430
(data[23] << 10);
2431
avg_lum += (data[36] & 3) |
2432
(data[26] << 2) |
2433
(data[25] << 10);
2434
avg_lum += ((data[36] >> 2) & 3) |
2435
(data[28] << 2) |
2436
(data[27] << 10);
2437
avg_lum += ((data[36] >> 4) & 3) |
2438
(data[30] << 2) |
2439
(data[29] << 10);
2440
avg_lum += ((data[36] >> 6) & 3) |
2441
(data[32] << 2) |
2442
(data[31] << 10);
2443
avg_lum += ((data[44] >> 4) & 3) |
2444
(data[34] << 2) |
2445
(data[33] << 10);
2446
avg_lum >>= 9;
2447
atomic_set(&sd->avg_lum, avg_lum);
2448
gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2449
return;
2450
}
2451
if (gspca_dev->last_packet_type == LAST_PACKET) {
2452
if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv
2453
& MODE_JPEG) {
2454
gspca_frame_add(gspca_dev, FIRST_PACKET,
2455
sd->jpeg_hdr, JPEG_HDR_SZ);
2456
gspca_frame_add(gspca_dev, INTER_PACKET,
2457
data, len);
2458
} else {
2459
gspca_frame_add(gspca_dev, FIRST_PACKET,
2460
data, len);
2461
}
2462
} else {
2463
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2464
}
2465
}
2466
2467
/* sub-driver description */
2468
static const struct sd_desc sd_desc = {
2469
.name = MODULE_NAME,
2470
.ctrls = sd_ctrls,
2471
.nctrls = ARRAY_SIZE(sd_ctrls),
2472
.config = sd_config,
2473
.init = sd_init,
2474
.start = sd_start,
2475
.stopN = sd_stopN,
2476
.pkt_scan = sd_pkt_scan,
2477
#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2478
.int_pkt_scan = sd_int_pkt_scan,
2479
#endif
2480
.dq_callback = sd_dqcallback,
2481
#ifdef CONFIG_VIDEO_ADV_DEBUG
2482
.set_register = sd_dbg_s_register,
2483
.get_register = sd_dbg_g_register,
2484
#endif
2485
.get_chip_ident = sd_chip_ident,
2486
};
2487
2488
#define SN9C20X(sensor, i2c_addr, flags) \
2489
.driver_info = ((flags & 0xff) << 16) \
2490
| (SENSOR_ ## sensor << 8) \
2491
| (i2c_addr)
2492
2493
static const struct usb_device_id device_table[] = {
2494
{USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2495
{USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2496
{USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2497
{USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2498
{USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2499
{USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2500
(FLIP_DETECT | HAS_NO_BUTTON))},
2501
{USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2502
{USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2503
{USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2504
{USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2505
{USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)},
2506
{USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2507
{USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2508
{USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2509
{USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2510
{USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2511
{USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2512
{USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2513
{USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2514
{USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2515
{USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2516
{USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)},
2517
{USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)},
2518
{USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2519
{USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2520
{USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2521
{USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2522
{USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2523
{USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2524
{USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2525
{USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2526
{USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2527
{USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2528
{USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2529
{USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2530
{USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2531
{}
2532
};
2533
MODULE_DEVICE_TABLE(usb, device_table);
2534
2535
/* -- device connect -- */
2536
static int sd_probe(struct usb_interface *intf,
2537
const struct usb_device_id *id)
2538
{
2539
return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2540
THIS_MODULE);
2541
}
2542
2543
static struct usb_driver sd_driver = {
2544
.name = MODULE_NAME,
2545
.id_table = device_table,
2546
.probe = sd_probe,
2547
.disconnect = gspca_disconnect,
2548
#ifdef CONFIG_PM
2549
.suspend = gspca_suspend,
2550
.resume = gspca_resume,
2551
.reset_resume = gspca_resume,
2552
#endif
2553
};
2554
2555
/* -- module insert / remove -- */
2556
static int __init sd_mod_init(void)
2557
{
2558
return usb_register(&sd_driver);
2559
}
2560
static void __exit sd_mod_exit(void)
2561
{
2562
usb_deregister(&sd_driver);
2563
}
2564
2565
module_init(sd_mod_init);
2566
module_exit(sd_mod_exit);
2567
2568