Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/video/gspca/w996Xcf.c
17653 views
1
/**
2
*
3
* GSPCA sub driver for W996[78]CF JPEG USB Dual Mode Camera Chip.
4
*
5
* Copyright (C) 2009 Hans de Goede <[email protected]>
6
*
7
* This module is adapted from the in kernel v4l1 w9968cf driver:
8
*
9
* Copyright (C) 2002-2004 by Luca Risolia <[email protected]>
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
#define Y_QUANTABLE (&sd->jpeg_hdr[JPEG_QT0_OFFSET])
37
#define UV_QUANTABLE (&sd->jpeg_hdr[JPEG_QT1_OFFSET])
38
39
static const struct v4l2_pix_format w9968cf_vga_mode[] = {
40
{160, 120, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
41
.bytesperline = 160 * 2,
42
.sizeimage = 160 * 120 * 2,
43
.colorspace = V4L2_COLORSPACE_JPEG},
44
{176, 144, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
45
.bytesperline = 176 * 2,
46
.sizeimage = 176 * 144 * 2,
47
.colorspace = V4L2_COLORSPACE_JPEG},
48
{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
49
.bytesperline = 320 * 2,
50
.sizeimage = 320 * 240 * 2,
51
.colorspace = V4L2_COLORSPACE_JPEG},
52
{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
53
.bytesperline = 352 * 2,
54
.sizeimage = 352 * 288 * 2,
55
.colorspace = V4L2_COLORSPACE_JPEG},
56
{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
57
.bytesperline = 640 * 2,
58
.sizeimage = 640 * 480 * 2,
59
.colorspace = V4L2_COLORSPACE_JPEG},
60
};
61
62
static void reg_w(struct sd *sd, u16 index, u16 value);
63
64
/*--------------------------------------------------------------------------
65
Write 64-bit data to the fast serial bus registers.
66
Return 0 on success, -1 otherwise.
67
--------------------------------------------------------------------------*/
68
static void w9968cf_write_fsb(struct sd *sd, u16* data)
69
{
70
struct usb_device *udev = sd->gspca_dev.dev;
71
u16 value;
72
int ret;
73
74
if (sd->gspca_dev.usb_err < 0)
75
return;
76
77
value = *data++;
78
memcpy(sd->gspca_dev.usb_buf, data, 6);
79
80
ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
81
USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
82
value, 0x06, sd->gspca_dev.usb_buf, 6, 500);
83
if (ret < 0) {
84
err("Write FSB registers failed (%d)", ret);
85
sd->gspca_dev.usb_err = ret;
86
}
87
}
88
89
/*--------------------------------------------------------------------------
90
Write data to the serial bus control register.
91
Return 0 on success, a negative number otherwise.
92
--------------------------------------------------------------------------*/
93
static void w9968cf_write_sb(struct sd *sd, u16 value)
94
{
95
int ret;
96
97
if (sd->gspca_dev.usb_err < 0)
98
return;
99
100
/* We don't use reg_w here, as that would cause all writes when
101
bitbanging i2c to be logged, making the logs impossible to read */
102
ret = usb_control_msg(sd->gspca_dev.dev,
103
usb_sndctrlpipe(sd->gspca_dev.dev, 0),
104
0,
105
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
106
value, 0x01, NULL, 0, 500);
107
108
udelay(W9968CF_I2C_BUS_DELAY);
109
110
if (ret < 0) {
111
err("Write SB reg [01] %04x failed", value);
112
sd->gspca_dev.usb_err = ret;
113
}
114
}
115
116
/*--------------------------------------------------------------------------
117
Read data from the serial bus control register.
118
Return 0 on success, a negative number otherwise.
119
--------------------------------------------------------------------------*/
120
static int w9968cf_read_sb(struct sd *sd)
121
{
122
int ret;
123
124
if (sd->gspca_dev.usb_err < 0)
125
return -1;
126
127
/* We don't use reg_r here, as the w9968cf is special and has 16
128
bit registers instead of 8 bit */
129
ret = usb_control_msg(sd->gspca_dev.dev,
130
usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
131
1,
132
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
133
0, 0x01, sd->gspca_dev.usb_buf, 2, 500);
134
if (ret >= 0) {
135
ret = sd->gspca_dev.usb_buf[0] |
136
(sd->gspca_dev.usb_buf[1] << 8);
137
} else {
138
err("Read SB reg [01] failed");
139
sd->gspca_dev.usb_err = ret;
140
}
141
142
udelay(W9968CF_I2C_BUS_DELAY);
143
144
return ret;
145
}
146
147
/*--------------------------------------------------------------------------
148
Upload quantization tables for the JPEG compression.
149
This function is called by w9968cf_start_transfer().
150
Return 0 on success, a negative number otherwise.
151
--------------------------------------------------------------------------*/
152
static void w9968cf_upload_quantizationtables(struct sd *sd)
153
{
154
u16 a, b;
155
int i, j;
156
157
reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */
158
159
for (i = 0, j = 0; i < 32; i++, j += 2) {
160
a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j + 1]) << 8);
161
b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j + 1]) << 8);
162
reg_w(sd, 0x40 + i, a);
163
reg_w(sd, 0x60 + i, b);
164
}
165
reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */
166
}
167
168
/****************************************************************************
169
* Low-level I2C I/O functions. *
170
* The adapter supports the following I2C transfer functions: *
171
* i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only) *
172
* i2c_adap_read_byte_data() *
173
* i2c_adap_read_byte() *
174
****************************************************************************/
175
176
static void w9968cf_smbus_start(struct sd *sd)
177
{
178
w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
179
w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
180
}
181
182
static void w9968cf_smbus_stop(struct sd *sd)
183
{
184
w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
185
w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
186
w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
187
}
188
189
static void w9968cf_smbus_write_byte(struct sd *sd, u8 v)
190
{
191
u8 bit;
192
int sda;
193
194
for (bit = 0 ; bit < 8 ; bit++) {
195
sda = (v & 0x80) ? 2 : 0;
196
v <<= 1;
197
/* SDE=1, SDA=sda, SCL=0 */
198
w9968cf_write_sb(sd, 0x10 | sda);
199
/* SDE=1, SDA=sda, SCL=1 */
200
w9968cf_write_sb(sd, 0x11 | sda);
201
/* SDE=1, SDA=sda, SCL=0 */
202
w9968cf_write_sb(sd, 0x10 | sda);
203
}
204
}
205
206
static void w9968cf_smbus_read_byte(struct sd *sd, u8 *v)
207
{
208
u8 bit;
209
210
/* No need to ensure SDA is high as we are always called after
211
read_ack which ends with SDA high */
212
*v = 0;
213
for (bit = 0 ; bit < 8 ; bit++) {
214
*v <<= 1;
215
/* SDE=1, SDA=1, SCL=1 */
216
w9968cf_write_sb(sd, 0x0013);
217
*v |= (w9968cf_read_sb(sd) & 0x0008) ? 1 : 0;
218
/* SDE=1, SDA=1, SCL=0 */
219
w9968cf_write_sb(sd, 0x0012);
220
}
221
}
222
223
static void w9968cf_smbus_write_nack(struct sd *sd)
224
{
225
/* No need to ensure SDA is high as we are always called after
226
read_byte which ends with SDA high */
227
w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
228
w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
229
}
230
231
static void w9968cf_smbus_read_ack(struct sd *sd)
232
{
233
int sda;
234
235
/* Ensure SDA is high before raising clock to avoid a spurious stop */
236
w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
237
w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
238
sda = w9968cf_read_sb(sd);
239
w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
240
if (sda >= 0 && (sda & 0x08)) {
241
PDEBUG(D_USBI, "Did not receive i2c ACK");
242
sd->gspca_dev.usb_err = -EIO;
243
}
244
}
245
246
/* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
247
static void w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
248
{
249
u16* data = (u16 *)sd->gspca_dev.usb_buf;
250
251
data[0] = 0x082f | ((sd->sensor_addr & 0x80) ? 0x1500 : 0x0);
252
data[0] |= (sd->sensor_addr & 0x40) ? 0x4000 : 0x0;
253
data[1] = 0x2082 | ((sd->sensor_addr & 0x40) ? 0x0005 : 0x0);
254
data[1] |= (sd->sensor_addr & 0x20) ? 0x0150 : 0x0;
255
data[1] |= (sd->sensor_addr & 0x10) ? 0x5400 : 0x0;
256
data[2] = 0x8208 | ((sd->sensor_addr & 0x08) ? 0x0015 : 0x0);
257
data[2] |= (sd->sensor_addr & 0x04) ? 0x0540 : 0x0;
258
data[2] |= (sd->sensor_addr & 0x02) ? 0x5000 : 0x0;
259
data[3] = 0x1d20 | ((sd->sensor_addr & 0x02) ? 0x0001 : 0x0);
260
data[3] |= (sd->sensor_addr & 0x01) ? 0x0054 : 0x0;
261
262
w9968cf_write_fsb(sd, data);
263
264
data[0] = 0x8208 | ((reg & 0x80) ? 0x0015 : 0x0);
265
data[0] |= (reg & 0x40) ? 0x0540 : 0x0;
266
data[0] |= (reg & 0x20) ? 0x5000 : 0x0;
267
data[1] = 0x0820 | ((reg & 0x20) ? 0x0001 : 0x0);
268
data[1] |= (reg & 0x10) ? 0x0054 : 0x0;
269
data[1] |= (reg & 0x08) ? 0x1500 : 0x0;
270
data[1] |= (reg & 0x04) ? 0x4000 : 0x0;
271
data[2] = 0x2082 | ((reg & 0x04) ? 0x0005 : 0x0);
272
data[2] |= (reg & 0x02) ? 0x0150 : 0x0;
273
data[2] |= (reg & 0x01) ? 0x5400 : 0x0;
274
data[3] = 0x001d;
275
276
w9968cf_write_fsb(sd, data);
277
278
data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
279
data[0] |= (value & 0x40) ? 0x0540 : 0x0;
280
data[0] |= (value & 0x20) ? 0x5000 : 0x0;
281
data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0);
282
data[1] |= (value & 0x10) ? 0x0054 : 0x0;
283
data[1] |= (value & 0x08) ? 0x1500 : 0x0;
284
data[1] |= (value & 0x04) ? 0x4000 : 0x0;
285
data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0);
286
data[2] |= (value & 0x02) ? 0x0150 : 0x0;
287
data[2] |= (value & 0x01) ? 0x5400 : 0x0;
288
data[3] = 0xfe1d;
289
290
w9968cf_write_fsb(sd, data);
291
292
PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
293
}
294
295
/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
296
static int w9968cf_i2c_r(struct sd *sd, u8 reg)
297
{
298
int ret = 0;
299
u8 value;
300
301
/* Fast serial bus data control disable */
302
w9968cf_write_sb(sd, 0x0013); /* don't change ! */
303
304
w9968cf_smbus_start(sd);
305
w9968cf_smbus_write_byte(sd, sd->sensor_addr);
306
w9968cf_smbus_read_ack(sd);
307
w9968cf_smbus_write_byte(sd, reg);
308
w9968cf_smbus_read_ack(sd);
309
w9968cf_smbus_stop(sd);
310
w9968cf_smbus_start(sd);
311
w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1);
312
w9968cf_smbus_read_ack(sd);
313
w9968cf_smbus_read_byte(sd, &value);
314
/* signal we don't want to read anymore, the v4l1 driver used to
315
send an ack here which is very wrong! (and then fixed
316
the issues this gave by retrying reads) */
317
w9968cf_smbus_write_nack(sd);
318
w9968cf_smbus_stop(sd);
319
320
/* Fast serial bus data control re-enable */
321
w9968cf_write_sb(sd, 0x0030);
322
323
if (sd->gspca_dev.usb_err >= 0) {
324
ret = value;
325
PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
326
} else
327
PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg);
328
329
return ret;
330
}
331
332
/*--------------------------------------------------------------------------
333
Turn on the LED on some webcams. A beep should be heard too.
334
Return 0 on success, a negative number otherwise.
335
--------------------------------------------------------------------------*/
336
static void w9968cf_configure(struct sd *sd)
337
{
338
reg_w(sd, 0x00, 0xff00); /* power-down */
339
reg_w(sd, 0x00, 0xbf17); /* reset everything */
340
reg_w(sd, 0x00, 0xbf10); /* normal operation */
341
reg_w(sd, 0x01, 0x0010); /* serial bus, SDS high */
342
reg_w(sd, 0x01, 0x0000); /* serial bus, SDS low */
343
reg_w(sd, 0x01, 0x0010); /* ..high 'beep-beep' */
344
reg_w(sd, 0x01, 0x0030); /* Set sda scl to FSB mode */
345
346
sd->stopped = 1;
347
}
348
349
static void w9968cf_init(struct sd *sd)
350
{
351
unsigned long hw_bufsize = sd->sif ? (352 * 288 * 2) : (640 * 480 * 2),
352
y0 = 0x0000,
353
u0 = y0 + hw_bufsize / 2,
354
v0 = u0 + hw_bufsize / 4,
355
y1 = v0 + hw_bufsize / 4,
356
u1 = y1 + hw_bufsize / 2,
357
v1 = u1 + hw_bufsize / 4;
358
359
reg_w(sd, 0x00, 0xff00); /* power off */
360
reg_w(sd, 0x00, 0xbf10); /* power on */
361
362
reg_w(sd, 0x03, 0x405d); /* DRAM timings */
363
reg_w(sd, 0x04, 0x0030); /* SDRAM timings */
364
365
reg_w(sd, 0x20, y0 & 0xffff); /* Y buf.0, low */
366
reg_w(sd, 0x21, y0 >> 16); /* Y buf.0, high */
367
reg_w(sd, 0x24, u0 & 0xffff); /* U buf.0, low */
368
reg_w(sd, 0x25, u0 >> 16); /* U buf.0, high */
369
reg_w(sd, 0x28, v0 & 0xffff); /* V buf.0, low */
370
reg_w(sd, 0x29, v0 >> 16); /* V buf.0, high */
371
372
reg_w(sd, 0x22, y1 & 0xffff); /* Y buf.1, low */
373
reg_w(sd, 0x23, y1 >> 16); /* Y buf.1, high */
374
reg_w(sd, 0x26, u1 & 0xffff); /* U buf.1, low */
375
reg_w(sd, 0x27, u1 >> 16); /* U buf.1, high */
376
reg_w(sd, 0x2a, v1 & 0xffff); /* V buf.1, low */
377
reg_w(sd, 0x2b, v1 >> 16); /* V buf.1, high */
378
379
reg_w(sd, 0x32, y1 & 0xffff); /* JPEG buf 0 low */
380
reg_w(sd, 0x33, y1 >> 16); /* JPEG buf 0 high */
381
382
reg_w(sd, 0x34, y1 & 0xffff); /* JPEG buf 1 low */
383
reg_w(sd, 0x35, y1 >> 16); /* JPEG bug 1 high */
384
385
reg_w(sd, 0x36, 0x0000);/* JPEG restart interval */
386
reg_w(sd, 0x37, 0x0804);/*JPEG VLE FIFO threshold*/
387
reg_w(sd, 0x38, 0x0000);/* disable hw up-scaling */
388
reg_w(sd, 0x3f, 0x0000); /* JPEG/MCTL test data */
389
}
390
391
static void w9968cf_set_crop_window(struct sd *sd)
392
{
393
int start_cropx, start_cropy, x, y, fw, fh, cw, ch,
394
max_width, max_height;
395
396
if (sd->sif) {
397
max_width = 352;
398
max_height = 288;
399
} else {
400
max_width = 640;
401
max_height = 480;
402
}
403
404
if (sd->sensor == SEN_OV7620) {
405
/* Sigh, this is dependend on the clock / framerate changes
406
made by the frequency control, sick. */
407
if (sd->ctrls[FREQ].val == 1) {
408
start_cropx = 277;
409
start_cropy = 37;
410
} else {
411
start_cropx = 105;
412
start_cropy = 37;
413
}
414
} else {
415
start_cropx = 320;
416
start_cropy = 35;
417
}
418
419
/* Work around to avoid FP arithmetics */
420
#define SC(x) ((x) << 10)
421
422
/* Scaling factors */
423
fw = SC(sd->gspca_dev.width) / max_width;
424
fh = SC(sd->gspca_dev.height) / max_height;
425
426
cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.width) / fh;
427
ch = (fw >= fh) ? SC(sd->gspca_dev.height) / fw : max_height;
428
429
sd->sensor_width = max_width;
430
sd->sensor_height = max_height;
431
432
x = (max_width - cw) / 2;
433
y = (max_height - ch) / 2;
434
435
reg_w(sd, 0x10, start_cropx + x);
436
reg_w(sd, 0x11, start_cropy + y);
437
reg_w(sd, 0x12, start_cropx + x + cw);
438
reg_w(sd, 0x13, start_cropy + y + ch);
439
}
440
441
static void w9968cf_mode_init_regs(struct sd *sd)
442
{
443
int val, vs_polarity, hs_polarity;
444
445
w9968cf_set_crop_window(sd);
446
447
reg_w(sd, 0x14, sd->gspca_dev.width);
448
reg_w(sd, 0x15, sd->gspca_dev.height);
449
450
/* JPEG width & height */
451
reg_w(sd, 0x30, sd->gspca_dev.width);
452
reg_w(sd, 0x31, sd->gspca_dev.height);
453
454
/* Y & UV frame buffer strides (in WORD) */
455
if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
456
V4L2_PIX_FMT_JPEG) {
457
reg_w(sd, 0x2c, sd->gspca_dev.width / 2);
458
reg_w(sd, 0x2d, sd->gspca_dev.width / 4);
459
} else
460
reg_w(sd, 0x2c, sd->gspca_dev.width);
461
462
reg_w(sd, 0x00, 0xbf17); /* reset everything */
463
reg_w(sd, 0x00, 0xbf10); /* normal operation */
464
465
/* Transfer size in WORDS (for UYVY format only) */
466
val = sd->gspca_dev.width * sd->gspca_dev.height;
467
reg_w(sd, 0x3d, val & 0xffff); /* low bits */
468
reg_w(sd, 0x3e, val >> 16); /* high bits */
469
470
if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
471
V4L2_PIX_FMT_JPEG) {
472
/* We may get called multiple times (usb isoc bw negotiat.) */
473
jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height,
474
sd->gspca_dev.width, 0x22); /* JPEG 420 */
475
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
476
w9968cf_upload_quantizationtables(sd);
477
}
478
479
/* Video Capture Control Register */
480
if (sd->sensor == SEN_OV7620) {
481
/* Seems to work around a bug in the image sensor */
482
vs_polarity = 1;
483
hs_polarity = 1;
484
} else {
485
vs_polarity = 1;
486
hs_polarity = 0;
487
}
488
489
val = (vs_polarity << 12) | (hs_polarity << 11);
490
491
/* NOTE: We may not have enough memory to do double buffering while
492
doing compression (amount of memory differs per model cam).
493
So we use the second image buffer also as jpeg stream buffer
494
(see w9968cf_init), and disable double buffering. */
495
if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
496
V4L2_PIX_FMT_JPEG) {
497
/* val |= 0x0002; YUV422P */
498
val |= 0x0003; /* YUV420P */
499
} else
500
val |= 0x0080; /* Enable HW double buffering */
501
502
/* val |= 0x0020; enable clamping */
503
/* val |= 0x0008; enable (1-2-1) filter */
504
/* val |= 0x000c; enable (2-3-6-3-2) filter */
505
506
val |= 0x8000; /* capt. enable */
507
508
reg_w(sd, 0x16, val);
509
510
sd->gspca_dev.empty_packet = 0;
511
}
512
513
static void w9968cf_stop0(struct sd *sd)
514
{
515
reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */
516
reg_w(sd, 0x16, 0x0000); /* stop video capture */
517
}
518
519
/* The w9968cf docs say that a 0 sized packet means EOF (and also SOF
520
for the next frame). This seems to simply not be true when operating
521
in JPEG mode, in this case there may be empty packets within the
522
frame. So in JPEG mode use the JPEG SOI marker to detect SOF.
523
524
Note to make things even more interesting the w9968cf sends *PLANAR* jpeg,
525
to be precise it sends: SOI, SOF, DRI, SOS, Y-data, SOS, U-data, SOS,
526
V-data, EOI. */
527
static void w9968cf_pkt_scan(struct gspca_dev *gspca_dev,
528
u8 *data, /* isoc packet */
529
int len) /* iso packet length */
530
{
531
struct sd *sd = (struct sd *) gspca_dev;
532
533
if (w9968cf_vga_mode[gspca_dev->curr_mode].pixelformat ==
534
V4L2_PIX_FMT_JPEG) {
535
if (len >= 2 &&
536
data[0] == 0xff &&
537
data[1] == 0xd8) {
538
gspca_frame_add(gspca_dev, LAST_PACKET,
539
NULL, 0);
540
gspca_frame_add(gspca_dev, FIRST_PACKET,
541
sd->jpeg_hdr, JPEG_HDR_SZ);
542
/* Strip the ff d8, our own header (which adds
543
huffman and quantization tables) already has this */
544
len -= 2;
545
data += 2;
546
}
547
} else {
548
/* In UYVY mode an empty packet signals EOF */
549
if (gspca_dev->empty_packet) {
550
gspca_frame_add(gspca_dev, LAST_PACKET,
551
NULL, 0);
552
gspca_frame_add(gspca_dev, FIRST_PACKET,
553
NULL, 0);
554
gspca_dev->empty_packet = 0;
555
}
556
}
557
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
558
}
559
560