Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/video/gspca/etoms.c
17633 views
1
/*
2
* Etoms Et61x151 GPL Linux driver by Michel Xhaard (09/09/2004)
3
*
4
* V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* any later version.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
*/
20
21
#define MODULE_NAME "etoms"
22
23
#include "gspca.h"
24
25
MODULE_AUTHOR("Michel Xhaard <[email protected]>");
26
MODULE_DESCRIPTION("Etoms USB Camera Driver");
27
MODULE_LICENSE("GPL");
28
29
/* specific webcam descriptor */
30
struct sd {
31
struct gspca_dev gspca_dev; /* !! must be the first item */
32
33
unsigned char brightness;
34
unsigned char contrast;
35
unsigned char colors;
36
unsigned char autogain;
37
38
char sensor;
39
#define SENSOR_PAS106 0
40
#define SENSOR_TAS5130CXX 1
41
signed char ag_cnt;
42
#define AG_CNT_START 13
43
};
44
45
/* V4L2 controls supported by the driver */
46
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
47
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
48
static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
49
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
50
static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
51
static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
52
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
53
static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
54
55
static const struct ctrl sd_ctrls[] = {
56
{
57
{
58
.id = V4L2_CID_BRIGHTNESS,
59
.type = V4L2_CTRL_TYPE_INTEGER,
60
.name = "Brightness",
61
.minimum = 1,
62
.maximum = 127,
63
.step = 1,
64
#define BRIGHTNESS_DEF 63
65
.default_value = BRIGHTNESS_DEF,
66
},
67
.set = sd_setbrightness,
68
.get = sd_getbrightness,
69
},
70
{
71
{
72
.id = V4L2_CID_CONTRAST,
73
.type = V4L2_CTRL_TYPE_INTEGER,
74
.name = "Contrast",
75
.minimum = 0,
76
.maximum = 255,
77
.step = 1,
78
#define CONTRAST_DEF 127
79
.default_value = CONTRAST_DEF,
80
},
81
.set = sd_setcontrast,
82
.get = sd_getcontrast,
83
},
84
#define COLOR_IDX 2
85
{
86
{
87
.id = V4L2_CID_SATURATION,
88
.type = V4L2_CTRL_TYPE_INTEGER,
89
.name = "Color",
90
.minimum = 0,
91
.maximum = 15,
92
.step = 1,
93
#define COLOR_DEF 7
94
.default_value = COLOR_DEF,
95
},
96
.set = sd_setcolors,
97
.get = sd_getcolors,
98
},
99
{
100
{
101
.id = V4L2_CID_AUTOGAIN,
102
.type = V4L2_CTRL_TYPE_BOOLEAN,
103
.name = "Auto Gain",
104
.minimum = 0,
105
.maximum = 1,
106
.step = 1,
107
#define AUTOGAIN_DEF 1
108
.default_value = AUTOGAIN_DEF,
109
},
110
.set = sd_setautogain,
111
.get = sd_getautogain,
112
},
113
};
114
115
static const struct v4l2_pix_format vga_mode[] = {
116
{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
117
.bytesperline = 320,
118
.sizeimage = 320 * 240,
119
.colorspace = V4L2_COLORSPACE_SRGB,
120
.priv = 1},
121
/* {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
122
.bytesperline = 640,
123
.sizeimage = 640 * 480,
124
.colorspace = V4L2_COLORSPACE_SRGB,
125
.priv = 0}, */
126
};
127
128
static const struct v4l2_pix_format sif_mode[] = {
129
{176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
130
.bytesperline = 176,
131
.sizeimage = 176 * 144,
132
.colorspace = V4L2_COLORSPACE_SRGB,
133
.priv = 1},
134
{352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
135
.bytesperline = 352,
136
.sizeimage = 352 * 288,
137
.colorspace = V4L2_COLORSPACE_SRGB,
138
.priv = 0},
139
};
140
141
#define ETOMS_ALT_SIZE_1000 12
142
143
#define ET_GPIO_DIR_CTRL 0x04 /* Control IO bit[0..5] (0 in 1 out) */
144
#define ET_GPIO_OUT 0x05 /* Only IO data */
145
#define ET_GPIO_IN 0x06 /* Read Only IO data */
146
#define ET_RESET_ALL 0x03
147
#define ET_ClCK 0x01
148
#define ET_CTRL 0x02 /* enable i2c OutClck Powerdown mode */
149
150
#define ET_COMP 0x12 /* Compression register */
151
#define ET_MAXQt 0x13
152
#define ET_MINQt 0x14
153
#define ET_COMP_VAL0 0x02
154
#define ET_COMP_VAL1 0x03
155
156
#define ET_REG1d 0x1d
157
#define ET_REG1e 0x1e
158
#define ET_REG1f 0x1f
159
#define ET_REG20 0x20
160
#define ET_REG21 0x21
161
#define ET_REG22 0x22
162
#define ET_REG23 0x23
163
#define ET_REG24 0x24
164
#define ET_REG25 0x25
165
/* base registers for luma calculation */
166
#define ET_LUMA_CENTER 0x39
167
168
#define ET_G_RED 0x4d
169
#define ET_G_GREEN1 0x4e
170
#define ET_G_BLUE 0x4f
171
#define ET_G_GREEN2 0x50
172
#define ET_G_GR_H 0x51
173
#define ET_G_GB_H 0x52
174
175
#define ET_O_RED 0x34
176
#define ET_O_GREEN1 0x35
177
#define ET_O_BLUE 0x36
178
#define ET_O_GREEN2 0x37
179
180
#define ET_SYNCHRO 0x68
181
#define ET_STARTX 0x69
182
#define ET_STARTY 0x6a
183
#define ET_WIDTH_LOW 0x6b
184
#define ET_HEIGTH_LOW 0x6c
185
#define ET_W_H_HEIGTH 0x6d
186
187
#define ET_REG6e 0x6e /* OBW */
188
#define ET_REG6f 0x6f /* OBW */
189
#define ET_REG70 0x70 /* OBW_AWB */
190
#define ET_REG71 0x71 /* OBW_AWB */
191
#define ET_REG72 0x72 /* OBW_AWB */
192
#define ET_REG73 0x73 /* Clkdelay ns */
193
#define ET_REG74 0x74 /* test pattern */
194
#define ET_REG75 0x75 /* test pattern */
195
196
#define ET_I2C_CLK 0x8c
197
#define ET_PXL_CLK 0x60
198
199
#define ET_I2C_BASE 0x89
200
#define ET_I2C_COUNT 0x8a
201
#define ET_I2C_PREFETCH 0x8b
202
#define ET_I2C_REG 0x88
203
#define ET_I2C_DATA7 0x87
204
#define ET_I2C_DATA6 0x86
205
#define ET_I2C_DATA5 0x85
206
#define ET_I2C_DATA4 0x84
207
#define ET_I2C_DATA3 0x83
208
#define ET_I2C_DATA2 0x82
209
#define ET_I2C_DATA1 0x81
210
#define ET_I2C_DATA0 0x80
211
212
#define PAS106_REG2 0x02 /* pxlClk = systemClk/(reg2) */
213
#define PAS106_REG3 0x03 /* line/frame H [11..4] */
214
#define PAS106_REG4 0x04 /* line/frame L [3..0] */
215
#define PAS106_REG5 0x05 /* exposure time line offset(default 5) */
216
#define PAS106_REG6 0x06 /* exposure time pixel offset(default 6) */
217
#define PAS106_REG7 0x07 /* signbit Dac (default 0) */
218
#define PAS106_REG9 0x09
219
#define PAS106_REG0e 0x0e /* global gain [4..0](default 0x0e) */
220
#define PAS106_REG13 0x13 /* end i2c write */
221
222
static const __u8 GainRGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
223
224
static const __u8 I2c2[] = { 0x08, 0x08, 0x08, 0x08, 0x0d };
225
226
static const __u8 I2c3[] = { 0x12, 0x05 };
227
228
static const __u8 I2c4[] = { 0x41, 0x08 };
229
230
/* read 'len' bytes to gspca_dev->usb_buf */
231
static void reg_r(struct gspca_dev *gspca_dev,
232
__u16 index,
233
__u16 len)
234
{
235
struct usb_device *dev = gspca_dev->dev;
236
237
#ifdef GSPCA_DEBUG
238
if (len > USB_BUF_SZ) {
239
err("reg_r: buffer overflow");
240
return;
241
}
242
#endif
243
usb_control_msg(dev,
244
usb_rcvctrlpipe(dev, 0),
245
0,
246
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
247
0,
248
index, gspca_dev->usb_buf, len, 500);
249
PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
250
index, gspca_dev->usb_buf[0]);
251
}
252
253
static void reg_w_val(struct gspca_dev *gspca_dev,
254
__u16 index,
255
__u8 val)
256
{
257
struct usb_device *dev = gspca_dev->dev;
258
259
gspca_dev->usb_buf[0] = val;
260
usb_control_msg(dev,
261
usb_sndctrlpipe(dev, 0),
262
0,
263
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
264
0,
265
index, gspca_dev->usb_buf, 1, 500);
266
}
267
268
static void reg_w(struct gspca_dev *gspca_dev,
269
__u16 index,
270
const __u8 *buffer,
271
__u16 len)
272
{
273
struct usb_device *dev = gspca_dev->dev;
274
275
#ifdef GSPCA_DEBUG
276
if (len > USB_BUF_SZ) {
277
err("reg_w: buffer overflow");
278
return;
279
}
280
PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
281
#endif
282
memcpy(gspca_dev->usb_buf, buffer, len);
283
usb_control_msg(dev,
284
usb_sndctrlpipe(dev, 0),
285
0,
286
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
287
0, index, gspca_dev->usb_buf, len, 500);
288
}
289
290
static int i2c_w(struct gspca_dev *gspca_dev,
291
__u8 reg,
292
const __u8 *buffer,
293
int len, __u8 mode)
294
{
295
/* buffer should be [D0..D7] */
296
__u8 ptchcount;
297
298
/* set the base address */
299
reg_w_val(gspca_dev, ET_I2C_BASE, 0x40);
300
/* sensor base for the pas106 */
301
/* set count and prefetch */
302
ptchcount = ((len & 0x07) << 4) | (mode & 0x03);
303
reg_w_val(gspca_dev, ET_I2C_COUNT, ptchcount);
304
/* set the register base */
305
reg_w_val(gspca_dev, ET_I2C_REG, reg);
306
while (--len >= 0)
307
reg_w_val(gspca_dev, ET_I2C_DATA0 + len, buffer[len]);
308
return 0;
309
}
310
311
static int i2c_r(struct gspca_dev *gspca_dev,
312
__u8 reg)
313
{
314
/* set the base address */
315
reg_w_val(gspca_dev, ET_I2C_BASE, 0x40);
316
/* sensor base for the pas106 */
317
/* set count and prefetch (cnd: 4 bits - mode: 4 bits) */
318
reg_w_val(gspca_dev, ET_I2C_COUNT, 0x11);
319
reg_w_val(gspca_dev, ET_I2C_REG, reg); /* set the register base */
320
reg_w_val(gspca_dev, ET_I2C_PREFETCH, 0x02); /* prefetch */
321
reg_w_val(gspca_dev, ET_I2C_PREFETCH, 0x00);
322
reg_r(gspca_dev, ET_I2C_DATA0, 1); /* read one byte */
323
return 0;
324
}
325
326
static int Et_WaitStatus(struct gspca_dev *gspca_dev)
327
{
328
int retry = 10;
329
330
while (retry--) {
331
reg_r(gspca_dev, ET_ClCK, 1);
332
if (gspca_dev->usb_buf[0] != 0)
333
return 1;
334
}
335
return 0;
336
}
337
338
static int et_video(struct gspca_dev *gspca_dev,
339
int on)
340
{
341
int ret;
342
343
reg_w_val(gspca_dev, ET_GPIO_OUT,
344
on ? 0x10 /* startvideo - set Bit5 */
345
: 0); /* stopvideo */
346
ret = Et_WaitStatus(gspca_dev);
347
if (ret != 0)
348
PDEBUG(D_ERR, "timeout video on/off");
349
return ret;
350
}
351
352
static void Et_init2(struct gspca_dev *gspca_dev)
353
{
354
__u8 value;
355
static const __u8 FormLine[] = { 0x84, 0x03, 0x14, 0xf4, 0x01, 0x05 };
356
357
PDEBUG(D_STREAM, "Open Init2 ET");
358
reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 0x2f);
359
reg_w_val(gspca_dev, ET_GPIO_OUT, 0x10);
360
reg_r(gspca_dev, ET_GPIO_IN, 1);
361
reg_w_val(gspca_dev, ET_ClCK, 0x14); /* 0x14 // 0x16 enabled pattern */
362
reg_w_val(gspca_dev, ET_CTRL, 0x1b);
363
364
/* compression et subsampling */
365
if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv)
366
value = ET_COMP_VAL1; /* 320 */
367
else
368
value = ET_COMP_VAL0; /* 640 */
369
reg_w_val(gspca_dev, ET_COMP, value);
370
reg_w_val(gspca_dev, ET_MAXQt, 0x1f);
371
reg_w_val(gspca_dev, ET_MINQt, 0x04);
372
/* undocumented registers */
373
reg_w_val(gspca_dev, ET_REG1d, 0xff);
374
reg_w_val(gspca_dev, ET_REG1e, 0xff);
375
reg_w_val(gspca_dev, ET_REG1f, 0xff);
376
reg_w_val(gspca_dev, ET_REG20, 0x35);
377
reg_w_val(gspca_dev, ET_REG21, 0x01);
378
reg_w_val(gspca_dev, ET_REG22, 0x00);
379
reg_w_val(gspca_dev, ET_REG23, 0xff);
380
reg_w_val(gspca_dev, ET_REG24, 0xff);
381
reg_w_val(gspca_dev, ET_REG25, 0x0f);
382
/* colors setting */
383
reg_w_val(gspca_dev, 0x30, 0x11); /* 0x30 */
384
reg_w_val(gspca_dev, 0x31, 0x40);
385
reg_w_val(gspca_dev, 0x32, 0x00);
386
reg_w_val(gspca_dev, ET_O_RED, 0x00); /* 0x34 */
387
reg_w_val(gspca_dev, ET_O_GREEN1, 0x00);
388
reg_w_val(gspca_dev, ET_O_BLUE, 0x00);
389
reg_w_val(gspca_dev, ET_O_GREEN2, 0x00);
390
/*************/
391
reg_w_val(gspca_dev, ET_G_RED, 0x80); /* 0x4d */
392
reg_w_val(gspca_dev, ET_G_GREEN1, 0x80);
393
reg_w_val(gspca_dev, ET_G_BLUE, 0x80);
394
reg_w_val(gspca_dev, ET_G_GREEN2, 0x80);
395
reg_w_val(gspca_dev, ET_G_GR_H, 0x00);
396
reg_w_val(gspca_dev, ET_G_GB_H, 0x00); /* 0x52 */
397
/* Window control registers */
398
reg_w_val(gspca_dev, 0x61, 0x80); /* use cmc_out */
399
reg_w_val(gspca_dev, 0x62, 0x02);
400
reg_w_val(gspca_dev, 0x63, 0x03);
401
reg_w_val(gspca_dev, 0x64, 0x14);
402
reg_w_val(gspca_dev, 0x65, 0x0e);
403
reg_w_val(gspca_dev, 0x66, 0x02);
404
reg_w_val(gspca_dev, 0x67, 0x02);
405
406
/**************************************/
407
reg_w_val(gspca_dev, ET_SYNCHRO, 0x8f); /* 0x68 */
408
reg_w_val(gspca_dev, ET_STARTX, 0x69); /* 0x6a //0x69 */
409
reg_w_val(gspca_dev, ET_STARTY, 0x0d); /* 0x0d //0x0c */
410
reg_w_val(gspca_dev, ET_WIDTH_LOW, 0x80);
411
reg_w_val(gspca_dev, ET_HEIGTH_LOW, 0xe0);
412
reg_w_val(gspca_dev, ET_W_H_HEIGTH, 0x60); /* 6d */
413
reg_w_val(gspca_dev, ET_REG6e, 0x86);
414
reg_w_val(gspca_dev, ET_REG6f, 0x01);
415
reg_w_val(gspca_dev, ET_REG70, 0x26);
416
reg_w_val(gspca_dev, ET_REG71, 0x7a);
417
reg_w_val(gspca_dev, ET_REG72, 0x01);
418
/* Clock Pattern registers ***************** */
419
reg_w_val(gspca_dev, ET_REG73, 0x00);
420
reg_w_val(gspca_dev, ET_REG74, 0x18); /* 0x28 */
421
reg_w_val(gspca_dev, ET_REG75, 0x0f); /* 0x01 */
422
/**********************************************/
423
reg_w_val(gspca_dev, 0x8a, 0x20);
424
reg_w_val(gspca_dev, 0x8d, 0x0f);
425
reg_w_val(gspca_dev, 0x8e, 0x08);
426
/**************************************/
427
reg_w_val(gspca_dev, 0x03, 0x08);
428
reg_w_val(gspca_dev, ET_PXL_CLK, 0x03);
429
reg_w_val(gspca_dev, 0x81, 0xff);
430
reg_w_val(gspca_dev, 0x80, 0x00);
431
reg_w_val(gspca_dev, 0x81, 0xff);
432
reg_w_val(gspca_dev, 0x80, 0x20);
433
reg_w_val(gspca_dev, 0x03, 0x01);
434
reg_w_val(gspca_dev, 0x03, 0x00);
435
reg_w_val(gspca_dev, 0x03, 0x08);
436
/********************************************/
437
438
/* reg_r(gspca_dev, ET_I2C_BASE, 1);
439
always 0x40 as the pas106 ??? */
440
/* set the sensor */
441
if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv)
442
value = 0x04; /* 320 */
443
else /* 640 */
444
value = 0x1e; /* 0x17 * setting PixelClock
445
* 0x03 mean 24/(3+1) = 6 Mhz
446
* 0x05 -> 24/(5+1) = 4 Mhz
447
* 0x0b -> 24/(11+1) = 2 Mhz
448
* 0x17 -> 24/(23+1) = 1 Mhz
449
*/
450
reg_w_val(gspca_dev, ET_PXL_CLK, value);
451
/* now set by fifo the FormatLine setting */
452
reg_w(gspca_dev, 0x62, FormLine, 6);
453
454
/* set exposure times [ 0..0x78] 0->longvalue 0x78->shortvalue */
455
reg_w_val(gspca_dev, 0x81, 0x47); /* 0x47; */
456
reg_w_val(gspca_dev, 0x80, 0x40); /* 0x40; */
457
/* Pedro change */
458
/* Brightness change Brith+ decrease value */
459
/* Brigth- increase value */
460
/* original value = 0x70; */
461
reg_w_val(gspca_dev, 0x81, 0x30); /* 0x20; - set brightness */
462
reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */
463
}
464
465
static void setbrightness(struct gspca_dev *gspca_dev)
466
{
467
struct sd *sd = (struct sd *) gspca_dev;
468
int i;
469
__u8 brightness = sd->brightness;
470
471
for (i = 0; i < 4; i++)
472
reg_w_val(gspca_dev, ET_O_RED + i, brightness);
473
}
474
475
static void setcontrast(struct gspca_dev *gspca_dev)
476
{
477
struct sd *sd = (struct sd *) gspca_dev;
478
__u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
479
__u8 contrast = sd->contrast;
480
481
memset(RGBG, contrast, sizeof(RGBG) - 2);
482
reg_w(gspca_dev, ET_G_RED, RGBG, 6);
483
}
484
485
static void setcolors(struct gspca_dev *gspca_dev)
486
{
487
struct sd *sd = (struct sd *) gspca_dev;
488
__u8 I2cc[] = { 0x05, 0x02, 0x02, 0x05, 0x0d };
489
__u8 i2cflags = 0x01;
490
/* __u8 green = 0; */
491
__u8 colors = sd->colors;
492
493
I2cc[3] = colors; /* red */
494
I2cc[0] = 15 - colors; /* blue */
495
/* green = 15 - ((((7*I2cc[0]) >> 2 ) + I2cc[3]) >> 1); */
496
/* I2cc[1] = I2cc[2] = green; */
497
if (sd->sensor == SENSOR_PAS106) {
498
i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3);
499
i2c_w(gspca_dev, PAS106_REG9, I2cc, sizeof I2cc, 1);
500
}
501
/* PDEBUG(D_CONF , "Etoms red %d blue %d green %d",
502
I2cc[3], I2cc[0], green); */
503
}
504
505
static void getcolors(struct gspca_dev *gspca_dev)
506
{
507
struct sd *sd = (struct sd *) gspca_dev;
508
509
if (sd->sensor == SENSOR_PAS106) {
510
/* i2c_r(gspca_dev, PAS106_REG9); * blue */
511
i2c_r(gspca_dev, PAS106_REG9 + 3); /* red */
512
sd->colors = gspca_dev->usb_buf[0] & 0x0f;
513
}
514
}
515
516
static void setautogain(struct gspca_dev *gspca_dev)
517
{
518
struct sd *sd = (struct sd *) gspca_dev;
519
520
if (sd->autogain)
521
sd->ag_cnt = AG_CNT_START;
522
else
523
sd->ag_cnt = -1;
524
}
525
526
static void Et_init1(struct gspca_dev *gspca_dev)
527
{
528
__u8 value;
529
/* __u8 I2c0 [] = {0x0a, 0x12, 0x05, 0x22, 0xac, 0x00, 0x01, 0x00}; */
530
__u8 I2c0[] = { 0x0a, 0x12, 0x05, 0x6d, 0xcd, 0x00, 0x01, 0x00 };
531
/* try 1/120 0x6d 0xcd 0x40 */
532
/* __u8 I2c0 [] = {0x0a, 0x12, 0x05, 0xfe, 0xfe, 0xc0, 0x01, 0x00};
533
* 1/60000 hmm ?? */
534
535
PDEBUG(D_STREAM, "Open Init1 ET");
536
reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 7);
537
reg_r(gspca_dev, ET_GPIO_IN, 1);
538
reg_w_val(gspca_dev, ET_RESET_ALL, 1);
539
reg_w_val(gspca_dev, ET_RESET_ALL, 0);
540
reg_w_val(gspca_dev, ET_ClCK, 0x10);
541
reg_w_val(gspca_dev, ET_CTRL, 0x19);
542
/* compression et subsampling */
543
if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv)
544
value = ET_COMP_VAL1;
545
else
546
value = ET_COMP_VAL0;
547
PDEBUG(D_STREAM, "Open mode %d Compression %d",
548
gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv,
549
value);
550
reg_w_val(gspca_dev, ET_COMP, value);
551
reg_w_val(gspca_dev, ET_MAXQt, 0x1d);
552
reg_w_val(gspca_dev, ET_MINQt, 0x02);
553
/* undocumented registers */
554
reg_w_val(gspca_dev, ET_REG1d, 0xff);
555
reg_w_val(gspca_dev, ET_REG1e, 0xff);
556
reg_w_val(gspca_dev, ET_REG1f, 0xff);
557
reg_w_val(gspca_dev, ET_REG20, 0x35);
558
reg_w_val(gspca_dev, ET_REG21, 0x01);
559
reg_w_val(gspca_dev, ET_REG22, 0x00);
560
reg_w_val(gspca_dev, ET_REG23, 0xf7);
561
reg_w_val(gspca_dev, ET_REG24, 0xff);
562
reg_w_val(gspca_dev, ET_REG25, 0x07);
563
/* colors setting */
564
reg_w_val(gspca_dev, ET_G_RED, 0x80);
565
reg_w_val(gspca_dev, ET_G_GREEN1, 0x80);
566
reg_w_val(gspca_dev, ET_G_BLUE, 0x80);
567
reg_w_val(gspca_dev, ET_G_GREEN2, 0x80);
568
reg_w_val(gspca_dev, ET_G_GR_H, 0x00);
569
reg_w_val(gspca_dev, ET_G_GB_H, 0x00);
570
/* Window control registers */
571
reg_w_val(gspca_dev, ET_SYNCHRO, 0xf0);
572
reg_w_val(gspca_dev, ET_STARTX, 0x56); /* 0x56 */
573
reg_w_val(gspca_dev, ET_STARTY, 0x05); /* 0x04 */
574
reg_w_val(gspca_dev, ET_WIDTH_LOW, 0x60);
575
reg_w_val(gspca_dev, ET_HEIGTH_LOW, 0x20);
576
reg_w_val(gspca_dev, ET_W_H_HEIGTH, 0x50);
577
reg_w_val(gspca_dev, ET_REG6e, 0x86);
578
reg_w_val(gspca_dev, ET_REG6f, 0x01);
579
reg_w_val(gspca_dev, ET_REG70, 0x86);
580
reg_w_val(gspca_dev, ET_REG71, 0x14);
581
reg_w_val(gspca_dev, ET_REG72, 0x00);
582
/* Clock Pattern registers */
583
reg_w_val(gspca_dev, ET_REG73, 0x00);
584
reg_w_val(gspca_dev, ET_REG74, 0x00);
585
reg_w_val(gspca_dev, ET_REG75, 0x0a);
586
reg_w_val(gspca_dev, ET_I2C_CLK, 0x04);
587
reg_w_val(gspca_dev, ET_PXL_CLK, 0x01);
588
/* set the sensor */
589
if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
590
I2c0[0] = 0x06;
591
i2c_w(gspca_dev, PAS106_REG2, I2c0, sizeof I2c0, 1);
592
i2c_w(gspca_dev, PAS106_REG9, I2c2, sizeof I2c2, 1);
593
value = 0x06;
594
i2c_w(gspca_dev, PAS106_REG2, &value, 1, 1);
595
i2c_w(gspca_dev, PAS106_REG3, I2c3, sizeof I2c3, 1);
596
/* value = 0x1f; */
597
value = 0x04;
598
i2c_w(gspca_dev, PAS106_REG0e, &value, 1, 1);
599
} else {
600
I2c0[0] = 0x0a;
601
602
i2c_w(gspca_dev, PAS106_REG2, I2c0, sizeof I2c0, 1);
603
i2c_w(gspca_dev, PAS106_REG9, I2c2, sizeof I2c2, 1);
604
value = 0x0a;
605
i2c_w(gspca_dev, PAS106_REG2, &value, 1, 1);
606
i2c_w(gspca_dev, PAS106_REG3, I2c3, sizeof I2c3, 1);
607
value = 0x04;
608
/* value = 0x10; */
609
i2c_w(gspca_dev, PAS106_REG0e, &value, 1, 1);
610
/* bit 2 enable bit 1:2 select 0 1 2 3
611
value = 0x07; * curve 0 *
612
i2c_w(gspca_dev, PAS106_REG0f, &value, 1, 1);
613
*/
614
}
615
616
/* value = 0x01; */
617
/* value = 0x22; */
618
/* i2c_w(gspca_dev, PAS106_REG5, &value, 1, 1); */
619
/* magnetude and sign bit for DAC */
620
i2c_w(gspca_dev, PAS106_REG7, I2c4, sizeof I2c4, 1);
621
/* now set by fifo the whole colors setting */
622
reg_w(gspca_dev, ET_G_RED, GainRGBG, 6);
623
getcolors(gspca_dev);
624
setcolors(gspca_dev);
625
}
626
627
/* this function is called at probe time */
628
static int sd_config(struct gspca_dev *gspca_dev,
629
const struct usb_device_id *id)
630
{
631
struct sd *sd = (struct sd *) gspca_dev;
632
struct cam *cam;
633
634
cam = &gspca_dev->cam;
635
sd->sensor = id->driver_info;
636
if (sd->sensor == SENSOR_PAS106) {
637
cam->cam_mode = sif_mode;
638
cam->nmodes = ARRAY_SIZE(sif_mode);
639
} else {
640
cam->cam_mode = vga_mode;
641
cam->nmodes = ARRAY_SIZE(vga_mode);
642
gspca_dev->ctrl_dis = (1 << COLOR_IDX);
643
}
644
sd->brightness = BRIGHTNESS_DEF;
645
sd->contrast = CONTRAST_DEF;
646
sd->colors = COLOR_DEF;
647
sd->autogain = AUTOGAIN_DEF;
648
sd->ag_cnt = -1;
649
return 0;
650
}
651
652
/* this function is called at probe and resume time */
653
static int sd_init(struct gspca_dev *gspca_dev)
654
{
655
struct sd *sd = (struct sd *) gspca_dev;
656
657
if (sd->sensor == SENSOR_PAS106)
658
Et_init1(gspca_dev);
659
else
660
Et_init2(gspca_dev);
661
reg_w_val(gspca_dev, ET_RESET_ALL, 0x08);
662
et_video(gspca_dev, 0); /* video off */
663
return 0;
664
}
665
666
/* -- start the camera -- */
667
static int sd_start(struct gspca_dev *gspca_dev)
668
{
669
struct sd *sd = (struct sd *) gspca_dev;
670
671
if (sd->sensor == SENSOR_PAS106)
672
Et_init1(gspca_dev);
673
else
674
Et_init2(gspca_dev);
675
676
setautogain(gspca_dev);
677
678
reg_w_val(gspca_dev, ET_RESET_ALL, 0x08);
679
et_video(gspca_dev, 1); /* video on */
680
return 0;
681
}
682
683
static void sd_stopN(struct gspca_dev *gspca_dev)
684
{
685
et_video(gspca_dev, 0); /* video off */
686
}
687
688
static __u8 Et_getgainG(struct gspca_dev *gspca_dev)
689
{
690
struct sd *sd = (struct sd *) gspca_dev;
691
692
if (sd->sensor == SENSOR_PAS106) {
693
i2c_r(gspca_dev, PAS106_REG0e);
694
PDEBUG(D_CONF, "Etoms gain G %d", gspca_dev->usb_buf[0]);
695
return gspca_dev->usb_buf[0];
696
}
697
return 0x1f;
698
}
699
700
static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain)
701
{
702
struct sd *sd = (struct sd *) gspca_dev;
703
704
if (sd->sensor == SENSOR_PAS106) {
705
__u8 i2cflags = 0x01;
706
707
i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3);
708
i2c_w(gspca_dev, PAS106_REG0e, &gain, 1, 1);
709
}
710
}
711
712
#define BLIMIT(bright) \
713
(u8)((bright > 0x1f) ? 0x1f : ((bright < 4) ? 3 : bright))
714
#define LIMIT(color) \
715
(u8)((color > 0xff) ? 0xff : ((color < 0) ? 0 : color))
716
717
static void do_autogain(struct gspca_dev *gspca_dev)
718
{
719
struct sd *sd = (struct sd *) gspca_dev;
720
__u8 luma;
721
__u8 luma_mean = 128;
722
__u8 luma_delta = 20;
723
__u8 spring = 4;
724
int Gbright;
725
__u8 r, g, b;
726
727
if (sd->ag_cnt < 0)
728
return;
729
if (--sd->ag_cnt >= 0)
730
return;
731
sd->ag_cnt = AG_CNT_START;
732
733
Gbright = Et_getgainG(gspca_dev);
734
reg_r(gspca_dev, ET_LUMA_CENTER, 4);
735
g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1;
736
r = gspca_dev->usb_buf[1];
737
b = gspca_dev->usb_buf[2];
738
r = ((r << 8) - (r << 4) - (r << 3)) >> 10;
739
b = ((b << 7) >> 10);
740
g = ((g << 9) + (g << 7) + (g << 5)) >> 10;
741
luma = LIMIT(r + g + b);
742
PDEBUG(D_FRAM, "Etoms luma G %d", luma);
743
if (luma < luma_mean - luma_delta || luma > luma_mean + luma_delta) {
744
Gbright += (luma_mean - luma) >> spring;
745
Gbright = BLIMIT(Gbright);
746
PDEBUG(D_FRAM, "Etoms Gbright %d", Gbright);
747
Et_setgainG(gspca_dev, (__u8) Gbright);
748
}
749
}
750
751
#undef BLIMIT
752
#undef LIMIT
753
754
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
755
u8 *data, /* isoc packet */
756
int len) /* iso packet length */
757
{
758
int seqframe;
759
760
seqframe = data[0] & 0x3f;
761
len = (int) (((data[0] & 0xc0) << 2) | data[1]);
762
if (seqframe == 0x3f) {
763
PDEBUG(D_FRAM,
764
"header packet found datalength %d !!", len);
765
PDEBUG(D_FRAM, "G %d R %d G %d B %d",
766
data[2], data[3], data[4], data[5]);
767
data += 30;
768
/* don't change datalength as the chips provided it */
769
gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
770
gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
771
return;
772
}
773
if (len) {
774
data += 8;
775
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
776
} else { /* Drop Packet */
777
gspca_dev->last_packet_type = DISCARD_PACKET;
778
}
779
}
780
781
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
782
{
783
struct sd *sd = (struct sd *) gspca_dev;
784
785
sd->brightness = val;
786
if (gspca_dev->streaming)
787
setbrightness(gspca_dev);
788
return 0;
789
}
790
791
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
792
{
793
struct sd *sd = (struct sd *) gspca_dev;
794
795
*val = sd->brightness;
796
return 0;
797
}
798
799
static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
800
{
801
struct sd *sd = (struct sd *) gspca_dev;
802
803
sd->contrast = val;
804
if (gspca_dev->streaming)
805
setcontrast(gspca_dev);
806
return 0;
807
}
808
809
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
810
{
811
struct sd *sd = (struct sd *) gspca_dev;
812
813
*val = sd->contrast;
814
return 0;
815
}
816
817
static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
818
{
819
struct sd *sd = (struct sd *) gspca_dev;
820
821
sd->colors = val;
822
if (gspca_dev->streaming)
823
setcolors(gspca_dev);
824
return 0;
825
}
826
827
static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
828
{
829
struct sd *sd = (struct sd *) gspca_dev;
830
831
*val = sd->colors;
832
return 0;
833
}
834
835
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
836
{
837
struct sd *sd = (struct sd *) gspca_dev;
838
839
sd->autogain = val;
840
if (gspca_dev->streaming)
841
setautogain(gspca_dev);
842
return 0;
843
}
844
845
static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
846
{
847
struct sd *sd = (struct sd *) gspca_dev;
848
849
*val = sd->autogain;
850
return 0;
851
}
852
853
/* sub-driver description */
854
static const struct sd_desc sd_desc = {
855
.name = MODULE_NAME,
856
.ctrls = sd_ctrls,
857
.nctrls = ARRAY_SIZE(sd_ctrls),
858
.config = sd_config,
859
.init = sd_init,
860
.start = sd_start,
861
.stopN = sd_stopN,
862
.pkt_scan = sd_pkt_scan,
863
.dq_callback = do_autogain,
864
};
865
866
/* -- module initialisation -- */
867
static const struct usb_device_id device_table[] = {
868
{USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106},
869
#if !defined CONFIG_USB_ET61X251 && !defined CONFIG_USB_ET61X251_MODULE
870
{USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX},
871
#endif
872
{}
873
};
874
875
MODULE_DEVICE_TABLE(usb, device_table);
876
877
/* -- device connect -- */
878
static int sd_probe(struct usb_interface *intf,
879
const struct usb_device_id *id)
880
{
881
return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
882
THIS_MODULE);
883
}
884
885
static struct usb_driver sd_driver = {
886
.name = MODULE_NAME,
887
.id_table = device_table,
888
.probe = sd_probe,
889
.disconnect = gspca_disconnect,
890
#ifdef CONFIG_PM
891
.suspend = gspca_suspend,
892
.resume = gspca_resume,
893
#endif
894
};
895
896
/* -- module insert / remove -- */
897
static int __init sd_mod_init(void)
898
{
899
return usb_register(&sd_driver);
900
}
901
902
static void __exit sd_mod_exit(void)
903
{
904
usb_deregister(&sd_driver);
905
}
906
907
module_init(sd_mod_init);
908
module_exit(sd_mod_exit);
909
910