blob: ba3a28d4f87fcc2cc915f405979dbdd49b9b862b [file] [log] [blame]
Hans de Goedea511ba92009-10-16 07:13:07 -03001/**
2 *
3 * GSPCA sub driver for W996[78]CF JPEG USB Dual Mode Camera Chip.
4 *
5 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
6 *
7 * This module is adapted from the in kernel v4l1 w9968cf driver:
8 *
9 * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27/* Note this is not a stand alone driver, it gets included in ov519.c, this
28 is a bit of a hack, but it needs the driver code for a lot of different
29 ov sensors which is already present in ov519.c (the old v4l1 driver used
30 the ovchipcam framework). When we have the time we really should move
31 the sensor drivers to v4l2 sub drivers, and properly split of this
32 driver from ov519.c */
33
34#define W9968CF_I2C_BUS_DELAY 4 /* delay in us for I2C bit r/w operations */
35
36/* FIXME make this runtime configurable */
37/* Comment/uncomment this for high/low quality of compressed video */
38#define W9968CF_DEC_FAST_LOWQUALITY_VIDEO
39
40#ifdef W9968CF_DEC_FAST_LOWQUALITY_VIDEO
41static const unsigned char Y_QUANTABLE[64] = {
42 16, 11, 10, 16, 24, 40, 51, 61,
43 12, 12, 14, 19, 26, 58, 60, 55,
44 14, 13, 16, 24, 40, 57, 69, 56,
45 14, 17, 22, 29, 51, 87, 80, 62,
46 18, 22, 37, 56, 68, 109, 103, 77,
47 24, 35, 55, 64, 81, 104, 113, 92,
48 49, 64, 78, 87, 103, 121, 120, 101,
49 72, 92, 95, 98, 112, 100, 103, 99
50};
51
52static const unsigned char UV_QUANTABLE[64] = {
53 17, 18, 24, 47, 99, 99, 99, 99,
54 18, 21, 26, 66, 99, 99, 99, 99,
55 24, 26, 56, 99, 99, 99, 99, 99,
56 47, 66, 99, 99, 99, 99, 99, 99,
57 99, 99, 99, 99, 99, 99, 99, 99,
58 99, 99, 99, 99, 99, 99, 99, 99,
59 99, 99, 99, 99, 99, 99, 99, 99,
60 99, 99, 99, 99, 99, 99, 99, 99
61};
62#else
63static const unsigned char Y_QUANTABLE[64] = {
64 8, 5, 5, 8, 12, 20, 25, 30,
65 6, 6, 7, 9, 13, 29, 30, 27,
66 7, 6, 8, 12, 20, 28, 34, 28,
67 7, 8, 11, 14, 25, 43, 40, 31,
68 9, 11, 18, 28, 34, 54, 51, 38,
69 12, 17, 27, 32, 40, 52, 56, 46,
70 24, 32, 39, 43, 51, 60, 60, 50,
71 36, 46, 47, 49, 56, 50, 51, 49
72};
73
74static const unsigned char UV_QUANTABLE[64] = {
75 8, 9, 12, 23, 49, 49, 49, 49,
76 9, 10, 13, 33, 49, 49, 49, 49,
77 12, 13, 28, 49, 49, 49, 49, 49,
78 23, 33, 49, 49, 49, 49, 49, 49,
79 49, 49, 49, 49, 49, 49, 49, 49,
80 49, 49, 49, 49, 49, 49, 49, 49,
81 49, 49, 49, 49, 49, 49, 49, 49,
82 49, 49, 49, 49, 49, 49, 49, 49
83};
84#endif
85
86static const struct v4l2_pix_format w9968cf_vga_mode[] = {
87 {160, 120, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
88 .bytesperline = 160 * 2,
89 .sizeimage = 160 * 120 * 2,
90 .colorspace = V4L2_COLORSPACE_JPEG},
91 {176, 144, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
92 .bytesperline = 176 * 2,
93 .sizeimage = 176 * 144 * 2,
94 .colorspace = V4L2_COLORSPACE_JPEG},
95 {320, 240, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
96 .bytesperline = 320 * 2,
97 .sizeimage = 320 * 240 * 2,
98 .colorspace = V4L2_COLORSPACE_JPEG},
99 {352, 288, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
100 .bytesperline = 352 * 2,
101 .sizeimage = 352 * 288 * 2,
102 .colorspace = V4L2_COLORSPACE_JPEG},
103/* {640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
104 .bytesperline = 640 * 2,
105 .sizeimage = 640 * 480 * 2,
106 .colorspace = V4L2_COLORSPACE_JPEG}, */
107};
108
109static int reg_w(struct sd *sd, __u16 index, __u16 value);
110
111/*--------------------------------------------------------------------------
112 Write 64-bit data to the fast serial bus registers.
113 Return 0 on success, -1 otherwise.
114 --------------------------------------------------------------------------*/
115static int w9968cf_write_fsb(struct sd *sd, u16* data)
116{
117 struct usb_device* udev = sd->gspca_dev.dev;
118 u16 value;
119 int ret;
120
121 value = *data++;
122 memcpy(sd->gspca_dev.usb_buf, data, 6);
123
124 ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
125 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
126 value, 0x06, sd->gspca_dev.usb_buf, 6, 500);
127 if (ret < 0) {
128 PDEBUG(D_ERR, "Write FSB registers failed (%d)", ret);
129 return ret;
130 }
131
132 return 0;
133}
134
135/*--------------------------------------------------------------------------
136 Write data to the serial bus control register.
137 Return 0 on success, a negative number otherwise.
138 --------------------------------------------------------------------------*/
139static int w9968cf_write_sb(struct sd *sd, u16 value)
140{
141 int ret;
142
143 /* We don't use reg_w here, as that would cause all writes when
144 bitbanging i2c to be logged, making the logs impossible to read */
145 ret = usb_control_msg(sd->gspca_dev.dev,
146 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
147 0,
148 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
149 value, 0x01, NULL, 0, 500);
150
151 udelay(W9968CF_I2C_BUS_DELAY);
152
153 if (ret < 0) {
154 PDEBUG(D_ERR, "Write SB reg [01] %04x failed", value);
155 return ret;
156 }
157
158 return 0;
159}
160
161/*--------------------------------------------------------------------------
162 Read data from the serial bus control register.
163 Return 0 on success, a negative number otherwise.
164 --------------------------------------------------------------------------*/
165static int w9968cf_read_sb(struct sd *sd)
166{
167 int ret;
168
169 /* We don't use reg_r here, as the w9968cf is special and has 16
170 bit registers instead of 8 bit */
171 ret = usb_control_msg(sd->gspca_dev.dev,
172 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
173 1,
174 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
175 0, 0x01, sd->gspca_dev.usb_buf, 2, 500);
176 if (ret >= 0)
177 ret = sd->gspca_dev.usb_buf[0] |
178 (sd->gspca_dev.usb_buf[1] << 8);
179 else
180 PDEBUG(D_ERR, "Read SB reg [01] failed");
181
182 udelay(W9968CF_I2C_BUS_DELAY);
183
184 return ret;
185}
186
187/*--------------------------------------------------------------------------
188 Upload quantization tables for the JPEG compression.
189 This function is called by w9968cf_start_transfer().
190 Return 0 on success, a negative number otherwise.
191 --------------------------------------------------------------------------*/
192static int w9968cf_upload_quantizationtables(struct sd *sd)
193{
194 u16 a, b;
195 int ret = 0, i, j;
196
197 ret += reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */
198
199 for (i = 0, j = 0; i < 32; i++, j += 2) {
200 a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8);
201 b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8);
202 ret += reg_w(sd, 0x40+i, a);
203 ret += reg_w(sd, 0x60+i, b);
204 }
205 ret += reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */
206
207 return ret;
208}
209
210/****************************************************************************
211 * Low-level I2C I/O functions. *
212 * The adapter supports the following I2C transfer functions: *
213 * i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only) *
214 * i2c_adap_read_byte_data() *
215 * i2c_adap_read_byte() *
216 ****************************************************************************/
217
218static int w9968cf_smbus_start(struct sd *sd)
219{
220 int ret = 0;
221
222 ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
223 ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
224
225 return ret;
226}
227
228static int w9968cf_smbus_stop(struct sd *sd)
229{
230 int ret = 0;
231
232 ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
233 ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
234 ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
235
236 return ret;
237}
238
239static int w9968cf_smbus_write_byte(struct sd *sd, u8 v)
240{
241 u8 bit;
242 int ret = 0, sda;
243
244 for (bit = 0 ; bit < 8 ; bit++) {
245 sda = (v & 0x80) ? 2 : 0;
246 v <<= 1;
247 /* SDE=1, SDA=sda, SCL=0 */
248 ret += w9968cf_write_sb(sd, 0x10 | sda);
249 /* SDE=1, SDA=sda, SCL=1 */
250 ret += w9968cf_write_sb(sd, 0x11 | sda);
251 /* SDE=1, SDA=sda, SCL=0 */
252 ret += w9968cf_write_sb(sd, 0x10 | sda);
253 }
254
255 return ret;
256}
257
258static int w9968cf_smbus_read_byte(struct sd *sd, u8* v)
259{
260 u8 bit;
261 int ret = 0;
262
263 /* No need to ensure SDA is high as we are always called after
264 read_ack which ends with SDA high */
265 *v = 0;
266 for (bit = 0 ; bit < 8 ; bit++) {
267 *v <<= 1;
268 /* SDE=1, SDA=1, SCL=1 */
269 ret += w9968cf_write_sb(sd, 0x0013);
270 *v |= (w9968cf_read_sb(sd) & 0x0008) ? 1 : 0;
271 /* SDE=1, SDA=1, SCL=0 */
272 ret += w9968cf_write_sb(sd, 0x0012);
273 }
274
275 return ret;
276}
277
278static int w9968cf_smbus_write_nack(struct sd *sd)
279{
280 int ret = 0;
281
282 /* No need to ensure SDA is high as we are always called after
283 read_byte which ends with SDA high */
284 ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
285 ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
286
287 return ret;
288}
289
290static int w9968cf_smbus_read_ack(struct sd *sd)
291{
292 int ret = 0, sda;
293
294 /* Ensure SDA is high before raising clock to avoid a spurious stop */
295 ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
296 ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
297 sda = w9968cf_read_sb(sd);
298 ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
299 if (sda < 0)
300 ret += sda;
301 else if (sda & 0x08) {
302 PDEBUG(D_USBI, "Did not receive i2c ACK");
303 ret += -1;
304 }
305
306 return ret;
307}
308
309/* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
310static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
311{
312 u16* data = (u16 *)sd->gspca_dev.usb_buf;
313 int ret = 0;
314
315 data[0] = 0x082f | ((sd->sensor_addr & 0x80) ? 0x1500 : 0x0);
316 data[0] |= (sd->sensor_addr & 0x40) ? 0x4000 : 0x0;
317 data[1] = 0x2082 | ((sd->sensor_addr & 0x40) ? 0x0005 : 0x0);
318 data[1] |= (sd->sensor_addr & 0x20) ? 0x0150 : 0x0;
319 data[1] |= (sd->sensor_addr & 0x10) ? 0x5400 : 0x0;
320 data[2] = 0x8208 | ((sd->sensor_addr & 0x08) ? 0x0015 : 0x0);
321 data[2] |= (sd->sensor_addr & 0x04) ? 0x0540 : 0x0;
322 data[2] |= (sd->sensor_addr & 0x02) ? 0x5000 : 0x0;
323 data[3] = 0x1d20 | ((sd->sensor_addr & 0x02) ? 0x0001 : 0x0);
324 data[3] |= (sd->sensor_addr & 0x01) ? 0x0054 : 0x0;
325
326 ret += w9968cf_write_fsb(sd, data);
327
328 data[0] = 0x8208 | ((reg & 0x80) ? 0x0015 : 0x0);
329 data[0] |= (reg & 0x40) ? 0x0540 : 0x0;
330 data[0] |= (reg & 0x20) ? 0x5000 : 0x0;
331 data[1] = 0x0820 | ((reg & 0x20) ? 0x0001 : 0x0);
332 data[1] |= (reg & 0x10) ? 0x0054 : 0x0;
333 data[1] |= (reg & 0x08) ? 0x1500 : 0x0;
334 data[1] |= (reg & 0x04) ? 0x4000 : 0x0;
335 data[2] = 0x2082 | ((reg & 0x04) ? 0x0005 : 0x0);
336 data[2] |= (reg & 0x02) ? 0x0150 : 0x0;
337 data[2] |= (reg & 0x01) ? 0x5400 : 0x0;
338 data[3] = 0x001d;
339
340 ret += w9968cf_write_fsb(sd, data);
341
342 data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
343 data[0] |= (value & 0x40) ? 0x0540 : 0x0;
344 data[0] |= (value & 0x20) ? 0x5000 : 0x0;
345 data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0);
346 data[1] |= (value & 0x10) ? 0x0054 : 0x0;
347 data[1] |= (value & 0x08) ? 0x1500 : 0x0;
348 data[1] |= (value & 0x04) ? 0x4000 : 0x0;
349 data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0);
350 data[2] |= (value & 0x02) ? 0x0150 : 0x0;
351 data[2] |= (value & 0x01) ? 0x5400 : 0x0;
352 data[3] = 0xfe1d;
353
354 ret += w9968cf_write_fsb(sd, data);
355
356 if (!ret)
357 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
358 else
359 PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg);
360
361 return ret;
362}
363
364/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
365static int w9968cf_i2c_r(struct sd *sd, u8 reg)
366{
367 int ret = 0;
368 u8 value;
369
370 /* Fast serial bus data control disable */
371 ret += w9968cf_write_sb(sd, 0x0013); /* don't change ! */
372
373 ret += w9968cf_smbus_start(sd);
374 ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr);
375 ret += w9968cf_smbus_read_ack(sd);
376 ret += w9968cf_smbus_write_byte(sd, reg);
377 ret += w9968cf_smbus_read_ack(sd);
378 ret += w9968cf_smbus_stop(sd);
379 ret += w9968cf_smbus_start(sd);
380 ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1);
381 ret += w9968cf_smbus_read_ack(sd);
382 ret += w9968cf_smbus_read_byte(sd, &value);
383 /* signal we don't want to read anymore, the v4l1 driver used to
384 send an ack here which is very wrong! (and then fixed
385 the issues this gave by retrying reads) */
386 ret += w9968cf_smbus_write_nack(sd);
387 ret += w9968cf_smbus_stop(sd);
388
389 /* Fast serial bus data control re-enable */
390 ret += w9968cf_write_sb(sd, 0x0030);
391
392 if (!ret) {
393 ret = value;
394 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
395 } else
396 PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg);
397
398 return ret;
399}
400
401
402/*--------------------------------------------------------------------------
403 Turn on the LED on some webcams. A beep should be heard too.
404 Return 0 on success, a negative number otherwise.
405 --------------------------------------------------------------------------*/
406static int w9968cf_configure(struct sd *sd)
407{
408 int ret = 0;
409
410 ret += reg_w(sd, 0x00, 0xff00); /* power-down */
411 ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */
412 ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */
413 ret += reg_w(sd, 0x01, 0x0010); /* serial bus, SDS high */
414 ret += reg_w(sd, 0x01, 0x0000); /* serial bus, SDS low */
415 ret += reg_w(sd, 0x01, 0x0010); /* ..high 'beep-beep' */
416 ret += reg_w(sd, 0x01, 0x0030); /* Set sda scl to FSB mode */
417
418 if (ret)
419 PDEBUG(D_ERR, "Couldn't turn on the LED");
420
421 sd->stopped = 1;
422
423 return ret;
424}
425
426static int w9968cf_init(struct sd *sd)
427{
428 int ret = 0;
429 unsigned long hw_bufsize = sd->sif ? (352 * 288 * 2) : (640 * 480 * 2),
430 y0 = 0x0000,
431 u0 = y0 + hw_bufsize/2,
432 v0 = u0 + hw_bufsize/4,
433 y1 = v0 + hw_bufsize/4,
434 u1 = y1 + hw_bufsize/2,
435 v1 = u1 + hw_bufsize/4;
436
437 ret += reg_w(sd, 0x00, 0xff00); /* power off */
438 ret += reg_w(sd, 0x00, 0xbf10); /* power on */
439
440 ret += reg_w(sd, 0x03, 0x405d); /* DRAM timings */
441 ret += reg_w(sd, 0x04, 0x0030); /* SDRAM timings */
442
443 ret += reg_w(sd, 0x20, y0 & 0xffff); /* Y buf.0, low */
444 ret += reg_w(sd, 0x21, y0 >> 16); /* Y buf.0, high */
445 ret += reg_w(sd, 0x24, u0 & 0xffff); /* U buf.0, low */
446 ret += reg_w(sd, 0x25, u0 >> 16); /* U buf.0, high */
447 ret += reg_w(sd, 0x28, v0 & 0xffff); /* V buf.0, low */
448 ret += reg_w(sd, 0x29, v0 >> 16); /* V buf.0, high */
449
450 ret += reg_w(sd, 0x22, y1 & 0xffff); /* Y buf.1, low */
451 ret += reg_w(sd, 0x23, y1 >> 16); /* Y buf.1, high */
452 ret += reg_w(sd, 0x26, u1 & 0xffff); /* U buf.1, low */
453 ret += reg_w(sd, 0x27, u1 >> 16); /* U buf.1, high */
454 ret += reg_w(sd, 0x2a, v1 & 0xffff); /* V buf.1, low */
455 ret += reg_w(sd, 0x2b, v1 >> 16); /* V buf.1, high */
456
457 ret += reg_w(sd, 0x32, y1 & 0xffff); /* JPEG buf 0 low */
458 ret += reg_w(sd, 0x33, y1 >> 16); /* JPEG buf 0 high */
459
460 ret += reg_w(sd, 0x34, y1 & 0xffff); /* JPEG buf 1 low */
461 ret += reg_w(sd, 0x35, y1 >> 16); /* JPEG bug 1 high */
462
463 ret += reg_w(sd, 0x36, 0x0000);/* JPEG restart interval */
464 ret += reg_w(sd, 0x37, 0x0804);/*JPEG VLE FIFO threshold*/
465 ret += reg_w(sd, 0x38, 0x0000);/* disable hw up-scaling */
466 ret += reg_w(sd, 0x3f, 0x0000); /* JPEG/MCTL test data */
467
468 return ret;
469}
470
471static int w9968cf_set_crop_window(struct sd *sd)
472{
473 int ret = 0, start_cropx, start_cropy, x, y, fw, fh, cw, ch,
474 max_width, max_height;
475
476 if (sd->sif) {
477 max_width = 352;
478 max_height = 288;
479 } else {
480 max_width = 640;
481 max_height = 480;
482 }
483
484 if (sd->sensor == SEN_OV7620) {
485 /* Sigh, this is dependend on the clock / framerate changes
486 made by the frequency control, sick. */
487 if (sd->freq == 1) {
488 start_cropx = 279;
489 start_cropy = 35;
490 } else {
491 start_cropx = 103;
492 start_cropy = 35;
493 }
494 } else {
495 start_cropx = 320;
496 start_cropy = 35;
497 }
498
499 /* Work around to avoid FP arithmetics */
500 #define SC(x) ((x) << 10)
501
502 /* Scaling factors */
503 fw = SC(sd->gspca_dev.width) / max_width;
504 fh = SC(sd->gspca_dev.height) / max_height;
505
506 cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.width)/fh;
507 ch = (fw >= fh) ? SC(sd->gspca_dev.height)/fw : max_height;
508
509 sd->sensor_width = max_width;
510 sd->sensor_height = max_height;
511
512 x = (max_width - cw) / 2;
513 y = (max_height - ch) / 2;
514
515 ret += reg_w(sd, 0x10, start_cropx + x);
516 ret += reg_w(sd, 0x11, start_cropy + y);
517 ret += reg_w(sd, 0x12, start_cropx + x + cw);
518 ret += reg_w(sd, 0x13, start_cropy + y + ch);
519
520 return ret;
521}
522
523static int w9968cf_mode_init_regs(struct sd *sd)
524{
525 int ret = 0, val, vs_polarity, hs_polarity;
526
527 ret += w9968cf_set_crop_window(sd);
528
529 ret += reg_w(sd, 0x14, sd->gspca_dev.width);
530 ret += reg_w(sd, 0x15, sd->gspca_dev.height);
531
532 /* JPEG width & height */
533 ret += reg_w(sd, 0x30, sd->gspca_dev.width);
534 ret += reg_w(sd, 0x31, sd->gspca_dev.height);
535
536 /* Y & UV frame buffer strides (in WORD) */
537 ret += reg_w(sd, 0x2c, sd->gspca_dev.width);
538
539 ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */
540 ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */
541
542 /* Transfer size */
543 /* FIXME JPEG * 4 ?? */
544 val = sd->gspca_dev.width * sd->gspca_dev.height;
545 ret += reg_w(sd, 0x3d, val & 0xffff); /* low bits */
546 ret += reg_w(sd, 0x3e, val >> 16); /* high bits */
547
548 /* Video Capture Control Register */
549 if (sd->sensor == SEN_OV7620) {
550 /* Seems to work around a bug in the image sensor */
551 vs_polarity = 1;
552 hs_polarity = 1;
553 } else {
554 vs_polarity = 1;
555 hs_polarity = 0;
556 }
557
558 val = (vs_polarity << 12) | (hs_polarity << 11);
559
560 val |= 0x0080; /* Enable HW double buffering */
561
562 /* val |= 0x0020; enable clamping */
563 /* val |= 0x0008; enable (1-2-1) filter */
564 /* val |= 0x000c; enable (2-3-6-3-2) filter */
565
566 val |= 0x8000; /* capt. enable */
567
568 ret += reg_w(sd, 0x16, val);
569
570 sd->gspca_dev.empty_packet = 0;
571
572 return ret;
573}
574
575static void w9968cf_pkt_scan(struct gspca_dev *gspca_dev,
576 struct gspca_frame *frame, /* target */
577 __u8 *data, /* isoc packet */
578 int len) /* iso packet length */
579{
580 /* An empty packet signals EOF */
581 if (gspca_dev->empty_packet) {
582 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
583 data, len);
584 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
585 NULL, 0);
586 gspca_dev->empty_packet = 0;
587 }
588 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
589}