Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/video/gspca/conex.c
17602 views
1
/*
2
* Connexant Cx11646 library
3
* Copyright (C) 2004 Michel Xhaard [email protected]
4
*
5
* V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
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 "conex"
23
24
#include "gspca.h"
25
#define CONEX_CAM 1 /* special JPEG header */
26
#include "jpeg.h"
27
28
MODULE_AUTHOR("Michel Xhaard <[email protected]>");
29
MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver");
30
MODULE_LICENSE("GPL");
31
32
/* specific webcam descriptor */
33
struct sd {
34
struct gspca_dev gspca_dev; /* !! must be the first item */
35
36
unsigned char brightness;
37
unsigned char contrast;
38
unsigned char colors;
39
u8 quality;
40
#define QUALITY_MIN 30
41
#define QUALITY_MAX 60
42
#define QUALITY_DEF 40
43
44
u8 jpeg_hdr[JPEG_HDR_SZ];
45
};
46
47
/* V4L2 controls supported by the driver */
48
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
49
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
50
static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
51
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
52
static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
53
static int sd_getcolors(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 = 0,
62
.maximum = 255,
63
.step = 1,
64
#define BRIGHTNESS_DEF 0xd4
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 = 0x0a,
76
.maximum = 0x1f,
77
.step = 1,
78
#define CONTRAST_DEF 0x0c
79
.default_value = CONTRAST_DEF,
80
},
81
.set = sd_setcontrast,
82
.get = sd_getcontrast,
83
},
84
{
85
{
86
.id = V4L2_CID_SATURATION,
87
.type = V4L2_CTRL_TYPE_INTEGER,
88
.name = "Color",
89
.minimum = 0,
90
.maximum = 7,
91
.step = 1,
92
#define COLOR_DEF 3
93
.default_value = COLOR_DEF,
94
},
95
.set = sd_setcolors,
96
.get = sd_getcolors,
97
},
98
};
99
100
static const struct v4l2_pix_format vga_mode[] = {
101
{176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
102
.bytesperline = 176,
103
.sizeimage = 176 * 144 * 3 / 8 + 590,
104
.colorspace = V4L2_COLORSPACE_JPEG,
105
.priv = 3},
106
{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
107
.bytesperline = 320,
108
.sizeimage = 320 * 240 * 3 / 8 + 590,
109
.colorspace = V4L2_COLORSPACE_JPEG,
110
.priv = 2},
111
{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
112
.bytesperline = 352,
113
.sizeimage = 352 * 288 * 3 / 8 + 590,
114
.colorspace = V4L2_COLORSPACE_JPEG,
115
.priv = 1},
116
{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
117
.bytesperline = 640,
118
.sizeimage = 640 * 480 * 3 / 8 + 590,
119
.colorspace = V4L2_COLORSPACE_JPEG,
120
.priv = 0},
121
};
122
123
/* the read bytes are found in gspca_dev->usb_buf */
124
static void reg_r(struct gspca_dev *gspca_dev,
125
__u16 index,
126
__u16 len)
127
{
128
struct usb_device *dev = gspca_dev->dev;
129
130
#ifdef GSPCA_DEBUG
131
if (len > USB_BUF_SZ) {
132
err("reg_r: buffer overflow");
133
return;
134
}
135
#endif
136
usb_control_msg(dev,
137
usb_rcvctrlpipe(dev, 0),
138
0,
139
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
140
0,
141
index, gspca_dev->usb_buf, len,
142
500);
143
PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
144
index, gspca_dev->usb_buf[0]);
145
}
146
147
/* the bytes to write are in gspca_dev->usb_buf */
148
static void reg_w_val(struct gspca_dev *gspca_dev,
149
__u16 index,
150
__u8 val)
151
{
152
struct usb_device *dev = gspca_dev->dev;
153
154
gspca_dev->usb_buf[0] = val;
155
usb_control_msg(dev,
156
usb_sndctrlpipe(dev, 0),
157
0,
158
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
159
0,
160
index, gspca_dev->usb_buf, 1, 500);
161
}
162
163
static void reg_w(struct gspca_dev *gspca_dev,
164
__u16 index,
165
const __u8 *buffer,
166
__u16 len)
167
{
168
struct usb_device *dev = gspca_dev->dev;
169
170
#ifdef GSPCA_DEBUG
171
if (len > USB_BUF_SZ) {
172
err("reg_w: buffer overflow");
173
return;
174
}
175
PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
176
#endif
177
memcpy(gspca_dev->usb_buf, buffer, len);
178
usb_control_msg(dev,
179
usb_sndctrlpipe(dev, 0),
180
0,
181
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
182
0,
183
index, gspca_dev->usb_buf, len, 500);
184
}
185
186
static const __u8 cx_sensor_init[][4] = {
187
{0x88, 0x11, 0x01, 0x01},
188
{0x88, 0x12, 0x70, 0x01},
189
{0x88, 0x0f, 0x00, 0x01},
190
{0x88, 0x05, 0x01, 0x01},
191
{}
192
};
193
194
static const __u8 cx11646_fw1[][3] = {
195
{0x00, 0x02, 0x00},
196
{0x01, 0x43, 0x00},
197
{0x02, 0xA7, 0x00},
198
{0x03, 0x8B, 0x01},
199
{0x04, 0xE9, 0x02},
200
{0x05, 0x08, 0x04},
201
{0x06, 0x08, 0x05},
202
{0x07, 0x07, 0x06},
203
{0x08, 0xE7, 0x06},
204
{0x09, 0xC6, 0x07},
205
{0x0A, 0x86, 0x08},
206
{0x0B, 0x46, 0x09},
207
{0x0C, 0x05, 0x0A},
208
{0x0D, 0xA5, 0x0A},
209
{0x0E, 0x45, 0x0B},
210
{0x0F, 0xE5, 0x0B},
211
{0x10, 0x85, 0x0C},
212
{0x11, 0x25, 0x0D},
213
{0x12, 0xC4, 0x0D},
214
{0x13, 0x45, 0x0E},
215
{0x14, 0xE4, 0x0E},
216
{0x15, 0x64, 0x0F},
217
{0x16, 0xE4, 0x0F},
218
{0x17, 0x64, 0x10},
219
{0x18, 0xE4, 0x10},
220
{0x19, 0x64, 0x11},
221
{0x1A, 0xE4, 0x11},
222
{0x1B, 0x64, 0x12},
223
{0x1C, 0xE3, 0x12},
224
{0x1D, 0x44, 0x13},
225
{0x1E, 0xC3, 0x13},
226
{0x1F, 0x24, 0x14},
227
{0x20, 0xA3, 0x14},
228
{0x21, 0x04, 0x15},
229
{0x22, 0x83, 0x15},
230
{0x23, 0xE3, 0x15},
231
{0x24, 0x43, 0x16},
232
{0x25, 0xA4, 0x16},
233
{0x26, 0x23, 0x17},
234
{0x27, 0x83, 0x17},
235
{0x28, 0xE3, 0x17},
236
{0x29, 0x43, 0x18},
237
{0x2A, 0xA3, 0x18},
238
{0x2B, 0x03, 0x19},
239
{0x2C, 0x63, 0x19},
240
{0x2D, 0xC3, 0x19},
241
{0x2E, 0x22, 0x1A},
242
{0x2F, 0x63, 0x1A},
243
{0x30, 0xC3, 0x1A},
244
{0x31, 0x23, 0x1B},
245
{0x32, 0x83, 0x1B},
246
{0x33, 0xE2, 0x1B},
247
{0x34, 0x23, 0x1C},
248
{0x35, 0x83, 0x1C},
249
{0x36, 0xE2, 0x1C},
250
{0x37, 0x23, 0x1D},
251
{0x38, 0x83, 0x1D},
252
{0x39, 0xE2, 0x1D},
253
{0x3A, 0x23, 0x1E},
254
{0x3B, 0x82, 0x1E},
255
{0x3C, 0xC3, 0x1E},
256
{0x3D, 0x22, 0x1F},
257
{0x3E, 0x63, 0x1F},
258
{0x3F, 0xC1, 0x1F},
259
{}
260
};
261
static void cx11646_fw(struct gspca_dev*gspca_dev)
262
{
263
int i = 0;
264
265
reg_w_val(gspca_dev, 0x006a, 0x02);
266
while (cx11646_fw1[i][1]) {
267
reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3);
268
i++;
269
}
270
reg_w_val(gspca_dev, 0x006a, 0x00);
271
}
272
273
static const __u8 cxsensor[] = {
274
0x88, 0x12, 0x70, 0x01,
275
0x88, 0x0d, 0x02, 0x01,
276
0x88, 0x0f, 0x00, 0x01,
277
0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
278
0x88, 0x02, 0x10, 0x01,
279
0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
280
0x88, 0x0B, 0x00, 0x01,
281
0x88, 0x0A, 0x0A, 0x01,
282
0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
283
0x88, 0x05, 0x01, 0x01,
284
0xA1, 0x18, 0x00, 0x01,
285
0x00
286
};
287
288
static const __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
289
static const __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
290
static const __u8 reg10[] = { 0xb1, 0xb1 };
291
static const __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */
292
static const __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f };
293
/* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
294
static const __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 };
295
/* 320{0x04,0x0c,0x05,0x0f}; //320 */
296
static const __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
297
static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
298
299
static void cx_sensor(struct gspca_dev*gspca_dev)
300
{
301
int i = 0;
302
int length;
303
const __u8 *ptsensor = cxsensor;
304
305
reg_w(gspca_dev, 0x0020, reg20, 8);
306
reg_w(gspca_dev, 0x0028, reg28, 8);
307
reg_w(gspca_dev, 0x0010, reg10, 8);
308
reg_w_val(gspca_dev, 0x0092, 0x03);
309
310
switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
311
case 0:
312
reg_w(gspca_dev, 0x0071, reg71a, 4);
313
break;
314
case 1:
315
reg_w(gspca_dev, 0x0071, reg71b, 4);
316
break;
317
default:
318
/* case 2: */
319
reg_w(gspca_dev, 0x0071, reg71c, 4);
320
break;
321
case 3:
322
reg_w(gspca_dev, 0x0071, reg71d, 4);
323
break;
324
}
325
reg_w(gspca_dev, 0x007b, reg7b, 6);
326
reg_w_val(gspca_dev, 0x00f8, 0x00);
327
reg_w(gspca_dev, 0x0010, reg10, 8);
328
reg_w_val(gspca_dev, 0x0098, 0x41);
329
for (i = 0; i < 11; i++) {
330
if (i == 3 || i == 5 || i == 8)
331
length = 8;
332
else
333
length = 4;
334
reg_w(gspca_dev, 0x00e5, ptsensor, length);
335
if (length == 4)
336
reg_r(gspca_dev, 0x00e8, 1);
337
else
338
reg_r(gspca_dev, 0x00e8, length);
339
ptsensor += length;
340
}
341
reg_r(gspca_dev, 0x00e7, 8);
342
}
343
344
static const __u8 cx_inits_176[] = {
345
0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
346
0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
347
0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
348
0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
349
0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
350
0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
351
0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
352
};
353
static const __u8 cx_inits_320[] = {
354
0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
355
0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
356
0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
357
0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
358
0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
359
0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
360
0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
361
};
362
static const __u8 cx_inits_352[] = {
363
0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
364
0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
365
0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
366
0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
367
0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
368
0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
369
0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
370
};
371
static const __u8 cx_inits_640[] = {
372
0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
373
0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
374
0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
375
0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
376
0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
377
0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
378
0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
379
};
380
381
static void cx11646_initsize(struct gspca_dev *gspca_dev)
382
{
383
const __u8 *cxinit;
384
static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
385
static const __u8 reg17[] =
386
{ 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
387
388
switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
389
case 0:
390
cxinit = cx_inits_640;
391
break;
392
case 1:
393
cxinit = cx_inits_352;
394
break;
395
default:
396
/* case 2: */
397
cxinit = cx_inits_320;
398
break;
399
case 3:
400
cxinit = cx_inits_176;
401
break;
402
}
403
reg_w_val(gspca_dev, 0x009a, 0x01);
404
reg_w_val(gspca_dev, 0x0010, 0x10);
405
reg_w(gspca_dev, 0x0012, reg12, 5);
406
reg_w(gspca_dev, 0x0017, reg17, 8);
407
reg_w_val(gspca_dev, 0x00c0, 0x00);
408
reg_w_val(gspca_dev, 0x00c1, 0x04);
409
reg_w_val(gspca_dev, 0x00c2, 0x04);
410
411
reg_w(gspca_dev, 0x0061, cxinit, 8);
412
cxinit += 8;
413
reg_w(gspca_dev, 0x00ca, cxinit, 8);
414
cxinit += 8;
415
reg_w(gspca_dev, 0x00d2, cxinit, 8);
416
cxinit += 8;
417
reg_w(gspca_dev, 0x00da, cxinit, 6);
418
cxinit += 8;
419
reg_w(gspca_dev, 0x0041, cxinit, 8);
420
cxinit += 8;
421
reg_w(gspca_dev, 0x0049, cxinit, 8);
422
cxinit += 8;
423
reg_w(gspca_dev, 0x0051, cxinit, 2);
424
425
reg_r(gspca_dev, 0x0010, 1);
426
}
427
428
static const __u8 cx_jpeg_init[][8] = {
429
{0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */
430
{0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
431
{0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
432
{0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
433
{0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
434
{0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
435
{0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
436
{0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
437
{0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
438
{0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
439
{0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
440
{0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
441
{0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
442
{0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
443
{0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
444
{0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
445
{0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
446
{0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
447
{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
448
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
449
{0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
450
{0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
451
{0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
452
{0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
453
{0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
454
{0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
455
{0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
456
{0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
457
{0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
458
{0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
459
{0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
460
{0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
461
{0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
462
{0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
463
{0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
464
{0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
465
{0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
466
{0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
467
{0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
468
{0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
469
{0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
470
{0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
471
{0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
472
{0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
473
{0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
474
{0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
475
{0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
476
{0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
477
{0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
478
{0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
479
{0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
480
{0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
481
{0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
482
{0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
483
{0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
484
{0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
485
{0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
486
{0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
487
{0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
488
{0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
489
{0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
490
{0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
491
{0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
492
{0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
493
{0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
494
{0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
495
{0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
496
{0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
497
{0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
498
{0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
499
{0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
500
{0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
501
{0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
502
{0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
503
{0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
504
{0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
505
{0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
506
{0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
507
{0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */
508
};
509
510
511
static const __u8 cxjpeg_640[][8] = {
512
{0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */
513
{0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
514
{0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
515
{0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
516
{0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
517
{0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
518
{0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
519
{0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
520
{0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
521
{0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
522
{0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
523
{0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
524
{0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
525
{0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
526
{0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
527
{0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
528
{0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
529
{0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00},
530
{0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
531
{0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
532
{0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
533
{0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF},
534
{0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
535
{0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
536
{0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
537
{0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
538
{0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
539
};
540
static const __u8 cxjpeg_352[][8] = {
541
{0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
542
{0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a},
543
{0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14},
544
{0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17},
545
{0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
546
{0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
547
{0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
548
{0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
549
{0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
550
{0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
551
{0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
552
{0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
553
{0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
554
{0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
555
{0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
556
{0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
557
{0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
558
{0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00},
559
{0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
560
{0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
561
{0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
562
{0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF},
563
{0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
564
{0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
565
{0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
566
{0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
567
{0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
568
};
569
static const __u8 cxjpeg_320[][8] = {
570
{0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
571
{0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
572
{0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
573
{0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
574
{0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
575
{0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
576
{0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
577
{0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
578
{0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
579
{0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
580
{0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
581
{0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
582
{0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
583
{0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
584
{0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
585
{0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
586
{0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
587
{0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00},
588
{0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
589
{0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
590
{0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
591
{0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF},
592
{0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
593
{0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
594
{0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
595
{0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
596
{0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
597
};
598
static const __u8 cxjpeg_176[][8] = {
599
{0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
600
{0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
601
{0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
602
{0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
603
{0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
604
{0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
605
{0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
606
{0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
607
{0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
608
{0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
609
{0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
610
{0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
611
{0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
612
{0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
613
{0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
614
{0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
615
{0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
616
{0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
617
{0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
618
{0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
619
{0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
620
{0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
621
{0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
622
{0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
623
{0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
624
{0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
625
{0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
626
};
627
/* 640 take with the zcx30x part */
628
static const __u8 cxjpeg_qtable[][8] = {
629
{0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
630
{0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
631
{0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
632
{0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
633
{0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
634
{0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
635
{0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
636
{0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
637
{0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
638
{0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
639
{0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32},
640
{0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
641
{0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
642
{0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
643
{0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
644
{0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
645
{0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
646
{0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */
647
};
648
649
650
static void cx11646_jpegInit(struct gspca_dev*gspca_dev)
651
{
652
int i;
653
int length;
654
655
reg_w_val(gspca_dev, 0x00c0, 0x01);
656
reg_w_val(gspca_dev, 0x00c3, 0x00);
657
reg_w_val(gspca_dev, 0x00c0, 0x00);
658
reg_r(gspca_dev, 0x0001, 1);
659
length = 8;
660
for (i = 0; i < 79; i++) {
661
if (i == 78)
662
length = 6;
663
reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length);
664
}
665
reg_r(gspca_dev, 0x0002, 1);
666
reg_w_val(gspca_dev, 0x0055, 0x14);
667
}
668
669
static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
670
static const __u8 regE5_8[] =
671
{ 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
672
static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 };
673
static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 };
674
static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 };
675
static const __u8 reg51[] = { 0x77, 0x03 };
676
#define reg70 0x03
677
678
static void cx11646_jpeg(struct gspca_dev*gspca_dev)
679
{
680
int i;
681
int length;
682
__u8 Reg55;
683
int retry;
684
685
reg_w_val(gspca_dev, 0x00c0, 0x01);
686
reg_w_val(gspca_dev, 0x00c3, 0x00);
687
reg_w_val(gspca_dev, 0x00c0, 0x00);
688
reg_r(gspca_dev, 0x0001, 1);
689
length = 8;
690
switch (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv) {
691
case 0:
692
for (i = 0; i < 27; i++) {
693
if (i == 26)
694
length = 2;
695
reg_w(gspca_dev, 0x0008, cxjpeg_640[i], length);
696
}
697
Reg55 = 0x28;
698
break;
699
case 1:
700
for (i = 0; i < 27; i++) {
701
if (i == 26)
702
length = 2;
703
reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length);
704
}
705
Reg55 = 0x16;
706
break;
707
default:
708
/* case 2: */
709
for (i = 0; i < 27; i++) {
710
if (i == 26)
711
length = 2;
712
reg_w(gspca_dev, 0x0008, cxjpeg_320[i], length);
713
}
714
Reg55 = 0x14;
715
break;
716
case 3:
717
for (i = 0; i < 27; i++) {
718
if (i == 26)
719
length = 2;
720
reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length);
721
}
722
Reg55 = 0x0B;
723
break;
724
}
725
726
reg_r(gspca_dev, 0x0002, 1);
727
reg_w_val(gspca_dev, 0x0055, Reg55);
728
reg_r(gspca_dev, 0x0002, 1);
729
reg_w(gspca_dev, 0x0010, reg10, 2);
730
reg_w_val(gspca_dev, 0x0054, 0x02);
731
reg_w_val(gspca_dev, 0x0054, 0x01);
732
reg_w_val(gspca_dev, 0x0000, 0x94);
733
reg_w_val(gspca_dev, 0x0053, 0xc0);
734
reg_w_val(gspca_dev, 0x00fc, 0xe1);
735
reg_w_val(gspca_dev, 0x0000, 0x00);
736
/* wait for completion */
737
retry = 50;
738
do {
739
reg_r(gspca_dev, 0x0002, 1);
740
/* 0x07 until 0x00 */
741
if (gspca_dev->usb_buf[0] == 0x00)
742
break;
743
reg_w_val(gspca_dev, 0x0053, 0x00);
744
} while (--retry);
745
if (retry == 0)
746
PDEBUG(D_ERR, "Damned Errors sending jpeg Table");
747
/* send the qtable now */
748
reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */
749
length = 8;
750
for (i = 0; i < 18; i++) {
751
if (i == 17)
752
length = 2;
753
reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length);
754
755
}
756
reg_r(gspca_dev, 0x0002, 1); /* 0x00 */
757
reg_r(gspca_dev, 0x0053, 1); /* 0x00 */
758
reg_w_val(gspca_dev, 0x0054, 0x02);
759
reg_w_val(gspca_dev, 0x0054, 0x01);
760
reg_w_val(gspca_dev, 0x0000, 0x94);
761
reg_w_val(gspca_dev, 0x0053, 0xc0);
762
763
reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
764
reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
765
reg_r(gspca_dev, 0x001f, 1); /* 0x38 */
766
reg_w(gspca_dev, 0x0012, reg12, 5);
767
reg_w(gspca_dev, 0x00e5, regE5_8, 8);
768
reg_r(gspca_dev, 0x00e8, 8);
769
reg_w(gspca_dev, 0x00e5, regE5a, 4);
770
reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
771
reg_w_val(gspca_dev, 0x009a, 0x01);
772
reg_w(gspca_dev, 0x00e5, regE5b, 4);
773
reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
774
reg_w(gspca_dev, 0x00e5, regE5c, 4);
775
reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
776
777
reg_w(gspca_dev, 0x0051, reg51, 2);
778
reg_w(gspca_dev, 0x0010, reg10, 2);
779
reg_w_val(gspca_dev, 0x0070, reg70);
780
}
781
782
static void cx11646_init1(struct gspca_dev *gspca_dev)
783
{
784
int i = 0;
785
786
reg_w_val(gspca_dev, 0x0010, 0x00);
787
reg_w_val(gspca_dev, 0x0053, 0x00);
788
reg_w_val(gspca_dev, 0x0052, 0x00);
789
reg_w_val(gspca_dev, 0x009b, 0x2f);
790
reg_w_val(gspca_dev, 0x009c, 0x10);
791
reg_r(gspca_dev, 0x0098, 1);
792
reg_w_val(gspca_dev, 0x0098, 0x40);
793
reg_r(gspca_dev, 0x0099, 1);
794
reg_w_val(gspca_dev, 0x0099, 0x07);
795
reg_w_val(gspca_dev, 0x0039, 0x40);
796
reg_w_val(gspca_dev, 0x003c, 0xff);
797
reg_w_val(gspca_dev, 0x003f, 0x1f);
798
reg_w_val(gspca_dev, 0x003d, 0x40);
799
/* reg_w_val(gspca_dev, 0x003d, 0x60); */
800
reg_r(gspca_dev, 0x0099, 1); /* ->0x07 */
801
802
while (cx_sensor_init[i][0]) {
803
reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]);
804
reg_r(gspca_dev, 0x00e8, 1); /* -> 0x00 */
805
if (i == 1) {
806
reg_w_val(gspca_dev, 0x00ed, 0x01);
807
reg_r(gspca_dev, 0x00ed, 1); /* -> 0x01 */
808
}
809
i++;
810
}
811
reg_w_val(gspca_dev, 0x00c3, 0x00);
812
}
813
814
/* this function is called at probe time */
815
static int sd_config(struct gspca_dev *gspca_dev,
816
const struct usb_device_id *id)
817
{
818
struct sd *sd = (struct sd *) gspca_dev;
819
struct cam *cam;
820
821
cam = &gspca_dev->cam;
822
cam->cam_mode = vga_mode;
823
cam->nmodes = ARRAY_SIZE(vga_mode);
824
825
sd->brightness = BRIGHTNESS_DEF;
826
sd->contrast = CONTRAST_DEF;
827
sd->colors = COLOR_DEF;
828
sd->quality = QUALITY_DEF;
829
return 0;
830
}
831
832
/* this function is called at probe and resume time */
833
static int sd_init(struct gspca_dev *gspca_dev)
834
{
835
cx11646_init1(gspca_dev);
836
cx11646_initsize(gspca_dev);
837
cx11646_fw(gspca_dev);
838
cx_sensor(gspca_dev);
839
cx11646_jpegInit(gspca_dev);
840
return 0;
841
}
842
843
static int sd_start(struct gspca_dev *gspca_dev)
844
{
845
struct sd *sd = (struct sd *) gspca_dev;
846
847
/* create the JPEG header */
848
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
849
0x22); /* JPEG 411 */
850
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
851
852
cx11646_initsize(gspca_dev);
853
cx11646_fw(gspca_dev);
854
cx_sensor(gspca_dev);
855
cx11646_jpeg(gspca_dev);
856
return 0;
857
}
858
859
/* called on streamoff with alt 0 and on disconnect */
860
static void sd_stop0(struct gspca_dev *gspca_dev)
861
{
862
int retry = 50;
863
864
if (!gspca_dev->present)
865
return;
866
reg_w_val(gspca_dev, 0x0000, 0x00);
867
reg_r(gspca_dev, 0x0002, 1);
868
reg_w_val(gspca_dev, 0x0053, 0x00);
869
870
while (retry--) {
871
/* reg_r(gspca_dev, 0x0002, 1);*/
872
reg_r(gspca_dev, 0x0053, 1);
873
if (gspca_dev->usb_buf[0] == 0)
874
break;
875
}
876
reg_w_val(gspca_dev, 0x0000, 0x00);
877
reg_r(gspca_dev, 0x0002, 1);
878
879
reg_w_val(gspca_dev, 0x0010, 0x00);
880
reg_r(gspca_dev, 0x0033, 1);
881
reg_w_val(gspca_dev, 0x00fc, 0xe0);
882
}
883
884
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
885
u8 *data, /* isoc packet */
886
int len) /* iso packet length */
887
{
888
struct sd *sd = (struct sd *) gspca_dev;
889
890
if (data[0] == 0xff && data[1] == 0xd8) {
891
892
/* start of frame */
893
gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
894
895
/* put the JPEG header in the new frame */
896
gspca_frame_add(gspca_dev, FIRST_PACKET,
897
sd->jpeg_hdr, JPEG_HDR_SZ);
898
data += 2;
899
len -= 2;
900
}
901
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
902
}
903
904
static void setbrightness(struct gspca_dev *gspca_dev)
905
{
906
struct sd *sd = (struct sd *) gspca_dev;
907
__u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
908
__u8 reg51c[2];
909
__u8 bright;
910
__u8 colors;
911
912
bright = sd->brightness;
913
regE5cbx[2] = bright;
914
reg_w(gspca_dev, 0x00e5, regE5cbx, 8);
915
reg_r(gspca_dev, 0x00e8, 8);
916
reg_w(gspca_dev, 0x00e5, regE5c, 4);
917
reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
918
919
colors = sd->colors;
920
reg51c[0] = 0x77;
921
reg51c[1] = colors;
922
reg_w(gspca_dev, 0x0051, reg51c, 2);
923
reg_w(gspca_dev, 0x0010, reg10, 2);
924
reg_w_val(gspca_dev, 0x0070, reg70);
925
}
926
927
static void setcontrast(struct gspca_dev *gspca_dev)
928
{
929
struct sd *sd = (struct sd *) gspca_dev;
930
__u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
931
/* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
932
__u8 reg51c[2];
933
934
regE5acx[2] = sd->contrast;
935
reg_w(gspca_dev, 0x00e5, regE5acx, 4);
936
reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
937
reg51c[0] = 0x77;
938
reg51c[1] = sd->colors;
939
reg_w(gspca_dev, 0x0051, reg51c, 2);
940
reg_w(gspca_dev, 0x0010, reg10, 2);
941
reg_w_val(gspca_dev, 0x0070, reg70);
942
}
943
944
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
945
{
946
struct sd *sd = (struct sd *) gspca_dev;
947
948
sd->brightness = val;
949
if (gspca_dev->streaming)
950
setbrightness(gspca_dev);
951
return 0;
952
}
953
954
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
955
{
956
struct sd *sd = (struct sd *) gspca_dev;
957
958
*val = sd->brightness;
959
return 0;
960
}
961
962
static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
963
{
964
struct sd *sd = (struct sd *) gspca_dev;
965
966
sd->contrast = val;
967
if (gspca_dev->streaming)
968
setcontrast(gspca_dev);
969
return 0;
970
}
971
972
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
973
{
974
struct sd *sd = (struct sd *) gspca_dev;
975
976
*val = sd->contrast;
977
return 0;
978
}
979
980
static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
981
{
982
struct sd *sd = (struct sd *) gspca_dev;
983
984
sd->colors = val;
985
if (gspca_dev->streaming) {
986
setbrightness(gspca_dev);
987
setcontrast(gspca_dev);
988
}
989
return 0;
990
}
991
992
static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
993
{
994
struct sd *sd = (struct sd *) gspca_dev;
995
996
*val = sd->colors;
997
return 0;
998
}
999
1000
static int sd_set_jcomp(struct gspca_dev *gspca_dev,
1001
struct v4l2_jpegcompression *jcomp)
1002
{
1003
struct sd *sd = (struct sd *) gspca_dev;
1004
1005
if (jcomp->quality < QUALITY_MIN)
1006
sd->quality = QUALITY_MIN;
1007
else if (jcomp->quality > QUALITY_MAX)
1008
sd->quality = QUALITY_MAX;
1009
else
1010
sd->quality = jcomp->quality;
1011
if (gspca_dev->streaming)
1012
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1013
return 0;
1014
}
1015
1016
static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1017
struct v4l2_jpegcompression *jcomp)
1018
{
1019
struct sd *sd = (struct sd *) gspca_dev;
1020
1021
memset(jcomp, 0, sizeof *jcomp);
1022
jcomp->quality = sd->quality;
1023
jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
1024
| V4L2_JPEG_MARKER_DQT;
1025
return 0;
1026
}
1027
1028
/* sub-driver description */
1029
static const struct sd_desc sd_desc = {
1030
.name = MODULE_NAME,
1031
.ctrls = sd_ctrls,
1032
.nctrls = ARRAY_SIZE(sd_ctrls),
1033
.config = sd_config,
1034
.init = sd_init,
1035
.start = sd_start,
1036
.stop0 = sd_stop0,
1037
.pkt_scan = sd_pkt_scan,
1038
.get_jcomp = sd_get_jcomp,
1039
.set_jcomp = sd_set_jcomp,
1040
};
1041
1042
/* -- module initialisation -- */
1043
static const struct usb_device_id device_table[] = {
1044
{USB_DEVICE(0x0572, 0x0041)},
1045
{}
1046
};
1047
MODULE_DEVICE_TABLE(usb, device_table);
1048
1049
/* -- device connect -- */
1050
static int sd_probe(struct usb_interface *intf,
1051
const struct usb_device_id *id)
1052
{
1053
return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1054
THIS_MODULE);
1055
}
1056
1057
static struct usb_driver sd_driver = {
1058
.name = MODULE_NAME,
1059
.id_table = device_table,
1060
.probe = sd_probe,
1061
.disconnect = gspca_disconnect,
1062
#ifdef CONFIG_PM
1063
.suspend = gspca_suspend,
1064
.resume = gspca_resume,
1065
#endif
1066
};
1067
1068
/* -- module insert / remove -- */
1069
static int __init sd_mod_init(void)
1070
{
1071
return usb_register(&sd_driver);
1072
}
1073
static void __exit sd_mod_exit(void)
1074
{
1075
usb_deregister(&sd_driver);
1076
}
1077
1078
module_init(sd_mod_init);
1079
module_exit(sd_mod_exit);
1080
1081