Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/video/gspca/sonixj.c
17628 views
1
/*
2
* Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver
3
*
4
* Copyright (C) 2009-2010 Jean-François Moine <http://moinejf.free.fr>
5
* Copyright (C) 2005 Michel Xhaard [email protected]
6
*
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* any later version.
11
*
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
16
*
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
*/
21
22
#define MODULE_NAME "sonixj"
23
24
#include <linux/input.h>
25
#include "gspca.h"
26
#include "jpeg.h"
27
28
MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
29
MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
30
MODULE_LICENSE("GPL");
31
32
/* controls */
33
enum e_ctrl {
34
BRIGHTNESS,
35
CONTRAST,
36
COLORS,
37
BLUE,
38
RED,
39
GAMMA,
40
AUTOGAIN,
41
HFLIP,
42
VFLIP,
43
SHARPNESS,
44
ILLUM,
45
FREQ,
46
NCTRLS /* number of controls */
47
};
48
49
/* specific webcam descriptor */
50
struct sd {
51
struct gspca_dev gspca_dev; /* !! must be the first item */
52
53
struct gspca_ctrl ctrls[NCTRLS];
54
55
atomic_t avg_lum;
56
u32 exposure;
57
58
struct work_struct work;
59
struct workqueue_struct *work_thread;
60
61
u32 pktsz; /* (used by pkt_scan) */
62
u16 npkt;
63
s8 nchg;
64
s8 short_mark;
65
66
u8 quality; /* image quality */
67
#define QUALITY_MIN 25
68
#define QUALITY_MAX 90
69
#define QUALITY_DEF 70
70
71
u8 reg01;
72
u8 reg17;
73
u8 reg18;
74
u8 flags;
75
76
s8 ag_cnt;
77
#define AG_CNT_START 13
78
79
u8 bridge;
80
#define BRIDGE_SN9C102P 0
81
#define BRIDGE_SN9C105 1
82
#define BRIDGE_SN9C110 2
83
#define BRIDGE_SN9C120 3
84
u8 sensor; /* Type of image sensor chip */
85
u8 i2c_addr;
86
87
u8 jpeg_hdr[JPEG_HDR_SZ];
88
};
89
enum sensors {
90
SENSOR_ADCM1700,
91
SENSOR_GC0307,
92
SENSOR_HV7131R,
93
SENSOR_MI0360,
94
SENSOR_MI0360B,
95
SENSOR_MO4000,
96
SENSOR_MT9V111,
97
SENSOR_OM6802,
98
SENSOR_OV7630,
99
SENSOR_OV7648,
100
SENSOR_OV7660,
101
SENSOR_PO1030,
102
SENSOR_PO2030N,
103
SENSOR_SOI768,
104
SENSOR_SP80708,
105
};
106
107
static void qual_upd(struct work_struct *work);
108
109
/* device flags */
110
#define F_PDN_INV 0x01 /* inverse pin S_PWR_DN / sn_xxx tables */
111
#define F_ILLUM 0x02 /* presence of illuminator */
112
113
/* sn9c1xx definitions */
114
/* register 0x01 */
115
#define S_PWR_DN 0x01 /* sensor power down */
116
#define S_PDN_INV 0x02 /* inverse pin S_PWR_DN */
117
#define V_TX_EN 0x04 /* video transfer enable */
118
#define LED 0x08 /* output to pin LED */
119
#define SCL_SEL_OD 0x20 /* open-drain mode */
120
#define SYS_SEL_48M 0x40 /* system clock 0: 24MHz, 1: 48MHz */
121
/* register 0x17 */
122
#define MCK_SIZE_MASK 0x1f /* sensor master clock */
123
#define SEN_CLK_EN 0x20 /* enable sensor clock */
124
#define DEF_EN 0x80 /* defect pixel by 0: soft, 1: hard */
125
126
/* V4L2 controls supported by the driver */
127
static void setbrightness(struct gspca_dev *gspca_dev);
128
static void setcontrast(struct gspca_dev *gspca_dev);
129
static void setcolors(struct gspca_dev *gspca_dev);
130
static void setredblue(struct gspca_dev *gspca_dev);
131
static void setgamma(struct gspca_dev *gspca_dev);
132
static void setautogain(struct gspca_dev *gspca_dev);
133
static void sethvflip(struct gspca_dev *gspca_dev);
134
static void setsharpness(struct gspca_dev *gspca_dev);
135
static void setillum(struct gspca_dev *gspca_dev);
136
static void setfreq(struct gspca_dev *gspca_dev);
137
138
static const struct ctrl sd_ctrls[NCTRLS] = {
139
[BRIGHTNESS] = {
140
{
141
.id = V4L2_CID_BRIGHTNESS,
142
.type = V4L2_CTRL_TYPE_INTEGER,
143
.name = "Brightness",
144
.minimum = 0,
145
.maximum = 0xff,
146
.step = 1,
147
.default_value = 0x80,
148
},
149
.set_control = setbrightness
150
},
151
[CONTRAST] = {
152
{
153
.id = V4L2_CID_CONTRAST,
154
.type = V4L2_CTRL_TYPE_INTEGER,
155
.name = "Contrast",
156
.minimum = 0,
157
#define CONTRAST_MAX 127
158
.maximum = CONTRAST_MAX,
159
.step = 1,
160
.default_value = 63,
161
},
162
.set_control = setcontrast
163
},
164
[COLORS] = {
165
{
166
.id = V4L2_CID_SATURATION,
167
.type = V4L2_CTRL_TYPE_INTEGER,
168
.name = "Saturation",
169
.minimum = 0,
170
.maximum = 40,
171
.step = 1,
172
#define COLORS_DEF 25
173
.default_value = COLORS_DEF,
174
},
175
.set_control = setcolors
176
},
177
[BLUE] = {
178
{
179
.id = V4L2_CID_BLUE_BALANCE,
180
.type = V4L2_CTRL_TYPE_INTEGER,
181
.name = "Blue Balance",
182
.minimum = 24,
183
.maximum = 40,
184
.step = 1,
185
.default_value = 32,
186
},
187
.set_control = setredblue
188
},
189
[RED] = {
190
{
191
.id = V4L2_CID_RED_BALANCE,
192
.type = V4L2_CTRL_TYPE_INTEGER,
193
.name = "Red Balance",
194
.minimum = 24,
195
.maximum = 40,
196
.step = 1,
197
.default_value = 32,
198
},
199
.set_control = setredblue
200
},
201
[GAMMA] = {
202
{
203
.id = V4L2_CID_GAMMA,
204
.type = V4L2_CTRL_TYPE_INTEGER,
205
.name = "Gamma",
206
.minimum = 0,
207
.maximum = 40,
208
.step = 1,
209
#define GAMMA_DEF 20
210
.default_value = GAMMA_DEF,
211
},
212
.set_control = setgamma
213
},
214
[AUTOGAIN] = {
215
{
216
.id = V4L2_CID_AUTOGAIN,
217
.type = V4L2_CTRL_TYPE_BOOLEAN,
218
.name = "Auto Gain",
219
.minimum = 0,
220
.maximum = 1,
221
.step = 1,
222
.default_value = 1
223
},
224
.set_control = setautogain
225
},
226
[HFLIP] = {
227
{
228
.id = V4L2_CID_HFLIP,
229
.type = V4L2_CTRL_TYPE_BOOLEAN,
230
.name = "Mirror",
231
.minimum = 0,
232
.maximum = 1,
233
.step = 1,
234
.default_value = 0,
235
},
236
.set_control = sethvflip
237
},
238
[VFLIP] = {
239
{
240
.id = V4L2_CID_VFLIP,
241
.type = V4L2_CTRL_TYPE_BOOLEAN,
242
.name = "Vflip",
243
.minimum = 0,
244
.maximum = 1,
245
.step = 1,
246
.default_value = 0,
247
},
248
.set_control = sethvflip
249
},
250
[SHARPNESS] = {
251
{
252
.id = V4L2_CID_SHARPNESS,
253
.type = V4L2_CTRL_TYPE_INTEGER,
254
.name = "Sharpness",
255
.minimum = 0,
256
.maximum = 255,
257
.step = 1,
258
.default_value = 90,
259
},
260
.set_control = setsharpness
261
},
262
[ILLUM] = {
263
{
264
.id = V4L2_CID_ILLUMINATORS_1,
265
.type = V4L2_CTRL_TYPE_BOOLEAN,
266
.name = "Illuminator / infrared",
267
.minimum = 0,
268
.maximum = 1,
269
.step = 1,
270
.default_value = 0,
271
},
272
.set_control = setillum
273
},
274
/* ov7630/ov7648/ov7660 only */
275
[FREQ] = {
276
{
277
.id = V4L2_CID_POWER_LINE_FREQUENCY,
278
.type = V4L2_CTRL_TYPE_MENU,
279
.name = "Light frequency filter",
280
.minimum = 0,
281
.maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
282
.step = 1,
283
.default_value = 1,
284
},
285
.set_control = setfreq
286
},
287
};
288
289
/* table of the disabled controls */
290
static const __u32 ctrl_dis[] = {
291
[SENSOR_ADCM1700] = (1 << AUTOGAIN) |
292
(1 << HFLIP) |
293
(1 << VFLIP) |
294
(1 << FREQ),
295
296
[SENSOR_GC0307] = (1 << HFLIP) |
297
(1 << VFLIP) |
298
(1 << FREQ),
299
300
[SENSOR_HV7131R] = (1 << HFLIP) |
301
(1 << FREQ),
302
303
[SENSOR_MI0360] = (1 << HFLIP) |
304
(1 << VFLIP) |
305
(1 << FREQ),
306
307
[SENSOR_MI0360B] = (1 << HFLIP) |
308
(1 << VFLIP) |
309
(1 << FREQ),
310
311
[SENSOR_MO4000] = (1 << HFLIP) |
312
(1 << VFLIP) |
313
(1 << FREQ),
314
315
[SENSOR_MT9V111] = (1 << HFLIP) |
316
(1 << VFLIP) |
317
(1 << FREQ),
318
319
[SENSOR_OM6802] = (1 << HFLIP) |
320
(1 << VFLIP) |
321
(1 << FREQ),
322
323
[SENSOR_OV7630] = (1 << HFLIP),
324
325
[SENSOR_OV7648] = (1 << HFLIP),
326
327
[SENSOR_OV7660] = (1 << AUTOGAIN) |
328
(1 << HFLIP) |
329
(1 << VFLIP),
330
331
[SENSOR_PO1030] = (1 << AUTOGAIN) |
332
(1 << HFLIP) |
333
(1 << VFLIP) |
334
(1 << FREQ),
335
336
[SENSOR_PO2030N] = (1 << AUTOGAIN) |
337
(1 << FREQ),
338
339
[SENSOR_SOI768] = (1 << AUTOGAIN) |
340
(1 << HFLIP) |
341
(1 << VFLIP) |
342
(1 << FREQ),
343
344
[SENSOR_SP80708] = (1 << AUTOGAIN) |
345
(1 << HFLIP) |
346
(1 << VFLIP) |
347
(1 << FREQ),
348
};
349
350
static const struct v4l2_pix_format cif_mode[] = {
351
{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
352
.bytesperline = 352,
353
.sizeimage = 352 * 288 * 4 / 8 + 590,
354
.colorspace = V4L2_COLORSPACE_JPEG,
355
.priv = 0},
356
};
357
static const struct v4l2_pix_format vga_mode[] = {
358
{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
359
.bytesperline = 160,
360
.sizeimage = 160 * 120 * 4 / 8 + 590,
361
.colorspace = V4L2_COLORSPACE_JPEG,
362
.priv = 2},
363
{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
364
.bytesperline = 320,
365
.sizeimage = 320 * 240 * 3 / 8 + 590,
366
.colorspace = V4L2_COLORSPACE_JPEG,
367
.priv = 1},
368
{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
369
.bytesperline = 640,
370
/* Note 3 / 8 is not large enough, not even 5 / 8 is ?! */
371
.sizeimage = 640 * 480 * 3 / 4 + 590,
372
.colorspace = V4L2_COLORSPACE_JPEG,
373
.priv = 0},
374
};
375
376
static const u8 sn_adcm1700[0x1c] = {
377
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
378
0x00, 0x43, 0x60, 0x00, 0x1a, 0x00, 0x00, 0x00,
379
/* reg8 reg9 rega regb regc regd rege regf */
380
0x80, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
382
0x03, 0x00, 0x05, 0x01, 0x05, 0x16, 0x12, 0x42,
383
/* reg18 reg19 reg1a reg1b */
384
0x06, 0x00, 0x00, 0x00
385
};
386
387
static const u8 sn_gc0307[0x1c] = {
388
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
389
0x00, 0x61, 0x62, 0x00, 0x1a, 0x00, 0x00, 0x00,
390
/* reg8 reg9 rega regb regc regd rege regf */
391
0x80, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
393
0x03, 0x00, 0x03, 0x01, 0x08, 0x28, 0x1e, 0x02,
394
/* reg18 reg19 reg1a reg1b */
395
0x06, 0x00, 0x00, 0x00
396
};
397
398
static const u8 sn_hv7131[0x1c] = {
399
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
400
0x00, 0x03, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
401
/* reg8 reg9 rega regb regc regd rege regf */
402
0x81, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
403
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
404
0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
405
/* reg18 reg19 reg1a reg1b */
406
0x0a, 0x00, 0x00, 0x00
407
};
408
409
static const u8 sn_mi0360[0x1c] = {
410
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
411
0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
412
/* reg8 reg9 rega regb regc regd rege regf */
413
0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
415
0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
416
/* reg18 reg19 reg1a reg1b */
417
0x06, 0x00, 0x00, 0x00
418
};
419
420
static const u8 sn_mi0360b[0x1c] = {
421
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
422
0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
423
/* reg8 reg9 rega regb regc regd rege regf */
424
0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
425
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
426
0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x40,
427
/* reg18 reg19 reg1a reg1b */
428
0x06, 0x00, 0x00, 0x00
429
};
430
431
static const u8 sn_mo4000[0x1c] = {
432
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
433
0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
434
/* reg8 reg9 rega regb regc regd rege regf */
435
0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
436
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
437
0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
438
/* reg18 reg19 reg1a reg1b */
439
0x08, 0x00, 0x00, 0x00
440
};
441
442
static const u8 sn_mt9v111[0x1c] = {
443
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
444
0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
445
/* reg8 reg9 rega regb regc regd rege regf */
446
0x81, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
447
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
448
0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
449
/* reg18 reg19 reg1a reg1b */
450
0x06, 0x00, 0x00, 0x00
451
};
452
453
static const u8 sn_om6802[0x1c] = {
454
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
455
0x00, 0x23, 0x72, 0x00, 0x1a, 0x20, 0x20, 0x19,
456
/* reg8 reg9 rega regb regc regd rege regf */
457
0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
458
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
459
0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
460
/* reg18 reg19 reg1a reg1b */
461
0x05, 0x00, 0x00, 0x00
462
};
463
464
static const u8 sn_ov7630[0x1c] = {
465
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
466
0x00, 0x21, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
467
/* reg8 reg9 rega regb regc regd rege regf */
468
0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
469
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
470
0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
471
/* reg18 reg19 reg1a reg1b */
472
0x0b, 0x00, 0x00, 0x00
473
};
474
475
static const u8 sn_ov7648[0x1c] = {
476
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
477
0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
478
/* reg8 reg9 rega regb regc regd rege regf */
479
0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
480
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
481
0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
482
/* reg18 reg19 reg1a reg1b */
483
0x0b, 0x00, 0x00, 0x00
484
};
485
486
static const u8 sn_ov7660[0x1c] = {
487
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
488
0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
489
/* reg8 reg9 rega regb regc regd rege regf */
490
0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
491
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
492
0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
493
/* reg18 reg19 reg1a reg1b */
494
0x07, 0x00, 0x00, 0x00
495
};
496
497
static const u8 sn_po1030[0x1c] = {
498
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
499
0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
500
/* reg8 reg9 rega regb regc regd rege regf */
501
0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
502
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
503
0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x00,
504
/* reg18 reg19 reg1a reg1b */
505
0x07, 0x00, 0x00, 0x00
506
};
507
508
static const u8 sn_po2030n[0x1c] = {
509
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
510
0x00, 0x63, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
511
/* reg8 reg9 rega regb regc regd rege regf */
512
0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
513
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
514
0x03, 0x00, 0x00, 0x01, 0x14, 0x28, 0x1e, 0x00,
515
/* reg18 reg19 reg1a reg1b */
516
0x07, 0x00, 0x00, 0x00
517
};
518
519
static const u8 sn_soi768[0x1c] = {
520
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
521
0x00, 0x21, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
522
/* reg8 reg9 rega regb regc regd rege regf */
523
0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
524
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
525
0x03, 0x00, 0x00, 0x01, 0x08, 0x28, 0x1e, 0x00,
526
/* reg18 reg19 reg1a reg1b */
527
0x07, 0x00, 0x00, 0x00
528
};
529
530
static const u8 sn_sp80708[0x1c] = {
531
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
532
0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
533
/* reg8 reg9 rega regb regc regd rege regf */
534
0x81, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
535
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
536
0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00,
537
/* reg18 reg19 reg1a reg1b */
538
0x07, 0x00, 0x00, 0x00
539
};
540
541
/* sequence specific to the sensors - !! index = SENSOR_xxx */
542
static const u8 *sn_tb[] = {
543
[SENSOR_ADCM1700] = sn_adcm1700,
544
[SENSOR_GC0307] = sn_gc0307,
545
[SENSOR_HV7131R] = sn_hv7131,
546
[SENSOR_MI0360] = sn_mi0360,
547
[SENSOR_MI0360B] = sn_mi0360b,
548
[SENSOR_MO4000] = sn_mo4000,
549
[SENSOR_MT9V111] = sn_mt9v111,
550
[SENSOR_OM6802] = sn_om6802,
551
[SENSOR_OV7630] = sn_ov7630,
552
[SENSOR_OV7648] = sn_ov7648,
553
[SENSOR_OV7660] = sn_ov7660,
554
[SENSOR_PO1030] = sn_po1030,
555
[SENSOR_PO2030N] = sn_po2030n,
556
[SENSOR_SOI768] = sn_soi768,
557
[SENSOR_SP80708] = sn_sp80708,
558
};
559
560
/* default gamma table */
561
static const u8 gamma_def[17] = {
562
0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
563
0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
564
};
565
/* gamma for sensor ADCM1700 */
566
static const u8 gamma_spec_0[17] = {
567
0x0f, 0x39, 0x5a, 0x74, 0x86, 0x95, 0xa6, 0xb4,
568
0xbd, 0xc4, 0xcc, 0xd4, 0xd5, 0xde, 0xe4, 0xed, 0xf5
569
};
570
/* gamma for sensors HV7131R and MT9V111 */
571
static const u8 gamma_spec_1[17] = {
572
0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
573
0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
574
};
575
/* gamma for sensor GC0307 */
576
static const u8 gamma_spec_2[17] = {
577
0x14, 0x37, 0x50, 0x6a, 0x7c, 0x8d, 0x9d, 0xab,
578
0xb5, 0xbf, 0xc2, 0xcb, 0xd1, 0xd6, 0xdb, 0xe1, 0xeb
579
};
580
/* gamma for sensor SP80708 */
581
static const u8 gamma_spec_3[17] = {
582
0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
583
0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
584
};
585
586
/* color matrix and offsets */
587
static const u8 reg84[] = {
588
0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
589
0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
590
0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
591
0x00, 0x00, 0x00 /* YUV offsets */
592
};
593
594
#define DELAY 0xdd
595
596
static const u8 adcm1700_sensor_init[][8] = {
597
{0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10},
598
{0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10}, /* reset */
599
{DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
600
{0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
601
{DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
602
{0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10},
603
{0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10},
604
{0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10},
605
{0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10},
606
{0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10},
607
{DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
608
{0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10},
609
{DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
610
{0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10},
611
{0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
612
{0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10},
613
{0xb0, 0x51, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
614
{}
615
};
616
static const u8 adcm1700_sensor_param1[][8] = {
617
{0xb0, 0x51, 0x26, 0xf9, 0x01, 0x00, 0x00, 0x10}, /* exposure? */
618
{0xd0, 0x51, 0x1e, 0x8e, 0x8e, 0x8e, 0x8e, 0x10},
619
620
{0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
621
{0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
622
{0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
623
{0xb0, 0x51, 0x32, 0x00, 0x72, 0x00, 0x00, 0x10},
624
{0xd0, 0x51, 0x1e, 0xbe, 0xd7, 0xe8, 0xbe, 0x10}, /* exposure? */
625
626
{0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
627
{0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
628
{0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
629
{0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10},
630
{}
631
};
632
static const u8 gc0307_sensor_init[][8] = {
633
{0xa0, 0x21, 0x43, 0x00, 0x00, 0x00, 0x00, 0x10},
634
{0xa0, 0x21, 0x44, 0xa2, 0x00, 0x00, 0x00, 0x10},
635
{0xa0, 0x21, 0x01, 0x6a, 0x00, 0x00, 0x00, 0x10},
636
{0xa0, 0x21, 0x02, 0x70, 0x00, 0x00, 0x00, 0x10},
637
{0xa0, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
638
{0xa0, 0x21, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
639
{0xa0, 0x21, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
640
{0xa0, 0x21, 0x11, 0x05, 0x00, 0x00, 0x00, 0x10},
641
{0xa0, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
642
{0xa0, 0x21, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
643
{0xa0, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10},
644
{0xa0, 0x21, 0x08, 0x02, 0x00, 0x00, 0x00, 0x10},
645
{0xa0, 0x21, 0x09, 0x01, 0x00, 0x00, 0x00, 0x10},
646
{0xa0, 0x21, 0x0a, 0xe8, 0x00, 0x00, 0x00, 0x10},
647
{0xa0, 0x21, 0x0b, 0x02, 0x00, 0x00, 0x00, 0x10},
648
{0xa0, 0x21, 0x0c, 0x80, 0x00, 0x00, 0x00, 0x10},
649
{0xa0, 0x21, 0x0d, 0x22, 0x00, 0x00, 0x00, 0x10},
650
{0xa0, 0x21, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x10},
651
{0xa0, 0x21, 0x0f, 0xb2, 0x00, 0x00, 0x00, 0x10},
652
{0xa0, 0x21, 0x12, 0x70, 0x00, 0x00, 0x00, 0x10},
653
{DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 10ms*/
654
{0xa0, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10},
655
{0xa0, 0x21, 0x15, 0xb8, 0x00, 0x00, 0x00, 0x10},
656
{0xa0, 0x21, 0x16, 0x13, 0x00, 0x00, 0x00, 0x10},
657
{0xa0, 0x21, 0x17, 0x52, 0x00, 0x00, 0x00, 0x10},
658
{0xa0, 0x21, 0x18, 0x50, 0x00, 0x00, 0x00, 0x10},
659
{0xa0, 0x21, 0x1e, 0x0d, 0x00, 0x00, 0x00, 0x10},
660
{0xa0, 0x21, 0x1f, 0x32, 0x00, 0x00, 0x00, 0x10},
661
{0xa0, 0x21, 0x61, 0x90, 0x00, 0x00, 0x00, 0x10},
662
{0xa0, 0x21, 0x63, 0x70, 0x00, 0x00, 0x00, 0x10},
663
{0xa0, 0x21, 0x65, 0x98, 0x00, 0x00, 0x00, 0x10},
664
{0xa0, 0x21, 0x67, 0x90, 0x00, 0x00, 0x00, 0x10},
665
{0xa0, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
666
{0xa0, 0x21, 0x04, 0x96, 0x00, 0x00, 0x00, 0x10},
667
{0xa0, 0x21, 0x45, 0x27, 0x00, 0x00, 0x00, 0x10},
668
{0xa0, 0x21, 0x47, 0x2c, 0x00, 0x00, 0x00, 0x10},
669
{0xa0, 0x21, 0x43, 0x47, 0x00, 0x00, 0x00, 0x10},
670
{0xa0, 0x21, 0x44, 0xd8, 0x00, 0x00, 0x00, 0x10},
671
{}
672
};
673
static const u8 gc0307_sensor_param1[][8] = {
674
{0xa0, 0x21, 0x68, 0x13, 0x00, 0x00, 0x00, 0x10},
675
{0xd0, 0x21, 0x61, 0x80, 0x00, 0x80, 0x00, 0x10},
676
{0xc0, 0x21, 0x65, 0x80, 0x00, 0x80, 0x00, 0x10},
677
{0xc0, 0x21, 0x63, 0xa0, 0x00, 0xa6, 0x00, 0x10},
678
/*param3*/
679
{0xa0, 0x21, 0x01, 0x6e, 0x00, 0x00, 0x00, 0x10},
680
{0xa0, 0x21, 0x02, 0x88, 0x00, 0x00, 0x00, 0x10},
681
{}
682
};
683
684
static const u8 hv7131r_sensor_init[][8] = {
685
{0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
686
{0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
687
{0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
688
/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
689
{0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
690
{0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
691
/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
692
693
{0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
694
{0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
695
{0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
696
{0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
697
{0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
698
{0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
699
{0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
700
{0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
701
702
{0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
703
{0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
704
{0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
705
{0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
706
{0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
707
708
{0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
709
{0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
710
{0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
711
{0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
712
{0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
713
{0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10},
714
/* set sensor clock */
715
{}
716
};
717
static const u8 mi0360_sensor_init[][8] = {
718
{0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
719
{0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
720
{0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
721
{0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
722
{0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
723
{0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
724
{0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
725
{0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
726
{0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
727
{0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
728
{0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
729
{0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
730
{0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
731
{0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
732
{0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
733
{0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
734
{0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
735
{0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
736
{0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
737
{0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
738
{0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
739
{0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
740
{0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
741
{0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
742
{0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
743
{0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
744
{0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
745
{0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
746
{0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
747
{0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
748
{0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
749
{0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
750
{0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
751
752
{0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
753
{0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
754
{0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
755
{0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
756
{0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
757
758
{0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
759
{0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
760
{0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
761
{0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
762
763
{0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
764
{0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
765
/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
766
/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
767
{0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
768
{0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
769
{}
770
};
771
static const u8 mi0360b_sensor_init[][8] = {
772
{0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
773
{0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
774
{DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
775
{0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
776
{DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
777
{0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
778
{0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
779
{0xd1, 0x5d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
780
{0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
781
{0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
782
{0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
783
{0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
784
{0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
785
{0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
786
{0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
787
{0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
788
{0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
789
{0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
790
{0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
791
{0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
792
{0xd1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
793
{0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
794
{0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
795
{0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
796
{0xd1, 0x5d, 0x2f, 0xf7, 0xb0, 0x00, 0x04, 0x10},
797
{0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
798
{0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
799
{0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
800
{0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
801
{0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
802
{0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
803
{0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
804
{0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
805
{0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
806
{0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
807
808
{0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
809
{0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
810
{0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
811
{0xd1, 0x5d, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10},
812
{0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10},
813
{}
814
};
815
static const u8 mi0360b_sensor_param1[][8] = {
816
{0xb1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
817
{0xb1, 0x5d, 0x06, 0x00, 0x53, 0x00, 0x00, 0x10},
818
{0xb1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10},
819
{0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
820
821
{0xd1, 0x5d, 0x2b, 0x00, 0xd1, 0x01, 0xc9, 0x10},
822
{0xd1, 0x5d, 0x2d, 0x00, 0xed, 0x00, 0xd1, 0x10},
823
{0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
824
{0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
825
{}
826
};
827
static const u8 mo4000_sensor_init[][8] = {
828
{0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
829
{0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
830
{0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
831
{0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
832
{0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
833
{0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
834
{0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
835
{0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
836
{0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
837
{0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
838
{0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
839
{0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
840
{0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
841
{0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
842
{0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
843
{0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
844
{0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
845
{0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
846
{0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
847
{0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
848
{}
849
};
850
static const u8 mt9v111_sensor_init[][8] = {
851
{0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
852
{DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
853
{0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
854
{0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
855
{0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
856
{0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
857
{0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
858
{0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
859
{0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
860
{0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
861
{0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
862
{0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
863
{0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
864
{0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
865
{0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
866
{0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
867
{0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
868
{0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
869
{}
870
};
871
static const u8 mt9v111_sensor_param1[][8] = {
872
{0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xad, 0x10}, /* G1 and B gains */
873
{0xd1, 0x5c, 0x2d, 0x00, 0xad, 0x00, 0x33, 0x10}, /* R and G2 gains */
874
{0xb1, 0x5c, 0x06, 0x00, 0x40, 0x00, 0x00, 0x10}, /* vert blanking */
875
{0xb1, 0x5c, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10}, /* horiz blanking */
876
{0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
877
{}
878
};
879
static const u8 om6802_init0[2][8] = {
880
/*fixme: variable*/
881
{0xa0, 0x34, 0x29, 0x0e, 0x00, 0x00, 0x00, 0x10},
882
{0xa0, 0x34, 0x23, 0xb0, 0x00, 0x00, 0x00, 0x10},
883
};
884
static const u8 om6802_sensor_init[][8] = {
885
{0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10},
886
/* factory mode */
887
{0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
888
/* output raw RGB */
889
{0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
890
/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
891
{0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
892
/* auto-exposure speed (0) / white balance mode (auto RGB) */
893
/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
894
* set color mode */
895
/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
896
* max AGC value in AE */
897
/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
898
* preset AGC */
899
/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
900
* preset brightness */
901
/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
902
* preset contrast */
903
/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
904
* preset gamma */
905
{0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
906
/* luminance mode (0x4f -> AutoExpo on) */
907
{0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
908
/* preset shutter */
909
/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
910
* auto frame rate */
911
/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
912
{0xa0, 0x34, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
913
{}
914
};
915
static const u8 om6802_sensor_param1[][8] = {
916
{0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10},
917
{0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10},
918
{0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10},
919
{0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10},
920
{}
921
};
922
static const u8 ov7630_sensor_init[][8] = {
923
{0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
924
{0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
925
{DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
926
{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
927
{0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
928
{DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
929
{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
930
/* win: i2c_r from 00 to 80 */
931
{0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
932
{0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
933
/* HDG: 0x11 was 0x00 change to 0x01 for better exposure (15 fps instead of 30)
934
0x13 was 0xc0 change to 0xc3 for auto gain and exposure */
935
{0xd1, 0x21, 0x11, 0x01, 0x48, 0xc3, 0x00, 0x10},
936
{0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
937
{0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
938
{0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
939
{0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
940
{0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
941
{0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
942
{0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
943
{0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
944
{0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
945
{0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
946
{0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
947
{0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
948
{0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
949
{0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
950
{0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
951
{0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
952
{0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
953
{0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
954
{0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
955
{0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
956
{0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
957
{0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
958
{0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
959
{}
960
};
961
static const u8 ov7630_sensor_param1[][8] = {
962
{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
963
{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
964
/*fixme: + 0x12, 0x04*/
965
/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
966
* set by setvflip */
967
{0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
968
{0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
969
{0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
970
/* */
971
/* {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
972
/* {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
973
/* */
974
{0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
975
/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
976
{}
977
};
978
979
static const u8 ov7648_sensor_init[][8] = {
980
{0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
981
{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
982
{DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
983
{0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
984
{0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
985
{0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
986
{0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
987
{0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
988
{0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
989
{0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
990
{0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
991
{0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
992
{0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
993
{0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
994
{0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
995
{0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
996
{0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
997
{0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
998
{0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
999
{0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
1000
{0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
1001
{0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
1002
1003
{0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
1004
/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
1005
/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
1006
/* {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
1007
{}
1008
};
1009
static const u8 ov7648_sensor_param1[][8] = {
1010
/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
1011
/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN
1012
* set by setvflip */
1013
{0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
1014
{0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
1015
/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1016
/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
1017
/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
1018
/*...*/
1019
{0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
1020
/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1021
/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1022
/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
1023
/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1024
/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
1025
1026
{}
1027
};
1028
1029
static const u8 ov7660_sensor_init[][8] = {
1030
{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
1031
{DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
1032
{0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
1033
/* Outformat = rawRGB */
1034
{0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
1035
{0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
1036
/* GAIN BLUE RED VREF */
1037
{0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
1038
/* COM 1 BAVE GEAVE AECHH */
1039
{0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
1040
{0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
1041
{0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
1042
/* AECH CLKRC COM7 COM8 */
1043
{0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
1044
{0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
1045
/* HSTART HSTOP VSTRT VSTOP */
1046
{0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
1047
{0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
1048
{0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
1049
/* BOS GBOS GROS ROS (BGGR offset) */
1050
/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
1051
{0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
1052
/* AEW AEB VPT BBIAS */
1053
{0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
1054
/* GbBIAS RSVD EXHCH EXHCL */
1055
{0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
1056
/* RBIAS ADVFL ASDVFH YAVE */
1057
{0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
1058
/* HSYST HSYEN HREF */
1059
{0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
1060
{0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
1061
/* ADC ACOM OFON TSLB */
1062
{0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
1063
/* COM11 COM12 COM13 COM14 */
1064
{0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
1065
/* EDGE COM15 COM16 COM17 */
1066
{0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
1067
{0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
1068
{0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
1069
{0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
1070
{0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
1071
{0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
1072
{0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
1073
{0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
1074
{0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
1075
{0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
1076
/* LCC1 LCC2 LCC3 LCC4 */
1077
{0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
1078
{0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
1079
{0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
1080
/* band gap reference [0:3] DBLV */
1081
{0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
1082
{0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
1083
{0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
1084
{0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
1085
{0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
1086
{0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
1087
{0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
1088
{0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
1089
{0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
1090
{0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
1091
/* not in all ms-win traces*/
1092
{0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
1093
{}
1094
};
1095
static const u8 ov7660_sensor_param1[][8] = {
1096
{0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
1097
/* bits[3..0]reserved */
1098
{0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
1099
{0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
1100
/* VREF vertical frame ctrl */
1101
{0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
1102
{0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
1103
{0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
1104
{0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
1105
{0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
1106
/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
1107
/****** (some exchanges in the win trace) ******/
1108
/*fixme:param2*/
1109
{0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
1110
{0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
1111
{0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
1112
{0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
1113
/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
1114
/****** (some exchanges in the win trace) ******/
1115
/******!! startsensor KO if changed !!****/
1116
/*fixme: param3*/
1117
{0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
1118
{0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
1119
{0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
1120
{0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
1121
{}
1122
};
1123
1124
static const u8 po1030_sensor_init[][8] = {
1125
/* the sensor registers are described in m5602/m5602_po1030.h */
1126
{0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */
1127
{DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
1128
{0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10},
1129
{0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10},
1130
{0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10},
1131
{0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
1132
{0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10},
1133
{0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
1134
{0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */
1135
{0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10},
1136
{0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10},
1137
{0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10},
1138
{0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
1139
{0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
1140
{0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */
1141
{0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10},
1142
{0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */
1143
{0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10},
1144
{0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10},
1145
{0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10},
1146
{0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
1147
{0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
1148
{0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10},
1149
{0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10},
1150
{0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10},
1151
{0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */
1152
{0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10},
1153
{0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10},
1154
1155
{0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
1156
{0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
1157
{0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10},
1158
{0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10},
1159
{0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10},
1160
{}
1161
};
1162
static const u8 po1030_sensor_param1[][8] = {
1163
/* from ms-win traces - these values change with auto gain/expo/wb.. */
1164
{0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
1165
{0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
1166
/* mean values */
1167
{0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */
1168
{0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */
1169
{0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */
1170
1171
{0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */
1172
{0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */
1173
{0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10},
1174
/* {0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */
1175
{}
1176
};
1177
1178
static const u8 po2030n_sensor_init[][8] = {
1179
{0xa1, 0x6e, 0x1e, 0x1a, 0x00, 0x00, 0x00, 0x10},
1180
{0xa1, 0x6e, 0x1f, 0x99, 0x00, 0x00, 0x00, 0x10},
1181
{DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
1182
{0xa1, 0x6e, 0x1e, 0x0a, 0x00, 0x00, 0x00, 0x10},
1183
{0xa1, 0x6e, 0x1f, 0x19, 0x00, 0x00, 0x00, 0x10},
1184
{DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
1185
{0xa1, 0x6e, 0x20, 0x44, 0x00, 0x00, 0x00, 0x10},
1186
{0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
1187
{0xa1, 0x6e, 0x05, 0x70, 0x00, 0x00, 0x00, 0x10},
1188
{0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1189
{0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1190
{0xd1, 0x6e, 0x08, 0x00, 0xd0, 0x00, 0x08, 0x10},
1191
{0xd1, 0x6e, 0x0c, 0x03, 0x50, 0x01, 0xe8, 0x10},
1192
{0xd1, 0x6e, 0x1d, 0x20, 0x0a, 0x19, 0x44, 0x10},
1193
{0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
1194
{0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x00, 0x10},
1195
{0xd1, 0x6e, 0x29, 0x00, 0x00, 0x00, 0x00, 0x10},
1196
{0xd1, 0x6e, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1197
{0xd1, 0x6e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
1198
{0xd1, 0x6e, 0x35, 0x00, 0x00, 0x00, 0x00, 0x10},
1199
{0xd1, 0x6e, 0x39, 0x00, 0x00, 0x00, 0x00, 0x10},
1200
{0xd1, 0x6e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x10},
1201
{0xd1, 0x6e, 0x41, 0x00, 0x00, 0x00, 0x00, 0x10},
1202
{0xd1, 0x6e, 0x45, 0x00, 0x00, 0x00, 0x00, 0x10},
1203
{0xd1, 0x6e, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10},
1204
{0xd1, 0x6e, 0x4d, 0x00, 0x00, 0x00, 0xed, 0x10},
1205
{0xd1, 0x6e, 0x51, 0x17, 0x4a, 0x2f, 0xc0, 0x10},
1206
{0xd1, 0x6e, 0x55, 0x00, 0x00, 0x00, 0x00, 0x10},
1207
{0xd1, 0x6e, 0x59, 0x00, 0x00, 0x00, 0x00, 0x10},
1208
{0xd1, 0x6e, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x10},
1209
{0xd1, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00, 0x10},
1210
{0xd1, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x10},
1211
{0xd1, 0x6e, 0x69, 0x00, 0x00, 0x00, 0x00, 0x10},
1212
{0xd1, 0x6e, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x10},
1213
{0xd1, 0x6e, 0x71, 0x00, 0x00, 0x00, 0x00, 0x10},
1214
{0xd1, 0x6e, 0x75, 0x00, 0x00, 0x00, 0x00, 0x10},
1215
{0xd1, 0x6e, 0x79, 0x00, 0x00, 0x00, 0x00, 0x10},
1216
{0xd1, 0x6e, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10},
1217
{0xd1, 0x6e, 0x81, 0x00, 0x00, 0x00, 0x00, 0x10},
1218
{0xd1, 0x6e, 0x85, 0x00, 0x00, 0x00, 0x08, 0x10},
1219
{0xd1, 0x6e, 0x89, 0x01, 0xe8, 0x00, 0x01, 0x10},
1220
{0xa1, 0x6e, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x10},
1221
{0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
1222
{0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x01, 0x10},
1223
{0xd1, 0x6e, 0x29, 0xe6, 0x00, 0xbd, 0x03, 0x10},
1224
{0xd1, 0x6e, 0x2d, 0x41, 0x38, 0x68, 0x40, 0x10},
1225
{0xd1, 0x6e, 0x31, 0x2b, 0x00, 0x36, 0x00, 0x10},
1226
{0xd1, 0x6e, 0x35, 0x30, 0x30, 0x08, 0x00, 0x10},
1227
{0xd1, 0x6e, 0x39, 0x00, 0x00, 0x33, 0x06, 0x10},
1228
{0xb1, 0x6e, 0x3d, 0x06, 0x02, 0x00, 0x00, 0x10},
1229
{}
1230
};
1231
static const u8 po2030n_sensor_param1[][8] = {
1232
{0xa1, 0x6e, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x10},
1233
{DELAY, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */
1234
{0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10},
1235
{0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
1236
{0xd1, 0x6e, 0x16, 0x50, 0x40, 0x49, 0x40, 0x10},
1237
/*param2*/
1238
{0xa1, 0x6e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
1239
{0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
1240
{0xa1, 0x6e, 0x05, 0x6f, 0x00, 0x00, 0x00, 0x10},
1241
{0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1242
{0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1243
{0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
1244
{0xc1, 0x6e, 0x16, 0x52, 0x40, 0x48, 0x00, 0x10},
1245
/*after start*/
1246
{0xa1, 0x6e, 0x15, 0x0f, 0x00, 0x00, 0x00, 0x10},
1247
{DELAY, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */
1248
{0xa1, 0x6e, 0x1a, 0x05, 0x00, 0x00, 0x00, 0x10},
1249
{DELAY, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */
1250
{0xa1, 0x6e, 0x1b, 0x53, 0x00, 0x00, 0x00, 0x10},
1251
{}
1252
};
1253
1254
static const u8 soi768_sensor_init[][8] = {
1255
{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
1256
{DELAY, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 96ms */
1257
{0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
1258
{0xa1, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
1259
{0xa1, 0x21, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x10},
1260
{0xa1, 0x21, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10},
1261
{}
1262
};
1263
static const u8 soi768_sensor_param1[][8] = {
1264
{0xa1, 0x21, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10},
1265
{0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1266
{0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
1267
{0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1268
{0xb1, 0x21, 0x01, 0x7f, 0x7f, 0x00, 0x00, 0x10},
1269
/* */
1270
/* {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1271
/* {0xa1, 0x21, 0x2d, 0x25, 0x00, 0x00, 0x00, 0x10}, */
1272
{0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
1273
/* {0xb1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1274
{0xa1, 0x21, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x10},
1275
/* the next sequence should be used for auto gain */
1276
{0xa1, 0x21, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10},
1277
/* global gain ? : 07 - change with 0x15 at the end */
1278
{0xa1, 0x21, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x10}, /* ???? : 063f */
1279
{0xa1, 0x21, 0x04, 0x06, 0x00, 0x00, 0x00, 0x10},
1280
{0xb1, 0x21, 0x2d, 0x00, 0x02, 0x00, 0x00, 0x10},
1281
/* exposure ? : 0200 - change with 0x1e at the end */
1282
{}
1283
};
1284
1285
static const u8 sp80708_sensor_init[][8] = {
1286
{0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
1287
{0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
1288
{0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
1289
{0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
1290
{0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1291
{0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
1292
{0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
1293
{0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
1294
{0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
1295
{0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
1296
{0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
1297
{0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
1298
{0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
1299
{0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
1300
{0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
1301
{0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
1302
{0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
1303
{0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
1304
{0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
1305
{0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
1306
{0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
1307
{0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
1308
{0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
1309
{0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
1310
{0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
1311
{0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
1312
{0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
1313
{0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
1314
{0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
1315
{0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
1316
{0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
1317
{0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
1318
{0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
1319
{0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
1320
{0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
1321
{0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
1322
{0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
1323
{0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
1324
{0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
1325
{0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
1326
{0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
1327
{0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
1328
{0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
1329
{0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
1330
{0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
1331
{0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
1332
{0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
1333
{0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
1334
{0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
1335
{0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
1336
{0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
1337
{0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
1338
{0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
1339
{0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
1340
{0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
1341
{0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
1342
{0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
1343
{0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
1344
{0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
1345
{0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
1346
{0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
1347
{0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
1348
{0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
1349
{0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
1350
{0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
1351
{0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
1352
{0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
1353
{0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
1354
{0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
1355
{0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
1356
{0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
1357
{}
1358
};
1359
static const u8 sp80708_sensor_param1[][8] = {
1360
{0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1361
{0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1362
{0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
1363
{0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
1364
{0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
1365
{0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
1366
{0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
1367
{}
1368
};
1369
1370
static const u8 (*sensor_init[])[8] = {
1371
[SENSOR_ADCM1700] = adcm1700_sensor_init,
1372
[SENSOR_GC0307] = gc0307_sensor_init,
1373
[SENSOR_HV7131R] = hv7131r_sensor_init,
1374
[SENSOR_MI0360] = mi0360_sensor_init,
1375
[SENSOR_MI0360B] = mi0360b_sensor_init,
1376
[SENSOR_MO4000] = mo4000_sensor_init,
1377
[SENSOR_MT9V111] = mt9v111_sensor_init,
1378
[SENSOR_OM6802] = om6802_sensor_init,
1379
[SENSOR_OV7630] = ov7630_sensor_init,
1380
[SENSOR_OV7648] = ov7648_sensor_init,
1381
[SENSOR_OV7660] = ov7660_sensor_init,
1382
[SENSOR_PO1030] = po1030_sensor_init,
1383
[SENSOR_PO2030N] = po2030n_sensor_init,
1384
[SENSOR_SOI768] = soi768_sensor_init,
1385
[SENSOR_SP80708] = sp80708_sensor_init,
1386
};
1387
1388
/* read <len> bytes to gspca_dev->usb_buf */
1389
static void reg_r(struct gspca_dev *gspca_dev,
1390
u16 value, int len)
1391
{
1392
int ret;
1393
1394
if (gspca_dev->usb_err < 0)
1395
return;
1396
#ifdef GSPCA_DEBUG
1397
if (len > USB_BUF_SZ) {
1398
err("reg_r: buffer overflow");
1399
return;
1400
}
1401
#endif
1402
ret = usb_control_msg(gspca_dev->dev,
1403
usb_rcvctrlpipe(gspca_dev->dev, 0),
1404
0,
1405
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1406
value, 0,
1407
gspca_dev->usb_buf, len,
1408
500);
1409
PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
1410
if (ret < 0) {
1411
err("reg_r err %d", ret);
1412
gspca_dev->usb_err = ret;
1413
}
1414
}
1415
1416
static void reg_w1(struct gspca_dev *gspca_dev,
1417
u16 value,
1418
u8 data)
1419
{
1420
int ret;
1421
1422
if (gspca_dev->usb_err < 0)
1423
return;
1424
PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
1425
gspca_dev->usb_buf[0] = data;
1426
ret = usb_control_msg(gspca_dev->dev,
1427
usb_sndctrlpipe(gspca_dev->dev, 0),
1428
0x08,
1429
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1430
value,
1431
0,
1432
gspca_dev->usb_buf, 1,
1433
500);
1434
if (ret < 0) {
1435
err("reg_w1 err %d", ret);
1436
gspca_dev->usb_err = ret;
1437
}
1438
}
1439
static void reg_w(struct gspca_dev *gspca_dev,
1440
u16 value,
1441
const u8 *buffer,
1442
int len)
1443
{
1444
int ret;
1445
1446
if (gspca_dev->usb_err < 0)
1447
return;
1448
PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
1449
value, buffer[0], buffer[1]);
1450
#ifdef GSPCA_DEBUG
1451
if (len > USB_BUF_SZ) {
1452
err("reg_w: buffer overflow");
1453
return;
1454
}
1455
#endif
1456
memcpy(gspca_dev->usb_buf, buffer, len);
1457
ret = usb_control_msg(gspca_dev->dev,
1458
usb_sndctrlpipe(gspca_dev->dev, 0),
1459
0x08,
1460
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1461
value, 0,
1462
gspca_dev->usb_buf, len,
1463
500);
1464
if (ret < 0) {
1465
err("reg_w err %d", ret);
1466
gspca_dev->usb_err = ret;
1467
}
1468
}
1469
1470
/* I2C write 1 byte */
1471
static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1472
{
1473
struct sd *sd = (struct sd *) gspca_dev;
1474
int ret;
1475
1476
if (gspca_dev->usb_err < 0)
1477
return;
1478
PDEBUG(D_USBO, "i2c_w1 [%02x] = %02x", reg, val);
1479
switch (sd->sensor) {
1480
case SENSOR_ADCM1700:
1481
case SENSOR_OM6802:
1482
case SENSOR_GC0307: /* i2c command = a0 (100 kHz) */
1483
gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
1484
break;
1485
default: /* i2c command = a1 (400 kHz) */
1486
gspca_dev->usb_buf[0] = 0x81 | (2 << 4);
1487
break;
1488
}
1489
gspca_dev->usb_buf[1] = sd->i2c_addr;
1490
gspca_dev->usb_buf[2] = reg;
1491
gspca_dev->usb_buf[3] = val;
1492
gspca_dev->usb_buf[4] = 0;
1493
gspca_dev->usb_buf[5] = 0;
1494
gspca_dev->usb_buf[6] = 0;
1495
gspca_dev->usb_buf[7] = 0x10;
1496
ret = usb_control_msg(gspca_dev->dev,
1497
usb_sndctrlpipe(gspca_dev->dev, 0),
1498
0x08,
1499
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1500
0x08, /* value = i2c */
1501
0,
1502
gspca_dev->usb_buf, 8,
1503
500);
1504
if (ret < 0) {
1505
err("i2c_w1 err %d", ret);
1506
gspca_dev->usb_err = ret;
1507
}
1508
}
1509
1510
/* I2C write 8 bytes */
1511
static void i2c_w8(struct gspca_dev *gspca_dev,
1512
const u8 *buffer)
1513
{
1514
int ret;
1515
1516
if (gspca_dev->usb_err < 0)
1517
return;
1518
PDEBUG(D_USBO, "i2c_w8 [%02x] = %02x ..",
1519
buffer[2], buffer[3]);
1520
memcpy(gspca_dev->usb_buf, buffer, 8);
1521
ret = usb_control_msg(gspca_dev->dev,
1522
usb_sndctrlpipe(gspca_dev->dev, 0),
1523
0x08,
1524
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1525
0x08, 0, /* value, index */
1526
gspca_dev->usb_buf, 8,
1527
500);
1528
msleep(2);
1529
if (ret < 0) {
1530
err("i2c_w8 err %d", ret);
1531
gspca_dev->usb_err = ret;
1532
}
1533
}
1534
1535
/* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */
1536
static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
1537
{
1538
struct sd *sd = (struct sd *) gspca_dev;
1539
u8 mode[8];
1540
1541
switch (sd->sensor) {
1542
case SENSOR_ADCM1700:
1543
case SENSOR_OM6802:
1544
case SENSOR_GC0307: /* i2c command = a0 (100 kHz) */
1545
mode[0] = 0x80 | 0x10;
1546
break;
1547
default: /* i2c command = 91 (400 kHz) */
1548
mode[0] = 0x81 | 0x10;
1549
break;
1550
}
1551
mode[1] = sd->i2c_addr;
1552
mode[2] = reg;
1553
mode[3] = 0;
1554
mode[4] = 0;
1555
mode[5] = 0;
1556
mode[6] = 0;
1557
mode[7] = 0x10;
1558
i2c_w8(gspca_dev, mode);
1559
msleep(2);
1560
mode[0] = (mode[0] & 0x81) | (len << 4) | 0x02;
1561
mode[2] = 0;
1562
i2c_w8(gspca_dev, mode);
1563
msleep(2);
1564
reg_r(gspca_dev, 0x0a, 5);
1565
}
1566
1567
static void i2c_w_seq(struct gspca_dev *gspca_dev,
1568
const u8 (*data)[8])
1569
{
1570
while ((*data)[0] != 0) {
1571
if ((*data)[0] != DELAY)
1572
i2c_w8(gspca_dev, *data);
1573
else
1574
msleep((*data)[1]);
1575
data++;
1576
}
1577
}
1578
1579
/* check the ID of the hv7131 sensor */
1580
/* this sequence is needed because it activates the sensor */
1581
static void hv7131r_probe(struct gspca_dev *gspca_dev)
1582
{
1583
i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
1584
msleep(10);
1585
reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
1586
msleep(10);
1587
i2c_r(gspca_dev, 0, 5); /* read sensor id */
1588
if (gspca_dev->usb_buf[0] == 0x02 /* chip ID (02 is R) */
1589
&& gspca_dev->usb_buf[1] == 0x09
1590
&& gspca_dev->usb_buf[2] == 0x01) {
1591
PDEBUG(D_PROBE, "Sensor HV7131R found");
1592
return;
1593
}
1594
warn("Erroneous HV7131R ID 0x%02x 0x%02x 0x%02x",
1595
gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1596
gspca_dev->usb_buf[2]);
1597
}
1598
1599
static void mi0360_probe(struct gspca_dev *gspca_dev)
1600
{
1601
struct sd *sd = (struct sd *) gspca_dev;
1602
int i, j;
1603
u16 val = 0;
1604
static const u8 probe_tb[][4][8] = {
1605
{ /* mi0360 */
1606
{0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1607
{0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1608
{0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1609
{0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1610
},
1611
{ /* mt9v111 */
1612
{0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1613
{0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1614
{0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1615
{}
1616
},
1617
};
1618
1619
for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1620
reg_w1(gspca_dev, 0x17, 0x62);
1621
reg_w1(gspca_dev, 0x01, 0x08);
1622
for (j = 0; j < 3; j++)
1623
i2c_w8(gspca_dev, probe_tb[i][j]);
1624
msleep(2);
1625
reg_r(gspca_dev, 0x0a, 5);
1626
val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1627
if (probe_tb[i][3][0] != 0)
1628
i2c_w8(gspca_dev, probe_tb[i][3]);
1629
reg_w1(gspca_dev, 0x01, 0x29);
1630
reg_w1(gspca_dev, 0x17, 0x42);
1631
if (val != 0xffff)
1632
break;
1633
}
1634
if (gspca_dev->usb_err < 0)
1635
return;
1636
switch (val) {
1637
case 0x8221:
1638
PDEBUG(D_PROBE, "Sensor mi0360b");
1639
sd->sensor = SENSOR_MI0360B;
1640
break;
1641
case 0x823a:
1642
PDEBUG(D_PROBE, "Sensor mt9v111");
1643
sd->sensor = SENSOR_MT9V111;
1644
break;
1645
case 0x8243:
1646
PDEBUG(D_PROBE, "Sensor mi0360");
1647
break;
1648
default:
1649
PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1650
break;
1651
}
1652
}
1653
1654
static void ov7630_probe(struct gspca_dev *gspca_dev)
1655
{
1656
struct sd *sd = (struct sd *) gspca_dev;
1657
u16 val;
1658
1659
/* check ov76xx */
1660
reg_w1(gspca_dev, 0x17, 0x62);
1661
reg_w1(gspca_dev, 0x01, 0x08);
1662
sd->i2c_addr = 0x21;
1663
i2c_r(gspca_dev, 0x0a, 2);
1664
val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1665
reg_w1(gspca_dev, 0x01, 0x29);
1666
reg_w1(gspca_dev, 0x17, 0x42);
1667
if (gspca_dev->usb_err < 0)
1668
return;
1669
if (val == 0x7628) { /* soi768 */
1670
sd->sensor = SENSOR_SOI768;
1671
/*fixme: only valid for 0c45:613e?*/
1672
gspca_dev->cam.input_flags =
1673
V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
1674
PDEBUG(D_PROBE, "Sensor soi768");
1675
return;
1676
}
1677
PDEBUG(D_PROBE, "Sensor ov%04x", val);
1678
}
1679
1680
static void ov7648_probe(struct gspca_dev *gspca_dev)
1681
{
1682
struct sd *sd = (struct sd *) gspca_dev;
1683
u16 val;
1684
1685
/* check ov76xx */
1686
reg_w1(gspca_dev, 0x17, 0x62);
1687
reg_w1(gspca_dev, 0x01, 0x08);
1688
sd->i2c_addr = 0x21;
1689
i2c_r(gspca_dev, 0x0a, 2);
1690
val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1691
reg_w1(gspca_dev, 0x01, 0x29);
1692
reg_w1(gspca_dev, 0x17, 0x42);
1693
if ((val & 0xff00) == 0x7600) { /* ov76xx */
1694
PDEBUG(D_PROBE, "Sensor ov%04x", val);
1695
return;
1696
}
1697
1698
/* check po1030 */
1699
reg_w1(gspca_dev, 0x17, 0x62);
1700
reg_w1(gspca_dev, 0x01, 0x08);
1701
sd->i2c_addr = 0x6e;
1702
i2c_r(gspca_dev, 0x00, 2);
1703
val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1704
reg_w1(gspca_dev, 0x01, 0x29);
1705
reg_w1(gspca_dev, 0x17, 0x42);
1706
if (gspca_dev->usb_err < 0)
1707
return;
1708
if (val == 0x1030) { /* po1030 */
1709
PDEBUG(D_PROBE, "Sensor po1030");
1710
sd->sensor = SENSOR_PO1030;
1711
return;
1712
}
1713
err("Unknown sensor %04x", val);
1714
}
1715
1716
/* 0c45:6142 sensor may be po2030n, gc0305 or gc0307 */
1717
static void po2030n_probe(struct gspca_dev *gspca_dev)
1718
{
1719
struct sd *sd = (struct sd *) gspca_dev;
1720
u16 val;
1721
1722
/* check gc0307 */
1723
reg_w1(gspca_dev, 0x17, 0x62);
1724
reg_w1(gspca_dev, 0x01, 0x08);
1725
reg_w1(gspca_dev, 0x02, 0x22);
1726
sd->i2c_addr = 0x21;
1727
i2c_r(gspca_dev, 0x00, 1);
1728
val = gspca_dev->usb_buf[4];
1729
reg_w1(gspca_dev, 0x01, 0x29); /* reset */
1730
reg_w1(gspca_dev, 0x17, 0x42);
1731
if (val == 0x99) { /* gc0307 (?) */
1732
PDEBUG(D_PROBE, "Sensor gc0307");
1733
sd->sensor = SENSOR_GC0307;
1734
return;
1735
}
1736
1737
/* check po2030n */
1738
reg_w1(gspca_dev, 0x17, 0x62);
1739
reg_w1(gspca_dev, 0x01, 0x0a);
1740
sd->i2c_addr = 0x6e;
1741
i2c_r(gspca_dev, 0x00, 2);
1742
val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1743
reg_w1(gspca_dev, 0x01, 0x29);
1744
reg_w1(gspca_dev, 0x17, 0x42);
1745
if (gspca_dev->usb_err < 0)
1746
return;
1747
if (val == 0x2030) {
1748
PDEBUG(D_PROBE, "Sensor po2030n");
1749
/* sd->sensor = SENSOR_PO2030N; */
1750
} else {
1751
err("Unknown sensor ID %04x", val);
1752
}
1753
}
1754
1755
/* this function is called at probe time */
1756
static int sd_config(struct gspca_dev *gspca_dev,
1757
const struct usb_device_id *id)
1758
{
1759
struct sd *sd = (struct sd *) gspca_dev;
1760
struct cam *cam;
1761
1762
sd->bridge = id->driver_info >> 16;
1763
sd->sensor = id->driver_info >> 8;
1764
sd->flags = id->driver_info;
1765
1766
cam = &gspca_dev->cam;
1767
if (sd->sensor == SENSOR_ADCM1700) {
1768
cam->cam_mode = cif_mode;
1769
cam->nmodes = ARRAY_SIZE(cif_mode);
1770
} else {
1771
cam->cam_mode = vga_mode;
1772
cam->nmodes = ARRAY_SIZE(vga_mode);
1773
}
1774
cam->npkt = 24; /* 24 packets per ISOC message */
1775
cam->ctrls = sd->ctrls;
1776
1777
sd->ag_cnt = -1;
1778
sd->quality = QUALITY_DEF;
1779
1780
/* if USB 1.1, let some bandwidth for the audio device */
1781
if (gspca_dev->audio && gspca_dev->dev->speed < USB_SPEED_HIGH)
1782
gspca_dev->nbalt--;
1783
1784
INIT_WORK(&sd->work, qual_upd);
1785
1786
return 0;
1787
}
1788
1789
/* this function is called at probe and resume time */
1790
static int sd_init(struct gspca_dev *gspca_dev)
1791
{
1792
struct sd *sd = (struct sd *) gspca_dev;
1793
const u8 *sn9c1xx;
1794
u8 regGpio[] = { 0x29, 0x70 }; /* no audio */
1795
u8 regF1;
1796
1797
/* setup a selector by bridge */
1798
reg_w1(gspca_dev, 0xf1, 0x01);
1799
reg_r(gspca_dev, 0x00, 1);
1800
reg_w1(gspca_dev, 0xf1, 0x00);
1801
reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
1802
regF1 = gspca_dev->usb_buf[0];
1803
if (gspca_dev->usb_err < 0)
1804
return gspca_dev->usb_err;
1805
PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
1806
if (gspca_dev->audio)
1807
regGpio[1] |= 0x04; /* with audio */
1808
switch (sd->bridge) {
1809
case BRIDGE_SN9C102P:
1810
case BRIDGE_SN9C105:
1811
if (regF1 != 0x11)
1812
return -ENODEV;
1813
break;
1814
default:
1815
/* case BRIDGE_SN9C110: */
1816
/* case BRIDGE_SN9C120: */
1817
if (regF1 != 0x12)
1818
return -ENODEV;
1819
}
1820
1821
switch (sd->sensor) {
1822
case SENSOR_MI0360:
1823
mi0360_probe(gspca_dev);
1824
break;
1825
case SENSOR_OV7630:
1826
ov7630_probe(gspca_dev);
1827
break;
1828
case SENSOR_OV7648:
1829
ov7648_probe(gspca_dev);
1830
break;
1831
case SENSOR_PO2030N:
1832
po2030n_probe(gspca_dev);
1833
break;
1834
}
1835
1836
switch (sd->bridge) {
1837
case BRIDGE_SN9C102P:
1838
reg_w1(gspca_dev, 0x02, regGpio[1]);
1839
break;
1840
default:
1841
reg_w(gspca_dev, 0x01, regGpio, 2);
1842
break;
1843
}
1844
1845
if (sd->sensor == SENSOR_OM6802)
1846
sd->ctrls[SHARPNESS].def = 0x10;
1847
1848
/* Note we do not disable the sensor clock here (power saving mode),
1849
as that also disables the button on the cam. */
1850
reg_w1(gspca_dev, 0xf1, 0x00);
1851
1852
/* set the i2c address */
1853
sn9c1xx = sn_tb[sd->sensor];
1854
sd->i2c_addr = sn9c1xx[9];
1855
1856
gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1857
if (!(sd->flags & F_ILLUM))
1858
gspca_dev->ctrl_dis |= (1 << ILLUM);
1859
1860
return gspca_dev->usb_err;
1861
}
1862
1863
static u32 setexposure(struct gspca_dev *gspca_dev,
1864
u32 expo)
1865
{
1866
struct sd *sd = (struct sd *) gspca_dev;
1867
1868
switch (sd->sensor) {
1869
case SENSOR_GC0307: {
1870
int a, b;
1871
1872
/* expo = 0..255 -> a = 19..43 */
1873
a = 19 + expo * 25 / 256;
1874
i2c_w1(gspca_dev, 0x68, a);
1875
a -= 12;
1876
b = a * a * 4; /* heuristic */
1877
i2c_w1(gspca_dev, 0x03, b >> 8);
1878
i2c_w1(gspca_dev, 0x04, b);
1879
break;
1880
}
1881
case SENSOR_HV7131R: {
1882
u8 Expodoit[] =
1883
{ 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 };
1884
1885
Expodoit[3] = expo >> 16;
1886
Expodoit[4] = expo >> 8;
1887
Expodoit[5] = expo;
1888
i2c_w8(gspca_dev, Expodoit);
1889
break;
1890
}
1891
case SENSOR_MI0360:
1892
case SENSOR_MI0360B: {
1893
u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1894
{ 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 };
1895
static const u8 doit[] = /* update sensor */
1896
{ 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1897
static const u8 sensorgo[] = /* sensor on */
1898
{ 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1899
1900
if (expo > 0x0635)
1901
expo = 0x0635;
1902
else if (expo < 0x0001)
1903
expo = 0x0001;
1904
expoMi[3] = expo >> 8;
1905
expoMi[4] = expo;
1906
i2c_w8(gspca_dev, expoMi);
1907
i2c_w8(gspca_dev, doit);
1908
i2c_w8(gspca_dev, sensorgo);
1909
break;
1910
}
1911
case SENSOR_MO4000: {
1912
u8 expoMof[] =
1913
{ 0xa1, 0x21, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x10 };
1914
u8 expoMo10[] =
1915
{ 0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10 };
1916
static const u8 gainMo[] =
1917
{ 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1918
1919
if (expo > 0x1fff)
1920
expo = 0x1fff;
1921
else if (expo < 0x0001)
1922
expo = 0x0001;
1923
expoMof[3] = (expo & 0x03fc) >> 2;
1924
i2c_w8(gspca_dev, expoMof);
1925
expoMo10[3] = ((expo & 0x1c00) >> 10)
1926
| ((expo & 0x0003) << 4);
1927
i2c_w8(gspca_dev, expoMo10);
1928
i2c_w8(gspca_dev, gainMo);
1929
PDEBUG(D_FRAM, "set exposure %d",
1930
((expoMo10[3] & 0x07) << 10)
1931
| (expoMof[3] << 2)
1932
| ((expoMo10[3] & 0x30) >> 4));
1933
break;
1934
}
1935
case SENSOR_MT9V111: {
1936
u8 expo_c1[] =
1937
{ 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1938
1939
if (expo > 0x0390)
1940
expo = 0x0390;
1941
else if (expo < 0x0060)
1942
expo = 0x0060;
1943
expo_c1[3] = expo >> 8;
1944
expo_c1[4] = expo;
1945
i2c_w8(gspca_dev, expo_c1);
1946
break;
1947
}
1948
case SENSOR_OM6802: {
1949
u8 gainOm[] =
1950
{ 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1951
/* preset AGC - works when AutoExpo = off */
1952
1953
if (expo > 0x03ff)
1954
expo = 0x03ff;
1955
if (expo < 0x0001)
1956
expo = 0x0001;
1957
gainOm[3] = expo >> 2;
1958
i2c_w8(gspca_dev, gainOm);
1959
reg_w1(gspca_dev, 0x96, expo >> 5);
1960
PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
1961
break;
1962
}
1963
}
1964
return expo;
1965
}
1966
1967
static void setbrightness(struct gspca_dev *gspca_dev)
1968
{
1969
struct sd *sd = (struct sd *) gspca_dev;
1970
unsigned int expo;
1971
int brightness;
1972
u8 k2;
1973
1974
brightness = sd->ctrls[BRIGHTNESS].val;
1975
k2 = (brightness - 0x80) >> 2;
1976
switch (sd->sensor) {
1977
case SENSOR_ADCM1700:
1978
if (k2 > 0x1f)
1979
k2 = 0; /* only positive Y offset */
1980
break;
1981
case SENSOR_HV7131R:
1982
expo = brightness << 12;
1983
if (expo > 0x002dc6c0)
1984
expo = 0x002dc6c0;
1985
else if (expo < 0x02a0)
1986
expo = 0x02a0;
1987
sd->exposure = setexposure(gspca_dev, expo);
1988
break;
1989
case SENSOR_MI0360:
1990
case SENSOR_MO4000:
1991
expo = brightness << 4;
1992
sd->exposure = setexposure(gspca_dev, expo);
1993
break;
1994
case SENSOR_MI0360B:
1995
expo = brightness << 2;
1996
sd->exposure = setexposure(gspca_dev, expo);
1997
break;
1998
case SENSOR_GC0307:
1999
expo = brightness;
2000
sd->exposure = setexposure(gspca_dev, expo);
2001
return; /* don't set the Y offset */
2002
case SENSOR_MT9V111:
2003
expo = brightness << 2;
2004
sd->exposure = setexposure(gspca_dev, expo);
2005
return; /* don't set the Y offset */
2006
case SENSOR_OM6802:
2007
expo = brightness << 2;
2008
sd->exposure = setexposure(gspca_dev, expo);
2009
k2 = brightness >> 3;
2010
break;
2011
}
2012
2013
reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
2014
}
2015
2016
static void setcontrast(struct gspca_dev *gspca_dev)
2017
{
2018
struct sd *sd = (struct sd *) gspca_dev;
2019
u8 k2;
2020
u8 contrast[6];
2021
2022
k2 = sd->ctrls[CONTRAST].val * 0x30 / (CONTRAST_MAX + 1)
2023
+ 0x10; /* 10..40 */
2024
contrast[0] = (k2 + 1) / 2; /* red */
2025
contrast[1] = 0;
2026
contrast[2] = k2; /* green */
2027
contrast[3] = 0;
2028
contrast[4] = (k2 + 1) / 5; /* blue */
2029
contrast[5] = 0;
2030
reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
2031
}
2032
2033
static void setcolors(struct gspca_dev *gspca_dev)
2034
{
2035
struct sd *sd = (struct sd *) gspca_dev;
2036
int i, v, colors;
2037
const s16 *uv;
2038
u8 reg8a[12]; /* U & V gains */
2039
static const s16 uv_com[6] = { /* same as reg84 in signed decimal */
2040
-24, -38, 64, /* UR UG UB */
2041
62, -51, -9 /* VR VG VB */
2042
};
2043
static const s16 uv_mi0360b[6] = {
2044
-20, -38, 64, /* UR UG UB */
2045
60, -51, -9 /* VR VG VB */
2046
};
2047
2048
colors = sd->ctrls[COLORS].val;
2049
if (sd->sensor == SENSOR_MI0360B)
2050
uv = uv_mi0360b;
2051
else
2052
uv = uv_com;
2053
for (i = 0; i < 6; i++) {
2054
v = uv[i] * colors / COLORS_DEF;
2055
reg8a[i * 2] = v;
2056
reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
2057
}
2058
reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
2059
}
2060
2061
static void setredblue(struct gspca_dev *gspca_dev)
2062
{
2063
struct sd *sd = (struct sd *) gspca_dev;
2064
2065
reg_w1(gspca_dev, 0x05, sd->ctrls[RED].val);
2066
/* reg_w1(gspca_dev, 0x07, 32); */
2067
reg_w1(gspca_dev, 0x06, sd->ctrls[BLUE].val);
2068
}
2069
2070
static void setgamma(struct gspca_dev *gspca_dev)
2071
{
2072
struct sd *sd = (struct sd *) gspca_dev;
2073
int i, val;
2074
u8 gamma[17];
2075
const u8 *gamma_base;
2076
static const u8 delta[17] = {
2077
0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
2078
0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
2079
};
2080
2081
switch (sd->sensor) {
2082
case SENSOR_ADCM1700:
2083
gamma_base = gamma_spec_0;
2084
break;
2085
case SENSOR_HV7131R:
2086
case SENSOR_MI0360B:
2087
case SENSOR_MT9V111:
2088
gamma_base = gamma_spec_1;
2089
break;
2090
case SENSOR_GC0307:
2091
gamma_base = gamma_spec_2;
2092
break;
2093
case SENSOR_SP80708:
2094
gamma_base = gamma_spec_3;
2095
break;
2096
default:
2097
gamma_base = gamma_def;
2098
break;
2099
}
2100
2101
val = sd->ctrls[GAMMA].val;
2102
for (i = 0; i < sizeof gamma; i++)
2103
gamma[i] = gamma_base[i]
2104
+ delta[i] * (val - GAMMA_DEF) / 32;
2105
reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
2106
}
2107
2108
static void setautogain(struct gspca_dev *gspca_dev)
2109
{
2110
struct sd *sd = (struct sd *) gspca_dev;
2111
2112
if (gspca_dev->ctrl_dis & (1 << AUTOGAIN))
2113
return;
2114
switch (sd->sensor) {
2115
case SENSOR_OV7630:
2116
case SENSOR_OV7648: {
2117
u8 comb;
2118
2119
if (sd->sensor == SENSOR_OV7630)
2120
comb = 0xc0;
2121
else
2122
comb = 0xa0;
2123
if (sd->ctrls[AUTOGAIN].val)
2124
comb |= 0x03;
2125
i2c_w1(&sd->gspca_dev, 0x13, comb);
2126
return;
2127
}
2128
}
2129
if (sd->ctrls[AUTOGAIN].val)
2130
sd->ag_cnt = AG_CNT_START;
2131
else
2132
sd->ag_cnt = -1;
2133
}
2134
2135
static void sethvflip(struct gspca_dev *gspca_dev)
2136
{
2137
struct sd *sd = (struct sd *) gspca_dev;
2138
u8 comn;
2139
2140
switch (sd->sensor) {
2141
case SENSOR_HV7131R:
2142
comn = 0x18; /* clkdiv = 1, ablcen = 1 */
2143
if (sd->ctrls[VFLIP].val)
2144
comn |= 0x01;
2145
i2c_w1(gspca_dev, 0x01, comn); /* sctra */
2146
break;
2147
case SENSOR_OV7630:
2148
comn = 0x02;
2149
if (!sd->ctrls[VFLIP].val)
2150
comn |= 0x80;
2151
i2c_w1(gspca_dev, 0x75, comn);
2152
break;
2153
case SENSOR_OV7648:
2154
comn = 0x06;
2155
if (sd->ctrls[VFLIP].val)
2156
comn |= 0x80;
2157
i2c_w1(gspca_dev, 0x75, comn);
2158
break;
2159
case SENSOR_PO2030N:
2160
/* Reg. 0x1E: Timing Generator Control Register 2 (Tgcontrol2)
2161
* (reset value: 0x0A)
2162
* bit7: HM: Horizontal Mirror: 0: disable, 1: enable
2163
* bit6: VM: Vertical Mirror: 0: disable, 1: enable
2164
* bit5: ST: Shutter Selection: 0: electrical, 1: mechanical
2165
* bit4: FT: Single Frame Transfer: 0: disable, 1: enable
2166
* bit3-0: X
2167
*/
2168
comn = 0x0a;
2169
if (sd->ctrls[HFLIP].val)
2170
comn |= 0x80;
2171
if (sd->ctrls[VFLIP].val)
2172
comn |= 0x40;
2173
i2c_w1(&sd->gspca_dev, 0x1e, comn);
2174
break;
2175
}
2176
}
2177
2178
static void setsharpness(struct gspca_dev *gspca_dev)
2179
{
2180
struct sd *sd = (struct sd *) gspca_dev;
2181
2182
reg_w1(gspca_dev, 0x99, sd->ctrls[SHARPNESS].val);
2183
}
2184
2185
static void setillum(struct gspca_dev *gspca_dev)
2186
{
2187
struct sd *sd = (struct sd *) gspca_dev;
2188
2189
if (gspca_dev->ctrl_dis & (1 << ILLUM))
2190
return;
2191
switch (sd->sensor) {
2192
case SENSOR_ADCM1700:
2193
reg_w1(gspca_dev, 0x02, /* gpio */
2194
sd->ctrls[ILLUM].val ? 0x64 : 0x60);
2195
break;
2196
case SENSOR_MT9V111:
2197
reg_w1(gspca_dev, 0x02,
2198
sd->ctrls[ILLUM].val ? 0x77 : 0x74);
2199
/* should have been: */
2200
/* 0x55 : 0x54); * 370i */
2201
/* 0x66 : 0x64); * Clip */
2202
break;
2203
}
2204
}
2205
2206
static void setfreq(struct gspca_dev *gspca_dev)
2207
{
2208
struct sd *sd = (struct sd *) gspca_dev;
2209
2210
if (gspca_dev->ctrl_dis & (1 << FREQ))
2211
return;
2212
if (sd->sensor == SENSOR_OV7660) {
2213
u8 com8;
2214
2215
com8 = 0xdf; /* auto gain/wb/expo */
2216
switch (sd->ctrls[FREQ].val) {
2217
case 0: /* Banding filter disabled */
2218
i2c_w1(gspca_dev, 0x13, com8 | 0x20);
2219
break;
2220
case 1: /* 50 hz */
2221
i2c_w1(gspca_dev, 0x13, com8);
2222
i2c_w1(gspca_dev, 0x3b, 0x0a);
2223
break;
2224
case 2: /* 60 hz */
2225
i2c_w1(gspca_dev, 0x13, com8);
2226
i2c_w1(gspca_dev, 0x3b, 0x02);
2227
break;
2228
}
2229
} else {
2230
u8 reg2a = 0, reg2b = 0, reg2d = 0;
2231
2232
/* Get reg2a / reg2d base values */
2233
switch (sd->sensor) {
2234
case SENSOR_OV7630:
2235
reg2a = 0x08;
2236
reg2d = 0x01;
2237
break;
2238
case SENSOR_OV7648:
2239
reg2a = 0x11;
2240
reg2d = 0x81;
2241
break;
2242
}
2243
2244
switch (sd->ctrls[FREQ].val) {
2245
case 0: /* Banding filter disabled */
2246
break;
2247
case 1: /* 50 hz (filter on and framerate adj) */
2248
reg2a |= 0x80;
2249
reg2b = 0xac;
2250
reg2d |= 0x04;
2251
break;
2252
case 2: /* 60 hz (filter on, no framerate adj) */
2253
reg2a |= 0x80;
2254
reg2d |= 0x04;
2255
break;
2256
}
2257
i2c_w1(gspca_dev, 0x2a, reg2a);
2258
i2c_w1(gspca_dev, 0x2b, reg2b);
2259
i2c_w1(gspca_dev, 0x2d, reg2d);
2260
}
2261
}
2262
2263
static void setjpegqual(struct gspca_dev *gspca_dev)
2264
{
2265
struct sd *sd = (struct sd *) gspca_dev;
2266
2267
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2268
#if USB_BUF_SZ < 64
2269
#error "No room enough in usb_buf for quantization table"
2270
#endif
2271
memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2272
usb_control_msg(gspca_dev->dev,
2273
usb_sndctrlpipe(gspca_dev->dev, 0),
2274
0x08,
2275
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
2276
0x0100, 0,
2277
gspca_dev->usb_buf, 64,
2278
500);
2279
memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2280
usb_control_msg(gspca_dev->dev,
2281
usb_sndctrlpipe(gspca_dev->dev, 0),
2282
0x08,
2283
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
2284
0x0140, 0,
2285
gspca_dev->usb_buf, 64,
2286
500);
2287
2288
sd->reg18 ^= 0x40;
2289
reg_w1(gspca_dev, 0x18, sd->reg18);
2290
}
2291
2292
/* JPEG quality update */
2293
/* This function is executed from a work queue. */
2294
static void qual_upd(struct work_struct *work)
2295
{
2296
struct sd *sd = container_of(work, struct sd, work);
2297
struct gspca_dev *gspca_dev = &sd->gspca_dev;
2298
2299
mutex_lock(&gspca_dev->usb_lock);
2300
PDEBUG(D_STREAM, "qual_upd %d%%", sd->quality);
2301
setjpegqual(gspca_dev);
2302
mutex_unlock(&gspca_dev->usb_lock);
2303
}
2304
2305
/* -- start the camera -- */
2306
static int sd_start(struct gspca_dev *gspca_dev)
2307
{
2308
struct sd *sd = (struct sd *) gspca_dev;
2309
int i;
2310
u8 reg01, reg17;
2311
u8 reg0102[2];
2312
const u8 *sn9c1xx;
2313
const u8 (*init)[8];
2314
const u8 *reg9a;
2315
int mode;
2316
static const u8 reg9a_def[] =
2317
{0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
2318
static const u8 reg9a_spec[] =
2319
{0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
2320
static const u8 regd4[] = {0x60, 0x00, 0x00};
2321
static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
2322
static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
2323
static const u8 CA_adcm1700[] =
2324
{ 0x14, 0xec, 0x0a, 0xf6 };
2325
static const u8 CA_po2030n[] =
2326
{ 0x1e, 0xe2, 0x14, 0xec };
2327
static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
2328
static const u8 CE_gc0307[] =
2329
{ 0x32, 0xce, 0x2d, 0xd3 };
2330
static const u8 CE_ov76xx[] =
2331
{ 0x32, 0xdd, 0x32, 0xdd };
2332
static const u8 CE_po2030n[] =
2333
{ 0x14, 0xe7, 0x1e, 0xdd };
2334
2335
/* create the JPEG header */
2336
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
2337
0x21); /* JPEG 422 */
2338
2339
/* initialize the bridge */
2340
sn9c1xx = sn_tb[sd->sensor];
2341
2342
/* sensor clock already enabled in sd_init */
2343
/* reg_w1(gspca_dev, 0xf1, 0x00); */
2344
reg01 = sn9c1xx[1];
2345
if (sd->flags & F_PDN_INV)
2346
reg01 ^= S_PDN_INV; /* power down inverted */
2347
reg_w1(gspca_dev, 0x01, reg01);
2348
2349
/* configure gpio */
2350
reg0102[0] = reg01;
2351
reg0102[1] = sn9c1xx[2];
2352
if (gspca_dev->audio)
2353
reg0102[1] |= 0x04; /* keep the audio connection */
2354
reg_w(gspca_dev, 0x01, reg0102, 2);
2355
reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
2356
reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
2357
switch (sd->sensor) {
2358
case SENSOR_GC0307:
2359
case SENSOR_OV7660:
2360
case SENSOR_PO1030:
2361
case SENSOR_PO2030N:
2362
case SENSOR_SOI768:
2363
case SENSOR_SP80708:
2364
reg9a = reg9a_spec;
2365
break;
2366
default:
2367
reg9a = reg9a_def;
2368
break;
2369
}
2370
reg_w(gspca_dev, 0x9a, reg9a, 6);
2371
2372
reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
2373
2374
reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
2375
2376
reg17 = sn9c1xx[0x17];
2377
switch (sd->sensor) {
2378
case SENSOR_GC0307:
2379
msleep(50); /*fixme: is it useful? */
2380
break;
2381
case SENSOR_OM6802:
2382
msleep(10);
2383
reg_w1(gspca_dev, 0x02, 0x73);
2384
reg17 |= SEN_CLK_EN;
2385
reg_w1(gspca_dev, 0x17, reg17);
2386
reg_w1(gspca_dev, 0x01, 0x22);
2387
msleep(100);
2388
reg01 = SCL_SEL_OD | S_PDN_INV;
2389
reg17 &= MCK_SIZE_MASK;
2390
reg17 |= 0x04; /* clock / 4 */
2391
break;
2392
}
2393
reg01 |= SYS_SEL_48M;
2394
reg_w1(gspca_dev, 0x01, reg01);
2395
reg17 |= SEN_CLK_EN;
2396
reg_w1(gspca_dev, 0x17, reg17);
2397
reg01 &= ~S_PWR_DN; /* sensor power on */
2398
reg_w1(gspca_dev, 0x01, reg01);
2399
reg01 &= ~SYS_SEL_48M;
2400
reg_w1(gspca_dev, 0x01, reg01);
2401
2402
switch (sd->sensor) {
2403
case SENSOR_HV7131R:
2404
hv7131r_probe(gspca_dev); /*fixme: is it useful? */
2405
break;
2406
case SENSOR_OM6802:
2407
msleep(10);
2408
reg_w1(gspca_dev, 0x01, reg01);
2409
i2c_w8(gspca_dev, om6802_init0[0]);
2410
i2c_w8(gspca_dev, om6802_init0[1]);
2411
msleep(15);
2412
reg_w1(gspca_dev, 0x02, 0x71);
2413
msleep(150);
2414
break;
2415
case SENSOR_SP80708:
2416
msleep(100);
2417
reg_w1(gspca_dev, 0x02, 0x62);
2418
break;
2419
}
2420
2421
/* initialize the sensor */
2422
i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
2423
2424
reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
2425
reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
2426
reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
2427
reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
2428
reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
2429
if (sd->sensor == SENSOR_ADCM1700) {
2430
reg_w1(gspca_dev, 0xd2, 0x3a); /* AE_H_SIZE = 116 */
2431
reg_w1(gspca_dev, 0xd3, 0x30); /* AE_V_SIZE = 96 */
2432
} else {
2433
reg_w1(gspca_dev, 0xd2, 0x6a); /* AE_H_SIZE = 212 */
2434
reg_w1(gspca_dev, 0xd3, 0x50); /* AE_V_SIZE = 160 */
2435
}
2436
reg_w1(gspca_dev, 0xc6, 0x00);
2437
reg_w1(gspca_dev, 0xc7, 0x00);
2438
if (sd->sensor == SENSOR_ADCM1700) {
2439
reg_w1(gspca_dev, 0xc8, 0x2c); /* AW_H_STOP = 352 */
2440
reg_w1(gspca_dev, 0xc9, 0x24); /* AW_V_STOP = 288 */
2441
} else {
2442
reg_w1(gspca_dev, 0xc8, 0x50); /* AW_H_STOP = 640 */
2443
reg_w1(gspca_dev, 0xc9, 0x3c); /* AW_V_STOP = 480 */
2444
}
2445
reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
2446
switch (sd->sensor) {
2447
case SENSOR_OM6802:
2448
/* case SENSOR_OV7648: * fixme: sometimes */
2449
break;
2450
default:
2451
reg17 |= DEF_EN;
2452
break;
2453
}
2454
reg_w1(gspca_dev, 0x17, reg17);
2455
2456
reg_w1(gspca_dev, 0x05, 0x00); /* red */
2457
reg_w1(gspca_dev, 0x07, 0x00); /* green */
2458
reg_w1(gspca_dev, 0x06, 0x00); /* blue */
2459
reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
2460
2461
setgamma(gspca_dev);
2462
2463
/*fixme: 8 times with all zeroes and 1 or 2 times with normal values */
2464
for (i = 0; i < 8; i++)
2465
reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
2466
switch (sd->sensor) {
2467
case SENSOR_ADCM1700:
2468
case SENSOR_OV7660:
2469
case SENSOR_SP80708:
2470
reg_w1(gspca_dev, 0x9a, 0x05);
2471
break;
2472
case SENSOR_GC0307:
2473
case SENSOR_MT9V111:
2474
case SENSOR_MI0360B:
2475
reg_w1(gspca_dev, 0x9a, 0x07);
2476
break;
2477
case SENSOR_OV7630:
2478
case SENSOR_OV7648:
2479
reg_w1(gspca_dev, 0x9a, 0x0a);
2480
break;
2481
case SENSOR_PO2030N:
2482
case SENSOR_SOI768:
2483
reg_w1(gspca_dev, 0x9a, 0x06);
2484
break;
2485
default:
2486
reg_w1(gspca_dev, 0x9a, 0x08);
2487
break;
2488
}
2489
setsharpness(gspca_dev);
2490
2491
reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
2492
reg_w1(gspca_dev, 0x05, 0x20); /* red */
2493
reg_w1(gspca_dev, 0x07, 0x20); /* green */
2494
reg_w1(gspca_dev, 0x06, 0x20); /* blue */
2495
2496
init = NULL;
2497
mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
2498
reg01 |= SYS_SEL_48M | V_TX_EN;
2499
reg17 &= ~MCK_SIZE_MASK;
2500
reg17 |= 0x02; /* clock / 2 */
2501
switch (sd->sensor) {
2502
case SENSOR_ADCM1700:
2503
init = adcm1700_sensor_param1;
2504
break;
2505
case SENSOR_GC0307:
2506
init = gc0307_sensor_param1;
2507
break;
2508
case SENSOR_HV7131R:
2509
case SENSOR_MI0360:
2510
if (mode)
2511
reg01 |= SYS_SEL_48M; /* 320x240: clk 48Mhz */
2512
else
2513
reg01 &= ~SYS_SEL_48M; /* 640x480: clk 24Mhz */
2514
reg17 &= ~MCK_SIZE_MASK;
2515
reg17 |= 0x01; /* clock / 1 */
2516
break;
2517
case SENSOR_MI0360B:
2518
init = mi0360b_sensor_param1;
2519
break;
2520
case SENSOR_MO4000:
2521
if (mode) { /* if 320x240 */
2522
reg01 &= ~SYS_SEL_48M; /* clk 24Mz */
2523
reg17 &= ~MCK_SIZE_MASK;
2524
reg17 |= 0x01; /* clock / 1 */
2525
}
2526
break;
2527
case SENSOR_MT9V111:
2528
init = mt9v111_sensor_param1;
2529
break;
2530
case SENSOR_OM6802:
2531
init = om6802_sensor_param1;
2532
if (!mode) { /* if 640x480 */
2533
reg17 &= ~MCK_SIZE_MASK;
2534
reg17 |= 0x04; /* clock / 4 */
2535
}
2536
break;
2537
case SENSOR_OV7630:
2538
init = ov7630_sensor_param1;
2539
break;
2540
case SENSOR_OV7648:
2541
init = ov7648_sensor_param1;
2542
reg17 &= ~MCK_SIZE_MASK;
2543
reg17 |= 0x01; /* clock / 1 */
2544
break;
2545
case SENSOR_OV7660:
2546
init = ov7660_sensor_param1;
2547
break;
2548
case SENSOR_PO1030:
2549
init = po1030_sensor_param1;
2550
break;
2551
case SENSOR_PO2030N:
2552
init = po2030n_sensor_param1;
2553
break;
2554
case SENSOR_SOI768:
2555
init = soi768_sensor_param1;
2556
break;
2557
case SENSOR_SP80708:
2558
init = sp80708_sensor_param1;
2559
break;
2560
}
2561
2562
/* more sensor initialization - param1 */
2563
if (init != NULL) {
2564
i2c_w_seq(gspca_dev, init);
2565
/* init = NULL; */
2566
}
2567
2568
reg_w(gspca_dev, 0xc0, C0, 6);
2569
switch (sd->sensor) {
2570
case SENSOR_ADCM1700:
2571
case SENSOR_GC0307:
2572
case SENSOR_SOI768:
2573
reg_w(gspca_dev, 0xca, CA_adcm1700, 4);
2574
break;
2575
case SENSOR_PO2030N:
2576
reg_w(gspca_dev, 0xca, CA_po2030n, 4);
2577
break;
2578
default:
2579
reg_w(gspca_dev, 0xca, CA, 4);
2580
break;
2581
}
2582
switch (sd->sensor) {
2583
case SENSOR_ADCM1700:
2584
case SENSOR_OV7630:
2585
case SENSOR_OV7648:
2586
case SENSOR_OV7660:
2587
case SENSOR_SOI768:
2588
reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
2589
break;
2590
case SENSOR_GC0307:
2591
reg_w(gspca_dev, 0xce, CE_gc0307, 4);
2592
break;
2593
case SENSOR_PO2030N:
2594
reg_w(gspca_dev, 0xce, CE_po2030n, 4);
2595
break;
2596
default:
2597
reg_w(gspca_dev, 0xce, CE, 4);
2598
/* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
2599
break;
2600
}
2601
2602
/* here change size mode 0 -> VGA; 1 -> CIF */
2603
sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
2604
reg_w1(gspca_dev, 0x18, sd->reg18);
2605
setjpegqual(gspca_dev);
2606
2607
reg_w1(gspca_dev, 0x17, reg17);
2608
reg_w1(gspca_dev, 0x01, reg01);
2609
sd->reg01 = reg01;
2610
sd->reg17 = reg17;
2611
2612
sethvflip(gspca_dev);
2613
setbrightness(gspca_dev);
2614
setcontrast(gspca_dev);
2615
setcolors(gspca_dev);
2616
setautogain(gspca_dev);
2617
setfreq(gspca_dev);
2618
2619
sd->pktsz = sd->npkt = 0;
2620
sd->nchg = sd->short_mark = 0;
2621
sd->work_thread = create_singlethread_workqueue(MODULE_NAME);
2622
2623
return gspca_dev->usb_err;
2624
}
2625
2626
static void sd_stopN(struct gspca_dev *gspca_dev)
2627
{
2628
struct sd *sd = (struct sd *) gspca_dev;
2629
static const u8 stophv7131[] =
2630
{ 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
2631
static const u8 stopmi0360[] =
2632
{ 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
2633
static const u8 stopov7648[] =
2634
{ 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
2635
static const u8 stopsoi768[] =
2636
{ 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
2637
u8 reg01;
2638
u8 reg17;
2639
2640
reg01 = sd->reg01;
2641
reg17 = sd->reg17 & ~SEN_CLK_EN;
2642
switch (sd->sensor) {
2643
case SENSOR_ADCM1700:
2644
case SENSOR_GC0307:
2645
case SENSOR_PO2030N:
2646
case SENSOR_SP80708:
2647
reg01 |= LED;
2648
reg_w1(gspca_dev, 0x01, reg01);
2649
reg01 &= ~(LED | V_TX_EN);
2650
reg_w1(gspca_dev, 0x01, reg01);
2651
/* reg_w1(gspca_dev, 0x02, 0x??); * LED off ? */
2652
break;
2653
case SENSOR_HV7131R:
2654
reg01 &= ~V_TX_EN;
2655
reg_w1(gspca_dev, 0x01, reg01);
2656
i2c_w8(gspca_dev, stophv7131);
2657
break;
2658
case SENSOR_MI0360:
2659
case SENSOR_MI0360B:
2660
reg01 &= ~V_TX_EN;
2661
reg_w1(gspca_dev, 0x01, reg01);
2662
/* reg_w1(gspca_dev, 0x02, 0x40); * LED off ? */
2663
i2c_w8(gspca_dev, stopmi0360);
2664
break;
2665
case SENSOR_MT9V111:
2666
case SENSOR_OM6802:
2667
case SENSOR_PO1030:
2668
reg01 &= ~V_TX_EN;
2669
reg_w1(gspca_dev, 0x01, reg01);
2670
break;
2671
case SENSOR_OV7630:
2672
case SENSOR_OV7648:
2673
reg01 &= ~V_TX_EN;
2674
reg_w1(gspca_dev, 0x01, reg01);
2675
i2c_w8(gspca_dev, stopov7648);
2676
break;
2677
case SENSOR_OV7660:
2678
reg01 &= ~V_TX_EN;
2679
reg_w1(gspca_dev, 0x01, reg01);
2680
break;
2681
case SENSOR_SOI768:
2682
i2c_w8(gspca_dev, stopsoi768);
2683
break;
2684
}
2685
2686
reg01 |= SCL_SEL_OD;
2687
reg_w1(gspca_dev, 0x01, reg01);
2688
reg01 |= S_PWR_DN; /* sensor power down */
2689
reg_w1(gspca_dev, 0x01, reg01);
2690
reg_w1(gspca_dev, 0x17, reg17);
2691
reg01 &= ~SYS_SEL_48M; /* clock 24MHz */
2692
reg_w1(gspca_dev, 0x01, reg01);
2693
reg01 |= LED;
2694
reg_w1(gspca_dev, 0x01, reg01);
2695
/* Don't disable sensor clock as that disables the button on the cam */
2696
/* reg_w1(gspca_dev, 0xf1, 0x01); */
2697
}
2698
2699
/* called on streamoff with alt==0 and on disconnect */
2700
/* the usb_lock is held at entry - restore on exit */
2701
static void sd_stop0(struct gspca_dev *gspca_dev)
2702
{
2703
struct sd *sd = (struct sd *) gspca_dev;
2704
2705
if (sd->work_thread != NULL) {
2706
mutex_unlock(&gspca_dev->usb_lock);
2707
destroy_workqueue(sd->work_thread);
2708
mutex_lock(&gspca_dev->usb_lock);
2709
sd->work_thread = NULL;
2710
}
2711
}
2712
2713
static void do_autogain(struct gspca_dev *gspca_dev)
2714
{
2715
struct sd *sd = (struct sd *) gspca_dev;
2716
int delta;
2717
int expotimes;
2718
u8 luma_mean = 130;
2719
u8 luma_delta = 20;
2720
2721
/* Thanks S., without your advice, autobright should not work :) */
2722
if (sd->ag_cnt < 0)
2723
return;
2724
if (--sd->ag_cnt >= 0)
2725
return;
2726
sd->ag_cnt = AG_CNT_START;
2727
2728
delta = atomic_read(&sd->avg_lum);
2729
PDEBUG(D_FRAM, "mean lum %d", delta);
2730
if (delta < luma_mean - luma_delta ||
2731
delta > luma_mean + luma_delta) {
2732
switch (sd->sensor) {
2733
case SENSOR_GC0307:
2734
expotimes = sd->exposure;
2735
expotimes += (luma_mean - delta) >> 6;
2736
if (expotimes < 0)
2737
expotimes = 0;
2738
sd->exposure = setexposure(gspca_dev,
2739
(unsigned int) expotimes);
2740
break;
2741
case SENSOR_HV7131R:
2742
expotimes = sd->exposure >> 8;
2743
expotimes += (luma_mean - delta) >> 4;
2744
if (expotimes < 0)
2745
expotimes = 0;
2746
sd->exposure = setexposure(gspca_dev,
2747
(unsigned int) (expotimes << 8));
2748
break;
2749
case SENSOR_OM6802:
2750
case SENSOR_MT9V111:
2751
expotimes = sd->exposure;
2752
expotimes += (luma_mean - delta) >> 2;
2753
if (expotimes < 0)
2754
expotimes = 0;
2755
sd->exposure = setexposure(gspca_dev,
2756
(unsigned int) expotimes);
2757
setredblue(gspca_dev);
2758
break;
2759
default:
2760
/* case SENSOR_MO4000: */
2761
/* case SENSOR_MI0360: */
2762
/* case SENSOR_MI0360B: */
2763
expotimes = sd->exposure;
2764
expotimes += (luma_mean - delta) >> 6;
2765
if (expotimes < 0)
2766
expotimes = 0;
2767
sd->exposure = setexposure(gspca_dev,
2768
(unsigned int) expotimes);
2769
setredblue(gspca_dev);
2770
break;
2771
}
2772
}
2773
}
2774
2775
/* set the average luminosity from an isoc marker */
2776
static void set_lum(struct sd *sd,
2777
u8 *data)
2778
{
2779
int avg_lum;
2780
2781
/* w0 w1 w2
2782
* w3 w4 w5
2783
* w6 w7 w8
2784
*/
2785
avg_lum = (data[27] << 8) + data[28] /* w3 */
2786
2787
+ (data[31] << 8) + data[32] /* w5 */
2788
2789
+ (data[23] << 8) + data[24] /* w1 */
2790
2791
+ (data[35] << 8) + data[36] /* w7 */
2792
2793
+ (data[29] << 10) + (data[30] << 2); /* w4 * 4 */
2794
avg_lum >>= 10;
2795
atomic_set(&sd->avg_lum, avg_lum);
2796
}
2797
2798
/* scan the URB packets */
2799
/* This function is run at interrupt level. */
2800
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2801
u8 *data, /* isoc packet */
2802
int len) /* iso packet length */
2803
{
2804
struct sd *sd = (struct sd *) gspca_dev;
2805
int i, new_qual;
2806
2807
/*
2808
* A frame ends on the marker
2809
* ff ff 00 c4 c4 96 ..
2810
* which is 62 bytes long and is followed by various information
2811
* including statuses and luminosity.
2812
*
2813
* A marker may be splitted on two packets.
2814
*
2815
* The 6th byte of a marker contains the bits:
2816
* 0x08: USB full
2817
* 0xc0: frame sequence
2818
* When the bit 'USB full' is set, the frame must be discarded;
2819
* this is also the case when the 2 bytes before the marker are
2820
* not the JPEG end of frame ('ff d9').
2821
*/
2822
2823
/*fixme: assumption about the following code:
2824
* - there can be only one marker in a packet
2825
*/
2826
2827
/* skip the remaining bytes of a short marker */
2828
i = sd->short_mark;
2829
if (i != 0) {
2830
sd->short_mark = 0;
2831
if (i < 0 /* if 'ff' at end of previous packet */
2832
&& data[0] == 0xff
2833
&& data[1] == 0x00)
2834
goto marker_found;
2835
if (data[0] == 0xff && data[1] == 0xff) {
2836
i = 0;
2837
goto marker_found;
2838
}
2839
len -= i;
2840
if (len <= 0)
2841
return;
2842
data += i;
2843
}
2844
2845
/* count the packets and their size */
2846
sd->npkt++;
2847
sd->pktsz += len;
2848
2849
/* search backwards if there is a marker in the packet */
2850
for (i = len - 1; --i >= 0; ) {
2851
if (data[i] != 0xff) {
2852
i--;
2853
continue;
2854
}
2855
if (data[i + 1] == 0xff) {
2856
2857
/* (there may be 'ff ff' inside a marker) */
2858
if (i + 2 >= len || data[i + 2] == 0x00)
2859
goto marker_found;
2860
}
2861
}
2862
2863
/* no marker found */
2864
/* add the JPEG header if first fragment */
2865
if (data[len - 1] == 0xff)
2866
sd->short_mark = -1;
2867
if (gspca_dev->last_packet_type == LAST_PACKET)
2868
gspca_frame_add(gspca_dev, FIRST_PACKET,
2869
sd->jpeg_hdr, JPEG_HDR_SZ);
2870
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2871
return;
2872
2873
/* marker found */
2874
/* if some error, discard the frame and decrease the quality */
2875
marker_found:
2876
new_qual = 0;
2877
if (i > 2) {
2878
if (data[i - 2] != 0xff || data[i - 1] != 0xd9) {
2879
gspca_dev->last_packet_type = DISCARD_PACKET;
2880
new_qual = -3;
2881
}
2882
} else if (i + 6 < len) {
2883
if (data[i + 6] & 0x08) {
2884
gspca_dev->last_packet_type = DISCARD_PACKET;
2885
new_qual = -5;
2886
}
2887
}
2888
2889
gspca_frame_add(gspca_dev, LAST_PACKET, data, i);
2890
2891
/* compute the filling rate and a new JPEG quality */
2892
if (new_qual == 0) {
2893
int r;
2894
2895
r = (sd->pktsz * 100) /
2896
(sd->npkt *
2897
gspca_dev->urb[0]->iso_frame_desc[0].length);
2898
if (r >= 85)
2899
new_qual = -3;
2900
else if (r < 75)
2901
new_qual = 2;
2902
}
2903
if (new_qual != 0) {
2904
sd->nchg += new_qual;
2905
if (sd->nchg < -6 || sd->nchg >= 12) {
2906
sd->nchg = 0;
2907
new_qual += sd->quality;
2908
if (new_qual < QUALITY_MIN)
2909
new_qual = QUALITY_MIN;
2910
else if (new_qual > QUALITY_MAX)
2911
new_qual = QUALITY_MAX;
2912
if (new_qual != sd->quality) {
2913
sd->quality = new_qual;
2914
queue_work(sd->work_thread, &sd->work);
2915
}
2916
}
2917
} else {
2918
sd->nchg = 0;
2919
}
2920
sd->pktsz = sd->npkt = 0;
2921
2922
/* if the marker is smaller than 62 bytes,
2923
* memorize the number of bytes to skip in the next packet */
2924
if (i + 62 > len) { /* no more usable data */
2925
sd->short_mark = i + 62 - len;
2926
return;
2927
}
2928
if (sd->ag_cnt >= 0)
2929
set_lum(sd, data + i);
2930
2931
/* if more data, start a new frame */
2932
i += 62;
2933
if (i < len) {
2934
data += i;
2935
len -= i;
2936
gspca_frame_add(gspca_dev, FIRST_PACKET,
2937
sd->jpeg_hdr, JPEG_HDR_SZ);
2938
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2939
}
2940
}
2941
2942
static int sd_get_jcomp(struct gspca_dev *gspca_dev,
2943
struct v4l2_jpegcompression *jcomp)
2944
{
2945
struct sd *sd = (struct sd *) gspca_dev;
2946
2947
memset(jcomp, 0, sizeof *jcomp);
2948
jcomp->quality = sd->quality;
2949
jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
2950
| V4L2_JPEG_MARKER_DQT;
2951
return 0;
2952
}
2953
2954
static int sd_querymenu(struct gspca_dev *gspca_dev,
2955
struct v4l2_querymenu *menu)
2956
{
2957
switch (menu->id) {
2958
case V4L2_CID_POWER_LINE_FREQUENCY:
2959
switch (menu->index) {
2960
case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2961
strcpy((char *) menu->name, "NoFliker");
2962
return 0;
2963
case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2964
strcpy((char *) menu->name, "50 Hz");
2965
return 0;
2966
case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2967
strcpy((char *) menu->name, "60 Hz");
2968
return 0;
2969
}
2970
break;
2971
}
2972
return -EINVAL;
2973
}
2974
2975
#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2976
static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2977
u8 *data, /* interrupt packet data */
2978
int len) /* interrupt packet length */
2979
{
2980
int ret = -EINVAL;
2981
2982
if (len == 1 && data[0] == 1) {
2983
input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2984
input_sync(gspca_dev->input_dev);
2985
input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2986
input_sync(gspca_dev->input_dev);
2987
ret = 0;
2988
}
2989
2990
return ret;
2991
}
2992
#endif
2993
2994
/* sub-driver description */
2995
static const struct sd_desc sd_desc = {
2996
.name = MODULE_NAME,
2997
.ctrls = sd_ctrls,
2998
.nctrls = NCTRLS,
2999
.config = sd_config,
3000
.init = sd_init,
3001
.start = sd_start,
3002
.stopN = sd_stopN,
3003
.stop0 = sd_stop0,
3004
.pkt_scan = sd_pkt_scan,
3005
.dq_callback = do_autogain,
3006
.get_jcomp = sd_get_jcomp,
3007
.querymenu = sd_querymenu,
3008
#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
3009
.int_pkt_scan = sd_int_pkt_scan,
3010
#endif
3011
};
3012
3013
/* -- module initialisation -- */
3014
#define BS(bridge, sensor) \
3015
.driver_info = (BRIDGE_ ## bridge << 16) \
3016
| (SENSOR_ ## sensor << 8)
3017
#define BSF(bridge, sensor, flags) \
3018
.driver_info = (BRIDGE_ ## bridge << 16) \
3019
| (SENSOR_ ## sensor << 8) \
3020
| (flags)
3021
static const struct usb_device_id device_table[] = {
3022
{USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)},
3023
{USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
3024
{USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, F_PDN_INV)},
3025
{USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, F_PDN_INV)},
3026
{USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
3027
{USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
3028
{USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
3029
{USB_DEVICE(0x06f8, 0x3004), BS(SN9C105, OV7660)},
3030
{USB_DEVICE(0x06f8, 0x3008), BS(SN9C105, OV7660)},
3031
/* {USB_DEVICE(0x0c45, 0x603a), BS(SN9C102P, OV7648)}, */
3032
{USB_DEVICE(0x0c45, 0x6040), BS(SN9C102P, HV7131R)},
3033
/* {USB_DEVICE(0x0c45, 0x607a), BS(SN9C102P, OV7648)}, */
3034
/* {USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
3035
{USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
3036
/* {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
3037
{USB_DEVICE(0x0c45, 0x60c0), BSF(SN9C105, MI0360, F_ILLUM)},
3038
/* or MT9V111 */
3039
/* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
3040
/* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
3041
/* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
3042
{USB_DEVICE(0x0c45, 0x60ce), BS(SN9C105, SP80708)},
3043
{USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)},
3044
/* {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */
3045
/* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
3046
/* {USB_DEVICE(0x0c45, 0x60f2), BS(SN9C105, OV7660)}, */
3047
{USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
3048
{USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
3049
{USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
3050
{USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/
3051
{USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)}, /* /GC0305*/
3052
/* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
3053
{USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)}, /*sn9c128*/
3054
{USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)}, /*sn9c128*/
3055
{USB_DEVICE(0x0c45, 0x610c), BS(SN9C120, HV7131R)}, /*sn9c128*/
3056
{USB_DEVICE(0x0c45, 0x610e), BS(SN9C120, OV7630)}, /*sn9c128*/
3057
/* {USB_DEVICE(0x0c45, 0x610f), BS(SN9C120, S5K53BEB)}, */
3058
/* {USB_DEVICE(0x0c45, 0x6122), BS(SN9C110, ICM105C)}, */
3059
/* {USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */
3060
{USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)}, /*sn9c325?*/
3061
/*bw600.inf:*/
3062
{USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)}, /*sn9c325?*/
3063
{USB_DEVICE(0x0c45, 0x612b), BS(SN9C110, ADCM1700)},
3064
{USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)},
3065
{USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)},
3066
/* {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */
3067
{USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)},
3068
/* or MT9V111 / MI0360B */
3069
/* {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
3070
{USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},
3071
{USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)},
3072
{USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)},
3073
{USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
3074
{USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
3075
{USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, /*sn9c120b*/
3076
/* or GC0305 / GC0307 */
3077
{USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/
3078
{USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/
3079
{USB_DEVICE(0x0c45, 0x614a), BSF(SN9C120, ADCM1700, F_ILLUM)},
3080
/* {USB_DEVICE(0x0c45, 0x614c), BS(SN9C120, GC0306)}, */ /*sn9c120b*/
3081
{}
3082
};
3083
MODULE_DEVICE_TABLE(usb, device_table);
3084
3085
/* -- device connect -- */
3086
static int sd_probe(struct usb_interface *intf,
3087
const struct usb_device_id *id)
3088
{
3089
return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
3090
THIS_MODULE);
3091
}
3092
3093
static struct usb_driver sd_driver = {
3094
.name = MODULE_NAME,
3095
.id_table = device_table,
3096
.probe = sd_probe,
3097
.disconnect = gspca_disconnect,
3098
#ifdef CONFIG_PM
3099
.suspend = gspca_suspend,
3100
.resume = gspca_resume,
3101
#endif
3102
};
3103
3104
/* -- module insert / remove -- */
3105
static int __init sd_mod_init(void)
3106
{
3107
return usb_register(&sd_driver);
3108
}
3109
static void __exit sd_mod_exit(void)
3110
{
3111
usb_deregister(&sd_driver);
3112
}
3113
3114
module_init(sd_mod_init);
3115
module_exit(sd_mod_exit);
3116
3117